@idevconn/create-icore 0.7.1 → 0.8.0
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/dist/cli.js +509 -353
- package/dist/index.cjs +644 -366
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +635 -358
- package/dist/manifest/audit.js +122 -0
- package/package.json +1 -1
- package/templates/apps/api/package.json +2 -2
- package/templates/apps/api/src/app/app.module.ts +2 -6
- package/templates/apps/api/src/app/features.module.ts +9 -0
- package/templates/apps/api/src/app/gateway-services.ts +7 -0
- package/templates/apps/api/src/main.ts +1 -5
- package/templates/apps/microservices/auth/src/app/app.module.ts +4 -93
- package/templates/apps/microservices/auth/src/app/auth.provider.ts +9 -0
- package/templates/apps/microservices/notes/src/app/app.module.ts +4 -86
- package/templates/apps/microservices/notes/src/app/db.provider.ts +9 -0
- package/templates/apps/microservices/upload/src/app/app.module.ts +4 -140
- package/templates/apps/microservices/upload/src/app/storage.provider.ts +9 -0
- package/templates/apps/templates/client-antd/src/components/layout/LayoutSider.tsx +15 -23
- package/templates/apps/templates/client-antd/src/nav.config.ts +17 -0
- package/templates/apps/templates/client-mui/src/components/layout/LayoutSider.tsx +19 -20
- package/templates/apps/templates/client-mui/src/nav.config.ts +17 -0
- package/templates/apps/templates/client-shadcn/src/components/layout/LayoutSider.tsx +20 -16
- package/templates/apps/templates/client-shadcn/src/nav.config.ts +17 -0
- package/templates/libs/auth-strategies/firebase/eslint.config.mjs +1 -0
- package/templates/libs/auth-strategies/firebase/package.json +4 -0
- package/templates/libs/auth-strategies/firebase/src/index.ts +1 -0
- package/templates/libs/auth-strategies/firebase/src/lib/__tests__/firebase-auth.module.unit.test.ts +49 -0
- package/templates/libs/auth-strategies/firebase/src/lib/firebase-auth.module.ts +41 -0
- package/templates/libs/auth-strategies/firebase/tsconfig.json +2 -0
- package/templates/libs/auth-strategies/mongodb/package.json +4 -1
- package/templates/libs/auth-strategies/mongodb/src/index.ts +1 -0
- package/templates/libs/auth-strategies/mongodb/src/lib/__tests__/mongodb-auth.module.unit.test.ts +16 -0
- package/templates/libs/auth-strategies/mongodb/src/lib/mongodb-auth.module.ts +45 -0
- package/templates/libs/auth-strategies/mongodb/tsconfig.json +2 -0
- package/templates/libs/auth-strategies/supabase/eslint.config.mjs +1 -0
- package/templates/libs/auth-strategies/supabase/package.json +3 -0
- package/templates/libs/auth-strategies/supabase/src/index.ts +1 -0
- package/templates/libs/auth-strategies/supabase/src/lib/__tests__/supabase-auth.module.unit.test.ts +43 -0
- package/templates/libs/auth-strategies/supabase/src/lib/supabase-auth.module.ts +41 -0
- package/templates/libs/auth-strategies/supabase/tsconfig.json +2 -0
- package/templates/libs/db-strategies/firestore/eslint.config.mjs +1 -1
- package/templates/libs/db-strategies/firestore/package.json +4 -0
- package/templates/libs/db-strategies/firestore/src/index.ts +1 -0
- package/templates/libs/db-strategies/firestore/src/lib/__tests__/firestore-db.module.unit.test.ts +37 -0
- package/templates/libs/db-strategies/firestore/src/lib/firestore-db.module.ts +41 -0
- package/templates/libs/db-strategies/firestore/tsconfig.json +2 -0
- package/templates/libs/db-strategies/mongodb/package.json +4 -1
- package/templates/libs/db-strategies/mongodb/src/index.ts +1 -0
- package/templates/libs/db-strategies/mongodb/src/lib/__tests__/mongodb-db.module.unit.test.ts +14 -0
- package/templates/libs/db-strategies/mongodb/src/lib/mongodb-db.module.ts +41 -0
- package/templates/libs/db-strategies/mongodb/tsconfig.json +2 -0
- package/templates/libs/db-strategies/supabase/eslint.config.mjs +6 -1
- package/templates/libs/db-strategies/supabase/package.json +3 -0
- package/templates/libs/db-strategies/supabase/src/index.ts +1 -0
- package/templates/libs/db-strategies/supabase/src/lib/__tests__/supabase-db.module.unit.test.ts +32 -0
- package/templates/libs/db-strategies/supabase/src/lib/supabase-db.module.ts +41 -0
- package/templates/libs/db-strategies/supabase/tsconfig.json +2 -0
- package/templates/libs/shared/src/strategies/__tests__/provide-strategy.unit.test.ts +73 -0
- package/templates/libs/shared/src/strategies/index.ts +1 -0
- package/templates/libs/shared/src/strategies/provide-strategy.ts +44 -0
- package/templates/libs/storage-strategies/cloudinary/eslint.config.mjs +1 -1
- package/templates/libs/storage-strategies/cloudinary/package.json +4 -0
- package/templates/libs/storage-strategies/cloudinary/src/index.ts +1 -0
- package/templates/libs/storage-strategies/cloudinary/src/lib/__tests__/cloudinary-storage.module.unit.test.ts +40 -0
- package/templates/libs/storage-strategies/cloudinary/src/lib/cloudinary-storage.module.ts +85 -0
- package/templates/libs/storage-strategies/cloudinary/tsconfig.json +2 -0
- package/templates/libs/storage-strategies/firebase/eslint.config.mjs +1 -1
- package/templates/libs/storage-strategies/firebase/package.json +4 -0
- package/templates/libs/storage-strategies/firebase/src/index.ts +1 -0
- package/templates/libs/storage-strategies/firebase/src/lib/__tests__/firebase-storage.module.unit.test.ts +42 -0
- package/templates/libs/storage-strategies/firebase/src/lib/firebase-storage.module.ts +46 -0
- package/templates/libs/storage-strategies/firebase/tsconfig.json +2 -0
- package/templates/libs/storage-strategies/mongodb/package.json +4 -1
- package/templates/libs/storage-strategies/mongodb/src/index.ts +1 -0
- package/templates/libs/storage-strategies/mongodb/src/lib/__tests__/mongodb-storage.module.unit.test.ts +14 -0
- package/templates/libs/storage-strategies/mongodb/src/lib/mongodb-storage.module.ts +41 -0
- package/templates/libs/storage-strategies/mongodb/tsconfig.json +2 -0
- package/templates/libs/storage-strategies/supabase/eslint.config.mjs +1 -0
- package/templates/libs/storage-strategies/supabase/package.json +3 -0
- package/templates/libs/storage-strategies/supabase/src/index.ts +1 -0
- package/templates/libs/storage-strategies/supabase/src/lib/__tests__/supabase-storage.module.unit.test.ts +46 -0
- package/templates/libs/storage-strategies/supabase/src/lib/supabase-storage.module.ts +46 -0
- package/templates/libs/storage-strategies/supabase/tsconfig.json +2 -0
- package/templates/package.json +1 -1
- package/templates/tools/create-icore/_template-shell/package.json +1 -1
- package/templates/tsconfig.base.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -236,9 +236,9 @@ Re-run with @latest to refresh:
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
// src/lib/scaffold.ts
|
|
239
|
-
import { copyFile, mkdir as mkdir2, readdir as readdir2, readFile as
|
|
239
|
+
import { copyFile, mkdir as mkdir2, readdir as readdir2, readFile as readFile7, stat, writeFile as writeFile8, rm as rm4 } from "fs/promises";
|
|
240
240
|
import { readFileSync } from "fs";
|
|
241
|
-
import { join as
|
|
241
|
+
import { join as join9 } from "path";
|
|
242
242
|
import { spawnSync } from "child_process";
|
|
243
243
|
|
|
244
244
|
// src/lib/scaffold-env.ts
|
|
@@ -279,6 +279,31 @@ async function stripGatewayTransport(targetDir, prefix) {
|
|
|
279
279
|
} catch {
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
|
+
var ROOT_PROVIDER_SDKS = {
|
|
283
|
+
supabase: ["@supabase/supabase-js"],
|
|
284
|
+
cloudinary: ["cloudinary"],
|
|
285
|
+
mongodb: ["mongoose"],
|
|
286
|
+
firebase: ["firebase-admin"]
|
|
287
|
+
};
|
|
288
|
+
async function pruneRootProviderDeps(targetDir, opts) {
|
|
289
|
+
const chosen = /* @__PURE__ */ new Set([opts.authProvider, opts.dbProvider, opts.upload]);
|
|
290
|
+
const drop = /* @__PURE__ */ new Set();
|
|
291
|
+
for (const [provider, sdks] of Object.entries(ROOT_PROVIDER_SDKS)) {
|
|
292
|
+
if (!chosen.has(provider)) for (const sdk of sdks) drop.add(sdk);
|
|
293
|
+
}
|
|
294
|
+
if (drop.size === 0) return;
|
|
295
|
+
const pkgPath = join2(targetDir, "package.json");
|
|
296
|
+
try {
|
|
297
|
+
const pkg = JSON.parse(await readFile2(pkgPath, "utf8"));
|
|
298
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
299
|
+
const deps = pkg[field];
|
|
300
|
+
if (!deps) continue;
|
|
301
|
+
for (const sdk of drop) delete deps[sdk];
|
|
302
|
+
}
|
|
303
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
304
|
+
} catch {
|
|
305
|
+
}
|
|
306
|
+
}
|
|
282
307
|
async function rewriteRootPackageJson(targetDir, opts) {
|
|
283
308
|
const pkgPath = join2(targetDir, "package.json");
|
|
284
309
|
const raw = await readFile2(pkgPath, "utf8");
|
|
@@ -418,42 +443,26 @@ async function stripTsconfigPath(targetDir, alias) {
|
|
|
418
443
|
} catch {
|
|
419
444
|
}
|
|
420
445
|
}
|
|
421
|
-
async function
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
"
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
try {
|
|
433
|
-
const appModule = await readFile3(appModulePath, "utf8");
|
|
434
|
-
const next = appModule.replace(/^import \{ AdminModule \} from '\.\/admin\/admin\.module';\n/m, "").replace(/,\s*AdminModule/g, "");
|
|
435
|
-
await writeFile2(appModulePath, next);
|
|
436
|
-
} catch {
|
|
437
|
-
}
|
|
438
|
-
await stripDeps(join3(targetDir, "apps/api/package.json"), [
|
|
439
|
-
"@icore/jobs-client",
|
|
440
|
-
"@bull-board/api",
|
|
441
|
-
"@bull-board/express"
|
|
446
|
+
async function removeFirebaseAdminLib(targetDir) {
|
|
447
|
+
await rm(join3(targetDir, "libs/firebase-admin"), { recursive: true, force: true });
|
|
448
|
+
await stripTsconfigPath(targetDir, "@icore/firebase-admin");
|
|
449
|
+
await stripDeps(join3(targetDir, "apps/microservices/auth/package.json"), [
|
|
450
|
+
"@icore/firebase-admin"
|
|
451
|
+
]);
|
|
452
|
+
await stripDeps(join3(targetDir, "apps/microservices/upload/package.json"), [
|
|
453
|
+
"@icore/firebase-admin"
|
|
454
|
+
]);
|
|
455
|
+
await stripDeps(join3(targetDir, "apps/microservices/notes/package.json"), [
|
|
456
|
+
"@icore/firebase-admin"
|
|
442
457
|
]);
|
|
443
|
-
const composePath = join3(targetDir, "docker-compose.yml");
|
|
444
|
-
try {
|
|
445
|
-
const compose = await readFile3(composePath, "utf8");
|
|
446
|
-
const next = compose.replace(/\n {2}jobs:[\s\S]+?(?=\n {2}\w+:|\nnetworks:)/m, "\n").replace(/\n {6}jobs:\n {8}condition: service_started/g, "").replace(/\n {6}JOBS_REDIS_URL:[^\n]*/g, "");
|
|
447
|
-
await writeFile2(composePath, next);
|
|
448
|
-
} catch {
|
|
449
|
-
}
|
|
450
458
|
}
|
|
451
|
-
async function
|
|
459
|
+
async function removeUploadStack(targetDir) {
|
|
452
460
|
const paths = [
|
|
453
|
-
"apps/microservices/
|
|
454
|
-
"apps/microservices/
|
|
455
|
-
"libs/
|
|
456
|
-
"
|
|
461
|
+
"apps/microservices/upload",
|
|
462
|
+
"apps/microservices/upload-e2e",
|
|
463
|
+
"libs/storage-strategies",
|
|
464
|
+
"libs/upload-client",
|
|
465
|
+
"apps/api/src/app/storage"
|
|
457
466
|
];
|
|
458
467
|
for (const p3 of paths) {
|
|
459
468
|
await rm(join3(targetDir, p3), { recursive: true, force: true });
|
|
@@ -461,319 +470,456 @@ async function removePaymentStack(targetDir) {
|
|
|
461
470
|
const appModulePath = join3(targetDir, "apps/api/src/app/app.module.ts");
|
|
462
471
|
try {
|
|
463
472
|
const appModule = await readFile3(appModulePath, "utf8");
|
|
464
|
-
const next = appModule.replace(/^import \{
|
|
473
|
+
const next = appModule.replace(/^import \{ StorageModule \} from '\.\/storage\/storage\.module';\n/m, "").replace(/,\s*StorageModule/g, "");
|
|
465
474
|
await writeFile2(appModulePath, next);
|
|
466
475
|
} catch {
|
|
467
476
|
}
|
|
468
|
-
|
|
469
|
-
"@icore/payment-client",
|
|
470
|
-
"@idevconn/payment"
|
|
471
|
-
]);
|
|
472
|
-
await stripGatewayTransport(targetDir, "PAYMENT");
|
|
473
|
-
const mainTsPath = join3(targetDir, "apps/api/src/main.ts");
|
|
474
|
-
try {
|
|
475
|
-
const src = await readFile3(mainTsPath, "utf8");
|
|
476
|
-
const next = src.replace(/\n\s*\{ name: 'payment', prefix: 'PAYMENT' \},/, "");
|
|
477
|
-
await writeFile2(mainTsPath, next);
|
|
478
|
-
} catch {
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
async function removeNotesStack(targetDir) {
|
|
482
|
-
for (const p3 of [
|
|
483
|
-
"apps/microservices/notes",
|
|
484
|
-
"apps/microservices/notes-e2e",
|
|
485
|
-
"libs/notes-client",
|
|
486
|
-
"apps/api/src/app/notes",
|
|
487
|
-
"apps/client/src/components/notes"
|
|
488
|
-
]) {
|
|
489
|
-
await rm(join3(targetDir, p3), { recursive: true, force: true });
|
|
490
|
-
}
|
|
491
|
-
await rm(join3(targetDir, "apps/client/src/routes/_dashboard/notes.tsx"), { force: true });
|
|
492
|
-
await rm(join3(targetDir, "apps/client/src/queries/notes.ts"), { force: true });
|
|
493
|
-
const appModulePath = join3(targetDir, "apps/api/src/app/app.module.ts");
|
|
477
|
+
const gatewayEnv = join3(targetDir, "apps/api/.env");
|
|
494
478
|
try {
|
|
495
|
-
const
|
|
496
|
-
const next =
|
|
497
|
-
|
|
479
|
+
const env = await readFile3(gatewayEnv, "utf8");
|
|
480
|
+
const next = env.split("\n").filter(
|
|
481
|
+
(line) => !line.startsWith("UPLOAD_") && !line.startsWith("# UPLOAD_") && !line.startsWith("MAX_FILE_SIZE_KB")
|
|
482
|
+
).join("\n");
|
|
483
|
+
await writeFile2(gatewayEnv, next);
|
|
498
484
|
} catch {
|
|
499
485
|
}
|
|
500
486
|
await stripDeps(join3(targetDir, "apps/api/package.json"), [
|
|
501
|
-
"@icore/
|
|
502
|
-
"@
|
|
487
|
+
"@icore/upload-client",
|
|
488
|
+
"@types/multer"
|
|
503
489
|
]);
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// src/manifest/wire-features.ts
|
|
493
|
+
import { readFile as readFile5, writeFile as writeFile4, rm as rm3 } from "fs/promises";
|
|
494
|
+
import { join as join5 } from "path";
|
|
495
|
+
|
|
496
|
+
// src/manifest/index.ts
|
|
497
|
+
var EMPTY = { libDirs: [], deps: {}, tsPaths: {} };
|
|
498
|
+
var MANIFEST = {
|
|
499
|
+
auth: {
|
|
500
|
+
supabase: {
|
|
501
|
+
libDirs: ["libs/auth-strategies/supabase"],
|
|
502
|
+
deps: { "@supabase/supabase-js": "^2.106.2" },
|
|
503
|
+
tsPaths: { "@icore/auth-supabase": ["libs/auth-strategies/supabase/src/index.ts"] },
|
|
504
|
+
nestModule: {
|
|
505
|
+
importFrom: "@icore/auth-supabase",
|
|
506
|
+
symbol: "SupabaseAuthModule",
|
|
507
|
+
into: "auth"
|
|
508
|
+
},
|
|
509
|
+
appTests: [
|
|
510
|
+
"apps/microservices/auth/src/app/__tests__/auth.controller.supabase.integration.unit.test.ts"
|
|
511
|
+
]
|
|
512
|
+
},
|
|
513
|
+
firebase: {
|
|
514
|
+
libDirs: ["libs/auth-strategies/firebase"],
|
|
515
|
+
deps: {},
|
|
516
|
+
tsPaths: { "@icore/auth-firebase": ["libs/auth-strategies/firebase/src/index.ts"] },
|
|
517
|
+
nestModule: {
|
|
518
|
+
importFrom: "@icore/auth-firebase",
|
|
519
|
+
symbol: "FirebaseAuthModule",
|
|
520
|
+
into: "auth"
|
|
521
|
+
},
|
|
522
|
+
appTests: [
|
|
523
|
+
"apps/microservices/auth/src/app/__tests__/auth.controller.firebase.integration.unit.test.ts"
|
|
524
|
+
]
|
|
525
|
+
},
|
|
526
|
+
mongodb: {
|
|
527
|
+
libDirs: ["libs/auth-strategies/mongodb"],
|
|
528
|
+
deps: { mongoose: "^9.6.3" },
|
|
529
|
+
tsPaths: { "@icore/auth-mongodb": ["libs/auth-strategies/mongodb/src/index.ts"] },
|
|
530
|
+
nestModule: { importFrom: "@icore/auth-mongodb", symbol: "MongoDbAuthModule", into: "auth" }
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
storage: {
|
|
534
|
+
supabase: {
|
|
535
|
+
libDirs: ["libs/storage-strategies/supabase"],
|
|
536
|
+
deps: { "@supabase/supabase-js": "^2.106.2" },
|
|
537
|
+
tsPaths: { "@icore/storage-supabase": ["libs/storage-strategies/supabase/src/index.ts"] },
|
|
538
|
+
nestModule: {
|
|
539
|
+
importFrom: "@icore/storage-supabase",
|
|
540
|
+
symbol: "SupabaseStorageModule",
|
|
541
|
+
into: "upload"
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
firebase: {
|
|
545
|
+
libDirs: ["libs/storage-strategies/firebase"],
|
|
546
|
+
deps: {},
|
|
547
|
+
tsPaths: { "@icore/storage-firebase": ["libs/storage-strategies/firebase/src/index.ts"] },
|
|
548
|
+
nestModule: {
|
|
549
|
+
importFrom: "@icore/storage-firebase",
|
|
550
|
+
symbol: "FirebaseStorageModule",
|
|
551
|
+
into: "upload"
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
cloudinary: {
|
|
555
|
+
libDirs: ["libs/storage-strategies/cloudinary"],
|
|
556
|
+
deps: { cloudinary: "^2.10.0" },
|
|
557
|
+
tsPaths: { "@icore/storage-cloudinary": ["libs/storage-strategies/cloudinary/src/index.ts"] },
|
|
558
|
+
nestModule: {
|
|
559
|
+
importFrom: "@icore/storage-cloudinary",
|
|
560
|
+
symbol: "CloudinaryStorageModule",
|
|
561
|
+
into: "upload"
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
mongodb: {
|
|
565
|
+
libDirs: ["libs/storage-strategies/mongodb"],
|
|
566
|
+
deps: { mongoose: "^9.6.3" },
|
|
567
|
+
tsPaths: { "@icore/storage-mongodb": ["libs/storage-strategies/mongodb/src/index.ts"] },
|
|
568
|
+
nestModule: {
|
|
569
|
+
importFrom: "@icore/storage-mongodb",
|
|
570
|
+
symbol: "MongoDbStorageModule",
|
|
571
|
+
into: "upload"
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
db: {
|
|
576
|
+
supabase: {
|
|
577
|
+
libDirs: ["libs/db-strategies/supabase"],
|
|
578
|
+
deps: { "@supabase/supabase-js": "^2.106.2" },
|
|
579
|
+
tsPaths: { "@icore/db-supabase": ["libs/db-strategies/supabase/src/index.ts"] },
|
|
580
|
+
nestModule: { importFrom: "@icore/db-supabase", symbol: "SupabaseDbModule", into: "notes" }
|
|
581
|
+
},
|
|
582
|
+
firebase: {
|
|
583
|
+
libDirs: ["libs/db-strategies/firestore"],
|
|
584
|
+
deps: {},
|
|
585
|
+
tsPaths: { "@icore/db-firestore": ["libs/db-strategies/firestore/src/index.ts"] },
|
|
586
|
+
nestModule: { importFrom: "@icore/db-firestore", symbol: "FirestoreDbModule", into: "notes" }
|
|
587
|
+
},
|
|
588
|
+
mongodb: {
|
|
589
|
+
libDirs: ["libs/db-strategies/mongodb"],
|
|
590
|
+
deps: { mongoose: "^9.6.3" },
|
|
591
|
+
tsPaths: { "@icore/db-mongodb": ["libs/db-strategies/mongodb/src/index.ts"] },
|
|
592
|
+
nestModule: { importFrom: "@icore/db-mongodb", symbol: "MongoDbDbModule", into: "notes" }
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
feature: {
|
|
596
|
+
notes: {
|
|
597
|
+
libDirs: [
|
|
598
|
+
"apps/microservices/notes",
|
|
599
|
+
"apps/microservices/notes-e2e",
|
|
600
|
+
"libs/notes-client",
|
|
601
|
+
"libs/db-strategies",
|
|
602
|
+
"apps/api/src/app/notes",
|
|
603
|
+
"apps/client/src/components/notes",
|
|
604
|
+
"apps/client/src/routes/_dashboard/notes.tsx",
|
|
605
|
+
"apps/client/src/queries/notes.ts"
|
|
606
|
+
],
|
|
607
|
+
deps: { "@icore/notes-client": "*", "@casl/ability": "^7.0.0" },
|
|
608
|
+
tsPaths: { "@icore/notes-client": ["libs/notes-client/src/index.ts"] },
|
|
609
|
+
gatewayModule: { importFrom: "./notes/notes.module", symbol: "NotesModule" },
|
|
610
|
+
gatewayService: { name: "notes", prefix: "NOTES" },
|
|
611
|
+
clientNav: { route: "/notes", labelKey: "nav.notes", iconName: "notes" }
|
|
612
|
+
},
|
|
613
|
+
payment: {
|
|
614
|
+
libDirs: [
|
|
615
|
+
"apps/microservices/payment",
|
|
616
|
+
"apps/microservices/payment-e2e",
|
|
617
|
+
"libs/payment-client",
|
|
618
|
+
"apps/api/src/app/payment"
|
|
619
|
+
],
|
|
620
|
+
deps: { "@icore/payment-client": "*", "@idevconn/payment": "^1.2.0" },
|
|
621
|
+
tsPaths: { "@icore/payment-client": ["libs/payment-client/src/index.ts"] },
|
|
622
|
+
gatewayModule: { importFrom: "./payment/payment.module", symbol: "PaymentModule" },
|
|
623
|
+
gatewayService: { name: "payment", prefix: "PAYMENT" }
|
|
624
|
+
},
|
|
625
|
+
jobs: {
|
|
626
|
+
libDirs: [
|
|
627
|
+
"apps/microservices/jobs",
|
|
628
|
+
"libs/jobs-client",
|
|
629
|
+
"apps/api/src/app/admin",
|
|
630
|
+
"Dockerfile.ms-jobs"
|
|
631
|
+
],
|
|
632
|
+
deps: {
|
|
633
|
+
"@icore/jobs-client": "*",
|
|
634
|
+
"@bull-board/api": "^7.1.5",
|
|
635
|
+
"@bull-board/express": "^7.1.5"
|
|
636
|
+
},
|
|
637
|
+
tsPaths: { "@icore/jobs-client": ["libs/jobs-client/src/index.ts"] },
|
|
638
|
+
gatewayModule: { importFrom: "./admin/admin.module", symbol: "AdminModule" },
|
|
639
|
+
dockerService: "jobs"
|
|
640
|
+
}
|
|
641
|
+
},
|
|
642
|
+
ui: { shadcn: EMPTY, antd: EMPTY, mui: EMPTY },
|
|
643
|
+
transport: { tcp: EMPTY, redis: EMPTY, nats: EMPTY, mqtt: EMPTY, rmq: EMPTY, kafka: EMPTY },
|
|
644
|
+
shared: {
|
|
645
|
+
firebaseAdmin: {
|
|
646
|
+
libDirs: ["libs/firebase-admin"],
|
|
647
|
+
deps: { "firebase-admin": "^13.10.0" },
|
|
648
|
+
tsPaths: { "@icore/firebase-admin": ["libs/firebase-admin/src/index.ts"] }
|
|
649
|
+
}
|
|
518
650
|
}
|
|
519
|
-
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
// src/manifest/wire-provider.ts
|
|
654
|
+
import { readFile as readFile4, writeFile as writeFile3, rm as rm2 } from "fs/promises";
|
|
655
|
+
import { join as join4 } from "path";
|
|
656
|
+
async function writeProvider(targetDir, axis, provider) {
|
|
657
|
+
const nestModule = axis.section[provider]?.nestModule;
|
|
658
|
+
if (!nestModule) throw new Error(`provider "${provider}" has no nestModule in the manifest`);
|
|
659
|
+
const { importFrom, symbol } = nestModule;
|
|
660
|
+
const content = `import { ${symbol} } from '${importFrom}';
|
|
661
|
+
|
|
662
|
+
const ENV_PATH = '${axis.envPath}';
|
|
663
|
+
|
|
664
|
+
export const ${axis.exportConst} = ${symbol}.forRoot(ENV_PATH);
|
|
665
|
+
`;
|
|
666
|
+
await writeFile3(join4(targetDir, axis.providerFile), content);
|
|
667
|
+
}
|
|
668
|
+
async function stripJsonKeys(path, drop) {
|
|
520
669
|
try {
|
|
521
|
-
const
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
).replace("import NoteOutlinedIcon from '@mui/icons-material/NoteOutlined';\n", "").replace(
|
|
529
|
-
/\n {8}<ListItemButton\n {10}component=\{Link\}\n {10}to="\/(?:_dashboard\/)?notes"[\s\S]*?<\/ListItemButton>/,
|
|
530
|
-
""
|
|
531
|
-
).replace(/\n\s*<Link to="\/(?:_dashboard\/)?notes">[\s\S]*?<\/Link>/m, "");
|
|
532
|
-
await writeFile2(siderPath, next);
|
|
670
|
+
const pkg = JSON.parse(await readFile4(path, "utf8"));
|
|
671
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
672
|
+
const deps = pkg[field];
|
|
673
|
+
if (!deps) continue;
|
|
674
|
+
for (const k of Object.keys(deps)) if (drop(k)) delete deps[k];
|
|
675
|
+
}
|
|
676
|
+
await writeFile3(path, JSON.stringify(pkg, null, 2) + "\n");
|
|
533
677
|
} catch {
|
|
534
678
|
}
|
|
535
|
-
|
|
679
|
+
}
|
|
680
|
+
async function stripTsconfigKeys(targetDir, aliases) {
|
|
681
|
+
const path = join4(targetDir, "tsconfig.base.json");
|
|
536
682
|
try {
|
|
537
|
-
const
|
|
538
|
-
const
|
|
539
|
-
|
|
683
|
+
const parsed = JSON.parse(await readFile4(path, "utf8"));
|
|
684
|
+
const paths = parsed.compilerOptions?.paths;
|
|
685
|
+
if (paths) for (const a of aliases) delete paths[a];
|
|
686
|
+
await writeFile3(path, JSON.stringify(parsed, null, 2) + "\n");
|
|
540
687
|
} catch {
|
|
541
688
|
}
|
|
542
689
|
}
|
|
543
|
-
async function
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
await
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
]);
|
|
554
|
-
await stripTsconfigPath(targetDir, "@icore/auth-firebase");
|
|
555
|
-
await stripTsconfigPath(targetDir, "@icore/auth-mongodb");
|
|
556
|
-
try {
|
|
557
|
-
const src = await readFile3(modulePath, "utf8");
|
|
558
|
-
const next = src.replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/gm, "").replace(/^import \{[^}]*FirebaseAuthStrategy[^}]*\} from '@icore\/auth-firebase';\n/gm, "").replace(/^import \{[^}]*MongoDbAuthStrategy[^}]*\} from '@icore\/auth-mongodb';\n/gm, "").replace(
|
|
559
|
-
/^import \{ MongooseModule, getConnectionToken \} from '@nestjs\/mongoose';\n/gm,
|
|
560
|
-
""
|
|
561
|
-
).replace(/^import \{ Connection \} from 'mongoose';\n/gm, "").replace(/^ {2}firebase: \[[^\]]*\],\n/gm, "").replace(/^ {2}mongodb: \[[^\]]*\],\n/gm, "").replace(/\nfunction makeFirebaseAuth[\s\S]*?\n}\n/gm, "").replace(/\nfunction makeMongoDbAuth[\s\S]*?\n}\n/gm, "").replace(/^ {4}MongooseModule\.forRootAsync[\s\S]*?\n {4}\}\),\n/gm, "").replace(AUTH_BRANCH, "return makeSupabaseAuth(cfg);").replace(/, connection: Connection/, "").replace(/, getConnectionToken\(\)/, "");
|
|
562
|
-
await writeFile2(modulePath, next);
|
|
563
|
-
} catch {
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
if (authProvider === "firebase") {
|
|
567
|
-
await rm(join3(targetDir, "libs/auth-strategies/supabase"), { recursive: true, force: true });
|
|
568
|
-
await rm(join3(targetDir, "libs/auth-strategies/mongodb"), { recursive: true, force: true });
|
|
569
|
-
await stripDeps(join3(targetDir, "apps/microservices/auth/package.json"), [
|
|
570
|
-
"@icore/auth-supabase",
|
|
571
|
-
"@icore/auth-mongodb"
|
|
572
|
-
]);
|
|
573
|
-
await stripTsconfigPath(targetDir, "@icore/auth-supabase");
|
|
574
|
-
await stripTsconfigPath(targetDir, "@icore/auth-mongodb");
|
|
575
|
-
try {
|
|
576
|
-
const src = await readFile3(modulePath, "utf8");
|
|
577
|
-
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/gm, "").replace(/^import \{[^}]*SupabaseAuthStrategy[^}]*\} from '@icore\/auth-supabase';\n/gm, "").replace(/^import \{[^}]*MongoDbAuthStrategy[^}]*\} from '@icore\/auth-mongodb';\n/gm, "").replace(
|
|
578
|
-
/^import \{ MongooseModule, getConnectionToken \} from '@nestjs\/mongoose';\n/gm,
|
|
579
|
-
""
|
|
580
|
-
).replace(/^import \{ Connection \} from 'mongoose';\n/gm, "").replace(/^ {2}supabase: \[[^\]]*\],\n/gm, "").replace(/^ {2}mongodb: \[[^\]]*\],\n/gm, "").replace(/\nfunction makeSupabaseAuth[\s\S]*?\n}\n/gm, "").replace(/\nfunction makeMongoDbAuth[\s\S]*?\n}\n/gm, "").replace(/^ {4}MongooseModule\.forRootAsync[\s\S]*?\n {4}\}\),\n/gm, "").replace(AUTH_BRANCH, "return makeFirebaseAuth(cfg);").replace(/, connection: Connection/, "").replace(/, getConnectionToken\(\)/, "");
|
|
581
|
-
await writeFile2(modulePath, next);
|
|
582
|
-
} catch {
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
if (authProvider === "mongodb") {
|
|
586
|
-
await rm(join3(targetDir, "libs/auth-strategies/supabase"), { recursive: true, force: true });
|
|
587
|
-
await rm(join3(targetDir, "libs/auth-strategies/firebase"), { recursive: true, force: true });
|
|
588
|
-
await stripDeps(join3(targetDir, "apps/microservices/auth/package.json"), [
|
|
589
|
-
"@icore/auth-supabase",
|
|
590
|
-
"@icore/auth-firebase",
|
|
591
|
-
"@icore/firebase-admin"
|
|
592
|
-
]);
|
|
593
|
-
await stripTsconfigPath(targetDir, "@icore/auth-supabase");
|
|
594
|
-
await stripTsconfigPath(targetDir, "@icore/auth-firebase");
|
|
595
|
-
try {
|
|
596
|
-
const src = await readFile3(modulePath, "utf8");
|
|
597
|
-
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/gm, "").replace(/^import \{[^}]*SupabaseAuthStrategy[^}]*\} from '@icore\/auth-supabase';\n/gm, "").replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/gm, "").replace(/^import \{[^}]*FirebaseAuthStrategy[^}]*\} from '@icore\/auth-firebase';\n/gm, "").replace(/^ {2}supabase: \[[^\]]*\],\n/gm, "").replace(/^ {2}firebase: \[[^\]]*\],\n/gm, "").replace(/\nfunction makeSupabaseAuth[\s\S]*?\n}\n/gm, "").replace(/\nfunction makeFirebaseAuth[\s\S]*?\n}\n/gm, "").replace(AUTH_BRANCH, "return makeMongoDbAuth(connection, cfg);");
|
|
598
|
-
await writeFile2(modulePath, next);
|
|
599
|
-
} catch {
|
|
600
|
-
}
|
|
690
|
+
async function cleanupUnusedAxis(targetDir, axis, chosen) {
|
|
691
|
+
for (const provider of Object.keys(axis.section)) {
|
|
692
|
+
if (provider === chosen) continue;
|
|
693
|
+
const unit = axis.section[provider];
|
|
694
|
+
for (const dir of unit.libDirs)
|
|
695
|
+
await rm2(join4(targetDir, dir), { recursive: true, force: true });
|
|
696
|
+
for (const t of unit.appTests ?? []) await rm2(join4(targetDir, t), { force: true });
|
|
697
|
+
const dropKeys = /* @__PURE__ */ new Set([...Object.keys(unit.tsPaths), ...Object.keys(unit.deps)]);
|
|
698
|
+
await stripJsonKeys(join4(targetDir, axis.msPackageJson), (k) => dropKeys.has(k));
|
|
699
|
+
await stripTsconfigKeys(targetDir, Object.keys(unit.tsPaths));
|
|
601
700
|
}
|
|
602
701
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
await stripDeps(join3(targetDir, "apps/microservices/upload/package.json"), [
|
|
635
|
-
"@icore/storage-mongodb"
|
|
636
|
-
]);
|
|
637
|
-
await stripTsconfigPath(targetDir, "@icore/storage-mongodb");
|
|
702
|
+
|
|
703
|
+
// src/manifest/wire-features.ts
|
|
704
|
+
var FEATURES_MODULE = "apps/api/src/app/features.module.ts";
|
|
705
|
+
var GATEWAY_SERVICES = "apps/api/src/app/gateway-services.ts";
|
|
706
|
+
var API_PKG = "apps/api/package.json";
|
|
707
|
+
var FEATURES = MANIFEST.feature;
|
|
708
|
+
function selectedFeatures(opts) {
|
|
709
|
+
const out = [];
|
|
710
|
+
if (opts.example === "notes") out.push("notes");
|
|
711
|
+
if (opts.payment !== "none") out.push("payment");
|
|
712
|
+
if (opts.jobs !== "none") out.push("jobs");
|
|
713
|
+
return out;
|
|
714
|
+
}
|
|
715
|
+
async function writeFeaturesWiring(targetDir, opts) {
|
|
716
|
+
const chosen = selectedFeatures(opts);
|
|
717
|
+
const mods = chosen.map((k) => FEATURES[k].gatewayModule).filter((m) => !!m);
|
|
718
|
+
const imports = mods.map((m) => `import { ${m.symbol} } from '${m.importFrom}';`).join("\n");
|
|
719
|
+
const symbols = mods.map((m) => m.symbol).join(", ");
|
|
720
|
+
const featuresModule = `import { Module } from '@nestjs/common';
|
|
721
|
+
` + (imports ? imports + "\n" : "") + `
|
|
722
|
+
@Module({
|
|
723
|
+
imports: [${symbols}],
|
|
724
|
+
})
|
|
725
|
+
export class FeaturesModule {}
|
|
726
|
+
`;
|
|
727
|
+
await writeFile4(join5(targetDir, FEATURES_MODULE), featuresModule);
|
|
728
|
+
const services = [{ name: "auth", prefix: "AUTH" }];
|
|
729
|
+
if (opts.upload !== "none") services.push({ name: "upload", prefix: "UPLOAD" });
|
|
730
|
+
for (const k of chosen) {
|
|
731
|
+
const svc = FEATURES[k].gatewayService;
|
|
732
|
+
if (svc) services.push(svc);
|
|
638
733
|
}
|
|
734
|
+
const entries = services.map((s) => ` { name: '${s.name}', prefix: '${s.prefix}' },`).join("\n");
|
|
735
|
+
const gatewayServices = `/** Microservices the gateway proxies. Generated by create-icore. */
|
|
736
|
+
export const GATEWAY_SERVICES = [
|
|
737
|
+
${entries}
|
|
738
|
+
];
|
|
739
|
+
`;
|
|
740
|
+
await writeFile4(join5(targetDir, GATEWAY_SERVICES), gatewayServices);
|
|
741
|
+
}
|
|
742
|
+
async function stripJobsDockerCompose(targetDir) {
|
|
743
|
+
const composePath = join5(targetDir, "docker-compose.yml");
|
|
639
744
|
try {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
/^import \{[^}]*FirebaseStorageStrategy[^}]*\} from '@icore\/storage-firebase';\n/gm,
|
|
644
|
-
""
|
|
645
|
-
).replace(/^ {2}firebase: \[[^\]]*\],\n/gm, "").replace(/\nfunction makeFirebaseStorage[\s\S]*?\n}\n/gm, "");
|
|
646
|
-
}
|
|
647
|
-
if (uploadProvider !== "cloudinary") {
|
|
648
|
-
src = src.replace(/^import \{ v2 as cloudinary \} from 'cloudinary';\n/gm, "").replace(
|
|
649
|
-
/^import \{[^}]*CloudinaryStorageStrategy[^}]*\} from '@icore\/storage-cloudinary';\n/gm,
|
|
650
|
-
""
|
|
651
|
-
).replace(/\nfunction makeCloudinaryStorage[\s\S]*?\n}\n/gm, "");
|
|
652
|
-
}
|
|
653
|
-
if (uploadProvider !== "supabase") {
|
|
654
|
-
src = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/gm, "").replace(
|
|
655
|
-
/^import \{[^}]*SupabaseStorageStrategy[^}]*\} from '@icore\/storage-supabase';\n/gm,
|
|
656
|
-
""
|
|
657
|
-
).replace(/\nfunction makeSupabaseStorage[\s\S]*?\n}\n/gm, "");
|
|
658
|
-
}
|
|
659
|
-
if (uploadProvider !== "mongodb") {
|
|
660
|
-
src = src.replace(
|
|
661
|
-
/^import \{[^}]*MongoDbStorageStrategy[^}]*\} from '@icore\/storage-mongodb';\n/gm,
|
|
662
|
-
""
|
|
663
|
-
).replace(
|
|
664
|
-
/^import \{ MongooseModule, getConnectionToken \} from '@nestjs\/mongoose';\n/gm,
|
|
665
|
-
""
|
|
666
|
-
).replace(/^import \{ Connection \} from 'mongoose';\n/gm, "").replace(/^ {2}mongodb: \[[^\]]*\],\n/gm, "").replace(/\nfunction makeMongoDbStorage[\s\S]*?\n}\n/gm, "").replace(/^ {4}MongooseModule\.forRootAsync[\s\S]*?\n {4}\}\),\n/gm, "");
|
|
667
|
-
}
|
|
668
|
-
const chosenReturn = uploadProvider === "mongodb" ? `return makeMongoDbStorage(connection);` : `return make${uploadProvider.charAt(0).toUpperCase() + uploadProvider.slice(1)}Storage(cfg);`;
|
|
669
|
-
src = src.replace(STORAGE_BRANCH, chosenReturn);
|
|
670
|
-
if (uploadProvider !== "mongodb") {
|
|
671
|
-
src = src.replace(/, connection: Connection/, "").replace(/, getConnectionToken\(\)/, "");
|
|
672
|
-
}
|
|
673
|
-
await writeFile2(modulePath, src);
|
|
745
|
+
const compose = await readFile5(composePath, "utf8");
|
|
746
|
+
const next = compose.replace(/\n {2}jobs:[\s\S]+?(?=\n {2}\w+:|\nnetworks:)/m, "\n").replace(/\n {6}jobs:\n {8}condition: service_started/g, "").replace(/\n {6}JOBS_REDIS_URL:[^\n]*/g, "");
|
|
747
|
+
await writeFile4(composePath, next);
|
|
674
748
|
} catch {
|
|
675
749
|
}
|
|
676
750
|
}
|
|
677
|
-
async function
|
|
678
|
-
const
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
await stripTsconfigPath(targetDir, "@icore/db-mongodb");
|
|
690
|
-
try {
|
|
691
|
-
const src = await readFile3(modulePath, "utf8");
|
|
692
|
-
const next = src.replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/gm, "").replace(/^import \{[^}]*FirestoreDBStrategy[^}]*\} from '@icore\/db-firestore';\n/gm, "").replace(/^import \{[^}]*MongoDbDBStrategy[^}]*\} from '@icore\/db-mongodb';\n/gm, "").replace(
|
|
693
|
-
/^import \{ MongooseModule, getConnectionToken \} from '@nestjs\/mongoose';\n/gm,
|
|
694
|
-
""
|
|
695
|
-
).replace(/^import \{ Connection \} from 'mongoose';\n/gm, "").replace(/^ {2}firestore: \[[^\]]*\],\n/gm, "").replace(/^ {2}firebase: \[[^\]]*\],\n/gm, "").replace(/^ {2}mongodb: \[[^\]]*\],\n/gm, "").replace(/\nfunction makeFirestoreDB[\s\S]*?\n}\n/gm, "").replace(/\nfunction makeMongoDb[\s\S]*?\n}\n/gm, "").replace(/^ {4}MongooseModule\.forRootAsync[\s\S]*?\n {4}\}\),\n/gm, "").replace(DB_BRANCH, "return makeSupabaseDB(cfg);").replace(/, connection: Connection/, "").replace(/, getConnectionToken\(\)/, "");
|
|
696
|
-
await writeFile2(modulePath, next);
|
|
697
|
-
} catch {
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
if (dbProvider === "firebase") {
|
|
701
|
-
await rm(join3(targetDir, "libs/db-strategies/supabase"), { recursive: true, force: true });
|
|
702
|
-
await rm(join3(targetDir, "libs/db-strategies/mongodb"), { recursive: true, force: true });
|
|
703
|
-
await stripDeps(join3(targetDir, "apps/microservices/notes/package.json"), [
|
|
704
|
-
"@icore/db-supabase",
|
|
705
|
-
"@icore/db-mongodb"
|
|
706
|
-
]);
|
|
707
|
-
await stripTsconfigPath(targetDir, "@icore/db-supabase");
|
|
708
|
-
await stripTsconfigPath(targetDir, "@icore/db-mongodb");
|
|
709
|
-
try {
|
|
710
|
-
const src = await readFile3(modulePath, "utf8");
|
|
711
|
-
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/gm, "").replace(/^import \{[^}]*SupabaseDBStrategy[^}]*\} from '@icore\/db-supabase';\n/gm, "").replace(/^import \{[^}]*MongoDbDBStrategy[^}]*\} from '@icore\/db-mongodb';\n/gm, "").replace(
|
|
712
|
-
/^import \{ MongooseModule, getConnectionToken \} from '@nestjs\/mongoose';\n/gm,
|
|
713
|
-
""
|
|
714
|
-
).replace(/^import \{ Connection \} from 'mongoose';\n/gm, "").replace(/^ {2}supabase: \[[^\]]*\],\n/gm, "").replace(/^ {2}mongodb: \[[^\]]*\],\n/gm, "").replace(/\nfunction makeSupabaseDB[\s\S]*?\n}\n/gm, "").replace(/\nfunction makeMongoDb[\s\S]*?\n}\n/gm, "").replace(/^ {4}MongooseModule\.forRootAsync[\s\S]*?\n {4}\}\),\n/gm, "").replace(/\nfunction requireEnv[\s\S]*?\n}\n/gm, "").replace(DB_BRANCH, "return makeFirestoreDB(cfg);").replace(/, connection: Connection/, "").replace(/, getConnectionToken\(\)/, "");
|
|
715
|
-
await writeFile2(modulePath, next);
|
|
716
|
-
} catch {
|
|
717
|
-
}
|
|
751
|
+
async function cleanupUnusedFeatures(targetDir, opts) {
|
|
752
|
+
const chosen = new Set(selectedFeatures(opts));
|
|
753
|
+
for (const key of ["notes", "payment", "jobs"]) {
|
|
754
|
+
if (chosen.has(key)) continue;
|
|
755
|
+
const unit = FEATURES[key];
|
|
756
|
+
for (const dir of unit.libDirs)
|
|
757
|
+
await rm3(join5(targetDir, dir), { recursive: true, force: true });
|
|
758
|
+
const dropKeys = /* @__PURE__ */ new Set([...Object.keys(unit.tsPaths), ...Object.keys(unit.deps)]);
|
|
759
|
+
await stripJsonKeys(join5(targetDir, API_PKG), (k) => dropKeys.has(k));
|
|
760
|
+
await stripTsconfigKeys(targetDir, Object.keys(unit.tsPaths));
|
|
761
|
+
if (unit.gatewayService) await stripGatewayTransport(targetDir, unit.gatewayService.prefix);
|
|
762
|
+
if (unit.dockerService === "jobs") await stripJobsDockerCompose(targetDir);
|
|
718
763
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// src/manifest/wire-client.ts
|
|
767
|
+
import { writeFile as writeFile5 } from "fs/promises";
|
|
768
|
+
import { join as join6 } from "path";
|
|
769
|
+
var NAV_CONFIG_FILE = "apps/client/src/nav.config.ts";
|
|
770
|
+
var BASE_NAV = [
|
|
771
|
+
{ to: "/dashboard", labelKey: "nav.dashboard", iconName: "dashboard", exact: true }
|
|
772
|
+
];
|
|
773
|
+
var PROFILE_NAV = { to: "/profile", labelKey: "nav.profile", iconName: "profile" };
|
|
774
|
+
function renderEntry(n) {
|
|
775
|
+
const parts = [`to: '${n.to}'`, `labelKey: '${n.labelKey}'`, `iconName: '${n.iconName}'`];
|
|
776
|
+
if (n.exact) parts.push("exact: true");
|
|
777
|
+
return ` { ${parts.join(", ")} },`;
|
|
778
|
+
}
|
|
779
|
+
async function writeNavConfig(targetDir, opts) {
|
|
780
|
+
const entries = [...BASE_NAV];
|
|
781
|
+
const notesNav = MANIFEST.feature.notes.clientNav;
|
|
782
|
+
if (opts.example === "notes" && notesNav) {
|
|
783
|
+
entries.push({
|
|
784
|
+
to: notesNav.route,
|
|
785
|
+
labelKey: notesNav.labelKey,
|
|
786
|
+
iconName: notesNav.iconName,
|
|
787
|
+
exact: notesNav.exact
|
|
788
|
+
});
|
|
735
789
|
}
|
|
790
|
+
entries.push(PROFILE_NAV);
|
|
791
|
+
const content = `/**
|
|
792
|
+
* Sidebar navigation. UI-agnostic: each LayoutSider maps \`iconName\` to its own
|
|
793
|
+
* icon library. Generated by create-icore.
|
|
794
|
+
*/
|
|
795
|
+
export interface NavItem {
|
|
796
|
+
to: string;
|
|
797
|
+
labelKey: string;
|
|
798
|
+
iconName: 'dashboard' | 'notes' | 'profile';
|
|
799
|
+
exact?: boolean;
|
|
736
800
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
801
|
+
|
|
802
|
+
export const NAV_CONFIG: NavItem[] = [
|
|
803
|
+
` + entries.map(renderEntry).join("\n") + `
|
|
804
|
+
];
|
|
805
|
+
`;
|
|
806
|
+
await writeFile5(join6(targetDir, NAV_CONFIG_FILE), content);
|
|
740
807
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
808
|
+
|
|
809
|
+
// src/manifest/blueprint.ts
|
|
810
|
+
import { writeFile as writeFile6 } from "fs/promises";
|
|
811
|
+
import { join as join7 } from "path";
|
|
812
|
+
async function writeBlueprintJson(targetDir, opts) {
|
|
813
|
+
const blueprint = {
|
|
814
|
+
schemaVersion: 1,
|
|
815
|
+
projectName: opts.projectName,
|
|
816
|
+
authProvider: opts.authProvider,
|
|
817
|
+
dbProvider: opts.dbProvider,
|
|
818
|
+
upload: opts.upload,
|
|
819
|
+
payment: opts.payment,
|
|
820
|
+
jobs: opts.jobs,
|
|
821
|
+
example: opts.example,
|
|
822
|
+
ui: opts.ui,
|
|
823
|
+
transport: opts.transport,
|
|
824
|
+
packageManager: opts.packageManager
|
|
825
|
+
};
|
|
826
|
+
await writeFile6(join7(targetDir, "blueprint.json"), JSON.stringify(blueprint, null, 2) + "\n");
|
|
827
|
+
}
|
|
828
|
+
async function writeJson(targetDir, rel, data) {
|
|
829
|
+
await writeFile6(join7(targetDir, rel, "blueprint.json"), JSON.stringify(data, null, 2) + "\n");
|
|
830
|
+
}
|
|
831
|
+
async function writeServiceBlueprints(targetDir, opts) {
|
|
832
|
+
const t = opts.transport;
|
|
833
|
+
await writeJson(targetDir, "apps/microservices/auth", {
|
|
834
|
+
schemaVersion: 1,
|
|
835
|
+
service: "auth",
|
|
836
|
+
authProvider: opts.authProvider,
|
|
837
|
+
transport: t
|
|
838
|
+
});
|
|
839
|
+
if (opts.upload !== "none") {
|
|
840
|
+
await writeJson(targetDir, "apps/microservices/upload", {
|
|
841
|
+
schemaVersion: 1,
|
|
842
|
+
service: "upload",
|
|
843
|
+
storageProvider: opts.upload,
|
|
844
|
+
transport: t
|
|
845
|
+
});
|
|
751
846
|
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
847
|
+
if (opts.example !== "none") {
|
|
848
|
+
await writeJson(targetDir, "apps/microservices/notes", {
|
|
849
|
+
schemaVersion: 1,
|
|
850
|
+
service: "notes",
|
|
851
|
+
dbProvider: opts.dbProvider,
|
|
852
|
+
transport: t
|
|
853
|
+
});
|
|
758
854
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
} catch {
|
|
855
|
+
if (opts.payment !== "none") {
|
|
856
|
+
await writeJson(targetDir, "apps/microservices/payment", {
|
|
857
|
+
schemaVersion: 1,
|
|
858
|
+
service: "payment",
|
|
859
|
+
paymentProvider: opts.payment,
|
|
860
|
+
transport: t
|
|
861
|
+
});
|
|
767
862
|
}
|
|
768
|
-
|
|
769
|
-
"
|
|
770
|
-
|
|
771
|
-
|
|
863
|
+
if (opts.jobs !== "none") {
|
|
864
|
+
await writeJson(targetDir, "apps/microservices/jobs", {
|
|
865
|
+
schemaVersion: 1,
|
|
866
|
+
service: "jobs",
|
|
867
|
+
jobsProvider: opts.jobs
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
const features = [];
|
|
871
|
+
if (opts.example !== "none") features.push("notes");
|
|
872
|
+
if (opts.payment !== "none") features.push("payment");
|
|
873
|
+
if (opts.jobs !== "none") features.push("jobs");
|
|
874
|
+
await writeJson(targetDir, "apps/api", {
|
|
875
|
+
schemaVersion: 1,
|
|
876
|
+
service: "api",
|
|
877
|
+
features,
|
|
878
|
+
transport: t
|
|
879
|
+
});
|
|
880
|
+
await writeJson(targetDir, "apps/client", {
|
|
881
|
+
schemaVersion: 1,
|
|
882
|
+
service: "client",
|
|
883
|
+
ui: opts.ui
|
|
884
|
+
});
|
|
772
885
|
}
|
|
773
886
|
|
|
887
|
+
// src/manifest/wire-auth.ts
|
|
888
|
+
var AUTH = {
|
|
889
|
+
section: MANIFEST.auth,
|
|
890
|
+
providerFile: "apps/microservices/auth/src/app/auth.provider.ts",
|
|
891
|
+
exportConst: "AuthProviderModule",
|
|
892
|
+
msPackageJson: "apps/microservices/auth/package.json",
|
|
893
|
+
envPath: "apps/microservices/auth/.env"
|
|
894
|
+
};
|
|
895
|
+
var writeAuthProvider = (targetDir, provider) => writeProvider(targetDir, AUTH, provider);
|
|
896
|
+
var cleanupUnusedAuth = (targetDir, chosen) => cleanupUnusedAxis(targetDir, AUTH, chosen);
|
|
897
|
+
|
|
898
|
+
// src/manifest/wire-storage.ts
|
|
899
|
+
var STORAGE = {
|
|
900
|
+
section: MANIFEST.storage,
|
|
901
|
+
providerFile: "apps/microservices/upload/src/app/storage.provider.ts",
|
|
902
|
+
exportConst: "StorageProviderModule",
|
|
903
|
+
msPackageJson: "apps/microservices/upload/package.json",
|
|
904
|
+
envPath: "apps/microservices/upload/.env"
|
|
905
|
+
};
|
|
906
|
+
var writeStorageProvider = (targetDir, provider) => writeProvider(targetDir, STORAGE, provider);
|
|
907
|
+
var cleanupUnusedStorage = (targetDir, chosen) => cleanupUnusedAxis(targetDir, STORAGE, chosen);
|
|
908
|
+
|
|
909
|
+
// src/manifest/wire-db.ts
|
|
910
|
+
var DB = {
|
|
911
|
+
section: MANIFEST.db,
|
|
912
|
+
providerFile: "apps/microservices/notes/src/app/db.provider.ts",
|
|
913
|
+
exportConst: "DbProviderModule",
|
|
914
|
+
msPackageJson: "apps/microservices/notes/package.json",
|
|
915
|
+
envPath: "apps/microservices/notes/.env"
|
|
916
|
+
};
|
|
917
|
+
var writeDbProvider = (targetDir, provider) => writeProvider(targetDir, DB, provider);
|
|
918
|
+
var cleanupUnusedDb = (targetDir, chosen) => cleanupUnusedAxis(targetDir, DB, chosen);
|
|
919
|
+
|
|
774
920
|
// src/lib/scaffold-pkg.ts
|
|
775
|
-
import { readFile as
|
|
776
|
-
import { join as
|
|
921
|
+
import { readFile as readFile6, writeFile as writeFile7, mkdir, readdir } from "fs/promises";
|
|
922
|
+
import { join as join8 } from "path";
|
|
777
923
|
|
|
778
924
|
// src/lib/options.ts
|
|
779
925
|
function pmRun(pm, script) {
|
|
@@ -782,8 +928,8 @@ function pmRun(pm, script) {
|
|
|
782
928
|
|
|
783
929
|
// src/lib/scaffold-pkg.ts
|
|
784
930
|
async function writePnpmWorkspace(targetDir) {
|
|
785
|
-
const pkgPath =
|
|
786
|
-
const pkg = JSON.parse(await
|
|
931
|
+
const pkgPath = join8(targetDir, "package.json");
|
|
932
|
+
const pkg = JSON.parse(await readFile6(pkgPath, "utf8"));
|
|
787
933
|
const workspaces = pkg.workspaces ?? [];
|
|
788
934
|
const packagesBlock = workspaces.map((p3) => ` - '${p3}'`).join("\n");
|
|
789
935
|
const allowBuilds = [
|
|
@@ -804,7 +950,7 @@ ${packagesBlock}
|
|
|
804
950
|
allowBuilds:
|
|
805
951
|
${allowBuilds}
|
|
806
952
|
`;
|
|
807
|
-
await
|
|
953
|
+
await writeFile7(join8(targetDir, "pnpm-workspace.yaml"), content);
|
|
808
954
|
}
|
|
809
955
|
async function rewritePnpmWorkspaceDeps(targetDir) {
|
|
810
956
|
async function walk(dir) {
|
|
@@ -817,9 +963,9 @@ async function rewritePnpmWorkspaceDeps(targetDir) {
|
|
|
817
963
|
}
|
|
818
964
|
for (const e of entries) {
|
|
819
965
|
if (e.isDirectory() && e.name !== "node_modules") {
|
|
820
|
-
found.push(...await walk(
|
|
966
|
+
found.push(...await walk(join8(dir, e.name)));
|
|
821
967
|
} else if (e.isFile() && e.name === "package.json") {
|
|
822
|
-
found.push(
|
|
968
|
+
found.push(join8(dir, e.name));
|
|
823
969
|
}
|
|
824
970
|
}
|
|
825
971
|
return found;
|
|
@@ -827,17 +973,17 @@ async function rewritePnpmWorkspaceDeps(targetDir) {
|
|
|
827
973
|
const pkgFiles = await walk(targetDir);
|
|
828
974
|
for (const f of pkgFiles) {
|
|
829
975
|
try {
|
|
830
|
-
const raw = await
|
|
976
|
+
const raw = await readFile6(f, "utf8");
|
|
831
977
|
const next = raw.replace(/"(@icore\/[^"]+)":\s*"\*"/g, '"$1": "workspace:*"');
|
|
832
|
-
if (next !== raw) await
|
|
978
|
+
if (next !== raw) await writeFile7(f, next);
|
|
833
979
|
} catch {
|
|
834
980
|
}
|
|
835
981
|
}
|
|
836
982
|
}
|
|
837
983
|
async function patchGitignoreForPm(targetDir, pm) {
|
|
838
|
-
const giPath =
|
|
984
|
+
const giPath = join8(targetDir, ".gitignore");
|
|
839
985
|
try {
|
|
840
|
-
let src = await
|
|
986
|
+
let src = await readFile6(giPath, "utf8");
|
|
841
987
|
src = src.replace(/^# Build artifacts.*\ntools\/create-icore\/templates\/\s*\n/m, "");
|
|
842
988
|
if (pm !== "yarn") {
|
|
843
989
|
src = src.replace(/^\.yarn\/\*\s*\n/m, "").replace(/^!\.yarn\/patches\s*\n/m, "").replace(/^!\.yarn\/plugins\s*\n/m, "").replace(/^!\.yarn\/releases\s*\n/m, "").replace(/^!\.yarn\/sdks\s*\n/m, "").replace(/^!\.yarn\/versions\s*\n/m, "").replace(/^\.pnp\.\*\s*\n/m, "");
|
|
@@ -852,7 +998,7 @@ async function patchGitignoreForPm(targetDir, pm) {
|
|
|
852
998
|
src += "\n# npm\nnpm-debug.log*\n";
|
|
853
999
|
}
|
|
854
1000
|
}
|
|
855
|
-
await
|
|
1001
|
+
await writeFile7(giPath, src);
|
|
856
1002
|
} catch {
|
|
857
1003
|
}
|
|
858
1004
|
}
|
|
@@ -867,7 +1013,7 @@ async function writeAiFiles(targetDir, opts) {
|
|
|
867
1013
|
if (opts.jobs !== "none") activeMSes.push(`jobs (standalone)`);
|
|
868
1014
|
const usesSupabase = opts.authProvider === "supabase" || opts.dbProvider === "supabase" || opts.upload === "supabase";
|
|
869
1015
|
const usesFirebase = opts.authProvider === "firebase" || opts.dbProvider === "firebase" || opts.upload === "firebase";
|
|
870
|
-
await
|
|
1016
|
+
await writeFile7(join8(targetDir, "CLAUDE.md"), "@AGENTS.md\n");
|
|
871
1017
|
const uiLabel = { shadcn: "shadcn/ui + Tailwind", antd: "Ant Design 6", mui: "MUI 6" }[opts.ui];
|
|
872
1018
|
const readme = `# ${opts.projectName}
|
|
873
1019
|
|
|
@@ -917,7 +1063,7 @@ ${pm === "yarn" ? "yarn remove-notes" : pm === "pnpm" ? "pnpm remove-notes" : "n
|
|
|
917
1063
|
|
|
918
1064
|
Apache-2.0
|
|
919
1065
|
`;
|
|
920
|
-
await
|
|
1066
|
+
await writeFile7(join8(targetDir, "README.md"), readme);
|
|
921
1067
|
const agents = `# ${opts.projectName} \u2014 Agent Instructions
|
|
922
1068
|
|
|
923
1069
|
## Stack snapshot
|
|
@@ -998,8 +1144,8 @@ ${opts.upload !== "none" ? `| \`apps/microservices/upload/.env\` | \`STORAGE_PRO
|
|
|
998
1144
|
- Test behaviour, not implementation. Fake strategies from \`@icore/shared\` (FakeAuthStrategy etc.) serve as test doubles.
|
|
999
1145
|
- Run: \`${nx} test <project>\`
|
|
1000
1146
|
`;
|
|
1001
|
-
await
|
|
1002
|
-
await mkdir(
|
|
1147
|
+
await writeFile7(join8(targetDir, "AGENTS.md"), agents);
|
|
1148
|
+
await mkdir(join8(targetDir, ".claude"), { recursive: true });
|
|
1003
1149
|
const mcpServers = {
|
|
1004
1150
|
nx: {
|
|
1005
1151
|
command: "npx",
|
|
@@ -1040,8 +1186,8 @@ ${opts.upload !== "none" ? `| \`apps/microservices/upload/.env\` | \`STORAGE_PRO
|
|
|
1040
1186
|
]
|
|
1041
1187
|
}
|
|
1042
1188
|
};
|
|
1043
|
-
await
|
|
1044
|
-
|
|
1189
|
+
await writeFile7(
|
|
1190
|
+
join8(targetDir, ".claude", "settings.json"),
|
|
1045
1191
|
JSON.stringify(settings, null, 2) + "\n"
|
|
1046
1192
|
);
|
|
1047
1193
|
}
|
|
@@ -1065,16 +1211,16 @@ async function copyTree(src, dest) {
|
|
|
1065
1211
|
const entries = await readdir2(src, { withFileTypes: true });
|
|
1066
1212
|
for (const entry of entries) {
|
|
1067
1213
|
if (IGNORE_TOP.has(entry.name)) continue;
|
|
1068
|
-
const s =
|
|
1069
|
-
const d =
|
|
1214
|
+
const s = join9(src, entry.name);
|
|
1215
|
+
const d = join9(dest, entry.name);
|
|
1070
1216
|
if (entry.isDirectory()) await copyTree(s, d);
|
|
1071
1217
|
else if (entry.isFile()) await copyFile(s, d);
|
|
1072
1218
|
}
|
|
1073
1219
|
}
|
|
1074
1220
|
async function selectClientTemplate(targetDir, opts) {
|
|
1075
|
-
const templatesRoot =
|
|
1076
|
-
const chosen =
|
|
1077
|
-
const destClient =
|
|
1221
|
+
const templatesRoot = join9(targetDir, "apps/templates");
|
|
1222
|
+
const chosen = join9(templatesRoot, `client-${opts.ui}`);
|
|
1223
|
+
const destClient = join9(targetDir, "apps/client");
|
|
1078
1224
|
let chosenUi = opts.ui;
|
|
1079
1225
|
try {
|
|
1080
1226
|
const s = await stat(chosen);
|
|
@@ -1082,9 +1228,9 @@ async function selectClientTemplate(targetDir, opts) {
|
|
|
1082
1228
|
await copyTree(chosen, destClient);
|
|
1083
1229
|
} catch {
|
|
1084
1230
|
chosenUi = "shadcn";
|
|
1085
|
-
await copyTree(
|
|
1231
|
+
await copyTree(join9(templatesRoot, "client-shadcn"), destClient);
|
|
1086
1232
|
}
|
|
1087
|
-
await
|
|
1233
|
+
await rm4(templatesRoot, { recursive: true, force: true });
|
|
1088
1234
|
await rewriteClientPaths(destClient, chosenUi);
|
|
1089
1235
|
}
|
|
1090
1236
|
async function rewriteClientPaths(clientDir, ui) {
|
|
@@ -1097,11 +1243,11 @@ async function rewriteClientPaths(clientDir, ui) {
|
|
|
1097
1243
|
"eslint.config.mjs"
|
|
1098
1244
|
];
|
|
1099
1245
|
for (const rel of candidates) {
|
|
1100
|
-
const path =
|
|
1246
|
+
const path = join9(clientDir, rel);
|
|
1101
1247
|
try {
|
|
1102
|
-
const raw = await
|
|
1248
|
+
const raw = await readFile7(path, "utf8");
|
|
1103
1249
|
const next = raw.replaceAll("../../../", "../../").replaceAll(`apps/templates/client-${ui}`, "apps/client").replaceAll(`client-${ui}`, "client");
|
|
1104
|
-
if (next !== raw) await
|
|
1250
|
+
if (next !== raw) await writeFile8(path, next);
|
|
1105
1251
|
} catch {
|
|
1106
1252
|
}
|
|
1107
1253
|
}
|
|
@@ -1117,12 +1263,12 @@ function gitInit(cwd, projectName) {
|
|
|
1117
1263
|
}
|
|
1118
1264
|
function resolveYarnBin(cwd) {
|
|
1119
1265
|
try {
|
|
1120
|
-
const yarnrc = readFileSync(
|
|
1266
|
+
const yarnrc = readFileSync(join9(cwd, ".yarnrc.yml"), "utf8");
|
|
1121
1267
|
const match = yarnrc.match(/^yarnPath:\s*(.+)$/m);
|
|
1122
|
-
if (match?.[1]) return
|
|
1268
|
+
if (match?.[1]) return join9(cwd, match[1].trim());
|
|
1123
1269
|
} catch {
|
|
1124
1270
|
}
|
|
1125
|
-
return
|
|
1271
|
+
return join9(cwd, ".yarn", "releases", "yarn-4.5.0.cjs");
|
|
1126
1272
|
}
|
|
1127
1273
|
function runInstall(cwd, pm) {
|
|
1128
1274
|
if (pm === "yarn") {
|
|
@@ -1145,19 +1291,29 @@ async function scaffold(opts, templatesDir2) {
|
|
|
1145
1291
|
await selectClientTemplate(opts.targetDir, opts);
|
|
1146
1292
|
await writeClientEnv(opts.targetDir);
|
|
1147
1293
|
if (opts.upload === "none") await removeUploadStack(opts.targetDir);
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
await
|
|
1152
|
-
await
|
|
1153
|
-
|
|
1294
|
+
await cleanupUnusedFeatures(opts.targetDir, opts);
|
|
1295
|
+
await writeFeaturesWiring(opts.targetDir, opts);
|
|
1296
|
+
await writeNavConfig(opts.targetDir, opts);
|
|
1297
|
+
await cleanupUnusedAuth(opts.targetDir, opts.authProvider);
|
|
1298
|
+
await writeAuthProvider(opts.targetDir, opts.authProvider);
|
|
1299
|
+
if (opts.upload !== "none") {
|
|
1300
|
+
await cleanupUnusedStorage(opts.targetDir, opts.upload);
|
|
1301
|
+
await writeStorageProvider(opts.targetDir, opts.upload);
|
|
1302
|
+
}
|
|
1303
|
+
if (opts.example !== "none") {
|
|
1304
|
+
await cleanupUnusedDb(opts.targetDir, opts.dbProvider);
|
|
1305
|
+
await writeDbProvider(opts.targetDir, opts.dbProvider);
|
|
1306
|
+
}
|
|
1154
1307
|
const firebaseUsed = opts.authProvider === "firebase" || opts.dbProvider === "firebase" || opts.upload === "firebase";
|
|
1155
1308
|
if (!firebaseUsed) await removeFirebaseAdminLib(opts.targetDir);
|
|
1309
|
+
await pruneRootProviderDeps(opts.targetDir, opts);
|
|
1310
|
+
await writeBlueprintJson(opts.targetDir, opts);
|
|
1311
|
+
await writeServiceBlueprints(opts.targetDir, opts);
|
|
1156
1312
|
if (opts.packageManager === "yarn") {
|
|
1157
|
-
await
|
|
1313
|
+
await writeFile8(join9(opts.targetDir, "yarn.lock"), "");
|
|
1158
1314
|
} else {
|
|
1159
|
-
await
|
|
1160
|
-
await
|
|
1315
|
+
await rm4(join9(opts.targetDir, ".yarn"), { recursive: true, force: true });
|
|
1316
|
+
await rm4(join9(opts.targetDir, ".yarnrc.yml"), { force: true });
|
|
1161
1317
|
}
|
|
1162
1318
|
if (opts.packageManager === "pnpm") {
|
|
1163
1319
|
await writePnpmWorkspace(opts.targetDir);
|