create-warlock 4.0.171 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/index.cjs +780 -0
- package/cjs/index.cjs.map +1 -0
- package/cjs/paths-Bl9Wn7qV.cjs +247 -0
- package/cjs/paths-Bl9Wn7qV.cjs.map +1 -0
- package/cjs/project-builder-helpers-DGcgf60P.cjs +27 -0
- package/cjs/project-builder-helpers-DGcgf60P.cjs.map +1 -0
- package/esm/commands/create-new-app/get-app-path.mjs +17 -0
- package/esm/commands/create-new-app/get-app-path.mjs.map +1 -0
- package/esm/commands/create-new-app/index.mjs +152 -0
- package/esm/commands/create-new-app/index.mjs.map +1 -0
- package/esm/commands/create-new-app/types.d.mts +18 -0
- package/esm/commands/create-warlock-app/index.mjs +57 -0
- package/esm/commands/create-warlock-app/index.mjs.map +1 -0
- package/esm/features/database-drivers.mjs +47 -0
- package/esm/features/database-drivers.mjs.map +1 -0
- package/esm/features/features-map.mjs +157 -0
- package/esm/features/features-map.mjs.map +1 -0
- package/esm/helpers/app.mjs +157 -0
- package/esm/helpers/app.mjs.map +1 -0
- package/esm/helpers/exec.mjs +58 -0
- package/esm/helpers/exec.mjs.map +1 -0
- package/esm/helpers/package-manager.mjs +84 -0
- package/esm/helpers/package-manager.mjs.map +1 -0
- package/esm/helpers/paths.mjs +16 -0
- package/esm/helpers/paths.mjs.map +1 -0
- package/esm/helpers/project-builder-helpers.mjs +28 -0
- package/esm/helpers/project-builder-helpers.mjs.map +1 -0
- package/esm/index.d.mts +14 -0
- package/esm/index.mjs +83 -0
- package/esm/index.mjs.map +1 -0
- package/esm/ui/{banner.js → banner.mjs} +51 -67
- package/esm/ui/banner.mjs.map +1 -0
- package/esm/ui/spinners.mjs +23 -0
- package/esm/ui/spinners.mjs.map +1 -0
- package/llms-full.txt +121 -0
- package/llms.txt +9 -0
- package/package.json +36 -40
- package/skills/create-a-warlock-project/SKILL.md +111 -0
- package/templates/warlock/.prettierrc.json +10 -11
- package/templates/warlock/_.gitignore +0 -1
- package/templates/warlock/package.json +71 -66
- package/templates/warlock/src/app/auth/controllers/login.controller.ts +5 -6
- package/templates/warlock/src/app/auth/controllers/reset-password.controller.ts +5 -6
- package/templates/warlock/src/app/auth/models/otp/migrations/22-12-2025_10-30-20.otp-migration.ts +33 -43
- package/templates/warlock/src/app/auth/requests/guarded.request.ts +5 -1
- package/templates/warlock/src/app/posts/controllers/create-new-post.controller.ts +5 -6
- package/templates/warlock/src/app/posts/controllers/update-post.controller.ts +4 -5
- package/templates/warlock/src/app/posts/models/post/migrations/09-01-2026_02-07-51-post.migration.ts +21 -34
- package/templates/warlock/src/app/posts/models/post/post.model.ts +0 -2
- package/templates/warlock/src/app/posts/{validation → schema}/create-post.schema.ts +1 -1
- package/templates/warlock/src/app/posts/{validation → schema}/update-post.schema.ts +1 -1
- package/templates/warlock/src/app/shared/utils/locales.ts +34 -0
- package/templates/warlock/src/app/shared/utils/router.ts +1 -1
- package/templates/warlock/src/app/uploads/controllers/fetch-uploaded-file.controller.ts +1 -1
- package/templates/warlock/src/app/users/controllers/create-new-user.controller.ts +4 -4
- package/templates/warlock/src/app/users/controllers/list-users.controller.ts +3 -12
- package/templates/warlock/src/app/users/models/user/migrations/11-12-2025_23-58-03-user.migration.ts +13 -33
- package/templates/warlock/src/app/users/{validation → schema}/create-user.schema.ts +1 -1
- package/templates/warlock/storage/.gitignore +2 -0
- package/templates/warlock/yarn.lock +2332 -0
- package/cjs/commands/create-new-app/get-app-path.d.ts +0 -2
- package/cjs/commands/create-new-app/get-app-path.d.ts.map +0 -1
- package/cjs/commands/create-new-app/get-app-path.js +0 -8
- package/cjs/commands/create-new-app/get-app-path.js.map +0 -1
- package/cjs/commands/create-new-app/index.d.ts +0 -2
- package/cjs/commands/create-new-app/index.d.ts.map +0 -1
- package/cjs/commands/create-new-app/index.js +0 -96
- package/cjs/commands/create-new-app/index.js.map +0 -1
- package/cjs/commands/create-new-app/types.d.ts +0 -16
- package/cjs/commands/create-new-app/types.d.ts.map +0 -1
- package/cjs/commands/create-warlock-app/index.d.ts +0 -3
- package/cjs/commands/create-warlock-app/index.d.ts.map +0 -1
- package/cjs/commands/create-warlock-app/index.js +0 -55
- package/cjs/commands/create-warlock-app/index.js.map +0 -1
- package/cjs/features/database-drivers.d.ts +0 -31
- package/cjs/features/database-drivers.d.ts.map +0 -1
- package/cjs/features/database-drivers.js +0 -53
- package/cjs/features/database-drivers.js.map +0 -1
- package/cjs/features/features-map.d.ts +0 -35
- package/cjs/features/features-map.d.ts.map +0 -1
- package/cjs/features/features-map.js +0 -120
- package/cjs/features/features-map.js.map +0 -1
- package/cjs/helpers/app.d.ts +0 -71
- package/cjs/helpers/app.d.ts.map +0 -1
- package/cjs/helpers/app.js +0 -196
- package/cjs/helpers/app.js.map +0 -1
- package/cjs/helpers/exec.d.ts +0 -10
- package/cjs/helpers/exec.d.ts.map +0 -1
- package/cjs/helpers/exec.js +0 -69
- package/cjs/helpers/exec.js.map +0 -1
- package/cjs/helpers/package-manager.d.ts +0 -18
- package/cjs/helpers/package-manager.d.ts.map +0 -1
- package/cjs/helpers/package-manager.js +0 -104
- package/cjs/helpers/package-manager.js.map +0 -1
- package/cjs/helpers/paths.d.ts +0 -4
- package/cjs/helpers/paths.d.ts.map +0 -1
- package/cjs/helpers/paths.js +0 -8
- package/cjs/helpers/paths.js.map +0 -1
- package/cjs/helpers/project-builder-helpers.d.ts +0 -6
- package/cjs/helpers/project-builder-helpers.d.ts.map +0 -1
- package/cjs/helpers/project-builder-helpers.js +0 -11
- package/cjs/helpers/project-builder-helpers.js.map +0 -1
- package/cjs/index.d.ts +0 -2
- package/cjs/index.d.ts.map +0 -1
- package/cjs/index.js +0 -3
- package/cjs/index.js.map +0 -1
- package/cjs/ui/banner.d.ts +0 -29
- package/cjs/ui/banner.d.ts.map +0 -1
- package/cjs/ui/banner.js +0 -142
- package/cjs/ui/banner.js.map +0 -1
- package/cjs/ui/spinners.d.ts +0 -18
- package/cjs/ui/spinners.d.ts.map +0 -1
- package/cjs/ui/spinners.js +0 -17
- package/cjs/ui/spinners.js.map +0 -1
- package/create-app.js +0 -5
- package/esm/commands/create-new-app/get-app-path.d.ts +0 -2
- package/esm/commands/create-new-app/get-app-path.d.ts.map +0 -1
- package/esm/commands/create-new-app/get-app-path.js +0 -8
- package/esm/commands/create-new-app/get-app-path.js.map +0 -1
- package/esm/commands/create-new-app/index.d.ts +0 -2
- package/esm/commands/create-new-app/index.d.ts.map +0 -1
- package/esm/commands/create-new-app/index.js +0 -96
- package/esm/commands/create-new-app/index.js.map +0 -1
- package/esm/commands/create-new-app/types.d.ts +0 -16
- package/esm/commands/create-new-app/types.d.ts.map +0 -1
- package/esm/commands/create-warlock-app/index.d.ts +0 -3
- package/esm/commands/create-warlock-app/index.d.ts.map +0 -1
- package/esm/commands/create-warlock-app/index.js +0 -55
- package/esm/commands/create-warlock-app/index.js.map +0 -1
- package/esm/features/database-drivers.d.ts +0 -31
- package/esm/features/database-drivers.d.ts.map +0 -1
- package/esm/features/database-drivers.js +0 -53
- package/esm/features/database-drivers.js.map +0 -1
- package/esm/features/features-map.d.ts +0 -35
- package/esm/features/features-map.d.ts.map +0 -1
- package/esm/features/features-map.js +0 -120
- package/esm/features/features-map.js.map +0 -1
- package/esm/helpers/app.d.ts +0 -71
- package/esm/helpers/app.d.ts.map +0 -1
- package/esm/helpers/app.js +0 -196
- package/esm/helpers/app.js.map +0 -1
- package/esm/helpers/exec.d.ts +0 -10
- package/esm/helpers/exec.d.ts.map +0 -1
- package/esm/helpers/exec.js +0 -69
- package/esm/helpers/exec.js.map +0 -1
- package/esm/helpers/package-manager.d.ts +0 -18
- package/esm/helpers/package-manager.d.ts.map +0 -1
- package/esm/helpers/package-manager.js +0 -104
- package/esm/helpers/package-manager.js.map +0 -1
- package/esm/helpers/paths.d.ts +0 -4
- package/esm/helpers/paths.d.ts.map +0 -1
- package/esm/helpers/paths.js +0 -8
- package/esm/helpers/paths.js.map +0 -1
- package/esm/helpers/project-builder-helpers.d.ts +0 -6
- package/esm/helpers/project-builder-helpers.d.ts.map +0 -1
- package/esm/helpers/project-builder-helpers.js +0 -11
- package/esm/helpers/project-builder-helpers.js.map +0 -1
- package/esm/index.d.ts +0 -2
- package/esm/index.d.ts.map +0 -1
- package/esm/index.js +0 -3
- package/esm/index.js.map +0 -1
- package/esm/ui/banner.d.ts +0 -29
- package/esm/ui/banner.d.ts.map +0 -1
- package/esm/ui/banner.js.map +0 -1
- package/esm/ui/spinners.d.ts +0 -18
- package/esm/ui/spinners.d.ts.map +0 -1
- package/esm/ui/spinners.js +0 -17
- package/esm/ui/spinners.js.map +0 -1
- package/templates/warlock/src/app/auth/requests/login.request.ts +0 -4
- package/templates/warlock/src/app/auth/requests/reset-password.request.ts +0 -4
- package/templates/warlock/src/app/posts/requests/create-post.request.ts +0 -4
- package/templates/warlock/src/app/posts/requests/update-post.request.ts +0 -4
- package/templates/warlock/src/app/users/requests/create-user.request.ts +0 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../@warlock.js/create-warlock/src/commands/create-new-app/index.ts"],"sourcesContent":["import {\r\n cancel,\r\n confirm,\r\n isCancel,\r\n multiselect,\r\n select,\r\n text,\r\n} from \"@clack/prompts\";\r\nimport { colors } from \"@mongez/copper\";\r\nimport { getJsonFile } from \"@warlock.js/fs\";\r\nimport {\r\n getDatabaseDriver,\r\n getDatabaseDriverOptions,\r\n} from \"../../features/database-drivers\";\r\nimport {\r\n getAiProviderOptions,\r\n getAllFeatureKeys,\r\n getDefaultFeatureKeys,\r\n getFeatureOptions,\r\n} from \"../../features/features-map\";\r\nimport { App } from \"../../helpers/app\";\r\nimport {\r\n detectPackageManagers,\r\n getPackageManager,\r\n getPreferredPackageManager,\r\n getSystemPackageManagers,\r\n setPackageManager,\r\n} from \"../../helpers/package-manager\";\r\nimport { packageRoot } from \"../../helpers/paths\";\r\nimport { showIntroBanner } from \"../../ui/banner\";\r\nimport { createWarlockApp } from \"../create-warlock-app\";\r\nimport getAppPath from \"./get-app-path\";\r\nimport { App as AppType, CliFlags } from \"./types\";\r\n\r\nexport default async function createNewApp(cli: CliFlags = {}) {\r\n // Start detecting package managers in the background to avoid delay later\r\n const pmDetectionPromise = detectPackageManagers();\r\n\r\n // Get version from package.json\r\n const packageJson: any = getJsonFile(packageRoot(\"package.json\"));\r\n const createWarlockVersion = packageJson.version;\r\n\r\n // Show the intro banner\r\n showIntroBanner(createWarlockVersion);\r\n\r\n console.log(colors.cyan(\"✨ Let's create something magical! ✨\\n\"));\r\n\r\n // Validate Node.js version (minimum v20)\r\n const [major] = process.versions.node.split(\".\").map(Number);\r\n if (major < 20) {\r\n cancel(\"Node.js version must be at least 20.0.0\");\r\n process.exit(0);\r\n }\r\n\r\n // Non-interactive path: build everything from flags and skip the prompts.\r\n if (cli.yes) {\r\n await createNonInteractive(cli);\r\n return;\r\n }\r\n\r\n // Step 1: Project name\r\n const appName = await text({\r\n message: \"What shall we call your project?\",\r\n placeholder: \"my-warlock-app\",\r\n });\r\n\r\n if (isCancel(appName) || !appName.trim()) {\r\n cancel(\"A project name is required to continue\");\r\n process.exit(0);\r\n }\r\n\r\n const appPath = getAppPath(appName);\r\n if (!appPath) return;\r\n\r\n // Step 2: Package Manager selection\r\n await pmDetectionPromise; // Ensure detection is complete\r\n\r\n const packageManager = await select({\r\n message: \"Which package manager do you want to use?\",\r\n options: getSystemPackageManagers().map(pm => ({\r\n value: pm,\r\n label: pm,\r\n })),\r\n initialValue: getPreferredPackageManager(),\r\n });\r\n\r\n if (isCancel(packageManager)) {\r\n cancel(\"Package manager selection cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n setPackageManager(packageManager as string);\r\n\r\n // Step 3: Database driver selection\r\n const databaseDriver = await select({\r\n message: \"Choose your database driver 🗄ï¸\",\r\n options: getDatabaseDriverOptions(),\r\n });\r\n\r\n if (isCancel(databaseDriver)) {\r\n cancel(\"Database selection cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n const selectedDriver = getDatabaseDriver(databaseDriver as string);\r\n\r\n // Step 4: Features selection\r\n const selectedFeatures = await multiselect({\r\n message: \"Select optional features to include ✨\",\r\n options: getFeatureOptions(),\r\n initialValues: getDefaultFeatureKeys(),\r\n required: false,\r\n });\r\n\r\n if (isCancel(selectedFeatures)) {\r\n cancel(\"Feature selection cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n // Step 4b: AI providers — selecting any pulls @warlock.js/ai automatically\r\n const selectedAiProviders = await multiselect({\r\n message: \"Add AI providers? The core AI package is included automatically 🤖\",\r\n options: getAiProviderOptions(),\r\n required: false,\r\n });\r\n\r\n if (isCancel(selectedAiProviders)) {\r\n cancel(\"AI provider selection cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n // Step 5: Git initialization\r\n const useGit =\r\n (await confirm({\r\n message: \"Initialize a Git repository? 📂\",\r\n })) === true;\r\n\r\n if (isCancel(useGit)) {\r\n cancel(\"Setup cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n // Step 6: JWT secret generation\r\n const useJWT =\r\n (await confirm({\r\n message: \"Generate JWT secret keys? ðŸ”\",\r\n })) === true;\r\n\r\n if (isCancel(useJWT)) {\r\n cancel(\"Setup cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n // Build app details\r\n const appDetails: Required<AppType> = {\r\n appName: appName,\r\n appType: \"warlock\",\r\n appPath: appPath,\r\n pkgManager: getPackageManager(),\r\n options: {\r\n databaseDriver: databaseDriver as string,\r\n databasePort: selectedDriver?.defaultPort || 27017,\r\n features: selectedFeatures as string[],\r\n aiProviders: selectedAiProviders as string[],\r\n useGit,\r\n useJWT,\r\n },\r\n };\r\n\r\n // Create the app\r\n await createWarlockApp(new App(appDetails));\r\n}\r\n\r\n/**\r\n * Non-interactive scaffold path for `--yes`. Builds the app from flags with\r\n * sensible defaults and skips every prompt. Validates the database driver and\r\n * feature/provider keys up front so a typo fails fast instead of mid-install.\r\n */\r\nasync function createNonInteractive(cli: CliFlags) {\r\n const appName = (cli.name ?? \"\").trim();\r\n\r\n if (!appName) {\r\n cancel(\"--yes requires a project name (first argument or --name=<name>)\");\r\n process.exit(1);\r\n }\r\n\r\n const appPath = getAppPath(appName);\r\n\r\n if (!appPath) return;\r\n\r\n await detectPackageManagers();\r\n\r\n const packageManager = cli.pm ?? getPreferredPackageManager();\r\n setPackageManager(packageManager);\r\n\r\n const databaseDriver = cli.db ?? \"mongodb\";\r\n const driver = getDatabaseDriver(databaseDriver);\r\n\r\n if (!driver) {\r\n cancel(`Unknown database driver \"${databaseDriver}\"`);\r\n process.exit(1);\r\n }\r\n\r\n const features = cli.features ?? [];\r\n const aiProviders = cli.ai ?? [];\r\n\r\n const allowedKeys = getAllFeatureKeys();\r\n const invalidKeys = [...features, ...aiProviders].filter(key => !allowedKeys.includes(key));\r\n\r\n if (invalidKeys.length > 0) {\r\n cancel(`Unknown feature(s): ${invalidKeys.join(\", \")}`);\r\n process.exit(1);\r\n }\r\n\r\n const appDetails: Required<AppType> = {\r\n appName,\r\n appType: \"warlock\",\r\n appPath,\r\n pkgManager: getPackageManager(),\r\n options: {\r\n databaseDriver,\r\n databasePort: driver.defaultPort,\r\n features,\r\n aiProviders,\r\n useGit: cli.git ?? false,\r\n useJWT: cli.jwt ?? false,\r\n },\r\n };\r\n\r\n await createWarlockApp(new App(appDetails));\r\n}\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region ../../@warlock.js/create-warlock/src/commands/create-new-app/types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Flags parsed from the command line for non-interactive scaffolding
|
|
4
|
+
* (`create-warlock my-app --db=postgres --features=test,herald --ai=openai --yes`).
|
|
5
|
+
*/
|
|
6
|
+
type CliFlags = {
|
|
7
|
+
yes?: boolean;
|
|
8
|
+
name?: string;
|
|
9
|
+
db?: string;
|
|
10
|
+
features?: string[];
|
|
11
|
+
ai?: string[];
|
|
12
|
+
pm?: string;
|
|
13
|
+
git?: boolean;
|
|
14
|
+
jwt?: boolean;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { CliFlags };
|
|
18
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getPackageManager, runPackageManagerCommand } from "../../helpers/package-manager.mjs";
|
|
2
|
+
import { showSuccessScreen } from "../../ui/banner.mjs";
|
|
3
|
+
import { spinnerMessages } from "../../ui/spinners.mjs";
|
|
4
|
+
import { spinner } from "@clack/prompts";
|
|
5
|
+
|
|
6
|
+
//#region ../../@warlock.js/create-warlock/src/commands/create-warlock-app/index.ts
|
|
7
|
+
async function createWarlockApp(application) {
|
|
8
|
+
const { useGit, useJWT, features, aiProviders, databaseDriver } = application.options;
|
|
9
|
+
const templateSpinner = spinner();
|
|
10
|
+
templateSpinner.start(spinnerMessages.copyingTemplate);
|
|
11
|
+
application.init().use("warlock").updatePackageJson().updateDotEnv().configureDatabaseEnv(databaseDriver);
|
|
12
|
+
templateSpinner.stop(spinnerMessages.templateCopied);
|
|
13
|
+
const installSpinner = spinner();
|
|
14
|
+
installSpinner.start(spinnerMessages.installingDeps);
|
|
15
|
+
await application.install().install;
|
|
16
|
+
installSpinner.stop(spinnerMessages.depsInstalled);
|
|
17
|
+
const selectedFeatures = [
|
|
18
|
+
databaseDriver,
|
|
19
|
+
...features,
|
|
20
|
+
...aiProviders
|
|
21
|
+
];
|
|
22
|
+
if (selectedFeatures.length > 0) {
|
|
23
|
+
const featuresSpinner = spinner();
|
|
24
|
+
featuresSpinner.start(spinnerMessages.addingFeatures);
|
|
25
|
+
if (await application.installFeatures(selectedFeatures)) {
|
|
26
|
+
await application.install().install;
|
|
27
|
+
featuresSpinner.stop(spinnerMessages.featuresAdded);
|
|
28
|
+
} else featuresSpinner.stop(spinnerMessages.featuresFailed);
|
|
29
|
+
}
|
|
30
|
+
if (useGit) {
|
|
31
|
+
const gitSpinner = spinner();
|
|
32
|
+
gitSpinner.start(spinnerMessages.initializingGit);
|
|
33
|
+
await application.git();
|
|
34
|
+
gitSpinner.stop(spinnerMessages.gitInitialized);
|
|
35
|
+
}
|
|
36
|
+
if (useJWT) {
|
|
37
|
+
const jwtSpinner = spinner();
|
|
38
|
+
jwtSpinner.start(spinnerMessages.generatingJwt);
|
|
39
|
+
await application.exec(runPackageManagerCommand("jwt"));
|
|
40
|
+
jwtSpinner.stop(spinnerMessages.jwtGenerated);
|
|
41
|
+
} else {
|
|
42
|
+
const warmSpinner = spinner();
|
|
43
|
+
warmSpinner.start(spinnerMessages.warmingCache);
|
|
44
|
+
await application.exec("npx warlock --warm-cache");
|
|
45
|
+
warmSpinner.stop(spinnerMessages.cacheWarmed);
|
|
46
|
+
}
|
|
47
|
+
showSuccessScreen({
|
|
48
|
+
projectName: application.name,
|
|
49
|
+
database: databaseDriver === "mongodb" ? "MongoDB" : "PostgreSQL",
|
|
50
|
+
features: [...features, ...aiProviders],
|
|
51
|
+
packageManager: getPackageManager()
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { createWarlockApp };
|
|
57
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../@warlock.js/create-warlock/src/commands/create-warlock-app/index.ts"],"sourcesContent":["import { spinner } from \"@clack/prompts\";\r\nimport { App } from \"../../helpers/app\";\r\nimport {\r\n getPackageManager,\r\n runPackageManagerCommand,\r\n} from \"../../helpers/package-manager\";\r\nimport { showSuccessScreen } from \"../../ui/banner\";\r\nimport { spinnerMessages } from \"../../ui/spinners\";\r\n\r\nexport async function createWarlockApp(application: App) {\r\n const options = application.options;\r\n const { useGit, useJWT, features, aiProviders, databaseDriver } = options;\r\n\r\n // Step 1: Initialize and copy template\r\n const templateSpinner = spinner();\r\n templateSpinner.start(spinnerMessages.copyingTemplate);\r\n\r\n application\r\n .init()\r\n .use(\"warlock\")\r\n .updatePackageJson()\r\n .updateDotEnv()\r\n .configureDatabaseEnv(databaseDriver);\r\n\r\n templateSpinner.stop(spinnerMessages.templateCopied);\r\n\r\n // Step 2: Install base dependencies (so the `warlock` binary is available)\r\n const installSpinner = spinner();\r\n installSpinner.start(spinnerMessages.installingDeps);\r\n\r\n await application.install().install;\r\n\r\n installSpinner.stop(spinnerMessages.depsInstalled);\r\n\r\n // Step 3: Add features via `warlock add --no-install`, then one batched install.\r\n // The DB driver, optional features, and AI providers all go through the single\r\n // source of truth (core's feature map) so versions never drift.\r\n const selectedFeatures = [databaseDriver, ...features, ...aiProviders];\r\n\r\n if (selectedFeatures.length > 0) {\r\n const featuresSpinner = spinner();\r\n featuresSpinner.start(spinnerMessages.addingFeatures);\r\n\r\n const added = await application.installFeatures(selectedFeatures);\r\n\r\n if (added) {\r\n await application.install().install;\r\n featuresSpinner.stop(spinnerMessages.featuresAdded);\r\n } else {\r\n featuresSpinner.stop(spinnerMessages.featuresFailed);\r\n }\r\n }\r\n\r\n // Step 4: Initialize Git repository if requested\r\n if (useGit) {\r\n const gitSpinner = spinner();\r\n gitSpinner.start(spinnerMessages.initializingGit);\r\n\r\n await application.git();\r\n\r\n gitSpinner.stop(spinnerMessages.gitInitialized);\r\n }\r\n\r\n // Step 5: Generate JWT or warm cache\r\n if (useJWT) {\r\n const jwtSpinner = spinner();\r\n jwtSpinner.start(spinnerMessages.generatingJwt);\r\n\r\n await application.exec(runPackageManagerCommand(\"jwt\"));\r\n\r\n jwtSpinner.stop(spinnerMessages.jwtGenerated);\r\n } else {\r\n const warmSpinner = spinner();\r\n warmSpinner.start(spinnerMessages.warmingCache);\r\n\r\n await application.exec(\"npx warlock --warm-cache\");\r\n\r\n warmSpinner.stop(spinnerMessages.cacheWarmed);\r\n }\r\n\r\n // Step 6: Show success screen\r\n showSuccessScreen({\r\n projectName: application.name,\r\n database: databaseDriver === \"mongodb\" ? \"MongoDB\" : \"PostgreSQL\",\r\n features: [...features, ...aiProviders],\r\n packageManager: getPackageManager(),\r\n });\r\n}\r\n"],"mappings":";;;;;;AASA,eAAsB,iBAAiB,aAAkB;CAEvD,MAAM,EAAE,QAAQ,QAAQ,UAAU,aAAa,mBAD/B,YAAY;CAI5B,MAAM,kBAAkB,QAAQ;CAChC,gBAAgB,MAAM,gBAAgB,eAAe;CAErD,YACG,KAAK,EACL,IAAI,SAAS,EACb,kBAAkB,EAClB,aAAa,EACb,qBAAqB,cAAc;CAEtC,gBAAgB,KAAK,gBAAgB,cAAc;CAGnD,MAAM,iBAAiB,QAAQ;CAC/B,eAAe,MAAM,gBAAgB,cAAc;CAEnD,MAAM,YAAY,QAAQ,EAAE;CAE5B,eAAe,KAAK,gBAAgB,aAAa;CAKjD,MAAM,mBAAmB;EAAC;EAAgB,GAAG;EAAU,GAAG;CAAW;CAErE,IAAI,iBAAiB,SAAS,GAAG;EAC/B,MAAM,kBAAkB,QAAQ;EAChC,gBAAgB,MAAM,gBAAgB,cAAc;EAIpD,IAAI,MAFgB,YAAY,gBAAgB,gBAAgB,GAErD;GACT,MAAM,YAAY,QAAQ,EAAE;GAC5B,gBAAgB,KAAK,gBAAgB,aAAa;EACpD,OACE,gBAAgB,KAAK,gBAAgB,cAAc;CAEvD;CAGA,IAAI,QAAQ;EACV,MAAM,aAAa,QAAQ;EAC3B,WAAW,MAAM,gBAAgB,eAAe;EAEhD,MAAM,YAAY,IAAI;EAEtB,WAAW,KAAK,gBAAgB,cAAc;CAChD;CAGA,IAAI,QAAQ;EACV,MAAM,aAAa,QAAQ;EAC3B,WAAW,MAAM,gBAAgB,aAAa;EAE9C,MAAM,YAAY,KAAK,yBAAyB,KAAK,CAAC;EAEtD,WAAW,KAAK,gBAAgB,YAAY;CAC9C,OAAO;EACL,MAAM,cAAc,QAAQ;EAC5B,YAAY,MAAM,gBAAgB,YAAY;EAE9C,MAAM,YAAY,KAAK,0BAA0B;EAEjD,YAAY,KAAK,gBAAgB,WAAW;CAC9C;CAGA,kBAAkB;EAChB,aAAa,YAAY;EACzB,UAAU,mBAAmB,YAAY,YAAY;EACrD,UAAU,CAAC,GAAG,UAAU,GAAG,WAAW;EACtC,gBAAgB,kBAAkB;CACpC,CAAC;AACH"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//#region ../../@warlock.js/create-warlock/src/features/database-drivers.ts
|
|
2
|
+
const databaseDrivers = [
|
|
3
|
+
{
|
|
4
|
+
value: "mongodb",
|
|
5
|
+
label: "MongoDB",
|
|
6
|
+
package: "mongodb",
|
|
7
|
+
packageVersion: "^7.0.0",
|
|
8
|
+
defaultPort: 27017
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
value: "postgres",
|
|
12
|
+
label: "PostgreSQL",
|
|
13
|
+
package: "pg",
|
|
14
|
+
packageVersion: "^8.11.0",
|
|
15
|
+
defaultPort: 5432
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
value: "mysql",
|
|
19
|
+
label: "MySQL (Coming Soon)",
|
|
20
|
+
package: "mysql2",
|
|
21
|
+
packageVersion: "^3.5.0",
|
|
22
|
+
defaultPort: 3306,
|
|
23
|
+
disabled: true,
|
|
24
|
+
hint: "MySQL support coming in a future release"
|
|
25
|
+
}
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Get database driver options for the select prompt
|
|
29
|
+
*/
|
|
30
|
+
function getDatabaseDriverOptions() {
|
|
31
|
+
return databaseDrivers.map((driver) => ({
|
|
32
|
+
value: driver.value,
|
|
33
|
+
label: driver.label,
|
|
34
|
+
hint: driver.hint,
|
|
35
|
+
disabled: driver.disabled
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get database driver config by value
|
|
40
|
+
*/
|
|
41
|
+
function getDatabaseDriver(value) {
|
|
42
|
+
return databaseDrivers.find((driver) => driver.value === value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
export { getDatabaseDriver, getDatabaseDriverOptions };
|
|
47
|
+
//# sourceMappingURL=database-drivers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-drivers.mjs","names":[],"sources":["../../../../../../@warlock.js/create-warlock/src/features/database-drivers.ts"],"sourcesContent":["/**\n * Database driver options and configuration\n */\nexport type DatabaseDriver = {\n value: string;\n label: string;\n package: string;\n packageVersion: string;\n defaultPort: number;\n disabled?: boolean;\n hint?: string;\n};\n\nexport const databaseDrivers: DatabaseDriver[] = [\n {\n value: \"mongodb\",\n label: \"MongoDB\",\n package: \"mongodb\",\n packageVersion: \"^7.0.0\",\n defaultPort: 27017,\n },\n {\n value: \"postgres\",\n label: \"PostgreSQL\",\n package: \"pg\",\n packageVersion: \"^8.11.0\",\n defaultPort: 5432,\n },\n {\n value: \"mysql\",\n label: \"MySQL (Coming Soon)\",\n package: \"mysql2\",\n packageVersion: \"^3.5.0\",\n defaultPort: 3306,\n disabled: true,\n hint: \"MySQL support coming in a future release\",\n },\n];\n\n/**\n * Get database driver options for the select prompt\n */\nexport function getDatabaseDriverOptions() {\n return databaseDrivers.map(driver => ({\n value: driver.value,\n label: driver.label,\n hint: driver.hint,\n disabled: driver.disabled,\n }));\n}\n\n/**\n * Get database driver config by value\n */\nexport function getDatabaseDriver(value: string): DatabaseDriver | undefined {\n return databaseDrivers.find(driver => driver.value === value);\n}\n\n/**\n * Get database driver dependency\n */\nexport function getDatabaseDependency(\n driverValue: string,\n): Record<string, string> {\n const driver = getDatabaseDriver(driverValue);\n if (!driver) return {};\n\n return {\n [driver.package]: driver.packageVersion,\n };\n}\n"],"mappings":";AAaA,MAAa,kBAAoC;CAC/C;EACE,OAAO;EACP,OAAO;EACP,SAAS;EACT,gBAAgB;EAChB,aAAa;CACf;CACA;EACE,OAAO;EACP,OAAO;EACP,SAAS;EACT,gBAAgB;EAChB,aAAa;CACf;CACA;EACE,OAAO;EACP,OAAO;EACP,SAAS;EACT,gBAAgB;EAChB,aAAa;EACb,UAAU;EACV,MAAM;CACR;AACF;;;;AAKA,SAAgB,2BAA2B;CACzC,OAAO,gBAAgB,KAAI,YAAW;EACpC,OAAO,OAAO;EACd,OAAO,OAAO;EACd,MAAM,OAAO;EACb,UAAU,OAAO;CACnB,EAAE;AACJ;;;;AAKA,SAAgB,kBAAkB,OAA2C;CAC3E,OAAO,gBAAgB,MAAK,WAAU,OAAO,UAAU,KAAK;AAC9D"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
//#region ../../@warlock.js/create-warlock/src/features/features-map.ts
|
|
2
|
+
/**
|
|
3
|
+
* Optional features offered in the general multiselect step. The database
|
|
4
|
+
* driver (its own select) and AI providers (their own step) are intentionally
|
|
5
|
+
* NOT here — they have dedicated prompts.
|
|
6
|
+
*/
|
|
7
|
+
const features = [
|
|
8
|
+
{
|
|
9
|
+
key: "react",
|
|
10
|
+
label: "React (rendering & mails)",
|
|
11
|
+
hint: "React + ReactDOM for non-interactive rendering and HTML/email generation",
|
|
12
|
+
group: "Rendering & Mail",
|
|
13
|
+
defaultSelected: true
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
key: "react-email",
|
|
17
|
+
label: "React Email",
|
|
18
|
+
hint: "Build email templates with React + Tailwind (pulls react + mail)",
|
|
19
|
+
group: "Rendering & Mail"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
key: "mail",
|
|
23
|
+
label: "Mail (Nodemailer)",
|
|
24
|
+
hint: "Send emails via SMTP",
|
|
25
|
+
group: "Rendering & Mail"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
key: "ses",
|
|
29
|
+
label: "Amazon SES",
|
|
30
|
+
hint: "Send emails via the AWS SES API",
|
|
31
|
+
group: "Rendering & Mail"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: "image",
|
|
35
|
+
label: "Image processing (Sharp)",
|
|
36
|
+
hint: "Resize, convert, and optimize images",
|
|
37
|
+
group: "Media"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: "s3",
|
|
41
|
+
label: "S3 storage",
|
|
42
|
+
hint: "AWS S3 for cloud file storage",
|
|
43
|
+
group: "Storage & Cache"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: "redis",
|
|
47
|
+
label: "Redis cache",
|
|
48
|
+
hint: "Redis driver for the cache layer",
|
|
49
|
+
group: "Storage & Cache"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: "scheduler",
|
|
53
|
+
label: "Scheduler",
|
|
54
|
+
hint: "Background tasks and cron jobs",
|
|
55
|
+
group: "Jobs & Messaging"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: "herald",
|
|
59
|
+
label: "Herald (RabbitMQ)",
|
|
60
|
+
hint: "Message broker for event-driven architecture",
|
|
61
|
+
group: "Jobs & Messaging"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: "socket",
|
|
65
|
+
label: "Socket.IO",
|
|
66
|
+
hint: "Realtime websocket server",
|
|
67
|
+
group: "Realtime"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
key: "swagger",
|
|
71
|
+
label: "Swagger",
|
|
72
|
+
hint: "OpenAPI documentation for your routes",
|
|
73
|
+
group: "API Docs"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: "postman",
|
|
77
|
+
label: "Postman",
|
|
78
|
+
hint: "Generate a Postman collection for your API",
|
|
79
|
+
group: "API Docs"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
key: "test",
|
|
83
|
+
label: "Testing (Vitest)",
|
|
84
|
+
hint: "Vitest + coverage + per-worker DB/cache test setup",
|
|
85
|
+
group: "Tooling"
|
|
86
|
+
}
|
|
87
|
+
];
|
|
88
|
+
/**
|
|
89
|
+
* AI providers offered in the dedicated AI step. Selecting any of these pulls
|
|
90
|
+
* the core `@warlock.js/ai` package automatically via the provider's `requires`
|
|
91
|
+
* in core's feature map — the scaffolder never lists `ai` as a standalone pick.
|
|
92
|
+
*/
|
|
93
|
+
const aiProviders = [
|
|
94
|
+
{
|
|
95
|
+
key: "openai",
|
|
96
|
+
label: "OpenAI",
|
|
97
|
+
hint: "GPT models via the OpenAI API"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
key: "google",
|
|
101
|
+
label: "Google (Gemini)",
|
|
102
|
+
hint: "Gemini models via Google AI"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
key: "anthropic",
|
|
106
|
+
label: "Anthropic (Claude)",
|
|
107
|
+
hint: "Claude models via the Anthropic API"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
key: "bedrock",
|
|
111
|
+
label: "AWS Bedrock",
|
|
112
|
+
hint: "Foundation models via Amazon Bedrock"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
key: "ollama",
|
|
116
|
+
label: "Ollama",
|
|
117
|
+
hint: "Local models via Ollama"
|
|
118
|
+
}
|
|
119
|
+
];
|
|
120
|
+
/**
|
|
121
|
+
* Feature options for the multiselect prompt, ordered by group with the group
|
|
122
|
+
* surfaced in the hint (keeps a flat list scannable without group widgets).
|
|
123
|
+
*/
|
|
124
|
+
function getFeatureOptions() {
|
|
125
|
+
return features.map((feature) => ({
|
|
126
|
+
value: feature.key,
|
|
127
|
+
label: feature.label,
|
|
128
|
+
hint: `${feature.group} — ${feature.hint}`
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Keys pre-checked in the feature multiselect.
|
|
133
|
+
*/
|
|
134
|
+
function getDefaultFeatureKeys() {
|
|
135
|
+
return features.filter((feature) => feature.defaultSelected).map((feature) => feature.key);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* AI provider options for the dedicated AI multiselect step.
|
|
139
|
+
*/
|
|
140
|
+
function getAiProviderOptions() {
|
|
141
|
+
return aiProviders.map((provider) => ({
|
|
142
|
+
value: provider.key,
|
|
143
|
+
label: provider.label,
|
|
144
|
+
hint: provider.hint
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Every selectable key the scaffolder knows about (features + AI providers).
|
|
149
|
+
* Used to validate `--features` / `--ai` flags in non-interactive mode.
|
|
150
|
+
*/
|
|
151
|
+
function getAllFeatureKeys() {
|
|
152
|
+
return [...features.map((feature) => feature.key), ...aiProviders.map((provider) => provider.key)];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//#endregion
|
|
156
|
+
export { getAiProviderOptions, getAllFeatureKeys, getDefaultFeatureKeys, getFeatureOptions };
|
|
157
|
+
//# sourceMappingURL=features-map.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features-map.mjs","names":[],"sources":["../../../../../../@warlock.js/create-warlock/src/features/features-map.ts"],"sourcesContent":["/**\n * Presentation manifest for the scaffolder's feature prompts.\n *\n * This file is **display metadata only** — keys, labels, hints, grouping, and\n * default selections. It deliberately holds NO dependency names or versions:\n * the single source of truth for what each feature installs is the `add`\n * command's feature map in `@warlock.js/core`\n * (`src/generations/add-command.action.ts`). The scaffolder collects the\n * selections here and delegates the actual install to `warlock add`, so the\n * two never drift on versions again.\n *\n * Every `key` below MUST exist in core's `allowedFeatures`; a CI guard should\n * assert that subset relationship so a typo fails the build instead of shipping.\n */\n\nexport type FeatureGroup =\n | \"Rendering & Mail\"\n | \"Media\"\n | \"Storage & Cache\"\n | \"Jobs & Messaging\"\n | \"Realtime\"\n | \"API Docs\"\n | \"Tooling\";\n\nexport type FeatureOption = {\n /** Must match a key in core's `add` feature map. */\n key: string;\n label: string;\n hint: string;\n group: FeatureGroup;\n defaultSelected?: boolean;\n};\n\n/**\n * Optional features offered in the general multiselect step. The database\n * driver (its own select) and AI providers (their own step) are intentionally\n * NOT here — they have dedicated prompts.\n */\nexport const features: FeatureOption[] = [\n // Rendering & Mail\n {\n key: \"react\",\n label: \"React (rendering & mails)\",\n hint: \"React + ReactDOM for non-interactive rendering and HTML/email generation\",\n group: \"Rendering & Mail\",\n defaultSelected: true,\n },\n {\n key: \"react-email\",\n label: \"React Email\",\n hint: \"Build email templates with React + Tailwind (pulls react + mail)\",\n group: \"Rendering & Mail\",\n },\n {\n key: \"mail\",\n label: \"Mail (Nodemailer)\",\n hint: \"Send emails via SMTP\",\n group: \"Rendering & Mail\",\n },\n {\n key: \"ses\",\n label: \"Amazon SES\",\n hint: \"Send emails via the AWS SES API\",\n group: \"Rendering & Mail\",\n },\n\n // Media\n {\n key: \"image\",\n label: \"Image processing (Sharp)\",\n hint: \"Resize, convert, and optimize images\",\n group: \"Media\",\n },\n\n // Storage & Cache\n {\n key: \"s3\",\n label: \"S3 storage\",\n hint: \"AWS S3 for cloud file storage\",\n group: \"Storage & Cache\",\n },\n {\n key: \"redis\",\n label: \"Redis cache\",\n hint: \"Redis driver for the cache layer\",\n group: \"Storage & Cache\",\n },\n\n // Jobs & Messaging\n {\n key: \"scheduler\",\n label: \"Scheduler\",\n hint: \"Background tasks and cron jobs\",\n group: \"Jobs & Messaging\",\n },\n {\n key: \"herald\",\n label: \"Herald (RabbitMQ)\",\n hint: \"Message broker for event-driven architecture\",\n group: \"Jobs & Messaging\",\n },\n\n // Realtime\n {\n key: \"socket\",\n label: \"Socket.IO\",\n hint: \"Realtime websocket server\",\n group: \"Realtime\",\n },\n\n // API Docs\n {\n key: \"swagger\",\n label: \"Swagger\",\n hint: \"OpenAPI documentation for your routes\",\n group: \"API Docs\",\n },\n {\n key: \"postman\",\n label: \"Postman\",\n hint: \"Generate a Postman collection for your API\",\n group: \"API Docs\",\n },\n\n // Tooling\n {\n key: \"test\",\n label: \"Testing (Vitest)\",\n hint: \"Vitest + coverage + per-worker DB/cache test setup\",\n group: \"Tooling\",\n },\n];\n\nexport type AiProviderOption = {\n /** Must match a provider key in core's `add` feature map. */\n key: string;\n label: string;\n hint: string;\n};\n\n/**\n * AI providers offered in the dedicated AI step. Selecting any of these pulls\n * the core `@warlock.js/ai` package automatically via the provider's `requires`\n * in core's feature map — the scaffolder never lists `ai` as a standalone pick.\n */\nexport const aiProviders: AiProviderOption[] = [\n { key: \"openai\", label: \"OpenAI\", hint: \"GPT models via the OpenAI API\" },\n { key: \"google\", label: \"Google (Gemini)\", hint: \"Gemini models via Google AI\" },\n { key: \"anthropic\", label: \"Anthropic (Claude)\", hint: \"Claude models via the Anthropic API\" },\n { key: \"bedrock\", label: \"AWS Bedrock\", hint: \"Foundation models via Amazon Bedrock\" },\n { key: \"ollama\", label: \"Ollama\", hint: \"Local models via Ollama\" },\n];\n\n/**\n * Feature options for the multiselect prompt, ordered by group with the group\n * surfaced in the hint (keeps a flat list scannable without group widgets).\n */\nexport function getFeatureOptions() {\n return features.map(feature => ({\n value: feature.key,\n label: feature.label,\n hint: `${feature.group} — ${feature.hint}`,\n }));\n}\n\n/**\n * Keys pre-checked in the feature multiselect.\n */\nexport function getDefaultFeatureKeys(): string[] {\n return features.filter(feature => feature.defaultSelected).map(feature => feature.key);\n}\n\n/**\n * AI provider options for the dedicated AI multiselect step.\n */\nexport function getAiProviderOptions() {\n return aiProviders.map(provider => ({\n value: provider.key,\n label: provider.label,\n hint: provider.hint,\n }));\n}\n\n/**\n * Every selectable key the scaffolder knows about (features + AI providers).\n * Used to validate `--features` / `--ai` flags in non-interactive mode.\n */\nexport function getAllFeatureKeys(): string[] {\n return [...features.map(feature => feature.key), ...aiProviders.map(provider => provider.key)];\n}\n"],"mappings":";;;;;;AAsCA,MAAa,WAA4B;CAEvC;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;EACP,iBAAiB;CACnB;CACA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CACA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CACA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CAGA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CAGA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CACA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CAGA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CACA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CAGA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CAGA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CACA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;CAGA;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,OAAO;CACT;AACF;;;;;;AAcA,MAAa,cAAkC;CAC7C;EAAE,KAAK;EAAU,OAAO;EAAU,MAAM;CAAgC;CACxE;EAAE,KAAK;EAAU,OAAO;EAAmB,MAAM;CAA8B;CAC/E;EAAE,KAAK;EAAa,OAAO;EAAsB,MAAM;CAAsC;CAC7F;EAAE,KAAK;EAAW,OAAO;EAAe,MAAM;CAAuC;CACrF;EAAE,KAAK;EAAU,OAAO;EAAU,MAAM;CAA0B;AACpE;;;;;AAMA,SAAgB,oBAAoB;CAClC,OAAO,SAAS,KAAI,aAAY;EAC9B,OAAO,QAAQ;EACf,OAAO,QAAQ;EACf,MAAM,GAAG,QAAQ,MAAM,KAAK,QAAQ;CACtC,EAAE;AACJ;;;;AAKA,SAAgB,wBAAkC;CAChD,OAAO,SAAS,QAAO,YAAW,QAAQ,eAAe,EAAE,KAAI,YAAW,QAAQ,GAAG;AACvF;;;;AAKA,SAAgB,uBAAuB;CACrC,OAAO,YAAY,KAAI,cAAa;EAClC,OAAO,SAAS;EAChB,OAAO,SAAS;EAChB,MAAM,SAAS;CACjB,EAAE;AACJ;;;;;AAMA,SAAgB,oBAA8B;CAC5C,OAAO,CAAC,GAAG,SAAS,KAAI,YAAW,QAAQ,GAAG,GAAG,GAAG,YAAY,KAAI,aAAY,SAAS,GAAG,CAAC;AAC/F"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { getDatabaseDriver } from "../features/database-drivers.mjs";
|
|
2
|
+
import { executeCommand, runCommand } from "./exec.mjs";
|
|
3
|
+
import { getPackageManager } from "./package-manager.mjs";
|
|
4
|
+
import { template } from "./paths.mjs";
|
|
5
|
+
import { copyDirectory, copyFile, fileExists, getFile, getJsonFile, putFile, putJsonFile, renameFile } from "@warlock.js/fs";
|
|
6
|
+
import path from "path";
|
|
7
|
+
|
|
8
|
+
//#region ../../@warlock.js/create-warlock/src/helpers/app.ts
|
|
9
|
+
var App = class {
|
|
10
|
+
constructor(app) {
|
|
11
|
+
this.app = app;
|
|
12
|
+
this.files = {};
|
|
13
|
+
this.jsonFiles = {};
|
|
14
|
+
this.isInstalled = false;
|
|
15
|
+
}
|
|
16
|
+
get options() {
|
|
17
|
+
return this.app.options;
|
|
18
|
+
}
|
|
19
|
+
use(templateName) {
|
|
20
|
+
copyDirectory(template(templateName), this.path);
|
|
21
|
+
if (fileExists(this.path + "/.env.example")) copyFile(this.path + "/.env.example", this.path + "/.env");
|
|
22
|
+
renameFile(this.path + "/_.gitignore", this.path + "/.gitignore");
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
init() {
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
terminate() {}
|
|
29
|
+
install() {
|
|
30
|
+
return runCommand(getPackageManager(), ["install"], this.path);
|
|
31
|
+
}
|
|
32
|
+
async exec(command) {
|
|
33
|
+
const [commandName, ...optionsList] = command.split(" ");
|
|
34
|
+
return await executeCommand(commandName, optionsList, this.path);
|
|
35
|
+
}
|
|
36
|
+
async git() {
|
|
37
|
+
const { initializeGitRepository } = await import("./project-builder-helpers.mjs");
|
|
38
|
+
return await initializeGitRepository(this.path);
|
|
39
|
+
}
|
|
40
|
+
updatePackageJson() {
|
|
41
|
+
this.package.replace("name", this.name.replaceAll("/", "-")).replaceAll("yarn", getPackageManager()).save();
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Wire DB_DRIVER and DB_PORT into .env.
|
|
46
|
+
*
|
|
47
|
+
* The driver's npm package is installed via `warlock add` (single source for
|
|
48
|
+
* versions), so this only touches environment configuration — not deps.
|
|
49
|
+
*/
|
|
50
|
+
configureDatabaseEnv(driverValue) {
|
|
51
|
+
const driver = getDatabaseDriver(driverValue);
|
|
52
|
+
if (!driver) return this;
|
|
53
|
+
let envContent = getFile(this.path + "/.env");
|
|
54
|
+
envContent = envContent.replace(/DB_PORT=\d+/, `DB_PORT=${driver.defaultPort}`);
|
|
55
|
+
if (envContent.includes("DB_DRIVER=")) envContent = envContent.replace(/DB_DRIVER=\w*/, `DB_DRIVER=${driver.value}`);
|
|
56
|
+
else envContent = envContent.replace(/DB_PORT=\d+/, `DB_PORT=${driver.defaultPort}\nDB_DRIVER=${driver.value}`);
|
|
57
|
+
putFile(this.path + "/.env", envContent);
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Install the selected optional features by delegating to the project's own
|
|
62
|
+
* `warlock add`. `--no-install` records every dependency in package.json and
|
|
63
|
+
* ejects configs / scripts / setup hooks WITHOUT installing — the caller runs
|
|
64
|
+
* one batched install afterwards. Versions come from core's feature map, so
|
|
65
|
+
* the scaffolder never duplicates them.
|
|
66
|
+
*
|
|
67
|
+
* `--no-install` is passed LAST on purpose: the CLI parser treats the
|
|
68
|
+
* positional after a bare flag as that flag's value, so it must follow the
|
|
69
|
+
* feature list, not precede it.
|
|
70
|
+
*/
|
|
71
|
+
async installFeatures(features) {
|
|
72
|
+
if (features.length === 0) return true;
|
|
73
|
+
return this.exec(`npx warlock add ${features.join(" ")} --no-install`);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get package json file
|
|
77
|
+
*/
|
|
78
|
+
get package() {
|
|
79
|
+
return this.json("package.json");
|
|
80
|
+
}
|
|
81
|
+
updateDotEnv() {
|
|
82
|
+
this.file(".env").replaceAll("appName", this.name).save();
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get env file to update
|
|
87
|
+
*/
|
|
88
|
+
get env() {
|
|
89
|
+
return this.file(".env");
|
|
90
|
+
}
|
|
91
|
+
get name() {
|
|
92
|
+
return this.app.appName;
|
|
93
|
+
}
|
|
94
|
+
get path() {
|
|
95
|
+
return this.app.appPath;
|
|
96
|
+
}
|
|
97
|
+
file(relativePath) {
|
|
98
|
+
const fullPath = path.resolve(this.path, relativePath);
|
|
99
|
+
if (!this.files[fullPath]) this.files[fullPath] = file(fullPath);
|
|
100
|
+
return this.files[fullPath];
|
|
101
|
+
}
|
|
102
|
+
json(relativePath) {
|
|
103
|
+
const fullPath = path.resolve(this.path, relativePath);
|
|
104
|
+
if (!this.jsonFiles[fullPath]) this.jsonFiles[fullPath] = jsonFile(fullPath);
|
|
105
|
+
return this.jsonFiles[fullPath];
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
var FileManager = class {
|
|
109
|
+
constructor(filePath) {
|
|
110
|
+
this.filePath = filePath;
|
|
111
|
+
this.parseContent();
|
|
112
|
+
}
|
|
113
|
+
parseContent() {
|
|
114
|
+
this.content = getFile(this.filePath);
|
|
115
|
+
}
|
|
116
|
+
replace(search, replace) {
|
|
117
|
+
this.content = this.content.replace(search, replace);
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
replaceAll(search, replace) {
|
|
121
|
+
this.content = this.content.replaceAll(search, replace);
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
save() {
|
|
125
|
+
putFile(this.filePath, this.content);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
var JsonFileManager = class extends FileManager {
|
|
129
|
+
parseContent() {
|
|
130
|
+
this.content = getJsonFile(this.filePath);
|
|
131
|
+
}
|
|
132
|
+
save() {
|
|
133
|
+
putJsonFile(this.filePath, this.content);
|
|
134
|
+
}
|
|
135
|
+
has(key) {
|
|
136
|
+
return this.content[key] !== void 0;
|
|
137
|
+
}
|
|
138
|
+
replace(key, value) {
|
|
139
|
+
this.content[key] = value;
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
replaceAll(key, value) {
|
|
143
|
+
const contentAsString = JSON.stringify(this.content);
|
|
144
|
+
this.content = JSON.parse(contentAsString.replaceAll(key, value));
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
function file(path) {
|
|
149
|
+
return new FileManager(path);
|
|
150
|
+
}
|
|
151
|
+
function jsonFile(path) {
|
|
152
|
+
return new JsonFileManager(path);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//#endregion
|
|
156
|
+
export { App };
|
|
157
|
+
//# sourceMappingURL=app.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.mjs","names":[],"sources":["../../../../../../@warlock.js/create-warlock/src/helpers/app.ts"],"sourcesContent":["import {\r\n copyDirectory,\r\n copyFile,\r\n fileExists,\r\n getFile,\r\n getJsonFile,\r\n putFile,\r\n putJsonFile,\r\n renameFile,\r\n} from \"@warlock.js/fs\";\r\nimport path from \"path\";\r\nimport { AppOptions, Application } from \"../commands/create-new-app/types\";\r\nimport { getDatabaseDriver } from \"../features/database-drivers\";\r\nimport { executeCommand, runCommand } from \"./exec\";\r\nimport { getPackageManager } from \"./package-manager\";\r\nimport { Template, template } from \"./paths\";\r\n\r\nexport class App {\r\n /**\r\n * Resolved files\r\n */\r\n protected files: Record<string, FileManager> = {};\r\n\r\n /**\r\n * Resolved JSON files\r\n */\r\n protected jsonFiles: Record<string, JsonFileManager> = {};\r\n\r\n public isInstalled = false;\r\n\r\n public constructor(protected app: Application) {}\r\n\r\n public get options(): AppOptions {\r\n return this.app.options;\r\n }\r\n\r\n public use(templateName: Template) {\r\n copyDirectory(template(templateName), this.path);\r\n\r\n if (fileExists(this.path + \"/.env.example\")) {\r\n copyFile(this.path + \"/.env.example\", this.path + \"/.env\");\r\n }\r\n\r\n renameFile(this.path + \"/_.gitignore\", this.path + \"/.gitignore\");\r\n\r\n return this;\r\n }\r\n\r\n public init() {\r\n return this;\r\n }\r\n\r\n public terminate() {\r\n // No longer using outro, using showSuccessScreen instead\r\n }\r\n\r\n public install() {\r\n return runCommand(getPackageManager(), [\"install\"], this.path);\r\n }\r\n\r\n public async exec(command: string) {\r\n const [commandName, ...optionsList] = command.split(\" \");\r\n return await executeCommand(commandName, optionsList, this.path);\r\n }\r\n\r\n public async git() {\r\n const { initializeGitRepository } = await import(\r\n \"./project-builder-helpers\"\r\n );\r\n return await initializeGitRepository(this.path);\r\n }\r\n\r\n public updatePackageJson() {\r\n this.package\r\n .replace(\"name\", this.name.replaceAll(\"/\", \"-\"))\r\n .replaceAll(\"yarn\", getPackageManager())\r\n .save();\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Wire DB_DRIVER and DB_PORT into .env.\r\n *\r\n * The driver's npm package is installed via `warlock add` (single source for\r\n * versions), so this only touches environment configuration — not deps.\r\n */\r\n public configureDatabaseEnv(driverValue: string) {\r\n const driver = getDatabaseDriver(driverValue);\r\n\r\n if (!driver) return this;\r\n\r\n let envContent = getFile(this.path + \"/.env\") as string;\r\n\r\n envContent = envContent.replace(/DB_PORT=\\d+/, `DB_PORT=${driver.defaultPort}`);\r\n\r\n if (envContent.includes(\"DB_DRIVER=\")) {\r\n envContent = envContent.replace(/DB_DRIVER=\\w*/, `DB_DRIVER=${driver.value}`);\r\n } else {\r\n envContent = envContent.replace(\r\n /DB_PORT=\\d+/,\r\n `DB_PORT=${driver.defaultPort}\\nDB_DRIVER=${driver.value}`,\r\n );\r\n }\r\n\r\n putFile(this.path + \"/.env\", envContent);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Install the selected optional features by delegating to the project's own\r\n * `warlock add`. `--no-install` records every dependency in package.json and\r\n * ejects configs / scripts / setup hooks WITHOUT installing — the caller runs\r\n * one batched install afterwards. Versions come from core's feature map, so\r\n * the scaffolder never duplicates them.\r\n *\r\n * `--no-install` is passed LAST on purpose: the CLI parser treats the\r\n * positional after a bare flag as that flag's value, so it must follow the\r\n * feature list, not precede it.\r\n */\r\n public async installFeatures(features: string[]) {\r\n if (features.length === 0) return true;\r\n\r\n return this.exec(`npx warlock add ${features.join(\" \")} --no-install`);\r\n }\r\n\r\n /**\r\n * Get package json file\r\n */\r\n public get package() {\r\n return this.json(\"package.json\");\r\n }\r\n\r\n public updateDotEnv() {\r\n this.file(\".env\").replaceAll(\"appName\", this.name).save();\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Get env file to update\r\n */\r\n public get env() {\r\n return this.file(\".env\");\r\n }\r\n\r\n public get name() {\r\n return this.app.appName;\r\n }\r\n\r\n public get path() {\r\n return this.app.appPath;\r\n }\r\n\r\n public file(relativePath: string) {\r\n const fullPath = path.resolve(this.path, relativePath);\r\n\r\n if (!this.files[fullPath]) {\r\n this.files[fullPath] = file(fullPath);\r\n }\r\n\r\n return this.files[fullPath];\r\n }\r\n\r\n public json(relativePath: string): JsonFileManager {\r\n const fullPath = path.resolve(this.path, relativePath);\r\n\r\n if (!this.jsonFiles[fullPath]) {\r\n this.jsonFiles[fullPath] = jsonFile(fullPath);\r\n }\r\n\r\n return this.jsonFiles[fullPath];\r\n }\r\n}\r\n\r\nexport function app(app: Application) {\r\n return new App(app);\r\n}\r\n\r\nexport class FileManager {\r\n public content!: string;\r\n public constructor(protected filePath: string) {\r\n this.parseContent();\r\n }\r\n\r\n protected parseContent() {\r\n this.content = getFile(this.filePath) as string;\r\n }\r\n\r\n public replace(search: string, replace: string) {\r\n this.content = this.content.replace(search, replace);\r\n\r\n return this;\r\n }\r\n\r\n public replaceAll(search: string, replace: string) {\r\n this.content = this.content.replaceAll(search, replace);\r\n\r\n return this;\r\n }\r\n\r\n public save() {\r\n putFile(this.filePath, this.content);\r\n }\r\n}\r\n\r\nexport class JsonFileManager extends FileManager {\r\n protected parseContent() {\r\n this.content = getJsonFile(this.filePath);\r\n }\r\n\r\n public save() {\r\n putJsonFile(this.filePath, this.content);\r\n }\r\n\r\n public has(key: string) {\r\n return this.content[key] !== undefined;\r\n }\r\n\r\n public replace(key: string, value: any) {\r\n this.content[key] = value;\r\n\r\n return this;\r\n }\r\n\r\n public replaceAll(key: string, value: any) {\r\n const contentAsString = JSON.stringify(this.content);\r\n\r\n this.content = JSON.parse(contentAsString.replaceAll(key, value));\r\n\r\n return this;\r\n }\r\n}\r\n\r\nexport function file(path: string) {\r\n return new FileManager(path);\r\n}\r\n\r\nexport function jsonFile(path: string) {\r\n return new JsonFileManager(path);\r\n}\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { log } from "@clack/prompts";
|
|
2
|
+
import { colors } from "@mongez/copper";
|
|
3
|
+
import childProcess from "cross-spawn";
|
|
4
|
+
|
|
5
|
+
//#region ../../@warlock.js/create-warlock/src/helpers/exec.ts
|
|
6
|
+
/**
|
|
7
|
+
* This function directly executes a command
|
|
8
|
+
*/
|
|
9
|
+
async function executeCommand(cmd, args, cwd) {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
const child = childProcess(cmd, args, {
|
|
12
|
+
cwd,
|
|
13
|
+
stdio: "ignore"
|
|
14
|
+
});
|
|
15
|
+
child.on("error", (e) => {
|
|
16
|
+
if (e) if (e.message) log.error(colors.red(String(e.message)) + `\n\n`);
|
|
17
|
+
else log.error(colors.red(String(e)) + `\n\n`);
|
|
18
|
+
resolve(false);
|
|
19
|
+
});
|
|
20
|
+
child.on("close", (code) => {
|
|
21
|
+
if (code === 0) resolve(true);
|
|
22
|
+
else resolve(false);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function runCommand(cmd, args, cwd) {
|
|
27
|
+
let child;
|
|
28
|
+
const install = new Promise((resolve) => {
|
|
29
|
+
try {
|
|
30
|
+
child = childProcess(cmd, args, {
|
|
31
|
+
cwd,
|
|
32
|
+
stdio: "ignore"
|
|
33
|
+
});
|
|
34
|
+
child.on("error", (e) => {
|
|
35
|
+
if (e) if (e.message) log.error(colors.red(String(e.message)) + `\n\n`);
|
|
36
|
+
else log.error(colors.red(String(e)) + `\n\n`);
|
|
37
|
+
resolve(false);
|
|
38
|
+
});
|
|
39
|
+
child.on("close", (code) => {
|
|
40
|
+
if (code === 0) resolve(true);
|
|
41
|
+
else resolve(false);
|
|
42
|
+
});
|
|
43
|
+
} catch (e) {
|
|
44
|
+
resolve(false);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const abort = async () => {
|
|
48
|
+
if (child) child.kill("SIGINT");
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
abort,
|
|
52
|
+
install
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
export { executeCommand, runCommand };
|
|
58
|
+
//# sourceMappingURL=exec.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.mjs","names":["spawn"],"sources":["../../../../../../@warlock.js/create-warlock/src/helpers/exec.ts"],"sourcesContent":["import { log } from \"@clack/prompts\";\r\nimport { colors } from \"@mongez/copper\";\r\nimport { ChildProcess } from \"child_process\";\r\nimport { default as childProcess, default as spawn } from \"cross-spawn\";\r\n\r\nexport default async function exec(command: string, options: any = {}) {\r\n const [commandName, ...optionsList] = command.split(\" \");\r\n\r\n const commandOutput = childProcess.sync(commandName, optionsList, options);\r\n\r\n // it means command didn't end as expected, then stop the rest of the program\r\n if (commandOutput.error !== null) {\r\n process.exit(1);\r\n }\r\n\r\n return commandOutput;\r\n}\r\n\r\n/**\r\n * This function directly executes a command\r\n */\r\nexport async function executeCommand(cmd: string, args: string[], cwd: string) {\r\n return new Promise<boolean>(resolve => {\r\n const child = spawn(cmd, args, {\r\n cwd,\r\n stdio: \"ignore\",\r\n });\r\n\r\n child.on(\"error\", e => {\r\n if (e) {\r\n if (e.message) {\r\n log.error(colors.red(String(e.message)) + `\\n\\n`);\r\n } else {\r\n log.error(colors.red(String(e)) + `\\n\\n`);\r\n }\r\n }\r\n resolve(false);\r\n });\r\n\r\n child.on(\"close\", code => {\r\n if (code === 0) {\r\n resolve(true);\r\n } else {\r\n resolve(false);\r\n }\r\n });\r\n });\r\n}\r\n\r\nexport function runCommand(cmd: string, args: string[], cwd: string) {\r\n let child: ChildProcess;\r\n\r\n const install = new Promise<boolean>(resolve => {\r\n try {\r\n child = spawn(cmd, args, {\r\n cwd,\r\n stdio: \"ignore\",\r\n });\r\n\r\n child.on(\"error\", e => {\r\n if (e) {\r\n if (e.message) {\r\n log.error(colors.red(String(e.message)) + `\\n\\n`);\r\n } else {\r\n log.error(colors.red(String(e)) + `\\n\\n`);\r\n }\r\n }\r\n resolve(false);\r\n });\r\n\r\n child.on(\"close\", code => {\r\n if (code === 0) {\r\n resolve(true);\r\n } else {\r\n resolve(false);\r\n }\r\n });\r\n } catch (e) {\r\n resolve(false);\r\n }\r\n });\r\n\r\n const abort = async () => {\r\n if (child) {\r\n child.kill(\"SIGINT\");\r\n }\r\n };\r\n\r\n return { abort, install };\r\n}\r\n"],"mappings":";;;;;;;;AAqBA,eAAsB,eAAe,KAAa,MAAgB,KAAa;CAC7E,OAAO,IAAI,SAAiB,YAAW;EACrC,MAAM,QAAQA,aAAM,KAAK,MAAM;GAC7B;GACA,OAAO;EACT,CAAC;EAED,MAAM,GAAG,UAAS,MAAK;GACrB,IAAI,GACF,IAAI,EAAE,SACJ,IAAI,MAAM,OAAO,IAAI,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM;QAEhD,IAAI,MAAM,OAAO,IAAI,OAAO,CAAC,CAAC,IAAI,MAAM;GAG5C,QAAQ,KAAK;EACf,CAAC;EAED,MAAM,GAAG,UAAS,SAAQ;GACxB,IAAI,SAAS,GACX,QAAQ,IAAI;QAEZ,QAAQ,KAAK;EAEjB,CAAC;CACH,CAAC;AACH;AAEA,SAAgB,WAAW,KAAa,MAAgB,KAAa;CACnE,IAAI;CAEJ,MAAM,UAAU,IAAI,SAAiB,YAAW;EAC9C,IAAI;GACF,QAAQA,aAAM,KAAK,MAAM;IACvB;IACA,OAAO;GACT,CAAC;GAED,MAAM,GAAG,UAAS,MAAK;IACrB,IAAI,GACF,IAAI,EAAE,SACJ,IAAI,MAAM,OAAO,IAAI,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM;SAEhD,IAAI,MAAM,OAAO,IAAI,OAAO,CAAC,CAAC,IAAI,MAAM;IAG5C,QAAQ,KAAK;GACf,CAAC;GAED,MAAM,GAAG,UAAS,SAAQ;IACxB,IAAI,SAAS,GACX,QAAQ,IAAI;SAEZ,QAAQ,KAAK;GAEjB,CAAC;EACH,SAAS,GAAG;GACV,QAAQ,KAAK;EACf;CACF,CAAC;CAED,MAAM,QAAQ,YAAY;EACxB,IAAI,OACF,MAAM,KAAK,QAAQ;CAEvB;CAEA,OAAO;EAAE;EAAO;CAAQ;AAC1B"}
|