@donotdev/cli 0.0.13 → 0.0.15
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/dependencies-matrix.json +357 -89
- package/dist/bin/commands/agent-setup.d.ts +6 -0
- package/dist/bin/commands/agent-setup.d.ts.map +1 -0
- package/dist/bin/commands/agent-setup.js +629 -0
- package/dist/bin/commands/agent-setup.js.map +1 -0
- package/dist/bin/commands/build.js +131 -50
- package/dist/bin/commands/bump.js +137 -49
- package/dist/bin/commands/cacheout.js +50 -21
- package/dist/bin/commands/create-app.js +270 -261
- package/dist/bin/commands/create-project.js +418 -197
- package/dist/bin/commands/deploy.js +1752 -712
- package/dist/bin/commands/dev.js +151 -35
- package/dist/bin/commands/emu.js +228 -70
- package/dist/bin/commands/format.js +50 -21
- package/dist/bin/commands/lint.js +50 -21
- package/dist/bin/commands/preview.js +155 -35
- package/dist/bin/commands/supabase-setup.d.ts +6 -0
- package/dist/bin/commands/supabase-setup.d.ts.map +1 -0
- package/dist/bin/commands/supabase-setup.js +7 -0
- package/dist/bin/commands/supabase-setup.js.map +1 -0
- package/dist/bin/commands/sync-secrets.js +224 -46
- package/dist/bin/commands/type-check.d.ts +14 -0
- package/dist/bin/commands/type-check.d.ts.map +1 -0
- package/dist/bin/commands/type-check.js +314 -0
- package/dist/bin/commands/type-check.js.map +1 -0
- package/dist/bin/commands/wai.js +7399 -11
- package/dist/bin/dndev.js +27 -2
- package/dist/bin/donotdev.js +27 -2
- package/dist/index.js +3960 -2996
- package/package.json +2 -2
- package/templates/app-demo/src/App.tsx.example +1 -0
- package/templates/app-demo/src/pages/FullPage.tsx.example +2 -2
- package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +2 -2
- package/templates/app-demo/src/themes.css.example +5 -12
- package/templates/app-expo/.env.example +64 -0
- package/templates/app-expo/.expo/README.md.example +5 -0
- package/templates/app-expo/.gitignore.example +36 -0
- package/templates/app-expo/README.md.example +58 -0
- package/templates/app-expo/app/.gitkeep +2 -0
- package/templates/app-expo/app/_layout.tsx.example +41 -0
- package/templates/app-expo/app/form.tsx.example +52 -0
- package/templates/app-expo/app/index.tsx.example +89 -0
- package/templates/app-expo/app/list.tsx.example +32 -0
- package/templates/app-expo/app/profile.tsx.example +76 -0
- package/templates/app-expo/app/signin.tsx.example +53 -0
- package/templates/app-expo/app.json.example +39 -0
- package/templates/app-expo/babel.config.js.example +10 -0
- package/templates/app-expo/eas.json.example +20 -0
- package/templates/app-expo/expo-env.d.ts.example +4 -0
- package/templates/app-expo/metro.config.js.example +20 -0
- package/templates/app-expo/service-account-key.json.example +12 -0
- package/templates/app-expo/tsconfig.json.example +19 -0
- package/templates/app-next/.env.example +4 -33
- package/templates/app-next/src/app/ClientLayout.tsx.example +2 -0
- package/templates/app-next/src/app/layout.tsx.example +7 -6
- package/templates/app-next/src/globals.css.example +2 -11
- package/templates/app-next/src/pages/HomePage.tsx.example +1 -1
- package/templates/app-next/src/themes.css.example +10 -13
- package/templates/app-vite/.env.example +3 -32
- package/templates/app-vite/index.html.example +2 -24
- package/templates/app-vite/src/App.tsx.example +2 -0
- package/templates/app-vite/src/globals.css.example +2 -12
- package/templates/app-vite/src/pages/FormPageExample.tsx.example +1 -2
- package/templates/app-vite/src/pages/HomePage.tsx.example +1 -1
- package/templates/app-vite/src/themes.css.example +109 -79
- package/templates/app-vite/vercel.json.example +11 -0
- package/templates/functions-firebase/build.mjs.example +2 -72
- package/templates/functions-firebase/functions-firebase/.env.example.example +23 -25
- package/templates/functions-firebase/functions-firebase/build.mjs.example +2 -72
- package/templates/functions-firebase/functions-firebase/tsconfig.json.example +1 -1
- package/templates/functions-supabase/supabase/functions/cancel-subscription/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/change-plan/index.ts.example +11 -0
- package/templates/functions-supabase/supabase/functions/create-checkout-session/index.ts.example +11 -0
- package/templates/functions-supabase/supabase/functions/create-customer-portal/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/crud/index.ts.example +16 -0
- package/templates/functions-supabase/supabase/functions/delete-account/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/get-custom-claims/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/get-user-auth-status/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/refresh-subscription-status/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/remove-custom-claims/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/set-custom-claims/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/migrations/20250101000000_idempotency.sql +24 -0
- package/templates/functions-supabase/supabase/migrations/20250101000001_rate_limits.sql +22 -0
- package/templates/functions-supabase/supabase/migrations/20250101000002_cleanup_jobs.sql +28 -0
- package/templates/functions-supabase/supabase/migrations/20250101000003_operation_metrics.sql +28 -0
- package/templates/functions-vercel/functions-vercel/tsconfig.json.example +1 -1
- package/templates/functions-vercel/functions-vercel/vercel.json.example +1 -1
- package/templates/functions-vercel/vercel.json.example +1 -1
- package/templates/github/github/workflows/firebase-deploy.yml.example +1 -1
- package/templates/github/workflows/firebase-deploy.yml.example +1 -1
- package/templates/overlay-firebase/env.fragment.example +34 -0
- package/templates/overlay-firebase/env.fragment.expo.example +34 -0
- package/templates/overlay-firebase/env.fragment.nextjs.example +34 -0
- package/templates/overlay-firebase/src/config/providers.expo.ts.example +49 -0
- package/templates/overlay-firebase/src/config/providers.ts.example +23 -0
- package/templates/overlay-supabase/env.fragment.example +7 -0
- package/templates/overlay-supabase/env.fragment.expo.example +7 -0
- package/templates/overlay-supabase/env.fragment.nextjs.example +7 -0
- package/templates/overlay-supabase/src/config/providers.expo.ts.example +35 -0
- package/templates/overlay-supabase/src/config/providers.ts.example +33 -0
- package/templates/overlay-supabase/vercel.headers.example +23 -0
- package/templates/overlay-supabase/vercel.json.example +22 -0
- package/templates/overlay-vercel/env.fragment.example +34 -0
- package/templates/overlay-vercel/env.fragment.nextjs.example +34 -0
- package/templates/overlay-vercel/src/config/providers.ts.example +24 -0
- package/templates/root-consumer/.claude/agents/architect.md.example +2 -310
- package/templates/root-consumer/.claude/agents/builder.md.example +2 -326
- package/templates/root-consumer/.claude/agents/coder.md.example +2 -83
- package/templates/root-consumer/.claude/agents/extractor.md.example +2 -231
- package/templates/root-consumer/.claude/agents/polisher.md.example +2 -132
- package/templates/root-consumer/.claude/agents/prompt-engineer.md.example +2 -81
- package/templates/root-consumer/.claude/commands/brainstorm.md.example +1 -1
- package/templates/root-consumer/.claude/commands/build.md.example +1 -1
- package/templates/root-consumer/.claude/commands/design.md.example +1 -1
- package/templates/root-consumer/.claude/commands/grill.md.example +30 -0
- package/templates/root-consumer/.claude/commands/polish.md.example +1 -1
- package/templates/root-consumer/.claude/commands/techdebt.md.example +28 -0
- package/templates/root-consumer/.clinerules.example +1 -0
- package/templates/root-consumer/.cursor/rules/no-docs.mdc.example +15 -0
- package/templates/root-consumer/.cursorrules.example +1 -0
- package/templates/root-consumer/.dndev/args.json.example +6 -0
- package/templates/root-consumer/.gemini/settings.json.example +2 -2
- package/templates/root-consumer/.github/copilot-instructions.md.example +1 -0
- package/templates/root-consumer/.windsurfrules.example +1 -0
- package/templates/root-consumer/AI.md.example +25 -108
- package/templates/root-consumer/CLAUDE.md.example +1 -128
- package/templates/root-consumer/CONVENTIONS.md.example +1 -0
- package/templates/root-consumer/GEMINI.md.example +1 -0
- package/templates/root-consumer/firebase.json.example +1 -1
- package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +54 -0
- package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +0 -18
- package/templates/root-consumer/guides/dndev/COMPONENTS_UI.md.example +1 -1
- package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +99 -30
- package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +186 -0
- package/templates/root-consumer/guides/dndev/INDEX.md.example +4 -1
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +143 -12
- package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +9 -3
- package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +12 -7
- package/templates/root-consumer/guides/dndev/SETUP_SOC2.md.example +234 -0
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +124 -0
- package/templates/root-consumer/guides/dndev/SETUP_THEMES.md.example +6 -2
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +176 -0
- package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +5 -9
- package/templates/root-consumer/guides/dndev/essences_reference.css.example +174 -0
- package/templates/root-consumer/guides/wai-way/agents/builder.md.example +10 -0
- package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +25 -5
- package/templates/root-consumer/guides/wai-way/agents/polisher.md.example +13 -2
- package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +2 -2
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +47 -11
- package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +15 -4
- package/templates/root-consumer/guides/wai-way/spec_template.md.example +7 -6
- package/templates/app-payload/.env.example +0 -28
- package/templates/app-payload/README.md.example +0 -233
- package/templates/app-payload/collections/Company.ts.example +0 -125
- package/templates/app-payload/collections/Hero.ts.example +0 -62
- package/templates/app-payload/collections/Media.ts.example +0 -41
- package/templates/app-payload/collections/Products.ts.example +0 -115
- package/templates/app-payload/collections/Services.ts.example +0 -104
- package/templates/app-payload/collections/Testimonials.ts.example +0 -92
- package/templates/app-payload/collections/Users.ts.example +0 -35
- package/templates/app-payload/src/server.ts.example +0 -79
- package/templates/app-payload/tsconfig.json.example +0 -24
|
@@ -2139,7 +2139,7 @@ var require_parse = __commonJS({
|
|
|
2139
2139
|
CHAR_NO_BREAK_SPACE,
|
|
2140
2140
|
CHAR_ZERO_WIDTH_NOBREAK_SPACE
|
|
2141
2141
|
} = require_constants();
|
|
2142
|
-
var
|
|
2142
|
+
var parse2 = (input, options = {}) => {
|
|
2143
2143
|
if (typeof input !== "string") {
|
|
2144
2144
|
throw new TypeError("Expected a string");
|
|
2145
2145
|
}
|
|
@@ -2339,7 +2339,7 @@ var require_parse = __commonJS({
|
|
|
2339
2339
|
push({ type: "eos" });
|
|
2340
2340
|
return ast;
|
|
2341
2341
|
};
|
|
2342
|
-
module.exports =
|
|
2342
|
+
module.exports = parse2;
|
|
2343
2343
|
}
|
|
2344
2344
|
});
|
|
2345
2345
|
|
|
@@ -2351,7 +2351,7 @@ var require_braces = __commonJS({
|
|
|
2351
2351
|
var stringify2 = require_stringify();
|
|
2352
2352
|
var compile = require_compile();
|
|
2353
2353
|
var expand = require_expand();
|
|
2354
|
-
var
|
|
2354
|
+
var parse2 = require_parse();
|
|
2355
2355
|
var braces = (input, options = {}) => {
|
|
2356
2356
|
let output = [];
|
|
2357
2357
|
if (Array.isArray(input)) {
|
|
@@ -2371,7 +2371,7 @@ var require_braces = __commonJS({
|
|
|
2371
2371
|
}
|
|
2372
2372
|
return output;
|
|
2373
2373
|
};
|
|
2374
|
-
braces.parse = (input, options = {}) =>
|
|
2374
|
+
braces.parse = (input, options = {}) => parse2(input, options);
|
|
2375
2375
|
braces.stringify = (input, options = {}) => {
|
|
2376
2376
|
if (typeof input === "string") {
|
|
2377
2377
|
return stringify2(braces.parse(input, options), options);
|
|
@@ -3028,7 +3028,7 @@ var require_parse2 = __commonJS({
|
|
|
3028
3028
|
var syntaxError = (type, char) => {
|
|
3029
3029
|
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
|
|
3030
3030
|
};
|
|
3031
|
-
var
|
|
3031
|
+
var parse2 = (input, options) => {
|
|
3032
3032
|
if (typeof input !== "string") {
|
|
3033
3033
|
throw new TypeError("Expected a string");
|
|
3034
3034
|
}
|
|
@@ -3177,7 +3177,7 @@ var require_parse2 = __commonJS({
|
|
|
3177
3177
|
output = token.close = `)$))${extglobStar}`;
|
|
3178
3178
|
}
|
|
3179
3179
|
if (token.inner.includes("*") && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
|
|
3180
|
-
const expression =
|
|
3180
|
+
const expression = parse2(rest, { ...options, fastpaths: false }).output;
|
|
3181
3181
|
output = token.close = `)${expression})${extglobStar})`;
|
|
3182
3182
|
}
|
|
3183
3183
|
if (token.prev.type === "bos") {
|
|
@@ -3702,7 +3702,7 @@ var require_parse2 = __commonJS({
|
|
|
3702
3702
|
}
|
|
3703
3703
|
return state;
|
|
3704
3704
|
};
|
|
3705
|
-
|
|
3705
|
+
parse2.fastpaths = (input, options) => {
|
|
3706
3706
|
const opts = { ...options };
|
|
3707
3707
|
const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
|
|
3708
3708
|
const len = input.length;
|
|
@@ -3768,7 +3768,7 @@ var require_parse2 = __commonJS({
|
|
|
3768
3768
|
}
|
|
3769
3769
|
return source;
|
|
3770
3770
|
};
|
|
3771
|
-
module.exports =
|
|
3771
|
+
module.exports = parse2;
|
|
3772
3772
|
}
|
|
3773
3773
|
});
|
|
3774
3774
|
|
|
@@ -3779,7 +3779,7 @@ var require_picomatch = __commonJS({
|
|
|
3779
3779
|
init_utils();
|
|
3780
3780
|
var path = __require("path");
|
|
3781
3781
|
var scan = require_scan();
|
|
3782
|
-
var
|
|
3782
|
+
var parse2 = require_parse2();
|
|
3783
3783
|
var utils = require_utils2();
|
|
3784
3784
|
var constants2 = require_constants2();
|
|
3785
3785
|
var isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
|
|
@@ -3867,7 +3867,7 @@ var require_picomatch = __commonJS({
|
|
|
3867
3867
|
picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
|
|
3868
3868
|
picomatch.parse = (pattern, options) => {
|
|
3869
3869
|
if (Array.isArray(pattern)) return pattern.map((p2) => picomatch.parse(p2, options));
|
|
3870
|
-
return
|
|
3870
|
+
return parse2(pattern, { ...options, fastpaths: false });
|
|
3871
3871
|
};
|
|
3872
3872
|
picomatch.scan = (input, options) => scan(input, options);
|
|
3873
3873
|
picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
|
|
@@ -3893,10 +3893,10 @@ var require_picomatch = __commonJS({
|
|
|
3893
3893
|
}
|
|
3894
3894
|
let parsed = { negated: false, fastpaths: true };
|
|
3895
3895
|
if (options.fastpaths !== false && (input[0] === "." || input[0] === "*")) {
|
|
3896
|
-
parsed.output =
|
|
3896
|
+
parsed.output = parse2.fastpaths(input, options);
|
|
3897
3897
|
}
|
|
3898
3898
|
if (!parsed.output) {
|
|
3899
|
-
parsed =
|
|
3899
|
+
parsed = parse2(input, options);
|
|
3900
3900
|
}
|
|
3901
3901
|
return picomatch.compileRe(parsed, options, returnOutput, returnState);
|
|
3902
3902
|
};
|
|
@@ -7758,11 +7758,39 @@ var init_PathResolver = __esm({
|
|
|
7758
7758
|
});
|
|
7759
7759
|
|
|
7760
7760
|
// packages/tooling/src/utils/errors.ts
|
|
7761
|
-
var DoNotDevError;
|
|
7761
|
+
var DO_NOT_DEV_ERROR_CODES, DoNotDevError;
|
|
7762
7762
|
var init_errors = __esm({
|
|
7763
7763
|
"packages/tooling/src/utils/errors.ts"() {
|
|
7764
7764
|
"use strict";
|
|
7765
7765
|
init_utils();
|
|
7766
|
+
DO_NOT_DEV_ERROR_CODES = {
|
|
7767
|
+
CONFIGURATION_ERROR: "configuration-error",
|
|
7768
|
+
CONFIG_NOT_FOUND: "config-not-found",
|
|
7769
|
+
CONFIG_INVALID: "config-invalid",
|
|
7770
|
+
PATH_RESOLUTION_ERROR: "path-resolution-error",
|
|
7771
|
+
FILE_OPERATION_ERROR: "file-operation-error",
|
|
7772
|
+
FILE_NOT_FOUND: "file-not-found",
|
|
7773
|
+
PERMISSION_DENIED: "permission-denied",
|
|
7774
|
+
GENERATION_ERROR: "generation-error",
|
|
7775
|
+
TEMPLATE_ERROR: "template-error",
|
|
7776
|
+
TEMPLATE_NOT_FOUND: "template-not-found",
|
|
7777
|
+
CLI_EXECUTION_ERROR: "cli-execution-error",
|
|
7778
|
+
COMMAND_NOT_FOUND: "command-not-found",
|
|
7779
|
+
COMMAND_FAILED: "command-failed",
|
|
7780
|
+
VALIDATION_ERROR: "validation-error",
|
|
7781
|
+
SCHEMA_ERROR: "schema-error",
|
|
7782
|
+
DEPENDENCY_ERROR: "dependency-error",
|
|
7783
|
+
DEPENDENCY_NOT_FOUND: "dependency-not-found",
|
|
7784
|
+
DEPENDENCY_VERSION_ERROR: "dependency-version-error",
|
|
7785
|
+
INVALID_ARGUMENT: "invalid-argument",
|
|
7786
|
+
MISSING_ARGUMENT: "missing-argument",
|
|
7787
|
+
MISSING_PROJECT_ID: "missing-project-id",
|
|
7788
|
+
FIREBASE_CLI_ERROR: "firebase-cli-error",
|
|
7789
|
+
DEPLOYMENT_FAILED: "deployment-failed",
|
|
7790
|
+
OPERATION_CANCELLED: "operation-cancelled",
|
|
7791
|
+
TIMEOUT_ERROR: "timeout-error",
|
|
7792
|
+
UNKNOWN_ERROR: "unknown-error"
|
|
7793
|
+
};
|
|
7766
7794
|
DoNotDevError = class _DoNotDevError extends Error {
|
|
7767
7795
|
/** The error code categorizing this error */
|
|
7768
7796
|
code;
|
|
@@ -7782,7 +7810,7 @@ var init_errors = __esm({
|
|
|
7782
7810
|
* @param {Record<string, any>} [options.context] - Additional context data
|
|
7783
7811
|
* @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
|
|
7784
7812
|
*/
|
|
7785
|
-
constructor(message, code =
|
|
7813
|
+
constructor(message, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
|
|
7786
7814
|
super(message);
|
|
7787
7815
|
this.name = "DoNotDevError";
|
|
7788
7816
|
this.code = code;
|
|
@@ -7813,7 +7841,7 @@ var init_errors = __esm({
|
|
|
7813
7841
|
* @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
|
|
7814
7842
|
* @returns {DoNotDevError} New DoNotDev error wrapping the original
|
|
7815
7843
|
*/
|
|
7816
|
-
static from(error2, context, code =
|
|
7844
|
+
static from(error2, context, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
|
|
7817
7845
|
if (!(error2 instanceof Error)) {
|
|
7818
7846
|
return new _DoNotDevError(
|
|
7819
7847
|
`Unknown error: ${String(error2)}`,
|
|
@@ -7850,21 +7878,21 @@ var init_errors = __esm({
|
|
|
7850
7878
|
}
|
|
7851
7879
|
const message = error2.message.toLowerCase();
|
|
7852
7880
|
if (error2.name === "ValidationError" || message.includes("validation")) {
|
|
7853
|
-
return
|
|
7881
|
+
return DO_NOT_DEV_ERROR_CODES.VALIDATION_ERROR;
|
|
7854
7882
|
}
|
|
7855
7883
|
if (message.includes("not found") || message.includes("no such file")) {
|
|
7856
|
-
return
|
|
7884
|
+
return DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND;
|
|
7857
7885
|
}
|
|
7858
7886
|
if (message.includes("permission") || message.includes("access denied")) {
|
|
7859
|
-
return
|
|
7887
|
+
return DO_NOT_DEV_ERROR_CODES.PERMISSION_DENIED;
|
|
7860
7888
|
}
|
|
7861
7889
|
if (message.includes("timeout") || message.includes("timed out")) {
|
|
7862
|
-
return
|
|
7890
|
+
return DO_NOT_DEV_ERROR_CODES.TIMEOUT_ERROR;
|
|
7863
7891
|
}
|
|
7864
7892
|
if (message.includes("dependency") || message.includes("module not found")) {
|
|
7865
|
-
return
|
|
7893
|
+
return DO_NOT_DEV_ERROR_CODES.DEPENDENCY_ERROR;
|
|
7866
7894
|
}
|
|
7867
|
-
return
|
|
7895
|
+
return DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR;
|
|
7868
7896
|
}
|
|
7869
7897
|
};
|
|
7870
7898
|
}
|
|
@@ -7884,6 +7912,7 @@ __export(pathResolver_exports, {
|
|
|
7884
7912
|
ensureDirSync: () => ensureDirSync,
|
|
7885
7913
|
findFiles: () => findFiles,
|
|
7886
7914
|
findNodeModulesDir: () => findNodeModulesDir,
|
|
7915
|
+
findPackageRootUp: () => findPackageRootUp,
|
|
7887
7916
|
fromAppRoot: () => fromAppRoot,
|
|
7888
7917
|
getAppRoot: () => getAppRoot,
|
|
7889
7918
|
getBasename: () => getBasename,
|
|
@@ -7900,7 +7929,6 @@ __export(pathResolver_exports, {
|
|
|
7900
7929
|
getRelativePathBetween: () => getRelativePathBetween,
|
|
7901
7930
|
getRepoRoot: () => getRepoRoot,
|
|
7902
7931
|
getTemplatesRoot: () => getTemplatesRoot,
|
|
7903
|
-
getToolingPath: () => getToolingPath,
|
|
7904
7932
|
glob: () => glob,
|
|
7905
7933
|
globSync: () => globSync,
|
|
7906
7934
|
isAbsolute: () => isAbsolute,
|
|
@@ -7939,6 +7967,7 @@ import {
|
|
|
7939
7967
|
extname as extname2,
|
|
7940
7968
|
relative as relative2,
|
|
7941
7969
|
resolve as resolve2,
|
|
7970
|
+
parse,
|
|
7942
7971
|
isAbsolute as pathIsAbsolute
|
|
7943
7972
|
} from "node:path";
|
|
7944
7973
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -7995,37 +8024,22 @@ function getBinPath(binaryName) {
|
|
|
7995
8024
|
}
|
|
7996
8025
|
return binaryName;
|
|
7997
8026
|
}
|
|
7998
|
-
function getToolingPath() {
|
|
7999
|
-
const mode = detectExecutionMode();
|
|
8000
|
-
if (mode === "development") {
|
|
8001
|
-
const repoRoot = getRepoRoot();
|
|
8002
|
-
const packagesToolingPath = normalizePath(repoRoot, PACKAGE_PATHS.TOOLING);
|
|
8003
|
-
if (pathExists(packagesToolingPath)) {
|
|
8004
|
-
return normalizePath(packagesToolingPath);
|
|
8005
|
-
}
|
|
8006
|
-
}
|
|
8007
|
-
throw new DoNotDevError(
|
|
8008
|
-
"Could not find tooling package. This function is only available in development mode.",
|
|
8009
|
-
"path-resolution-error"
|
|
8010
|
-
);
|
|
8011
|
-
}
|
|
8012
8027
|
function detectExecutionMode() {
|
|
8013
|
-
const
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
return "development";
|
|
8028
|
+
const fileUrlPath = fileURLToPath2(import.meta.url);
|
|
8029
|
+
if (fileUrlPath.includes("node_modules")) {
|
|
8030
|
+
return "published";
|
|
8017
8031
|
}
|
|
8018
|
-
|
|
8019
|
-
if (fileUrlPath.includes("node_modules/@donotdev/cli")) {
|
|
8032
|
+
if (fileUrlPath.includes("/dist/")) {
|
|
8020
8033
|
return "published";
|
|
8021
8034
|
}
|
|
8022
|
-
return "
|
|
8035
|
+
return "development";
|
|
8023
8036
|
}
|
|
8024
8037
|
function getTemplatesRoot() {
|
|
8025
8038
|
const mode = detectExecutionMode();
|
|
8026
8039
|
if (mode === "development") {
|
|
8027
|
-
const
|
|
8028
|
-
|
|
8040
|
+
const fileUrlPath = fileURLToPath2(import.meta.url);
|
|
8041
|
+
const frameworkRoot = normalizePath(dirname2(fileUrlPath), "../../../..");
|
|
8042
|
+
return normalizePath(frameworkRoot, PACKAGE_PATHS.CLI, "templates");
|
|
8029
8043
|
} else {
|
|
8030
8044
|
try {
|
|
8031
8045
|
const cliRoot2 = resolveFrameworkPackage("@donotdev/cli");
|
|
@@ -8047,10 +8061,43 @@ function getTemplatesRoot() {
|
|
|
8047
8061
|
}
|
|
8048
8062
|
} catch {
|
|
8049
8063
|
}
|
|
8064
|
+
try {
|
|
8065
|
+
const currentScriptDir = getDirnameFromUrl(import.meta.url);
|
|
8066
|
+
const packageRoot = findPackageRootUp(currentScriptDir, "@donotdev/cli");
|
|
8067
|
+
if (packageRoot) {
|
|
8068
|
+
const templatesPath = normalizePath(packageRoot, "templates");
|
|
8069
|
+
if (pathExists(templatesPath)) {
|
|
8070
|
+
return templatesPath;
|
|
8071
|
+
}
|
|
8072
|
+
}
|
|
8073
|
+
} catch {
|
|
8074
|
+
}
|
|
8050
8075
|
const cliRoot = getCliRootFromBundle();
|
|
8051
8076
|
return normalizePath(cliRoot, "templates");
|
|
8052
8077
|
}
|
|
8053
8078
|
}
|
|
8079
|
+
function findPackageRootUp(startDir, packageName) {
|
|
8080
|
+
let currentDir = normalizePath(startDir);
|
|
8081
|
+
const root = parse(currentDir).root;
|
|
8082
|
+
const fs2 = createRequire2(import.meta.url)("node:fs");
|
|
8083
|
+
while (currentDir !== root) {
|
|
8084
|
+
const packageJsonPath = joinPath(currentDir, "package.json");
|
|
8085
|
+
if (fs2.existsSync(packageJsonPath)) {
|
|
8086
|
+
try {
|
|
8087
|
+
const content = fs2.readFileSync(packageJsonPath, "utf8");
|
|
8088
|
+
const pkg = JSON.parse(content);
|
|
8089
|
+
if (pkg.name === packageName) {
|
|
8090
|
+
return currentDir;
|
|
8091
|
+
}
|
|
8092
|
+
} catch {
|
|
8093
|
+
}
|
|
8094
|
+
}
|
|
8095
|
+
const parentDir = getDirname(currentDir);
|
|
8096
|
+
if (parentDir === currentDir) break;
|
|
8097
|
+
currentDir = parentDir;
|
|
8098
|
+
}
|
|
8099
|
+
return null;
|
|
8100
|
+
}
|
|
8054
8101
|
function getCliRootFromBundle() {
|
|
8055
8102
|
const currentDir = getDirnameFromUrl(import.meta.url);
|
|
8056
8103
|
return normalizePath(currentDir, "..", "..", "..");
|
|
@@ -8170,7 +8217,6 @@ var init_pathResolver = __esm({
|
|
|
8170
8217
|
"use strict";
|
|
8171
8218
|
init_utils();
|
|
8172
8219
|
init_PathResolver();
|
|
8173
|
-
init_errors();
|
|
8174
8220
|
pathResolverInstance = PathResolver.getInstance({ debug: false });
|
|
8175
8221
|
getPathResolver = (options) => PathResolver.getInstance(options);
|
|
8176
8222
|
getRepoRoot = () => pathResolverInstance.getRepoRoot();
|
|
@@ -8244,6 +8290,48 @@ var init_pathResolver = __esm({
|
|
|
8244
8290
|
}
|
|
8245
8291
|
});
|
|
8246
8292
|
|
|
8293
|
+
// packages/tooling/src/utils/typed-file-operations.ts
|
|
8294
|
+
function readTurboJson(filePath) {
|
|
8295
|
+
if (!pathExists(filePath)) {
|
|
8296
|
+
return null;
|
|
8297
|
+
}
|
|
8298
|
+
const content = readSync(filePath, { format: "json" });
|
|
8299
|
+
if (!content || typeof content !== "object") {
|
|
8300
|
+
throw new DoNotDevError(
|
|
8301
|
+
`Invalid turbo.json: ${filePath}`,
|
|
8302
|
+
DO_NOT_DEV_ERROR_CODES.CONFIG_INVALID,
|
|
8303
|
+
{ context: { filePath } }
|
|
8304
|
+
);
|
|
8305
|
+
}
|
|
8306
|
+
return content;
|
|
8307
|
+
}
|
|
8308
|
+
function readTsConfigJson(filePath) {
|
|
8309
|
+
if (!pathExists(filePath)) {
|
|
8310
|
+
throw new DoNotDevError(
|
|
8311
|
+
`tsconfig.json not found: ${filePath}`,
|
|
8312
|
+
DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND,
|
|
8313
|
+
{ context: { filePath } }
|
|
8314
|
+
);
|
|
8315
|
+
}
|
|
8316
|
+
const content = readSync(filePath, { format: "json" });
|
|
8317
|
+
if (!content || typeof content !== "object") {
|
|
8318
|
+
throw new DoNotDevError(
|
|
8319
|
+
`Invalid tsconfig.json: ${filePath}`,
|
|
8320
|
+
DO_NOT_DEV_ERROR_CODES.CONFIG_INVALID,
|
|
8321
|
+
{ context: { filePath } }
|
|
8322
|
+
);
|
|
8323
|
+
}
|
|
8324
|
+
return content;
|
|
8325
|
+
}
|
|
8326
|
+
var init_typed_file_operations = __esm({
|
|
8327
|
+
"packages/tooling/src/utils/typed-file-operations.ts"() {
|
|
8328
|
+
"use strict";
|
|
8329
|
+
init_utils();
|
|
8330
|
+
init_pathResolver();
|
|
8331
|
+
init_errors();
|
|
8332
|
+
}
|
|
8333
|
+
});
|
|
8334
|
+
|
|
8247
8335
|
// packages/tooling/src/bundler/utils.ts
|
|
8248
8336
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
8249
8337
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
@@ -8271,23 +8359,12 @@ var init_utils = __esm({
|
|
|
8271
8359
|
}
|
|
8272
8360
|
});
|
|
8273
8361
|
|
|
8274
|
-
// packages/cli/src/bin/commands/create-project.ts
|
|
8275
|
-
init_utils();
|
|
8276
|
-
|
|
8277
|
-
// packages/tooling/src/index.ts
|
|
8278
|
-
init_utils();
|
|
8279
|
-
|
|
8280
|
-
// packages/tooling/src/cli/index.ts
|
|
8281
|
-
init_utils();
|
|
8282
|
-
|
|
8283
8362
|
// packages/tooling/src/utils/cli-input.ts
|
|
8284
|
-
init_utils();
|
|
8285
|
-
init_dist2();
|
|
8286
8363
|
async function askForInput(message, defaultValue = "") {
|
|
8287
8364
|
const result = await he({
|
|
8288
8365
|
message,
|
|
8289
8366
|
placeholder: defaultValue || void 0,
|
|
8290
|
-
|
|
8367
|
+
defaultValue: defaultValue || void 0
|
|
8291
8368
|
});
|
|
8292
8369
|
if (pD(result)) {
|
|
8293
8370
|
xe("Operation cancelled.");
|
|
@@ -8323,11 +8400,28 @@ async function askForSelection(message, choices, defaultValue = 0) {
|
|
|
8323
8400
|
}
|
|
8324
8401
|
return result;
|
|
8325
8402
|
}
|
|
8403
|
+
var init_cli_input = __esm({
|
|
8404
|
+
"packages/tooling/src/utils/cli-input.ts"() {
|
|
8405
|
+
"use strict";
|
|
8406
|
+
init_utils();
|
|
8407
|
+
init_dist2();
|
|
8408
|
+
}
|
|
8409
|
+
});
|
|
8410
|
+
|
|
8411
|
+
// packages/cli/src/bin/commands/create-project.ts
|
|
8412
|
+
init_utils();
|
|
8413
|
+
|
|
8414
|
+
// packages/tooling/src/index.ts
|
|
8415
|
+
init_utils();
|
|
8416
|
+
|
|
8417
|
+
// packages/tooling/src/cli/index.ts
|
|
8418
|
+
init_utils();
|
|
8326
8419
|
|
|
8327
8420
|
// packages/tooling/src/utils/create-utils.ts
|
|
8328
8421
|
init_utils();
|
|
8329
8422
|
init_cli_output();
|
|
8330
8423
|
init_pathResolver();
|
|
8424
|
+
init_typed_file_operations();
|
|
8331
8425
|
async function copyTemplateFiles(sourceDir, destDir, replacements) {
|
|
8332
8426
|
if (!pathExists(sourceDir)) {
|
|
8333
8427
|
log.warn(`Warning: Template directory does not exist: ${sourceDir}`);
|
|
@@ -8512,12 +8606,7 @@ async function mergeRootTsConfig(rootDir, allAppNames, includeFunctions = false)
|
|
|
8512
8606
|
return;
|
|
8513
8607
|
}
|
|
8514
8608
|
try {
|
|
8515
|
-
const tsconfig =
|
|
8516
|
-
if (!tsconfig) {
|
|
8517
|
-
throw new Error(
|
|
8518
|
-
`tsconfig.json is empty or invalid JSON at ${tsconfigPath}`
|
|
8519
|
-
);
|
|
8520
|
-
}
|
|
8609
|
+
const tsconfig = readTsConfigJson(tsconfigPath);
|
|
8521
8610
|
tsconfig.references = tsconfig.references || [];
|
|
8522
8611
|
const existingPaths = new Set(
|
|
8523
8612
|
tsconfig.references.map((ref) => ref.path)
|
|
@@ -8551,7 +8640,7 @@ async function mergeRootTurboJson(rootDir) {
|
|
|
8551
8640
|
return;
|
|
8552
8641
|
}
|
|
8553
8642
|
try {
|
|
8554
|
-
const turboJson =
|
|
8643
|
+
const turboJson = readTurboJson(turboJsonPath);
|
|
8555
8644
|
if (!turboJson) {
|
|
8556
8645
|
throw new Error(
|
|
8557
8646
|
`turbo.json is empty or invalid JSON at ${turboJsonPath}`
|
|
@@ -8603,7 +8692,7 @@ async function mergeRootTurboJson(rootDir) {
|
|
|
8603
8692
|
}
|
|
8604
8693
|
} catch (error2) {
|
|
8605
8694
|
log.warn(
|
|
8606
|
-
`Warning: Could not merge root turbo.json: ${error2.message
|
|
8695
|
+
`Warning: Could not merge root turbo.json: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
8607
8696
|
);
|
|
8608
8697
|
}
|
|
8609
8698
|
}
|
|
@@ -8699,6 +8788,10 @@ var APP_QUESTIONNAIRE = [
|
|
|
8699
8788
|
{
|
|
8700
8789
|
title: "Next.js \u2014 Static content/SEO (SSR, SSG) \u2014 BETA",
|
|
8701
8790
|
value: "nextjs"
|
|
8791
|
+
},
|
|
8792
|
+
{
|
|
8793
|
+
title: "Expo \u2014 Mobile app (iOS + Android)",
|
|
8794
|
+
value: "expo"
|
|
8702
8795
|
}
|
|
8703
8796
|
]
|
|
8704
8797
|
},
|
|
@@ -8725,6 +8818,10 @@ var APP_QUESTIONNAIRE = [
|
|
|
8725
8818
|
{
|
|
8726
8819
|
title: "Vercel \u2014 Serverless functions (edge + node.js)",
|
|
8727
8820
|
value: "vercel"
|
|
8821
|
+
},
|
|
8822
|
+
{
|
|
8823
|
+
title: "Supabase \u2014 Postgres + Auth + Storage",
|
|
8824
|
+
value: "supabase"
|
|
8728
8825
|
}
|
|
8729
8826
|
]
|
|
8730
8827
|
}
|
|
@@ -8791,6 +8888,7 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
|
|
|
8791
8888
|
|
|
8792
8889
|
// packages/tooling/src/scaffolding/create-app.ts
|
|
8793
8890
|
init_utils();
|
|
8891
|
+
init_cli_input();
|
|
8794
8892
|
init_cli_output();
|
|
8795
8893
|
|
|
8796
8894
|
// packages/tooling/src/utils/dependency-resolver.ts
|
|
@@ -8824,6 +8922,15 @@ function generateScripts(templateName, options) {
|
|
|
8824
8922
|
scripts.preview = "next start";
|
|
8825
8923
|
scripts.lint = "eslint src/";
|
|
8826
8924
|
scripts["type-check"] = "tsc --noEmit";
|
|
8925
|
+
} else if (templateName.includes("expo")) {
|
|
8926
|
+
scripts.dev = "expo start";
|
|
8927
|
+
scripts.start = "expo start";
|
|
8928
|
+
scripts.android = "expo start --android";
|
|
8929
|
+
scripts.ios = "expo start --ios";
|
|
8930
|
+
scripts.web = "expo start --web";
|
|
8931
|
+
scripts.build = "expo export";
|
|
8932
|
+
scripts.lint = "eslint .";
|
|
8933
|
+
scripts["type-check"] = "tsc --noEmit";
|
|
8827
8934
|
} else if (templateName === "consumer-root") {
|
|
8828
8935
|
scripts.dev = "turbo run dev";
|
|
8829
8936
|
scripts.build = "turbo run build";
|
|
@@ -8912,7 +9019,7 @@ function generatePackageJson(templateName, mode, options = {}) {
|
|
|
8912
9019
|
result.main = "./index.ts";
|
|
8913
9020
|
result.types = "./index.ts";
|
|
8914
9021
|
}
|
|
8915
|
-
if (templateName.includes("vite") || templateName.includes("nextjs") || templateName.includes("functions")) {
|
|
9022
|
+
if (templateName.includes("vite") || templateName.includes("nextjs") || templateName.includes("expo") || templateName.includes("functions")) {
|
|
8916
9023
|
if (!dependencies.entities) {
|
|
8917
9024
|
dependencies.entities = "workspace:*";
|
|
8918
9025
|
}
|
|
@@ -8960,6 +9067,40 @@ function generatePackageJson(templateName, mode, options = {}) {
|
|
|
8960
9067
|
// packages/tooling/src/scaffolding/create-app.ts
|
|
8961
9068
|
init_pathResolver();
|
|
8962
9069
|
init_pathResolver();
|
|
9070
|
+
|
|
9071
|
+
// packages/tooling/src/scaffolding/scaffold-matrix.ts
|
|
9072
|
+
init_utils();
|
|
9073
|
+
var MATRIX = [
|
|
9074
|
+
{ builder: "vite", backend: "none", baseTemplate: "app-vite", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
9075
|
+
{ builder: "vite", backend: "firebase", baseTemplate: "app-vite", overlay: "overlay-firebase", deployConfig: "firebase", functionsTemplate: "functions-firebase" },
|
|
9076
|
+
{ builder: "vite", backend: "supabase", baseTemplate: "app-vite", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate: null },
|
|
9077
|
+
{ builder: "vite", backend: "vercel", baseTemplate: "app-vite", overlay: "overlay-vercel", deployConfig: "vercel-vercel", functionsTemplate: "functions-vercel" },
|
|
9078
|
+
{ builder: "nextjs", backend: "none", baseTemplate: "app-next", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
9079
|
+
{ builder: "nextjs", backend: "firebase", baseTemplate: "app-next", overlay: "overlay-firebase", deployConfig: "firebase", functionsTemplate: "functions-firebase" },
|
|
9080
|
+
{ builder: "nextjs", backend: "supabase", baseTemplate: "app-next", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate: null },
|
|
9081
|
+
{ builder: "nextjs", backend: "vercel", baseTemplate: "app-next", overlay: "overlay-vercel", deployConfig: "vercel-vercel", functionsTemplate: "functions-vercel" },
|
|
9082
|
+
{ builder: "expo", backend: "none", baseTemplate: "app-expo", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
9083
|
+
{ builder: "expo", backend: "firebase", baseTemplate: "app-expo", overlay: "overlay-firebase", deployConfig: null, functionsTemplate: "functions-firebase" },
|
|
9084
|
+
{ builder: "expo", backend: "supabase", baseTemplate: "app-expo", overlay: "overlay-supabase", deployConfig: null, functionsTemplate: null },
|
|
9085
|
+
{ builder: "demo", backend: "none", baseTemplate: "app-demo", overlay: null, deployConfig: null, functionsTemplate: null }
|
|
9086
|
+
];
|
|
9087
|
+
function comboKey(builder, backend) {
|
|
9088
|
+
return `${builder}-${backend}`;
|
|
9089
|
+
}
|
|
9090
|
+
var ROWS_BY_KEY = /* @__PURE__ */ new Map();
|
|
9091
|
+
for (const row of MATRIX) {
|
|
9092
|
+
ROWS_BY_KEY.set(comboKey(row.builder, row.backend), row);
|
|
9093
|
+
}
|
|
9094
|
+
function getScaffoldRow(builder, backend) {
|
|
9095
|
+
const key = comboKey(builder, backend);
|
|
9096
|
+
const row = ROWS_BY_KEY.get(key);
|
|
9097
|
+
if (!row) {
|
|
9098
|
+
throw new Error(`Unsupported scaffold combo: ${key}. Supported: ${[...ROWS_BY_KEY.keys()].join(", ")}`);
|
|
9099
|
+
}
|
|
9100
|
+
return row;
|
|
9101
|
+
}
|
|
9102
|
+
|
|
9103
|
+
// packages/tooling/src/scaffolding/create-app.ts
|
|
8963
9104
|
var SHOW_WIP = process.env.SHOW_WIP === "true" || process.argv.includes("--wip");
|
|
8964
9105
|
async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
8965
9106
|
const isInteractive = !appName || !appConfig;
|
|
@@ -9045,14 +9186,19 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9045
9186
|
const s = Y2();
|
|
9046
9187
|
s.start(`Creating app: ${appName}`);
|
|
9047
9188
|
await ensureDir(appDir);
|
|
9048
|
-
const
|
|
9189
|
+
const builder = appTemplate;
|
|
9190
|
+
const backend = appConfig.needsBackend && appConfig.backendPlatform ? appConfig.backendPlatform : "none";
|
|
9191
|
+
const row = getScaffoldRow(builder, backend);
|
|
9192
|
+
const templateDir = row.baseTemplate;
|
|
9049
9193
|
const firebaseProjectId = (appConfig?.firebaseProjectId ?? "").trim() || appName.toLowerCase().replace(/\s+/g, "-");
|
|
9050
9194
|
const firebaseRegion = appConfig?.firebaseRegion ?? "europe-west1";
|
|
9195
|
+
const backendPlatform = appConfig.backendPlatform ?? "firebase";
|
|
9196
|
+
const deployConfig = row.deployConfig;
|
|
9051
9197
|
const replacements = {
|
|
9052
9198
|
projectName: appName,
|
|
9053
9199
|
appName,
|
|
9054
9200
|
appShortName: appName.toUpperCase().replace(/-/g, " "),
|
|
9055
|
-
includeFunctions: Boolean(
|
|
9201
|
+
includeFunctions: Boolean(row.functionsTemplate),
|
|
9056
9202
|
needsCRUD: Boolean(appConfig.needsCRUD),
|
|
9057
9203
|
setupGithubActions: false,
|
|
9058
9204
|
appNames: [appName],
|
|
@@ -9062,8 +9208,13 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9062
9208
|
monorepoRelativePath: "../../packages/tooling",
|
|
9063
9209
|
appTemplate,
|
|
9064
9210
|
isNextjs: appTemplate === "nextjs",
|
|
9211
|
+
isExpo: appTemplate === "expo",
|
|
9065
9212
|
YOUR_FIREBASE_PROJECT_ID: firebaseProjectId,
|
|
9066
|
-
YOUR_REGION: firebaseRegion
|
|
9213
|
+
YOUR_REGION: firebaseRegion,
|
|
9214
|
+
backendPlatform,
|
|
9215
|
+
isFirebase: backendPlatform === "firebase",
|
|
9216
|
+
isSupabase: backendPlatform === "supabase",
|
|
9217
|
+
isVercel: backendPlatform === "vercel"
|
|
9067
9218
|
};
|
|
9068
9219
|
const templateSourceDir = joinPath(templatesRoot, templateDir);
|
|
9069
9220
|
const templateFiles = await glob("**/*", {
|
|
@@ -9084,118 +9235,155 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9084
9235
|
await replacePlaceholders(destPath, replacements);
|
|
9085
9236
|
}
|
|
9086
9237
|
}
|
|
9238
|
+
if (row.overlay) {
|
|
9239
|
+
const overlayDir = joinPath(templatesRoot, row.overlay);
|
|
9240
|
+
if (pathExists(overlayDir)) {
|
|
9241
|
+
const overlayFiles = await glob("**/*", {
|
|
9242
|
+
cwd: overlayDir,
|
|
9243
|
+
dot: true,
|
|
9244
|
+
onlyFiles: true
|
|
9245
|
+
});
|
|
9246
|
+
for (const file of overlayFiles) {
|
|
9247
|
+
if (file.startsWith("env.fragment")) continue;
|
|
9248
|
+
if (file === "vercel.headers.example") continue;
|
|
9249
|
+
if (file === "vercel.json.example") continue;
|
|
9250
|
+
if (file === "src/config/providers.ts.example") {
|
|
9251
|
+
const variantFile = `src/config/providers.${appTemplate}.ts.example`;
|
|
9252
|
+
if (overlayFiles.includes(variantFile)) continue;
|
|
9253
|
+
}
|
|
9254
|
+
const providersVariant = file.match(/^src\/config\/providers\.(\w+)\.ts\.example$/);
|
|
9255
|
+
if (providersVariant) {
|
|
9256
|
+
if (providersVariant[1] !== appTemplate) continue;
|
|
9257
|
+
const destPath2 = joinPath(appDir, "src/config/providers.ts");
|
|
9258
|
+
await ensureDir(getDirname(destPath2));
|
|
9259
|
+
await copy(joinPath(overlayDir, file), destPath2);
|
|
9260
|
+
if (await isTextFile(destPath2)) await replacePlaceholders(destPath2, replacements);
|
|
9261
|
+
continue;
|
|
9262
|
+
}
|
|
9263
|
+
const sourcePath = joinPath(overlayDir, file);
|
|
9264
|
+
let destFileName = file;
|
|
9265
|
+
if (destFileName.endsWith(".example")) {
|
|
9266
|
+
destFileName = destFileName.slice(0, -8);
|
|
9267
|
+
}
|
|
9268
|
+
const destPath = joinPath(appDir, destFileName);
|
|
9269
|
+
await ensureDir(getDirname(destPath));
|
|
9270
|
+
await copy(sourcePath, destPath);
|
|
9271
|
+
if (await isTextFile(destPath)) {
|
|
9272
|
+
await replacePlaceholders(destPath, replacements);
|
|
9273
|
+
}
|
|
9274
|
+
}
|
|
9275
|
+
const fragmentName = appTemplate === "nextjs" ? "env.fragment.nextjs.example" : appTemplate === "expo" ? "env.fragment.expo.example" : "env.fragment.example";
|
|
9276
|
+
const fragmentPath = joinPath(overlayDir, fragmentName);
|
|
9277
|
+
const envPath = joinPath(appDir, ".env");
|
|
9278
|
+
if (pathExists(fragmentPath) && pathExists(envPath)) {
|
|
9279
|
+
const baseEnv = readSync(envPath);
|
|
9280
|
+
const fragment = readSync(fragmentPath);
|
|
9281
|
+
await write(envPath, baseEnv + "\n" + fragment, { overwrite: true });
|
|
9282
|
+
}
|
|
9283
|
+
if (deployConfig === "vercel-supabase") {
|
|
9284
|
+
const vercelPath = joinPath(appDir, "vercel.json");
|
|
9285
|
+
const headersFragmentPath = joinPath(overlayDir, "vercel.headers.example");
|
|
9286
|
+
const fullVercelPath = joinPath(overlayDir, "vercel.json.example");
|
|
9287
|
+
if (pathExists(vercelPath) && pathExists(headersFragmentPath)) {
|
|
9288
|
+
const vercelJson = readSync(vercelPath, { format: "json" });
|
|
9289
|
+
const headersFragment = readSync(headersFragmentPath, { format: "json" });
|
|
9290
|
+
vercelJson.headers = [...vercelJson.headers ?? [], ...headersFragment];
|
|
9291
|
+
await write(vercelPath, vercelJson, { format: "json", overwrite: true });
|
|
9292
|
+
} else if (pathExists(fullVercelPath)) {
|
|
9293
|
+
await copy(fullVercelPath, vercelPath);
|
|
9294
|
+
if (await isTextFile(vercelPath)) await replacePlaceholders(vercelPath, replacements);
|
|
9295
|
+
}
|
|
9296
|
+
}
|
|
9297
|
+
}
|
|
9298
|
+
}
|
|
9087
9299
|
const executionMode = detectExecutionMode();
|
|
9088
9300
|
const templateName = appTemplate === "demo" ? "demo" : executionMode === "development" ? `dev-${appTemplate}` : `consumer-${appTemplate}`;
|
|
9089
9301
|
const packageJson = generatePackageJson(templateName, executionMode, {
|
|
9090
9302
|
appName,
|
|
9091
9303
|
template: appTemplate === "demo" ? "vite" : appTemplate,
|
|
9092
|
-
includeFunctions: Boolean(
|
|
9304
|
+
includeFunctions: Boolean(row.functionsTemplate),
|
|
9305
|
+
platform: appTemplate === "demo" ? void 0 : backendPlatform
|
|
9093
9306
|
});
|
|
9094
9307
|
const packageJsonPath = joinPath(appDir, "package.json");
|
|
9095
9308
|
await write(packageJsonPath, packageJson, {
|
|
9096
9309
|
format: "json",
|
|
9097
9310
|
overwrite: true
|
|
9098
9311
|
});
|
|
9099
|
-
if (
|
|
9100
|
-
const platform = appConfig.backendPlatform;
|
|
9312
|
+
if (row.functionsTemplate) {
|
|
9101
9313
|
const functionsRootDir = joinPath(appDir, "functions");
|
|
9102
|
-
const functionsTemplateName =
|
|
9103
|
-
const
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
templatesRoot,
|
|
9119
|
-
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9136
|
-
|
|
9137
|
-
|
|
9138
|
-
|
|
9139
|
-
|
|
9140
|
-
await replacePlaceholders(destPath, {
|
|
9141
|
-
...replacements,
|
|
9142
|
-
APP_NAME: appName
|
|
9143
|
-
});
|
|
9314
|
+
const functionsTemplateName = row.functionsTemplate;
|
|
9315
|
+
const functionsTemplateExists = pathExists(joinPath(templatesRoot, functionsTemplateName));
|
|
9316
|
+
if (!functionsTemplateExists) {
|
|
9317
|
+
log.warn(`Functions template "${functionsTemplateName}" not found \u2014 skipping functions scaffolding.`);
|
|
9318
|
+
} else {
|
|
9319
|
+
const functionsPackageJson = generatePackageJson(
|
|
9320
|
+
functionsTemplateName,
|
|
9321
|
+
executionMode,
|
|
9322
|
+
{ appName, platform: row.functionsTemplate.replace("functions-", "") }
|
|
9323
|
+
);
|
|
9324
|
+
const packageJsonPath2 = joinPath(functionsRootDir, "package.json");
|
|
9325
|
+
await ensureDir(functionsRootDir);
|
|
9326
|
+
await write(packageJsonPath2, functionsPackageJson, {
|
|
9327
|
+
format: "json",
|
|
9328
|
+
overwrite: true
|
|
9329
|
+
});
|
|
9330
|
+
const templateDir2 = joinPath(templatesRoot, functionsTemplateName);
|
|
9331
|
+
const templateFiles2 = await glob("**/*", {
|
|
9332
|
+
cwd: templateDir2,
|
|
9333
|
+
dot: true,
|
|
9334
|
+
onlyFiles: true
|
|
9335
|
+
});
|
|
9336
|
+
for (const file of templateFiles2) {
|
|
9337
|
+
if (file === "package.json.example") continue;
|
|
9338
|
+
const sourcePath = joinPath(templateDir2, file);
|
|
9339
|
+
let destFileName = file;
|
|
9340
|
+
if (destFileName.endsWith(".example")) {
|
|
9341
|
+
destFileName = destFileName.slice(0, -8);
|
|
9342
|
+
}
|
|
9343
|
+
const destPath = joinPath(functionsRootDir, destFileName);
|
|
9344
|
+
await ensureDir(getDirname(destPath));
|
|
9345
|
+
await copy(sourcePath, destPath);
|
|
9346
|
+
if (await isTextFile(destPath)) {
|
|
9347
|
+
await replacePlaceholders(destPath, {
|
|
9348
|
+
...replacements,
|
|
9349
|
+
APP_NAME: appName
|
|
9350
|
+
});
|
|
9351
|
+
}
|
|
9144
9352
|
}
|
|
9145
9353
|
}
|
|
9146
9354
|
}
|
|
9147
9355
|
const deploymentTemplateDir = joinPath(templatesRoot, "root-consumer");
|
|
9148
|
-
|
|
9149
|
-
deploymentTemplateDir,
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
9356
|
+
if (deployConfig === "firebase") {
|
|
9357
|
+
const firebaseJsonSource = joinPath(deploymentTemplateDir, "firebase.json.example");
|
|
9358
|
+
if (pathExists(firebaseJsonSource)) {
|
|
9359
|
+
await copy(firebaseJsonSource, joinPath(appDir, "firebase.json"));
|
|
9360
|
+
const firebaseJsonDest = joinPath(appDir, "firebase.json");
|
|
9361
|
+
if (await isTextFile(firebaseJsonDest)) await replacePlaceholders(firebaseJsonDest, replacements);
|
|
9362
|
+
}
|
|
9363
|
+
const firebasercSource = joinPath(deploymentTemplateDir, ".firebaserc.example");
|
|
9364
|
+
if (pathExists(firebasercSource)) {
|
|
9365
|
+
await copy(firebasercSource, joinPath(appDir, ".firebaserc"));
|
|
9366
|
+
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
9367
|
+
if (await isTextFile(firebasercDest)) await replacePlaceholders(firebasercDest, replacements);
|
|
9368
|
+
}
|
|
9369
|
+
if (row.functionsTemplate === "functions-firebase") {
|
|
9370
|
+
for (const example of ["firestore.rules.example", "firestore.indexes.json.example", "storage.rules.example"]) {
|
|
9371
|
+
const src = joinPath(deploymentTemplateDir, example);
|
|
9372
|
+
if (pathExists(src)) {
|
|
9373
|
+
await copy(src, joinPath(appDir, example.replace(".example", "")));
|
|
9374
|
+
}
|
|
9375
|
+
}
|
|
9157
9376
|
}
|
|
9158
9377
|
}
|
|
9159
|
-
|
|
9160
|
-
deploymentTemplateDir,
|
|
9161
|
-
".firebaserc.example"
|
|
9162
|
-
);
|
|
9163
|
-
if (pathExists(firebasercSource)) {
|
|
9164
|
-
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
9165
|
-
await copy(firebasercSource, firebasercDest);
|
|
9166
|
-
if (await isTextFile(firebasercDest)) {
|
|
9167
|
-
await replacePlaceholders(firebasercDest, replacements);
|
|
9168
|
-
}
|
|
9169
|
-
}
|
|
9170
|
-
if (appConfig.needsBackend && appConfig.backendPlatform === "firebase") {
|
|
9171
|
-
const rulesFiles = [
|
|
9172
|
-
"firestore.rules.example",
|
|
9173
|
-
"firestore.indexes.json.example",
|
|
9174
|
-
"storage.rules.example"
|
|
9175
|
-
];
|
|
9176
|
-
for (const example of rulesFiles) {
|
|
9177
|
-
const src = joinPath(deploymentTemplateDir, example);
|
|
9178
|
-
if (pathExists(src)) {
|
|
9179
|
-
const destName = example.replace(".example", "");
|
|
9180
|
-
const dest = joinPath(appDir, destName);
|
|
9181
|
-
await copy(src, dest);
|
|
9182
|
-
}
|
|
9183
|
-
}
|
|
9184
|
-
}
|
|
9185
|
-
if (appTemplate === "nextjs" || appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
|
|
9186
|
-
const vercelJsonSource = joinPath(
|
|
9187
|
-
deploymentTemplateDir,
|
|
9188
|
-
"vercel.json.example"
|
|
9189
|
-
);
|
|
9378
|
+
if (deployConfig === "vercel-vercel") {
|
|
9379
|
+
const vercelJsonSource = joinPath(deploymentTemplateDir, "vercel.json.example");
|
|
9190
9380
|
if (pathExists(vercelJsonSource)) {
|
|
9381
|
+
await copy(vercelJsonSource, joinPath(appDir, "vercel.json"));
|
|
9191
9382
|
const vercelJsonDest = joinPath(appDir, "vercel.json");
|
|
9192
|
-
await
|
|
9193
|
-
if (await isTextFile(vercelJsonDest)) {
|
|
9194
|
-
await replacePlaceholders(vercelJsonDest, replacements);
|
|
9195
|
-
}
|
|
9383
|
+
if (await isTextFile(vercelJsonDest)) await replacePlaceholders(vercelJsonDest, replacements);
|
|
9196
9384
|
}
|
|
9197
9385
|
}
|
|
9198
|
-
const backendInfo =
|
|
9386
|
+
const backendInfo = row.functionsTemplate ? ` with ${row.functionsTemplate.replace("functions-", "")} functions` : "";
|
|
9199
9387
|
s.stop(`Created ${appName}${backendInfo}`);
|
|
9200
9388
|
const rootPackageJsonPath = joinPath(workspaceRoot, "package.json");
|
|
9201
9389
|
if (pathExists(rootPackageJsonPath)) {
|
|
@@ -9207,7 +9395,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9207
9395
|
}
|
|
9208
9396
|
if (isInteractive) {
|
|
9209
9397
|
Se("\u{1F389} App created successfully!");
|
|
9210
|
-
const firebaseStep =
|
|
9398
|
+
const firebaseStep = row.functionsTemplate === "functions-firebase" ? `2. Set Firebase project: cd apps/${appName} && firebase use --add (or edit .firebaserc)
|
|
9211
9399
|
3. bun install
|
|
9212
9400
|
4. bun run dev` : `2. bun install
|
|
9213
9401
|
3. bun run dev`;
|
|
@@ -9225,9 +9413,28 @@ Happy coding!`,
|
|
|
9225
9413
|
|
|
9226
9414
|
// packages/tooling/src/scaffolding/create-project.ts
|
|
9227
9415
|
init_utils();
|
|
9416
|
+
init_cli_input();
|
|
9228
9417
|
init_cli_output();
|
|
9229
9418
|
init_pathResolver();
|
|
9230
9419
|
var SHOW_WIP2 = process.env.SHOW_WIP === "true" || process.argv.includes("--wip");
|
|
9420
|
+
var BACKEND_CHOICES = [
|
|
9421
|
+
{ title: "None", value: "none" },
|
|
9422
|
+
{
|
|
9423
|
+
title: "Firebase \u2014 Full platform (Auth, Firestore, Storage, Functions, Hosting)",
|
|
9424
|
+
value: "firebase"
|
|
9425
|
+
},
|
|
9426
|
+
{
|
|
9427
|
+
title: "Supabase \u2014 Auth, Postgres, Storage, Functions",
|
|
9428
|
+
value: "supabase"
|
|
9429
|
+
},
|
|
9430
|
+
{
|
|
9431
|
+
title: "Vercel \u2014 Serverless functions + Hosting (e.g. Next.js API routes)",
|
|
9432
|
+
value: "vercel"
|
|
9433
|
+
}
|
|
9434
|
+
];
|
|
9435
|
+
function getDefaultBackendIndex(framework) {
|
|
9436
|
+
return framework === "nextjs" ? 3 : 1;
|
|
9437
|
+
}
|
|
9231
9438
|
function calculateRelativePath(from, to) {
|
|
9232
9439
|
try {
|
|
9233
9440
|
return getRelativePathBetween(from, to).replace(/\\/g, "/");
|
|
@@ -9336,10 +9543,6 @@ async function main(options) {
|
|
|
9336
9543
|
Me("Merge mode: Merging root files, creating new apps", "\u{1F527} Mode");
|
|
9337
9544
|
}
|
|
9338
9545
|
}
|
|
9339
|
-
let installDemoApp = await askForConfirmation(
|
|
9340
|
-
"Would you like to install the demo app? (component showcase)",
|
|
9341
|
-
false
|
|
9342
|
-
);
|
|
9343
9546
|
let appNames = [];
|
|
9344
9547
|
const appConfigs = {};
|
|
9345
9548
|
let anyAppNeedsBackend = false;
|
|
@@ -9367,21 +9570,25 @@ async function main(options) {
|
|
|
9367
9570
|
{
|
|
9368
9571
|
title: "Next.js \u2014 Static content/SEO (SSR, SSG) \u2014 DoNotDev support: BETA",
|
|
9369
9572
|
value: "nextjs"
|
|
9573
|
+
},
|
|
9574
|
+
{
|
|
9575
|
+
title: "Expo \u2014 Mobile app (iOS + Android, single codebase)",
|
|
9576
|
+
value: "expo"
|
|
9370
9577
|
}
|
|
9371
9578
|
],
|
|
9372
9579
|
0
|
|
9373
9580
|
);
|
|
9374
|
-
const
|
|
9375
|
-
`
|
|
9376
|
-
|
|
9581
|
+
const backendValue = await askForSelection(
|
|
9582
|
+
`Backend for "${trimmedName}"?`,
|
|
9583
|
+
[...BACKEND_CHOICES],
|
|
9584
|
+
getDefaultBackendIndex(framework)
|
|
9377
9585
|
);
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
}
|
|
9586
|
+
const needsBackend = backendValue !== "none";
|
|
9587
|
+
if (needsBackend) anyAppNeedsBackend = true;
|
|
9381
9588
|
appConfigs[trimmedName] = {
|
|
9382
9589
|
template: framework,
|
|
9383
9590
|
needsBackend,
|
|
9384
|
-
backendPlatform: needsBackend ?
|
|
9591
|
+
backendPlatform: needsBackend ? backendValue : void 0,
|
|
9385
9592
|
needsCRUD: false,
|
|
9386
9593
|
selectedEntities: [],
|
|
9387
9594
|
userAuth: "none",
|
|
@@ -9427,17 +9634,17 @@ async function main(options) {
|
|
|
9427
9634
|
],
|
|
9428
9635
|
0
|
|
9429
9636
|
);
|
|
9430
|
-
const
|
|
9431
|
-
`
|
|
9432
|
-
|
|
9637
|
+
const backendValue = await askForSelection(
|
|
9638
|
+
`Backend for "${trimmedName}"?`,
|
|
9639
|
+
[...BACKEND_CHOICES],
|
|
9640
|
+
getDefaultBackendIndex(framework)
|
|
9433
9641
|
);
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
}
|
|
9642
|
+
const needsBackend = backendValue !== "none";
|
|
9643
|
+
if (needsBackend) anyAppNeedsBackend = true;
|
|
9437
9644
|
appConfigs[trimmedName] = {
|
|
9438
9645
|
template: framework,
|
|
9439
9646
|
needsBackend,
|
|
9440
|
-
backendPlatform: needsBackend ?
|
|
9647
|
+
backendPlatform: needsBackend ? backendValue : void 0,
|
|
9441
9648
|
needsCRUD: false,
|
|
9442
9649
|
selectedEntities: [],
|
|
9443
9650
|
userAuth: "none",
|
|
@@ -9445,6 +9652,10 @@ async function main(options) {
|
|
|
9445
9652
|
features: []
|
|
9446
9653
|
};
|
|
9447
9654
|
}
|
|
9655
|
+
let installDemoApp = await askForConfirmation(
|
|
9656
|
+
"Would you like to install the demo app? (component showcase)",
|
|
9657
|
+
false
|
|
9658
|
+
);
|
|
9448
9659
|
let allAppNames = [...appNames];
|
|
9449
9660
|
let appsToCreate = [];
|
|
9450
9661
|
let appsToSkip = [];
|
|
@@ -9510,9 +9721,6 @@ async function main(options) {
|
|
|
9510
9721
|
log.info(
|
|
9511
9722
|
`Creating project "${projectName}" with ${appNames.length} app(s): ${appNames.join(", ")}`
|
|
9512
9723
|
);
|
|
9513
|
-
let needsAuth = false;
|
|
9514
|
-
let needsOAuth = false;
|
|
9515
|
-
let needsBilling = false;
|
|
9516
9724
|
for (const appName of appNames) {
|
|
9517
9725
|
if (!appConfigs[appName]) {
|
|
9518
9726
|
log.warn(`Missing config for app "${appName}", using defaults`);
|
|
@@ -9567,12 +9775,14 @@ async function main(options) {
|
|
|
9567
9775
|
overwrite: true
|
|
9568
9776
|
});
|
|
9569
9777
|
const relativeMonorepoPath = executionMode === "development" ? calculateRelativePath(projectDirNormalized, monorepoRoot) : "";
|
|
9778
|
+
const primaryPlatform = Object.values(appConfigs).find((c) => c.backendPlatform)?.backendPlatform ?? "firebase";
|
|
9570
9779
|
const rootPackageJson = generatePackageJson(
|
|
9571
9780
|
"consumer-root",
|
|
9572
9781
|
executionMode,
|
|
9573
9782
|
{
|
|
9574
9783
|
projectName,
|
|
9575
|
-
includeFunctions: anyAppNeedsBackend
|
|
9784
|
+
includeFunctions: anyAppNeedsBackend,
|
|
9785
|
+
platform: primaryPlatform
|
|
9576
9786
|
}
|
|
9577
9787
|
);
|
|
9578
9788
|
const packageJsonPath = joinPath(projectDirNormalized, "package.json");
|
|
@@ -9596,9 +9806,12 @@ async function main(options) {
|
|
|
9596
9806
|
firebaseSecretName: projectName.toUpperCase().replace(/-/g, "_"),
|
|
9597
9807
|
YOUR_FIREBASE_PROJECT_ID: firebaseProjectId,
|
|
9598
9808
|
YOUR_REGION: firebaseRegion,
|
|
9599
|
-
needsAuth,
|
|
9600
|
-
|
|
9601
|
-
|
|
9809
|
+
needsAuth: false,
|
|
9810
|
+
// Determined by agent in WAI-WAY Phase 0
|
|
9811
|
+
needsOAuth: false,
|
|
9812
|
+
// Determined by agent in WAI-WAY Phase 0
|
|
9813
|
+
needsBilling: false
|
|
9814
|
+
// Determined by agent in WAI-WAY Phase 0
|
|
9602
9815
|
};
|
|
9603
9816
|
const firebaseRootFiles = /* @__PURE__ */ new Set([
|
|
9604
9817
|
"firebase.json.example",
|
|
@@ -9628,8 +9841,12 @@ async function main(options) {
|
|
|
9628
9841
|
}
|
|
9629
9842
|
}
|
|
9630
9843
|
if (setupGithubActions) {
|
|
9631
|
-
const ciTemplateDir = joinPath(templatesRoot, "github
|
|
9632
|
-
await copyTemplateFiles(
|
|
9844
|
+
const ciTemplateDir = joinPath(templatesRoot, "github");
|
|
9845
|
+
await copyTemplateFiles(
|
|
9846
|
+
ciTemplateDir,
|
|
9847
|
+
projectDirNormalized,
|
|
9848
|
+
rootReplacements
|
|
9849
|
+
);
|
|
9633
9850
|
}
|
|
9634
9851
|
s.stop("Project structure created");
|
|
9635
9852
|
} else {
|
|
@@ -9654,9 +9871,9 @@ async function main(options) {
|
|
|
9654
9871
|
}
|
|
9655
9872
|
const relativeMonorepoPath = executionMode === "development" ? calculateRelativePath(projectDirNormalized, monorepoRoot) : "../../packages/tooling";
|
|
9656
9873
|
await mergeRootPackageJson(projectDirNormalized, allAppNames, {
|
|
9657
|
-
needsAuth,
|
|
9658
|
-
needsOAuth,
|
|
9659
|
-
needsBilling,
|
|
9874
|
+
needsAuth: false,
|
|
9875
|
+
needsOAuth: false,
|
|
9876
|
+
needsBilling: false,
|
|
9660
9877
|
monorepoRelativePath: relativeMonorepoPath
|
|
9661
9878
|
});
|
|
9662
9879
|
await mergeRootTsConfig(
|
|
@@ -9740,14 +9957,18 @@ async function main(options) {
|
|
|
9740
9957
|
Me(
|
|
9741
9958
|
`1. ${cdCommand}
|
|
9742
9959
|
2. bun install
|
|
9743
|
-
3. Open the project in your IDE
|
|
9744
|
-
4. Tell your AI agent:
|
|
9960
|
+
3. Open the project in your IDE
|
|
9961
|
+
4. Tell your AI agent:
|
|
9962
|
+
|
|
9963
|
+
"Read AI.md and build my app"
|
|
9964
|
+
|
|
9965
|
+
The AI agent will use the MCP server automatically.
|
|
9966
|
+
It handles everything: spec, scaffold, entities, pages.
|
|
9745
9967
|
|
|
9746
|
-
|
|
9968
|
+
Cursor users: enable MCP in Settings > Tools & MCP > toggle "donotdev" ON
|
|
9969
|
+
Claude Code / Windsurf: MCP auto-connects, nothing to do
|
|
9747
9970
|
|
|
9748
|
-
` + (anyAppNeedsBackend ? `Dev server: dndev dev | With emulators: dndev emu
|
|
9749
|
-
` : `Dev server: dndev dev
|
|
9750
|
-
`) + `AI setup: dndev agent (re-configure MCP if needed)`,
|
|
9971
|
+
` + (anyAppNeedsBackend ? `Dev server: dndev dev | With emulators: dndev emu` : `Dev server: dndev dev`),
|
|
9751
9972
|
"\u{1F4CB} Next Steps"
|
|
9752
9973
|
);
|
|
9753
9974
|
} catch (error2) {
|