Express frameworks docs + CLI (#512)
* Manual setup docs * Added the onboarding * The emails package now works with Node > 18 * Added CLi support for Express, including custom init command finished messages * Need to actually log out the installation complete message… * Fix for an old Remix reference * Renamed the page export * Use resolvedOptions.triggerUrl * Typo in manual instructions
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@trigger.dev/cli": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Added Express support to the CLI
|
||||||
@@ -51,7 +51,7 @@ export function FrameworkSelector() {
|
|||||||
<FrameworkLink to={projectSetupNextjsPath(organization, project)} supported>
|
<FrameworkLink to={projectSetupNextjsPath(organization, project)} supported>
|
||||||
<NextjsLogo className="w-32" />
|
<NextjsLogo className="w-32" />
|
||||||
</FrameworkLink>
|
</FrameworkLink>
|
||||||
<FrameworkLink to={projectSetupExpressPath(organization, project)}>
|
<FrameworkLink to={projectSetupExpressPath(organization, project)} supported>
|
||||||
<ExpressLogo className="w-36" />
|
<ExpressLogo className="w-36" />
|
||||||
</FrameworkLink>
|
</FrameworkLink>
|
||||||
<FrameworkLink to={projectSetupRemixPath(organization, project)} supported>
|
<FrameworkLink to={projectSetupRemixPath(organization, project)} supported>
|
||||||
|
|||||||
+105
-10
@@ -1,21 +1,116 @@
|
|||||||
import { ExpressLogo } from "~/assets/logos/ExpressLogo";
|
import { ChatBubbleLeftRightIcon, Squares2X2Icon } from "@heroicons/react/20/solid";
|
||||||
import { FrameworkComingSoon } from "~/components/frameworks/FrameworkComingSoon";
|
import invariant from "tiny-invariant";
|
||||||
|
import { Feedback } from "~/components/Feedback";
|
||||||
|
import { PageGradient } from "~/components/PageGradient";
|
||||||
|
import { InitCommand, RunDevCommand, TriggerDevStep } from "~/components/SetupCommands";
|
||||||
|
import { StepContentContainer } from "~/components/StepContentContainer";
|
||||||
|
import { InlineCode } from "~/components/code/InlineCode";
|
||||||
import { BreadcrumbLink } from "~/components/navigation/NavBar";
|
import { BreadcrumbLink } from "~/components/navigation/NavBar";
|
||||||
|
import { Badge } from "~/components/primitives/Badge";
|
||||||
|
import { Button, LinkButton } from "~/components/primitives/Buttons";
|
||||||
|
import { Callout } from "~/components/primitives/Callout";
|
||||||
|
import { ClipboardField } from "~/components/primitives/ClipboardField";
|
||||||
|
import { Header1 } from "~/components/primitives/Headers";
|
||||||
|
import { Paragraph } from "~/components/primitives/Paragraph";
|
||||||
|
import { StepNumber } from "~/components/primitives/StepNumber";
|
||||||
|
import { useAppOrigin } from "~/hooks/useAppOrigin";
|
||||||
|
import { useDevEnvironment } from "~/hooks/useEnvironments";
|
||||||
|
import { useOrganization } from "~/hooks/useOrganizations";
|
||||||
|
import { useProject } from "~/hooks/useProject";
|
||||||
|
import { useProjectSetupComplete } from "~/hooks/useProjectSetupComplete";
|
||||||
import { Handle } from "~/utils/handle";
|
import { Handle } from "~/utils/handle";
|
||||||
import { trimTrailingSlash } from "~/utils/pathBuilder";
|
import { projectSetupPath, trimTrailingSlash } from "~/utils/pathBuilder";
|
||||||
|
|
||||||
export const handle: Handle = {
|
export const handle: Handle = {
|
||||||
breadcrumb: (match) => <BreadcrumbLink to={trimTrailingSlash(match.pathname)} title="Express" />,
|
breadcrumb: (match) => <BreadcrumbLink to={trimTrailingSlash(match.pathname)} title="Express" />,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
const organization = useOrganization();
|
||||||
|
const project = useProject();
|
||||||
|
useProjectSetupComplete();
|
||||||
|
const devEnvironment = useDevEnvironment();
|
||||||
|
invariant(devEnvironment, "Dev environment must be defined");
|
||||||
|
const appOrigin = useAppOrigin();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FrameworkComingSoon
|
<PageGradient>
|
||||||
frameworkName="Express"
|
<div className="mx-auto max-w-3xl">
|
||||||
githubIssueUrl="https://github.com/triggerdotdev/trigger.dev/issues/451"
|
<div className="flex items-center justify-between">
|
||||||
githubIssueNumber={451}
|
<Header1 spacing className="text-bright">
|
||||||
>
|
Get setup in 5 minutes
|
||||||
<ExpressLogo className="w-56" />
|
</Header1>
|
||||||
</FrameworkComingSoon>
|
<div className="flex items-center gap-2">
|
||||||
|
<LinkButton
|
||||||
|
to={projectSetupPath(organization, project)}
|
||||||
|
variant="tertiary/small"
|
||||||
|
LeadingIcon={Squares2X2Icon}
|
||||||
|
>
|
||||||
|
Choose a different framework
|
||||||
|
</LinkButton>
|
||||||
|
<Feedback
|
||||||
|
button={
|
||||||
|
<Button variant="tertiary/small" LeadingIcon={ChatBubbleLeftRightIcon}>
|
||||||
|
I'm stuck!
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
defaultValue="help"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Callout
|
||||||
|
variant={"info"}
|
||||||
|
to="https://github.com/triggerdotdev/trigger.dev/discussions/430"
|
||||||
|
className="mb-8"
|
||||||
|
>
|
||||||
|
Trigger.dev has full support for serverless. We will be adding support for long-running
|
||||||
|
servers soon.
|
||||||
|
</Callout>
|
||||||
|
<div>
|
||||||
|
<StepNumber
|
||||||
|
stepNumber="1"
|
||||||
|
title="Manually set up Trigger.dev in your existing Express project"
|
||||||
|
/>
|
||||||
|
<StepContentContainer className="flex flex-col gap-2">
|
||||||
|
<Paragraph className="mt-2">Copy your server API Key to your clipboard:</Paragraph>
|
||||||
|
<div className="mb-2 flex w-full items-center justify-between">
|
||||||
|
<ClipboardField
|
||||||
|
secure
|
||||||
|
className="w-fit"
|
||||||
|
value={devEnvironment.apiKey}
|
||||||
|
variant={"secondary/medium"}
|
||||||
|
icon={<Badge variant="outline">Server</Badge>}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Paragraph>Now follow this guide:</Paragraph>
|
||||||
|
<LinkButton
|
||||||
|
to="https://trigger.dev/docs/documentation/guides/manual/express"
|
||||||
|
variant="primary/medium"
|
||||||
|
TrailingIcon="external-link"
|
||||||
|
>
|
||||||
|
Manual installation guide
|
||||||
|
</LinkButton>
|
||||||
|
</StepContentContainer>
|
||||||
|
<StepNumber stepNumber="2" title="Run your Express app" />
|
||||||
|
<StepContentContainer>
|
||||||
|
<RunDevCommand />
|
||||||
|
<Callout variant="info">
|
||||||
|
You may be using the `start` script instead, in which case substitute `dev` in the
|
||||||
|
above commands.
|
||||||
|
</Callout>
|
||||||
|
</StepContentContainer>
|
||||||
|
<StepNumber stepNumber="3" title="Run the CLI 'dev' command" />
|
||||||
|
<StepContentContainer>
|
||||||
|
<TriggerDevStep />
|
||||||
|
</StepContentContainer>
|
||||||
|
<StepNumber stepNumber="6" title="Wait for Jobs" displaySpinner />
|
||||||
|
<StepContentContainer>
|
||||||
|
<Paragraph>This page will automatically refresh.</Paragraph>
|
||||||
|
</StepContentContainer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PageGradient>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,193 @@
|
|||||||
We're in the process of building support for the Express framework. You can follow along with progress or contribute via [this GitHub issue](https://github.com/triggerdotdev/trigger.dev/issues).
|
## Installing Required Packages
|
||||||
|
|
||||||
|
Start by installing the necessary packages in your Express.js project directory. You can use npm, pnpm, or yarn as your package manager.
|
||||||
|
|
||||||
|
<CodeGroup>
|
||||||
|
|
||||||
|
```bash npm
|
||||||
|
npm install @trigger.dev/sdk @trigger.dev/express
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash pnpm
|
||||||
|
pnpm install @trigger.dev/sdk @trigger.dev/express
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash yarn
|
||||||
|
yarn add @trigger.dev/sdk @trigger.dev/express
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeGroup>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<Note>Ensure that you execute this command within a Express project.</Note>
|
||||||
|
|
||||||
|
## Obtaining the Development Server API Key
|
||||||
|
|
||||||
|
To locate your development Server API key, login to the [Trigger.dev
|
||||||
|
dashboard](https://cloud.trigger.dev) and select the Project you want to
|
||||||
|
connect to. Then click on the Environments & API Keys tab in the left menu.
|
||||||
|
You can copy your development Server API Key from the field at the top of this page.
|
||||||
|
(Your development key will start with `tr_dev_`).
|
||||||
|
|
||||||
|
## Adding Environment Variables
|
||||||
|
|
||||||
|
Create a `.env` file at the root of your project and include your Trigger API key and URL like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
TRIGGER_API_KEY=ENTER_YOUR_DEVELOPMENT_API_KEY_HERE
|
||||||
|
TRIGGER_API_URL=https://api.trigger.dev # this is only necessary if you are self-hosting
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `ENTER_YOUR_DEVELOPMENT_API_KEY_HERE` with the actual API key obtained from the previous step.
|
||||||
|
|
||||||
|
## Configuring the Trigger Client
|
||||||
|
|
||||||
|
Create a file for your Trigger client, in this case we create it at `<root>/trigger.(ts/js)`
|
||||||
|
|
||||||
|
```ts trigger.(ts/js)
|
||||||
|
import { TriggerClient } from "@trigger.dev/sdk";
|
||||||
|
|
||||||
|
export const client = new TriggerClient({
|
||||||
|
id: "my-app",
|
||||||
|
apiKey: process.env.TRIGGER_API_KEY!,
|
||||||
|
apiUrl: process.env.TRIGGER_API_URL!,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace **"my-app"** with an appropriate identifier for your project.
|
||||||
|
|
||||||
|
## Adding the API endpoint
|
||||||
|
|
||||||
|
There are a few different options depending on how your Express project is configured.
|
||||||
|
|
||||||
|
- App middleware
|
||||||
|
- Entire app for Trigger.dev (only relevant if it's the only thing your project is for)
|
||||||
|
|
||||||
|
Select the appropriate code example from below:
|
||||||
|
|
||||||
|
<CodeGroup>
|
||||||
|
|
||||||
|
```typescript app middleware
|
||||||
|
//import the client from the other file
|
||||||
|
import { client } from "./trigger";
|
||||||
|
import { createMiddleware } from "@trigger.dev/express";
|
||||||
|
|
||||||
|
//import your job files
|
||||||
|
import "./jobs/example";
|
||||||
|
|
||||||
|
//..your existing Express code
|
||||||
|
const app: Express = express();
|
||||||
|
|
||||||
|
//add the middleware
|
||||||
|
app.use(createMiddleware(client));
|
||||||
|
|
||||||
|
//..the rest of your Express code
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript entire app
|
||||||
|
//if the entire app is just for Trigger.dev
|
||||||
|
import { client } from "./trigger";
|
||||||
|
import { createExpressServer } from "@trigger.dev/express";
|
||||||
|
|
||||||
|
//import your job files
|
||||||
|
import "./jobs/example";
|
||||||
|
|
||||||
|
//this creates an app
|
||||||
|
createExpressServer(client);
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeGroup>
|
||||||
|
|
||||||
|
## Creating the Example Job
|
||||||
|
|
||||||
|
Create a Job file. In this case created `<root>/jobs/example.(ts/js)`
|
||||||
|
|
||||||
|
```typescript jobs/example.(ts/js)
|
||||||
|
import { eventTrigger } from "@trigger.dev/sdk";
|
||||||
|
import { client } from "../trigger";
|
||||||
|
|
||||||
|
// your first job
|
||||||
|
client.defineJob({
|
||||||
|
id: "example-job",
|
||||||
|
name: "Example Job",
|
||||||
|
version: "0.0.1",
|
||||||
|
trigger: eventTrigger({
|
||||||
|
name: "example.event",
|
||||||
|
}),
|
||||||
|
run: async (payload, io, ctx) => {
|
||||||
|
await io.logger.info("Hello world!", { payload });
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: "Hello world!",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding Configuration to `package.json`
|
||||||
|
|
||||||
|
Inside the `package.json` file, add the following configuration under the root object:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"trigger.dev": {
|
||||||
|
"endpointId": "my-app"
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace **"my-app"** with the appropriate identifier you used in the trigger.js configuration file.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
### Run your Express app
|
||||||
|
|
||||||
|
Run your Express app locally, like you normally would. For example:
|
||||||
|
|
||||||
|
<CodeGroup>
|
||||||
|
|
||||||
|
```bash npm
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash pnpm
|
||||||
|
pnpm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash yarn
|
||||||
|
yarn run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeGroup>
|
||||||
|
|
||||||
|
<Note>You might use `npm run start` instead of dev</Note>
|
||||||
|
|
||||||
|
### Run the CLI 'dev' command
|
||||||
|
|
||||||
|
In a **_separate terminal window or tab_** run:
|
||||||
|
|
||||||
|
<CodeGroup>
|
||||||
|
|
||||||
|
```bash npm
|
||||||
|
npx @trigger.dev/cli@latest dev
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash pnpm
|
||||||
|
pnpm dlx @trigger.dev/cli@latest dev
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash yarn
|
||||||
|
yarn dlx @trigger.dev/cli@latest dev
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeGroup>
|
||||||
|
<br />
|
||||||
|
<Note>
|
||||||
|
You can optionally pass the port if you're not running on 3000 by adding
|
||||||
|
`--port 3001` to the end
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
You can optionally pass the hostname if you're not running on localhost by adding
|
||||||
|
`--hostname <host>`. Example, in case your Express is running on 0.0.0.0: `--hostname 0.0.0.0`.
|
||||||
|
</Note>
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/degit": "^2.8.3",
|
"@types/degit": "^2.8.3",
|
||||||
|
"boxen": "^7.1.1",
|
||||||
"chalk": "^5.2.0",
|
"chalk": "^5.2.0",
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
"commander": "^9.4.1",
|
"commander": "^9.4.1",
|
||||||
|
|||||||
@@ -129,18 +129,20 @@ export const initCommand = async (options: InitCommandOptions) => {
|
|||||||
|
|
||||||
await addConfigurationToPackageJson(resolvedPath, resolvedOptions);
|
await addConfigurationToPackageJson(resolvedPath, resolvedOptions);
|
||||||
|
|
||||||
await printNextSteps(resolvedOptions, authorizedKey, packageManager, framework);
|
const projectUrl = `${resolvedOptions.triggerUrl}/orgs/${authorizedKey.organization.slug}/projects/${authorizedKey.project.slug}`;
|
||||||
|
if (framework.printInstallationComplete) {
|
||||||
|
await framework.printInstallationComplete(projectUrl);
|
||||||
|
} else {
|
||||||
|
await printNextSteps(projectUrl, packageManager, framework);
|
||||||
|
}
|
||||||
telemetryClient.init.completed(resolvedOptions);
|
telemetryClient.init.completed(resolvedOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function printNextSteps(
|
async function printNextSteps(
|
||||||
options: ResolvedOptions,
|
projectUrl: string,
|
||||||
authorizedKey: WhoamiResponse,
|
|
||||||
packageManager: PackageManager,
|
packageManager: PackageManager,
|
||||||
framework: Framework
|
framework: Framework
|
||||||
) {
|
) {
|
||||||
const projectUrl = `${options.triggerUrl}/orgs/${authorizedKey.organization.slug}/projects/${authorizedKey.project.slug}`;
|
|
||||||
|
|
||||||
logger.success(`✔ Successfully initialized Trigger.dev!`);
|
logger.success(`✔ Successfully initialized Trigger.dev!`);
|
||||||
|
|
||||||
logger.info("Next steps:");
|
logger.info("Next steps:");
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import mock from "mock-fs";
|
||||||
|
import { Express } from ".";
|
||||||
|
import { getFramework } from "..";
|
||||||
|
import { pathExists } from "../../utils/fileSystem";
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
mock.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Express project detection", () => {
|
||||||
|
test("has dependency", async () => {
|
||||||
|
mock({
|
||||||
|
"package.json": JSON.stringify({ dependencies: { express: "1.0.0" } }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const framework = await getFramework("", "npm");
|
||||||
|
expect(framework?.id).toEqual("express");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("no dependency", async () => {
|
||||||
|
mock({
|
||||||
|
"package.json": JSON.stringify({ dependencies: { foo: "1.0.0" } }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const framework = await getFramework("", "npm");
|
||||||
|
expect(framework?.id).not.toEqual("express");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { Framework, ProjectInstallOptions } from "..";
|
||||||
|
import { InstallPackage } from "../../utils/addDependencies";
|
||||||
|
import { PackageManager } from "../../utils/getUserPkgManager";
|
||||||
|
import { logger } from "../../utils/logger";
|
||||||
|
import { readPackageJson } from "../../utils/readPackageJson";
|
||||||
|
import { standardWatchFilePaths } from "../watchConfig";
|
||||||
|
import boxen from "boxen";
|
||||||
|
|
||||||
|
export class Express implements Framework {
|
||||||
|
id = "express";
|
||||||
|
name = "Express";
|
||||||
|
|
||||||
|
async isMatch(path: string, packageManager: PackageManager): Promise<boolean> {
|
||||||
|
//check for the express package
|
||||||
|
const packageJsonContent = await readPackageJson(path);
|
||||||
|
if (packageJsonContent?.dependencies?.express) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async dependencies(): Promise<InstallPackage[]> {
|
||||||
|
return [
|
||||||
|
{ name: "@trigger.dev/sdk", tag: "latest" },
|
||||||
|
{ name: "@trigger.dev/express", tag: "latest" },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
possibleEnvFilenames(): string[] {
|
||||||
|
return [".env"];
|
||||||
|
}
|
||||||
|
|
||||||
|
async install(path: string, { typescript, endpointSlug }: ProjectInstallOptions): Promise<void> {}
|
||||||
|
|
||||||
|
async postInstall(path: string, options: ProjectInstallOptions): Promise<void> {}
|
||||||
|
|
||||||
|
async printInstallationComplete(projectUrl: string): Promise<void> {
|
||||||
|
logger.info(
|
||||||
|
boxen(
|
||||||
|
"Automatic installation isn't currently supported for Express. \nFollow the steps in our manual installation guide: https://trigger.dev/docs/documentation/guides/manual/express",
|
||||||
|
{ padding: 1, margin: 1, borderStyle: "double", borderColor: "magenta" }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultHostnames = ["localhost", "[::]"];
|
||||||
|
defaultPorts = [3000, 8000, 80, 8080];
|
||||||
|
watchFilePaths = standardWatchFilePaths;
|
||||||
|
watchIgnoreRegex = /(node_modules)/;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { InstallPackage } from "../utils/addDependencies";
|
import { InstallPackage } from "../utils/addDependencies";
|
||||||
import { PackageManager } from "../utils/getUserPkgManager";
|
import { PackageManager } from "../utils/getUserPkgManager";
|
||||||
import { Astro } from "./astro";
|
import { Astro } from "./astro";
|
||||||
|
import { Express } from "./express";
|
||||||
import { NextJs } from "./nextjs";
|
import { NextJs } from "./nextjs";
|
||||||
import { Remix } from "./remix";
|
import { Remix } from "./remix";
|
||||||
|
|
||||||
@@ -32,6 +33,9 @@ export interface Framework {
|
|||||||
/** You can check for middleware, add extra instructions, etc */
|
/** You can check for middleware, add extra instructions, etc */
|
||||||
postInstall(path: string, options: ProjectInstallOptions): Promise<void>;
|
postInstall(path: string, options: ProjectInstallOptions): Promise<void>;
|
||||||
|
|
||||||
|
/** You can (optionally) override the initComplete messages */
|
||||||
|
printInstallationComplete?(projectUrl: string): Promise<void>;
|
||||||
|
|
||||||
/** Used by the dev command, if a hostname isn't passed in */
|
/** Used by the dev command, if a hostname isn't passed in */
|
||||||
defaultHostnames: string[];
|
defaultHostnames: string[];
|
||||||
|
|
||||||
@@ -46,7 +50,7 @@ export interface Framework {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** The order of these matters. The first one that matches the folder will be used, so stricter ones should be first. */
|
/** The order of these matters. The first one that matches the folder will be used, so stricter ones should be first. */
|
||||||
const frameworks: Framework[] = [new NextJs(), new Remix(), new Astro()];
|
const frameworks: Framework[] = [new NextJs(), new Remix(), new Astro(), new Express()];
|
||||||
|
|
||||||
export const getFramework = async (
|
export const getFramework = async (
|
||||||
path: string,
|
path: string,
|
||||||
|
|||||||
@@ -34,6 +34,6 @@
|
|||||||
"typescript": "^4.9.4"
|
"typescript": "^4.9.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+3
-13
@@ -639,6 +639,7 @@ importers:
|
|||||||
'@types/mock-fs': ^4.13.1
|
'@types/mock-fs': ^4.13.1
|
||||||
'@types/node': '16'
|
'@types/node': '16'
|
||||||
'@types/node-fetch': ^2.6.2
|
'@types/node-fetch': ^2.6.2
|
||||||
|
boxen: ^7.1.1
|
||||||
chalk: ^5.2.0
|
chalk: ^5.2.0
|
||||||
chokidar: ^3.5.3
|
chokidar: ^3.5.3
|
||||||
commander: ^9.4.1
|
commander: ^9.4.1
|
||||||
@@ -670,6 +671,7 @@ importers:
|
|||||||
zod: 3.21.4
|
zod: 3.21.4
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/degit': 2.8.3
|
'@types/degit': 2.8.3
|
||||||
|
boxen: 7.1.1
|
||||||
chalk: 5.2.0
|
chalk: 5.2.0
|
||||||
chokidar: 3.5.3
|
chokidar: 3.5.3
|
||||||
commander: 9.5.0
|
commander: 9.5.0
|
||||||
@@ -14639,7 +14641,7 @@ packages:
|
|||||||
/axios/0.21.4_debug@4.3.2:
|
/axios/0.21.4_debug@4.3.2:
|
||||||
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
|
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects: 1.15.2_debug@4.3.2
|
follow-redirects: 1.15.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
dev: false
|
dev: false
|
||||||
@@ -19183,18 +19185,6 @@ packages:
|
|||||||
debug:
|
debug:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/follow-redirects/1.15.2_debug@4.3.2:
|
|
||||||
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
|
||||||
engines: {node: '>=4.0'}
|
|
||||||
peerDependencies:
|
|
||||||
debug: '*'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
debug:
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
debug: 4.3.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/for-each/0.3.3:
|
/for-each/0.3.3:
|
||||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user