@idevconn/create-icore 0.5.0 → 0.5.2
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 +84 -25
- package/dist/index.cjs +81 -24
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +80 -24
- package/package.json +3 -1
- package/templates/apps/api/.env.example +14 -0
- package/templates/apps/microservices/auth/package.json +1 -1
- package/templates/apps/microservices/auth/src/app/app.module.ts +17 -30
- package/templates/apps/microservices/auth/src/main.ts +6 -23
- package/templates/apps/microservices/jobs/src/app/redis-connection.ts +35 -0
- package/templates/apps/microservices/jobs/src/app/workers/cleanup.worker.ts +2 -1
- package/templates/apps/microservices/jobs/src/app/workers/email.worker.ts +2 -1
- package/templates/apps/microservices/jobs/src/app/workers/image-process.worker.ts +2 -1
- package/templates/apps/microservices/notes/src/app/app.module.ts +22 -27
- package/templates/apps/microservices/notes/src/main.ts +6 -23
- package/templates/apps/microservices/payment/src/app/app.module.ts +6 -4
- package/templates/apps/microservices/payment/src/main.ts +6 -23
- package/templates/apps/microservices/upload/package.json +1 -1
- package/templates/apps/microservices/upload/src/app/app.module.ts +18 -30
- package/templates/apps/microservices/upload/src/main.ts +6 -23
- package/templates/libs/auth-strategies/firebase/src/lib/__tests__/firebase-auth.contract.unit.test.ts +1 -1
- package/templates/libs/auth-strategies/supabase/src/lib/__tests__/supabase-auth.contract.unit.test.ts +1 -1
- package/templates/libs/db-strategies/firestore/src/lib/__tests__/firestore-db.contract.unit.test.ts +1 -1
- package/templates/libs/db-strategies/supabase/src/lib/__tests__/supabase-db.contract.unit.test.ts +1 -1
- package/templates/libs/firebase-admin/README.md +11 -0
- package/templates/libs/firebase-admin/eslint.config.mjs +24 -0
- package/templates/libs/firebase-admin/package.json +12 -0
- package/templates/libs/firebase-admin/project.json +19 -0
- package/templates/libs/firebase-admin/src/index.ts +1 -0
- package/templates/libs/firebase-admin/src/lib/__tests__/firebase-admin.unit.test.ts +105 -0
- package/templates/libs/firebase-admin/src/lib/firebase-admin.ts +70 -0
- package/templates/libs/firebase-admin/tsconfig.json +24 -0
- package/templates/libs/firebase-admin/tsconfig.lib.json +23 -0
- package/templates/libs/firebase-admin/tsconfig.spec.json +22 -0
- package/templates/libs/firebase-admin/vitest.config.mts +21 -0
- package/templates/libs/jobs-client/src/lib/jobs-client.service.ts +14 -2
- package/templates/libs/jobs-client/tsconfig.json +2 -1
- package/templates/libs/notes-client/tsconfig.json +2 -1
- package/templates/libs/payment-client/tsconfig.json +2 -1
- package/templates/libs/shared/src/__tests__/bootstrap.unit.test.ts +92 -0
- package/templates/libs/shared/src/__tests__/transport.unit.test.ts +14 -2
- package/templates/libs/shared/src/bootstrap.ts +79 -0
- package/templates/libs/shared/src/index.ts +1 -0
- package/templates/libs/shared/src/strategies/__tests__/fake-auth.contract.unit.test.ts +1 -1
- package/templates/libs/shared/src/strategies/__tests__/fake-db.contract.unit.test.ts +1 -1
- package/templates/libs/shared/src/strategies/__tests__/fake-storage.contract.unit.test.ts +1 -1
- package/templates/libs/shared/src/strategies/index.ts +3 -3
- package/templates/libs/shared/src/testing.ts +14 -0
- package/templates/libs/shared/src/transport.ts +25 -3
- package/templates/libs/shared/tsconfig.lib.json +3 -1
- package/templates/libs/shared/vitest.config.mts +11 -1
- package/templates/libs/storage-strategies/cloudinary/src/lib/__tests__/cloudinary-storage.contract.unit.test.ts +1 -1
- package/templates/libs/storage-strategies/firebase/src/lib/__tests__/firebase-storage.contract.unit.test.ts +1 -1
- package/templates/libs/storage-strategies/supabase/src/lib/__tests__/supabase-storage.contract.unit.test.ts +1 -1
- package/templates/tsconfig.base.json +3 -1
- /package/templates/libs/shared/src/strategies/{contract/auth-contract.ts → __tests__/auth.contract.unit.test.ts} +0 -0
- /package/templates/libs/shared/src/strategies/{contract/db-contract.ts → __tests__/db.contract.unit.test.ts} +0 -0
- /package/templates/libs/shared/src/strategies/{contract/storage-contract.ts → __tests__/storage.contract.unit.test.ts} +0 -0
package/dist/cli.js
CHANGED
|
@@ -234,6 +234,13 @@ import { copyFile, mkdir, readdir, readFile as readFile2, stat, writeFile, rm }
|
|
|
234
234
|
import { readFileSync } from "fs";
|
|
235
235
|
import { join as join2 } from "path";
|
|
236
236
|
import { spawnSync } from "child_process";
|
|
237
|
+
|
|
238
|
+
// src/lib/options.ts
|
|
239
|
+
function pmRun(pm, script) {
|
|
240
|
+
return pm === "npm" ? `npm run ${script}` : `${pm} ${script}`;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/lib/scaffold.ts
|
|
237
244
|
var IGNORE_TOP = /* @__PURE__ */ new Set([
|
|
238
245
|
".git",
|
|
239
246
|
"node_modules",
|
|
@@ -266,6 +273,10 @@ async function rewriteRootPackageJson(targetDir, opts) {
|
|
|
266
273
|
pkg["version"] = "0.0.1";
|
|
267
274
|
pkg["private"] = true;
|
|
268
275
|
delete pkg.description;
|
|
276
|
+
if (opts.transport === "nats") {
|
|
277
|
+
const deps = pkg["dependencies"] ??= {};
|
|
278
|
+
deps["nats"] = "^2.29.3";
|
|
279
|
+
}
|
|
269
280
|
if (opts.packageManager !== "yarn") {
|
|
270
281
|
delete pkg.packageManager;
|
|
271
282
|
}
|
|
@@ -322,9 +333,9 @@ async function writeNotesEnv(targetDir, opts) {
|
|
|
322
333
|
async function writeGatewayEnv(targetDir, opts) {
|
|
323
334
|
const envExample = join2(targetDir, "apps/api/.env.example");
|
|
324
335
|
const env = await readFile2(envExample, "utf8");
|
|
325
|
-
let next = env.replace(/^AUTH_TRANSPORT=.*$/m, `AUTH_TRANSPORT=${opts.transport}`).replace(/^UPLOAD_TRANSPORT=.*$/m, `UPLOAD_TRANSPORT=${opts.transport}`);
|
|
336
|
+
let next = env.replace(/^AUTH_TRANSPORT=.*$/m, `AUTH_TRANSPORT=${opts.transport}`).replace(/^UPLOAD_TRANSPORT=.*$/m, `UPLOAD_TRANSPORT=${opts.transport}`).replace(/^NOTES_TRANSPORT=.*$/m, `NOTES_TRANSPORT=${opts.transport}`).replace(/^PAYMENT_TRANSPORT=.*$/m, `PAYMENT_TRANSPORT=${opts.transport}`);
|
|
326
337
|
if (opts.transport !== "tcp") {
|
|
327
|
-
next = next.replace(/^# (AUTH_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (UPLOAD_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
338
|
+
next = next.replace(/^# (AUTH_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (UPLOAD_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (NOTES_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (PAYMENT_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
328
339
|
}
|
|
329
340
|
await writeFile(join2(targetDir, "apps/api/.env"), next);
|
|
330
341
|
}
|
|
@@ -337,6 +348,17 @@ async function writeRootEnv(targetDir, opts) {
|
|
|
337
348
|
];
|
|
338
349
|
await writeFile(join2(targetDir, ".env"), lines.join("\n"));
|
|
339
350
|
}
|
|
351
|
+
async function stripGatewayTransport(targetDir, prefix) {
|
|
352
|
+
const gatewayEnv = join2(targetDir, "apps/api/.env");
|
|
353
|
+
try {
|
|
354
|
+
const env = await readFile2(gatewayEnv, "utf8");
|
|
355
|
+
const next = env.split("\n").filter(
|
|
356
|
+
(line) => !line.startsWith(`${prefix}_`) && !line.startsWith(`# ${prefix}_`) && !line.includes(`${prefix} MS transport`)
|
|
357
|
+
).join("\n");
|
|
358
|
+
await writeFile(gatewayEnv, next);
|
|
359
|
+
} catch {
|
|
360
|
+
}
|
|
361
|
+
}
|
|
340
362
|
async function writeClientEnv(targetDir) {
|
|
341
363
|
const envExample = join2(targetDir, "apps/client/.env.example");
|
|
342
364
|
try {
|
|
@@ -421,6 +443,7 @@ async function removePaymentStack(targetDir) {
|
|
|
421
443
|
"@icore/payment-client",
|
|
422
444
|
"@idevconn/payment"
|
|
423
445
|
]);
|
|
446
|
+
await stripGatewayTransport(targetDir, "PAYMENT");
|
|
424
447
|
}
|
|
425
448
|
async function removeNotesStack(targetDir) {
|
|
426
449
|
for (const p3 of [
|
|
@@ -442,6 +465,7 @@ async function removeNotesStack(targetDir) {
|
|
|
442
465
|
} catch {
|
|
443
466
|
}
|
|
444
467
|
await stripDeps(join2(targetDir, "apps/api/package.json"), ["@icore/notes-client"]);
|
|
468
|
+
await stripGatewayTransport(targetDir, "NOTES");
|
|
445
469
|
const tsconfigPath = join2(targetDir, "tsconfig.base.json");
|
|
446
470
|
try {
|
|
447
471
|
const src = await readFile2(tsconfigPath, "utf8");
|
|
@@ -498,15 +522,17 @@ async function stripTsconfigPath(targetDir, alias) {
|
|
|
498
522
|
}
|
|
499
523
|
async function removeUnusedAuthStrategies(targetDir, authProvider) {
|
|
500
524
|
const modulePath = join2(targetDir, "apps/microservices/auth/src/app/app.module.ts");
|
|
525
|
+
const AUTH_BRANCH = /if \(provider === 'supabase'\) return makeSupabaseAuth\(cfg\);\n\s*return makeFirebaseAuth\(cfg\);/m;
|
|
501
526
|
if (authProvider === "supabase") {
|
|
502
527
|
await rm(join2(targetDir, "libs/auth-strategies/firebase"), { recursive: true, force: true });
|
|
503
528
|
await stripDeps(join2(targetDir, "apps/microservices/auth/package.json"), [
|
|
504
|
-
"@icore/auth-firebase"
|
|
529
|
+
"@icore/auth-firebase",
|
|
530
|
+
"@icore/firebase-admin"
|
|
505
531
|
]);
|
|
506
532
|
await stripTsconfigPath(targetDir, "@icore/auth-firebase");
|
|
507
533
|
try {
|
|
508
534
|
const src = await readFile2(modulePath, "utf8");
|
|
509
|
-
const next = src.replace(/^import
|
|
535
|
+
const next = src.replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/m, "").replace(/^import \{[^}]*FirebaseAuthStrategy[^}]*\} from '@icore\/auth-firebase';\n/m, "").replace(/^ {2}firebase: \[[^\]]*\],\n/m, "").replace(/\nfunction makeFirebaseAuth[\s\S]*?\n}\n/m, "").replace(AUTH_BRANCH, "return makeSupabaseAuth(cfg);");
|
|
510
536
|
await writeFile(modulePath, next);
|
|
511
537
|
} catch {
|
|
512
538
|
}
|
|
@@ -519,10 +545,7 @@ async function removeUnusedAuthStrategies(targetDir, authProvider) {
|
|
|
519
545
|
await stripTsconfigPath(targetDir, "@icore/auth-supabase");
|
|
520
546
|
try {
|
|
521
547
|
const src = await readFile2(modulePath, "utf8");
|
|
522
|
-
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(/^import \{[^}]*SupabaseAuthStrategy[^}]*\} from '@icore\/auth-supabase';\n/m, "").replace(
|
|
523
|
-
/\n {10}case 'supabase': \{[\s\S]*?return new SupabaseAuthStrategy\(\{ client \}\);\n {10}\}\n/m,
|
|
524
|
-
""
|
|
525
|
-
);
|
|
548
|
+
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(/^import \{[^}]*SupabaseAuthStrategy[^}]*\} from '@icore\/auth-supabase';\n/m, "").replace(/\nfunction makeSupabaseAuth[\s\S]*?\n}\n/m, "").replace(AUTH_BRANCH, "return makeFirebaseAuth(cfg);");
|
|
526
549
|
await writeFile(modulePath, next);
|
|
527
550
|
} catch {
|
|
528
551
|
}
|
|
@@ -534,7 +557,8 @@ async function removeUnusedStorageStrategies(targetDir, uploadProvider) {
|
|
|
534
557
|
if (uploadProvider !== "firebase") {
|
|
535
558
|
await rm(join2(targetDir, "libs/storage-strategies/firebase"), { recursive: true, force: true });
|
|
536
559
|
await stripDeps(join2(targetDir, "apps/microservices/upload/package.json"), [
|
|
537
|
-
"@icore/storage-firebase"
|
|
560
|
+
"@icore/storage-firebase",
|
|
561
|
+
"@icore/firebase-admin"
|
|
538
562
|
]);
|
|
539
563
|
await stripTsconfigPath(targetDir, "@icore/storage-firebase");
|
|
540
564
|
}
|
|
@@ -558,26 +582,26 @@ async function removeUnusedStorageStrategies(targetDir, uploadProvider) {
|
|
|
558
582
|
try {
|
|
559
583
|
let src = await readFile2(modulePath, "utf8");
|
|
560
584
|
if (uploadProvider !== "firebase") {
|
|
561
|
-
src = src.replace(/^import
|
|
585
|
+
src = src.replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/m, "").replace(
|
|
562
586
|
/^import \{[^}]*FirebaseStorageStrategy[^}]*\} from '@icore\/storage-firebase';\n/m,
|
|
563
587
|
""
|
|
564
|
-
).replace(/^
|
|
588
|
+
).replace(/^ {2}firebase: \[[^\]]*\],\n/m, "").replace(/\nfunction makeFirebaseStorage[\s\S]*?\n}\n/m, "");
|
|
565
589
|
}
|
|
566
590
|
if (uploadProvider !== "cloudinary") {
|
|
567
591
|
src = src.replace(/^import \{ v2 as cloudinary \} from 'cloudinary';\n/m, "").replace(
|
|
568
592
|
/^import \{[^}]*CloudinaryStorageStrategy[^}]*\} from '@icore\/storage-cloudinary';\n/m,
|
|
569
593
|
""
|
|
570
|
-
).replace(
|
|
594
|
+
).replace(/\nfunction makeCloudinaryStorage[\s\S]*?\n}\n/m, "");
|
|
571
595
|
}
|
|
572
596
|
if (uploadProvider !== "supabase") {
|
|
573
597
|
src = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(
|
|
574
598
|
/^import \{[^}]*SupabaseStorageStrategy[^}]*\} from '@icore\/storage-supabase';\n/m,
|
|
575
599
|
""
|
|
576
|
-
).replace(
|
|
577
|
-
/\n {10}case 'supabase': \{[\s\S]*?bucket: requireEnv\(cfg, 'SUPABASE_STORAGE_BUCKET'\),\n {12}\}\);\n {10}\}\n/m,
|
|
578
|
-
""
|
|
579
|
-
);
|
|
600
|
+
).replace(/\nfunction makeSupabaseStorage[\s\S]*?\n}\n/m, "");
|
|
580
601
|
}
|
|
602
|
+
const STORAGE_BRANCH = /if \(provider === 'supabase'\) return makeSupabaseStorage\(cfg\);\n\s*if \(provider === 'firebase'\) return makeFirebaseStorage\(cfg\);\n\s*return makeCloudinaryStorage\(cfg\);/m;
|
|
603
|
+
const chosenReturn = `return make${uploadProvider.charAt(0).toUpperCase() + uploadProvider.slice(1)}Storage(cfg);`;
|
|
604
|
+
src = src.replace(STORAGE_BRANCH, chosenReturn);
|
|
581
605
|
await writeFile(modulePath, src);
|
|
582
606
|
} catch {
|
|
583
607
|
}
|
|
@@ -587,14 +611,15 @@ async function removeUnusedDbStrategies(targetDir, dbProvider) {
|
|
|
587
611
|
if (dbProvider === "supabase") {
|
|
588
612
|
await rm(join2(targetDir, "libs/db-strategies/firestore"), { recursive: true, force: true });
|
|
589
613
|
await stripDeps(join2(targetDir, "apps/microservices/notes/package.json"), [
|
|
590
|
-
"@icore/db-firestore"
|
|
614
|
+
"@icore/db-firestore",
|
|
615
|
+
"@icore/firebase-admin"
|
|
591
616
|
]);
|
|
592
617
|
await stripTsconfigPath(targetDir, "@icore/db-firestore");
|
|
593
618
|
try {
|
|
594
619
|
const src = await readFile2(modulePath, "utf8");
|
|
595
|
-
const next = src.replace(/^import
|
|
596
|
-
|
|
597
|
-
""
|
|
620
|
+
const next = src.replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/m, "").replace(/^import \{[^}]*FirestoreDBStrategy[^}]*\} from '@icore\/db-firestore';\n/m, "").replace(/^ {2}firestore: \[[^\]]*\],\n/m, "").replace(/^ {2}firebase: \[[^\]]*\],\n/m, "").replace(/\nfunction makeFirestoreDB[\s\S]*?\n}\n/m, "").replace(
|
|
621
|
+
/if \(provider === 'supabase'\) return makeSupabaseDB\(cfg\);\n\s*return makeFirestoreDB\(cfg\);/m,
|
|
622
|
+
"return makeSupabaseDB(cfg);"
|
|
598
623
|
);
|
|
599
624
|
await writeFile(modulePath, next);
|
|
600
625
|
} catch {
|
|
@@ -608,15 +633,19 @@ async function removeUnusedDbStrategies(targetDir, dbProvider) {
|
|
|
608
633
|
await stripTsconfigPath(targetDir, "@icore/db-supabase");
|
|
609
634
|
try {
|
|
610
635
|
const src = await readFile2(modulePath, "utf8");
|
|
611
|
-
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(/^import \{[^}]*SupabaseDBStrategy[^}]*\} from '@icore\/db-supabase';\n/m, "").replace(
|
|
612
|
-
|
|
613
|
-
""
|
|
636
|
+
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(/^import \{[^}]*SupabaseDBStrategy[^}]*\} from '@icore\/db-supabase';\n/m, "").replace(/\nfunction makeSupabaseDB[\s\S]*?\n}\n/m, "").replace(
|
|
637
|
+
/if \(provider === 'supabase'\) return makeSupabaseDB\(cfg\);\n\s*return makeFirestoreDB\(cfg\);/m,
|
|
638
|
+
"return makeFirestoreDB(cfg);"
|
|
614
639
|
);
|
|
615
640
|
await writeFile(modulePath, next);
|
|
616
641
|
} catch {
|
|
617
642
|
}
|
|
618
643
|
}
|
|
619
644
|
}
|
|
645
|
+
async function removeFirebaseAdminLib(targetDir) {
|
|
646
|
+
await rm(join2(targetDir, "libs/firebase-admin"), { recursive: true, force: true });
|
|
647
|
+
await stripTsconfigPath(targetDir, "@icore/firebase-admin");
|
|
648
|
+
}
|
|
620
649
|
async function removeUploadStack(targetDir) {
|
|
621
650
|
const paths = [
|
|
622
651
|
"apps/microservices/upload",
|
|
@@ -729,17 +758,45 @@ async function scaffold(opts, templatesDir2) {
|
|
|
729
758
|
await removeUnusedAuthStrategies(opts.targetDir, opts.authProvider);
|
|
730
759
|
await removeUnusedStorageStrategies(opts.targetDir, opts.upload);
|
|
731
760
|
await removeUnusedDbStrategies(opts.targetDir, opts.dbProvider);
|
|
761
|
+
const firebaseUsed = opts.authProvider === "firebase" || opts.dbProvider === "firebase" || opts.upload === "firebase";
|
|
762
|
+
if (!firebaseUsed) await removeFirebaseAdminLib(opts.targetDir);
|
|
732
763
|
if (opts.packageManager === "yarn") {
|
|
733
764
|
await writeFile(join2(opts.targetDir, "yarn.lock"), "");
|
|
765
|
+
} else {
|
|
766
|
+
await rm(join2(opts.targetDir, ".yarn"), { recursive: true, force: true });
|
|
767
|
+
await rm(join2(opts.targetDir, ".yarnrc.yml"), { force: true });
|
|
734
768
|
}
|
|
769
|
+
await patchGitignoreForPm(opts.targetDir, opts.packageManager);
|
|
735
770
|
await writeAiFiles(opts.targetDir, opts);
|
|
736
771
|
if (opts.install) runInstall(opts.targetDir, opts.packageManager);
|
|
737
772
|
if (opts.initGit) gitInit(opts.targetDir, opts.projectName);
|
|
738
773
|
}
|
|
774
|
+
async function patchGitignoreForPm(targetDir, pm) {
|
|
775
|
+
const giPath = join2(targetDir, ".gitignore");
|
|
776
|
+
try {
|
|
777
|
+
let src = await readFile2(giPath, "utf8");
|
|
778
|
+
src = src.replace(/^# Build artifacts.*\ntools\/create-icore\/templates\/\s*\n/m, "");
|
|
779
|
+
if (pm !== "yarn") {
|
|
780
|
+
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, "");
|
|
781
|
+
}
|
|
782
|
+
if (pm === "pnpm") {
|
|
783
|
+
if (!src.includes(".pnpm-debug.log")) {
|
|
784
|
+
src += "\n# pnpm\n.pnpm-debug.log*\n";
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (pm === "npm") {
|
|
788
|
+
if (!src.includes("npm-debug.log")) {
|
|
789
|
+
src += "\n# npm\nnpm-debug.log*\n";
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
await writeFile(giPath, src);
|
|
793
|
+
} catch {
|
|
794
|
+
}
|
|
795
|
+
}
|
|
739
796
|
async function writeAiFiles(targetDir, opts) {
|
|
740
797
|
const pm = opts.packageManager;
|
|
741
798
|
const nx = pm === "npm" ? "npx nx" : `${pm} nx`;
|
|
742
|
-
const devCmd =
|
|
799
|
+
const devCmd = pmRun(pm, "dev");
|
|
743
800
|
const activeMSes = ["auth (port 4001)"];
|
|
744
801
|
if (opts.upload !== "none") activeMSes.push(`upload (port 4002)`);
|
|
745
802
|
if (opts.payment !== "none") activeMSes.push(`payment (port 4003)`);
|
|
@@ -956,7 +1013,9 @@ async function main() {
|
|
|
956
1013
|
p2.log.info(`Next:`);
|
|
957
1014
|
p2.log.info(` cd ${opts.projectName}`);
|
|
958
1015
|
if (!opts.install) p2.log.info(` ${opts.packageManager} install`);
|
|
959
|
-
p2.log.info(
|
|
1016
|
+
p2.log.info(
|
|
1017
|
+
` ${pmRun(opts.packageManager, "dev")} # gateway + auth MS + upload MS + client`
|
|
1018
|
+
);
|
|
960
1019
|
p2.log.info(` open http://localhost:4200`);
|
|
961
1020
|
p2.log.info(` edit apps/microservices/auth/.env to plug in real ${opts.authProvider} creds`);
|
|
962
1021
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
collectOptions: () => collectOptions,
|
|
34
|
+
pmRun: () => pmRun,
|
|
34
35
|
scaffold: () => scaffold
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -39,6 +40,11 @@ module.exports = __toCommonJS(src_exports);
|
|
|
39
40
|
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
40
41
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
41
42
|
|
|
43
|
+
// src/lib/options.ts
|
|
44
|
+
function pmRun(pm, script) {
|
|
45
|
+
return pm === "npm" ? `npm run ${script}` : `${pm} ${script}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
42
48
|
// src/lib/scaffold.ts
|
|
43
49
|
var import_promises = require("fs/promises");
|
|
44
50
|
var import_node_fs = require("fs");
|
|
@@ -76,6 +82,10 @@ async function rewriteRootPackageJson(targetDir, opts) {
|
|
|
76
82
|
pkg["version"] = "0.0.1";
|
|
77
83
|
pkg["private"] = true;
|
|
78
84
|
delete pkg.description;
|
|
85
|
+
if (opts.transport === "nats") {
|
|
86
|
+
const deps = pkg["dependencies"] ??= {};
|
|
87
|
+
deps["nats"] = "^2.29.3";
|
|
88
|
+
}
|
|
79
89
|
if (opts.packageManager !== "yarn") {
|
|
80
90
|
delete pkg.packageManager;
|
|
81
91
|
}
|
|
@@ -132,9 +142,9 @@ async function writeNotesEnv(targetDir, opts) {
|
|
|
132
142
|
async function writeGatewayEnv(targetDir, opts) {
|
|
133
143
|
const envExample = (0, import_node_path.join)(targetDir, "apps/api/.env.example");
|
|
134
144
|
const env = await (0, import_promises.readFile)(envExample, "utf8");
|
|
135
|
-
let next = env.replace(/^AUTH_TRANSPORT=.*$/m, `AUTH_TRANSPORT=${opts.transport}`).replace(/^UPLOAD_TRANSPORT=.*$/m, `UPLOAD_TRANSPORT=${opts.transport}`);
|
|
145
|
+
let next = env.replace(/^AUTH_TRANSPORT=.*$/m, `AUTH_TRANSPORT=${opts.transport}`).replace(/^UPLOAD_TRANSPORT=.*$/m, `UPLOAD_TRANSPORT=${opts.transport}`).replace(/^NOTES_TRANSPORT=.*$/m, `NOTES_TRANSPORT=${opts.transport}`).replace(/^PAYMENT_TRANSPORT=.*$/m, `PAYMENT_TRANSPORT=${opts.transport}`);
|
|
136
146
|
if (opts.transport !== "tcp") {
|
|
137
|
-
next = next.replace(/^# (AUTH_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (UPLOAD_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
147
|
+
next = next.replace(/^# (AUTH_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (UPLOAD_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (NOTES_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (PAYMENT_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
138
148
|
}
|
|
139
149
|
await (0, import_promises.writeFile)((0, import_node_path.join)(targetDir, "apps/api/.env"), next);
|
|
140
150
|
}
|
|
@@ -147,6 +157,17 @@ async function writeRootEnv(targetDir, opts) {
|
|
|
147
157
|
];
|
|
148
158
|
await (0, import_promises.writeFile)((0, import_node_path.join)(targetDir, ".env"), lines.join("\n"));
|
|
149
159
|
}
|
|
160
|
+
async function stripGatewayTransport(targetDir, prefix) {
|
|
161
|
+
const gatewayEnv = (0, import_node_path.join)(targetDir, "apps/api/.env");
|
|
162
|
+
try {
|
|
163
|
+
const env = await (0, import_promises.readFile)(gatewayEnv, "utf8");
|
|
164
|
+
const next = env.split("\n").filter(
|
|
165
|
+
(line) => !line.startsWith(`${prefix}_`) && !line.startsWith(`# ${prefix}_`) && !line.includes(`${prefix} MS transport`)
|
|
166
|
+
).join("\n");
|
|
167
|
+
await (0, import_promises.writeFile)(gatewayEnv, next);
|
|
168
|
+
} catch {
|
|
169
|
+
}
|
|
170
|
+
}
|
|
150
171
|
async function writeClientEnv(targetDir) {
|
|
151
172
|
const envExample = (0, import_node_path.join)(targetDir, "apps/client/.env.example");
|
|
152
173
|
try {
|
|
@@ -231,6 +252,7 @@ async function removePaymentStack(targetDir) {
|
|
|
231
252
|
"@icore/payment-client",
|
|
232
253
|
"@idevconn/payment"
|
|
233
254
|
]);
|
|
255
|
+
await stripGatewayTransport(targetDir, "PAYMENT");
|
|
234
256
|
}
|
|
235
257
|
async function removeNotesStack(targetDir) {
|
|
236
258
|
for (const p2 of [
|
|
@@ -252,6 +274,7 @@ async function removeNotesStack(targetDir) {
|
|
|
252
274
|
} catch {
|
|
253
275
|
}
|
|
254
276
|
await stripDeps((0, import_node_path.join)(targetDir, "apps/api/package.json"), ["@icore/notes-client"]);
|
|
277
|
+
await stripGatewayTransport(targetDir, "NOTES");
|
|
255
278
|
const tsconfigPath = (0, import_node_path.join)(targetDir, "tsconfig.base.json");
|
|
256
279
|
try {
|
|
257
280
|
const src = await (0, import_promises.readFile)(tsconfigPath, "utf8");
|
|
@@ -308,15 +331,17 @@ async function stripTsconfigPath(targetDir, alias) {
|
|
|
308
331
|
}
|
|
309
332
|
async function removeUnusedAuthStrategies(targetDir, authProvider) {
|
|
310
333
|
const modulePath = (0, import_node_path.join)(targetDir, "apps/microservices/auth/src/app/app.module.ts");
|
|
334
|
+
const AUTH_BRANCH = /if \(provider === 'supabase'\) return makeSupabaseAuth\(cfg\);\n\s*return makeFirebaseAuth\(cfg\);/m;
|
|
311
335
|
if (authProvider === "supabase") {
|
|
312
336
|
await (0, import_promises.rm)((0, import_node_path.join)(targetDir, "libs/auth-strategies/firebase"), { recursive: true, force: true });
|
|
313
337
|
await stripDeps((0, import_node_path.join)(targetDir, "apps/microservices/auth/package.json"), [
|
|
314
|
-
"@icore/auth-firebase"
|
|
338
|
+
"@icore/auth-firebase",
|
|
339
|
+
"@icore/firebase-admin"
|
|
315
340
|
]);
|
|
316
341
|
await stripTsconfigPath(targetDir, "@icore/auth-firebase");
|
|
317
342
|
try {
|
|
318
343
|
const src = await (0, import_promises.readFile)(modulePath, "utf8");
|
|
319
|
-
const next = src.replace(/^import
|
|
344
|
+
const next = src.replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/m, "").replace(/^import \{[^}]*FirebaseAuthStrategy[^}]*\} from '@icore\/auth-firebase';\n/m, "").replace(/^ {2}firebase: \[[^\]]*\],\n/m, "").replace(/\nfunction makeFirebaseAuth[\s\S]*?\n}\n/m, "").replace(AUTH_BRANCH, "return makeSupabaseAuth(cfg);");
|
|
320
345
|
await (0, import_promises.writeFile)(modulePath, next);
|
|
321
346
|
} catch {
|
|
322
347
|
}
|
|
@@ -329,10 +354,7 @@ async function removeUnusedAuthStrategies(targetDir, authProvider) {
|
|
|
329
354
|
await stripTsconfigPath(targetDir, "@icore/auth-supabase");
|
|
330
355
|
try {
|
|
331
356
|
const src = await (0, import_promises.readFile)(modulePath, "utf8");
|
|
332
|
-
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(/^import \{[^}]*SupabaseAuthStrategy[^}]*\} from '@icore\/auth-supabase';\n/m, "").replace(
|
|
333
|
-
/\n {10}case 'supabase': \{[\s\S]*?return new SupabaseAuthStrategy\(\{ client \}\);\n {10}\}\n/m,
|
|
334
|
-
""
|
|
335
|
-
);
|
|
357
|
+
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(/^import \{[^}]*SupabaseAuthStrategy[^}]*\} from '@icore\/auth-supabase';\n/m, "").replace(/\nfunction makeSupabaseAuth[\s\S]*?\n}\n/m, "").replace(AUTH_BRANCH, "return makeFirebaseAuth(cfg);");
|
|
336
358
|
await (0, import_promises.writeFile)(modulePath, next);
|
|
337
359
|
} catch {
|
|
338
360
|
}
|
|
@@ -344,7 +366,8 @@ async function removeUnusedStorageStrategies(targetDir, uploadProvider) {
|
|
|
344
366
|
if (uploadProvider !== "firebase") {
|
|
345
367
|
await (0, import_promises.rm)((0, import_node_path.join)(targetDir, "libs/storage-strategies/firebase"), { recursive: true, force: true });
|
|
346
368
|
await stripDeps((0, import_node_path.join)(targetDir, "apps/microservices/upload/package.json"), [
|
|
347
|
-
"@icore/storage-firebase"
|
|
369
|
+
"@icore/storage-firebase",
|
|
370
|
+
"@icore/firebase-admin"
|
|
348
371
|
]);
|
|
349
372
|
await stripTsconfigPath(targetDir, "@icore/storage-firebase");
|
|
350
373
|
}
|
|
@@ -368,26 +391,26 @@ async function removeUnusedStorageStrategies(targetDir, uploadProvider) {
|
|
|
368
391
|
try {
|
|
369
392
|
let src = await (0, import_promises.readFile)(modulePath, "utf8");
|
|
370
393
|
if (uploadProvider !== "firebase") {
|
|
371
|
-
src = src.replace(/^import
|
|
394
|
+
src = src.replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/m, "").replace(
|
|
372
395
|
/^import \{[^}]*FirebaseStorageStrategy[^}]*\} from '@icore\/storage-firebase';\n/m,
|
|
373
396
|
""
|
|
374
|
-
).replace(/^
|
|
397
|
+
).replace(/^ {2}firebase: \[[^\]]*\],\n/m, "").replace(/\nfunction makeFirebaseStorage[\s\S]*?\n}\n/m, "");
|
|
375
398
|
}
|
|
376
399
|
if (uploadProvider !== "cloudinary") {
|
|
377
400
|
src = src.replace(/^import \{ v2 as cloudinary \} from 'cloudinary';\n/m, "").replace(
|
|
378
401
|
/^import \{[^}]*CloudinaryStorageStrategy[^}]*\} from '@icore\/storage-cloudinary';\n/m,
|
|
379
402
|
""
|
|
380
|
-
).replace(
|
|
403
|
+
).replace(/\nfunction makeCloudinaryStorage[\s\S]*?\n}\n/m, "");
|
|
381
404
|
}
|
|
382
405
|
if (uploadProvider !== "supabase") {
|
|
383
406
|
src = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(
|
|
384
407
|
/^import \{[^}]*SupabaseStorageStrategy[^}]*\} from '@icore\/storage-supabase';\n/m,
|
|
385
408
|
""
|
|
386
|
-
).replace(
|
|
387
|
-
/\n {10}case 'supabase': \{[\s\S]*?bucket: requireEnv\(cfg, 'SUPABASE_STORAGE_BUCKET'\),\n {12}\}\);\n {10}\}\n/m,
|
|
388
|
-
""
|
|
389
|
-
);
|
|
409
|
+
).replace(/\nfunction makeSupabaseStorage[\s\S]*?\n}\n/m, "");
|
|
390
410
|
}
|
|
411
|
+
const STORAGE_BRANCH = /if \(provider === 'supabase'\) return makeSupabaseStorage\(cfg\);\n\s*if \(provider === 'firebase'\) return makeFirebaseStorage\(cfg\);\n\s*return makeCloudinaryStorage\(cfg\);/m;
|
|
412
|
+
const chosenReturn = `return make${uploadProvider.charAt(0).toUpperCase() + uploadProvider.slice(1)}Storage(cfg);`;
|
|
413
|
+
src = src.replace(STORAGE_BRANCH, chosenReturn);
|
|
391
414
|
await (0, import_promises.writeFile)(modulePath, src);
|
|
392
415
|
} catch {
|
|
393
416
|
}
|
|
@@ -397,14 +420,15 @@ async function removeUnusedDbStrategies(targetDir, dbProvider) {
|
|
|
397
420
|
if (dbProvider === "supabase") {
|
|
398
421
|
await (0, import_promises.rm)((0, import_node_path.join)(targetDir, "libs/db-strategies/firestore"), { recursive: true, force: true });
|
|
399
422
|
await stripDeps((0, import_node_path.join)(targetDir, "apps/microservices/notes/package.json"), [
|
|
400
|
-
"@icore/db-firestore"
|
|
423
|
+
"@icore/db-firestore",
|
|
424
|
+
"@icore/firebase-admin"
|
|
401
425
|
]);
|
|
402
426
|
await stripTsconfigPath(targetDir, "@icore/db-firestore");
|
|
403
427
|
try {
|
|
404
428
|
const src = await (0, import_promises.readFile)(modulePath, "utf8");
|
|
405
|
-
const next = src.replace(/^import
|
|
406
|
-
|
|
407
|
-
""
|
|
429
|
+
const next = src.replace(/^import \{[^}]*\} from '@icore\/firebase-admin';\n/m, "").replace(/^import \{[^}]*FirestoreDBStrategy[^}]*\} from '@icore\/db-firestore';\n/m, "").replace(/^ {2}firestore: \[[^\]]*\],\n/m, "").replace(/^ {2}firebase: \[[^\]]*\],\n/m, "").replace(/\nfunction makeFirestoreDB[\s\S]*?\n}\n/m, "").replace(
|
|
430
|
+
/if \(provider === 'supabase'\) return makeSupabaseDB\(cfg\);\n\s*return makeFirestoreDB\(cfg\);/m,
|
|
431
|
+
"return makeSupabaseDB(cfg);"
|
|
408
432
|
);
|
|
409
433
|
await (0, import_promises.writeFile)(modulePath, next);
|
|
410
434
|
} catch {
|
|
@@ -418,15 +442,19 @@ async function removeUnusedDbStrategies(targetDir, dbProvider) {
|
|
|
418
442
|
await stripTsconfigPath(targetDir, "@icore/db-supabase");
|
|
419
443
|
try {
|
|
420
444
|
const src = await (0, import_promises.readFile)(modulePath, "utf8");
|
|
421
|
-
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(/^import \{[^}]*SupabaseDBStrategy[^}]*\} from '@icore\/db-supabase';\n/m, "").replace(
|
|
422
|
-
|
|
423
|
-
""
|
|
445
|
+
const next = src.replace(/^import \{ createClient \} from '@supabase\/supabase-js';\n/m, "").replace(/^import \{[^}]*SupabaseDBStrategy[^}]*\} from '@icore\/db-supabase';\n/m, "").replace(/\nfunction makeSupabaseDB[\s\S]*?\n}\n/m, "").replace(
|
|
446
|
+
/if \(provider === 'supabase'\) return makeSupabaseDB\(cfg\);\n\s*return makeFirestoreDB\(cfg\);/m,
|
|
447
|
+
"return makeFirestoreDB(cfg);"
|
|
424
448
|
);
|
|
425
449
|
await (0, import_promises.writeFile)(modulePath, next);
|
|
426
450
|
} catch {
|
|
427
451
|
}
|
|
428
452
|
}
|
|
429
453
|
}
|
|
454
|
+
async function removeFirebaseAdminLib(targetDir) {
|
|
455
|
+
await (0, import_promises.rm)((0, import_node_path.join)(targetDir, "libs/firebase-admin"), { recursive: true, force: true });
|
|
456
|
+
await stripTsconfigPath(targetDir, "@icore/firebase-admin");
|
|
457
|
+
}
|
|
430
458
|
async function removeUploadStack(targetDir) {
|
|
431
459
|
const paths = [
|
|
432
460
|
"apps/microservices/upload",
|
|
@@ -539,17 +567,45 @@ async function scaffold(opts, templatesDir) {
|
|
|
539
567
|
await removeUnusedAuthStrategies(opts.targetDir, opts.authProvider);
|
|
540
568
|
await removeUnusedStorageStrategies(opts.targetDir, opts.upload);
|
|
541
569
|
await removeUnusedDbStrategies(opts.targetDir, opts.dbProvider);
|
|
570
|
+
const firebaseUsed = opts.authProvider === "firebase" || opts.dbProvider === "firebase" || opts.upload === "firebase";
|
|
571
|
+
if (!firebaseUsed) await removeFirebaseAdminLib(opts.targetDir);
|
|
542
572
|
if (opts.packageManager === "yarn") {
|
|
543
573
|
await (0, import_promises.writeFile)((0, import_node_path.join)(opts.targetDir, "yarn.lock"), "");
|
|
574
|
+
} else {
|
|
575
|
+
await (0, import_promises.rm)((0, import_node_path.join)(opts.targetDir, ".yarn"), { recursive: true, force: true });
|
|
576
|
+
await (0, import_promises.rm)((0, import_node_path.join)(opts.targetDir, ".yarnrc.yml"), { force: true });
|
|
544
577
|
}
|
|
578
|
+
await patchGitignoreForPm(opts.targetDir, opts.packageManager);
|
|
545
579
|
await writeAiFiles(opts.targetDir, opts);
|
|
546
580
|
if (opts.install) runInstall(opts.targetDir, opts.packageManager);
|
|
547
581
|
if (opts.initGit) gitInit(opts.targetDir, opts.projectName);
|
|
548
582
|
}
|
|
583
|
+
async function patchGitignoreForPm(targetDir, pm) {
|
|
584
|
+
const giPath = (0, import_node_path.join)(targetDir, ".gitignore");
|
|
585
|
+
try {
|
|
586
|
+
let src = await (0, import_promises.readFile)(giPath, "utf8");
|
|
587
|
+
src = src.replace(/^# Build artifacts.*\ntools\/create-icore\/templates\/\s*\n/m, "");
|
|
588
|
+
if (pm !== "yarn") {
|
|
589
|
+
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, "");
|
|
590
|
+
}
|
|
591
|
+
if (pm === "pnpm") {
|
|
592
|
+
if (!src.includes(".pnpm-debug.log")) {
|
|
593
|
+
src += "\n# pnpm\n.pnpm-debug.log*\n";
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
if (pm === "npm") {
|
|
597
|
+
if (!src.includes("npm-debug.log")) {
|
|
598
|
+
src += "\n# npm\nnpm-debug.log*\n";
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
await (0, import_promises.writeFile)(giPath, src);
|
|
602
|
+
} catch {
|
|
603
|
+
}
|
|
604
|
+
}
|
|
549
605
|
async function writeAiFiles(targetDir, opts) {
|
|
550
606
|
const pm = opts.packageManager;
|
|
551
607
|
const nx = pm === "npm" ? "npx nx" : `${pm} nx`;
|
|
552
|
-
const devCmd =
|
|
608
|
+
const devCmd = pmRun(pm, "dev");
|
|
553
609
|
const activeMSes = ["auth (port 4001)"];
|
|
554
610
|
if (opts.upload !== "none") activeMSes.push(`upload (port 4002)`);
|
|
555
611
|
if (opts.payment !== "none") activeMSes.push(`payment (port 4003)`);
|
|
@@ -960,5 +1016,6 @@ Re-run with @latest to refresh:
|
|
|
960
1016
|
// Annotate the CommonJS export names for ESM import in node:
|
|
961
1017
|
0 && (module.exports = {
|
|
962
1018
|
collectOptions,
|
|
1019
|
+
pmRun,
|
|
963
1020
|
scaffold
|
|
964
1021
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -7,6 +7,12 @@ type ExampleMode = 'notes' | 'none';
|
|
|
7
7
|
type UiLibrary = 'shadcn' | 'antd' | 'mui';
|
|
8
8
|
type MsTransport = 'tcp' | 'redis' | 'nats';
|
|
9
9
|
type PackageManager = 'yarn' | 'npm' | 'pnpm';
|
|
10
|
+
/**
|
|
11
|
+
* Returns the correct invocation for a package.json script.
|
|
12
|
+
* yarn/pnpm: `yarn <script>` / `pnpm <script>`
|
|
13
|
+
* npm: `npm run <script>` (npm requires the `run` keyword for custom scripts)
|
|
14
|
+
*/
|
|
15
|
+
declare function pmRun(pm: PackageManager, script: string): string;
|
|
10
16
|
interface CreateIcoreOptions {
|
|
11
17
|
projectName: string;
|
|
12
18
|
targetDir: string;
|
|
@@ -31,4 +37,4 @@ interface PromptInput {
|
|
|
31
37
|
}
|
|
32
38
|
declare function collectOptions({ argv, cwd }: PromptInput): Promise<CreateIcoreOptions>;
|
|
33
39
|
|
|
34
|
-
export { type AuthProvider, type CreateIcoreOptions, type DbProvider, type ExampleMode, type JobsProvider, type MsTransport, type PackageManager, type PaymentProvider, type UiLibrary, type UploadProvider, collectOptions, scaffold };
|
|
40
|
+
export { type AuthProvider, type CreateIcoreOptions, type DbProvider, type ExampleMode, type JobsProvider, type MsTransport, type PackageManager, type PaymentProvider, type UiLibrary, type UploadProvider, collectOptions, pmRun, scaffold };
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,12 @@ type ExampleMode = 'notes' | 'none';
|
|
|
7
7
|
type UiLibrary = 'shadcn' | 'antd' | 'mui';
|
|
8
8
|
type MsTransport = 'tcp' | 'redis' | 'nats';
|
|
9
9
|
type PackageManager = 'yarn' | 'npm' | 'pnpm';
|
|
10
|
+
/**
|
|
11
|
+
* Returns the correct invocation for a package.json script.
|
|
12
|
+
* yarn/pnpm: `yarn <script>` / `pnpm <script>`
|
|
13
|
+
* npm: `npm run <script>` (npm requires the `run` keyword for custom scripts)
|
|
14
|
+
*/
|
|
15
|
+
declare function pmRun(pm: PackageManager, script: string): string;
|
|
10
16
|
interface CreateIcoreOptions {
|
|
11
17
|
projectName: string;
|
|
12
18
|
targetDir: string;
|
|
@@ -31,4 +37,4 @@ interface PromptInput {
|
|
|
31
37
|
}
|
|
32
38
|
declare function collectOptions({ argv, cwd }: PromptInput): Promise<CreateIcoreOptions>;
|
|
33
39
|
|
|
34
|
-
export { type AuthProvider, type CreateIcoreOptions, type DbProvider, type ExampleMode, type JobsProvider, type MsTransport, type PackageManager, type PaymentProvider, type UiLibrary, type UploadProvider, collectOptions, scaffold };
|
|
40
|
+
export { type AuthProvider, type CreateIcoreOptions, type DbProvider, type ExampleMode, type JobsProvider, type MsTransport, type PackageManager, type PaymentProvider, type UiLibrary, type UploadProvider, collectOptions, pmRun, scaffold };
|