@idevconn/create-icore 0.1.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/LICENSE +201 -0
- package/README.md +56 -0
- package/dist/cli.js +300 -0
- package/dist/index.cjs +303 -0
- package/dist/index.d.cts +26 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +265 -0
- package/package.json +72 -0
- package/templates/.husky/pre-commit +56 -0
- package/templates/.nvmrc +1 -0
- package/templates/.prettierignore +7 -0
- package/templates/.prettierrc +7 -0
- package/templates/.yarnrc.yml +7 -0
- package/templates/apps/api/.env.example +19 -0
- package/templates/apps/api/eslint.config.mjs +23 -0
- package/templates/apps/api/package.json +20 -0
- package/templates/apps/api/project.json +76 -0
- package/templates/apps/api/src/app/abilities/__tests__/ability.guard.unit.test.ts +49 -0
- package/templates/apps/api/src/app/abilities/abilities.module.ts +10 -0
- package/templates/apps/api/src/app/abilities/ability.factory.ts +13 -0
- package/templates/apps/api/src/app/abilities/ability.guard.ts +29 -0
- package/templates/apps/api/src/app/abilities/check-ability.decorator.ts +12 -0
- package/templates/apps/api/src/app/app.module.ts +19 -0
- package/templates/apps/api/src/app/auth/__tests__/auth.guard.unit.test.ts +66 -0
- package/templates/apps/api/src/app/auth/auth.controller.ts +62 -0
- package/templates/apps/api/src/app/auth/auth.guard.ts +42 -0
- package/templates/apps/api/src/app/auth/auth.module.ts +17 -0
- package/templates/apps/api/src/app/auth/public.decorator.ts +4 -0
- package/templates/apps/api/src/app/profile/profile.controller.ts +15 -0
- package/templates/apps/api/src/app/profile/profile.module.ts +5 -0
- package/templates/apps/api/src/app/storage/__tests__/assert-ownership.unit.test.ts +28 -0
- package/templates/apps/api/src/app/storage/assert-ownership.ts +8 -0
- package/templates/apps/api/src/app/storage/storage.controller.ts +108 -0
- package/templates/apps/api/src/app/storage/storage.module.ts +10 -0
- package/templates/apps/api/src/assets/.gitkeep +0 -0
- package/templates/apps/api/src/main.ts +43 -0
- package/templates/apps/api/tsconfig.app.json +13 -0
- package/templates/apps/api/tsconfig.json +16 -0
- package/templates/apps/api/tsconfig.spec.json +16 -0
- package/templates/apps/api/vitest.config.mts +21 -0
- package/templates/apps/api/webpack.config.js +25 -0
- package/templates/apps/microservices/auth/.env.example +38 -0
- package/templates/apps/microservices/auth/package.json +19 -0
- package/templates/apps/microservices/auth/project.json +65 -0
- package/templates/apps/microservices/auth/src/app/__tests__/auth.controller.firebase.integration.unit.test.ts +53 -0
- package/templates/apps/microservices/auth/src/app/__tests__/auth.controller.supabase.integration.unit.test.ts +47 -0
- package/templates/apps/microservices/auth/src/app/__tests__/auth.controller.unit.test.ts +87 -0
- package/templates/apps/microservices/auth/src/app/app.module.ts +66 -0
- package/templates/apps/microservices/auth/src/app/auth.controller.ts +60 -0
- package/templates/apps/microservices/auth/src/assets/.gitkeep +0 -0
- package/templates/apps/microservices/auth/src/main.ts +28 -0
- package/templates/apps/microservices/auth/tsconfig.app.json +13 -0
- package/templates/apps/microservices/auth/tsconfig.json +16 -0
- package/templates/apps/microservices/auth/tsconfig.spec.json +16 -0
- package/templates/apps/microservices/auth/vitest.config.mts +21 -0
- package/templates/apps/microservices/auth/webpack.config.js +25 -0
- package/templates/apps/microservices/upload/.env.example +30 -0
- package/templates/apps/microservices/upload/package.json +21 -0
- package/templates/apps/microservices/upload/project.json +65 -0
- package/templates/apps/microservices/upload/src/app/__tests__/storage.controller.unit.test.ts +49 -0
- package/templates/apps/microservices/upload/src/app/app.module.ts +117 -0
- package/templates/apps/microservices/upload/src/app/storage.controller.ts +51 -0
- package/templates/apps/microservices/upload/src/assets/.gitkeep +0 -0
- package/templates/apps/microservices/upload/src/main.ts +28 -0
- package/templates/apps/microservices/upload/tsconfig.app.json +13 -0
- package/templates/apps/microservices/upload/tsconfig.json +16 -0
- package/templates/apps/microservices/upload/tsconfig.spec.json +16 -0
- package/templates/apps/microservices/upload/vitest.config.mts +22 -0
- package/templates/apps/microservices/upload/webpack.config.js +25 -0
- package/templates/apps/templates/client-shadcn/.env.example +2 -0
- package/templates/apps/templates/client-shadcn/eslint.config.mjs +10 -0
- package/templates/apps/templates/client-shadcn/index.html +17 -0
- package/templates/apps/templates/client-shadcn/project.json +9 -0
- package/templates/apps/templates/client-shadcn/public/favicon.ico +0 -0
- package/templates/apps/templates/client-shadcn/src/app/app.module.css +1 -0
- package/templates/apps/templates/client-shadcn/src/app/app.spec.tsx +9 -0
- package/templates/apps/templates/client-shadcn/src/app/app.tsx +7 -0
- package/templates/apps/templates/client-shadcn/src/assets/.gitkeep +0 -0
- package/templates/apps/templates/client-shadcn/src/components/AccessDeniedPage.tsx +15 -0
- package/templates/apps/templates/client-shadcn/src/components/PageLayout.tsx +55 -0
- package/templates/apps/templates/client-shadcn/src/components/layout/LayoutFooter.tsx +8 -0
- package/templates/apps/templates/client-shadcn/src/components/layout/LayoutHeader.tsx +57 -0
- package/templates/apps/templates/client-shadcn/src/components/layout/LayoutSider.tsx +44 -0
- package/templates/apps/templates/client-shadcn/src/components/ui/button.tsx +50 -0
- package/templates/apps/templates/client-shadcn/src/components/ui/card.tsx +63 -0
- package/templates/apps/templates/client-shadcn/src/components/ui/input.tsx +23 -0
- package/templates/apps/templates/client-shadcn/src/components/ui/label.tsx +18 -0
- package/templates/apps/templates/client-shadcn/src/globals.css +27 -0
- package/templates/apps/templates/client-shadcn/src/layouts/MainLayout.tsx +17 -0
- package/templates/apps/templates/client-shadcn/src/lib/notify.ts +15 -0
- package/templates/apps/templates/client-shadcn/src/lib/utils.ts +6 -0
- package/templates/apps/templates/client-shadcn/src/main.tsx +50 -0
- package/templates/apps/templates/client-shadcn/src/routeTree.gen.ts +136 -0
- package/templates/apps/templates/client-shadcn/src/routes/__root.tsx +5 -0
- package/templates/apps/templates/client-shadcn/src/routes/_dashboard/dashboard.tsx +33 -0
- package/templates/apps/templates/client-shadcn/src/routes/_dashboard/profile.tsx +88 -0
- package/templates/apps/templates/client-shadcn/src/routes/_dashboard.tsx +16 -0
- package/templates/apps/templates/client-shadcn/src/routes/index.tsx +33 -0
- package/templates/apps/templates/client-shadcn/src/routes/login.tsx +93 -0
- package/templates/apps/templates/client-shadcn/src/styles.css +1 -0
- package/templates/apps/templates/client-shadcn/tsconfig.app.json +27 -0
- package/templates/apps/templates/client-shadcn/tsconfig.json +21 -0
- package/templates/apps/templates/client-shadcn/tsconfig.spec.json +30 -0
- package/templates/apps/templates/client-shadcn/vite.config.mts +92 -0
- package/templates/apps/templates/client-shadcn-e2e/eslint.config.mjs +12 -0
- package/templates/apps/templates/client-shadcn-e2e/playwright.config.ts +69 -0
- package/templates/apps/templates/client-shadcn-e2e/project.json +10 -0
- package/templates/apps/templates/client-shadcn-e2e/src/icore.spec.ts +27 -0
- package/templates/apps/templates/client-shadcn-e2e/tsconfig.json +19 -0
- package/templates/eslint.config.mjs +20 -0
- package/templates/libs/auth-client/README.md +11 -0
- package/templates/libs/auth-client/eslint.config.mjs +22 -0
- package/templates/libs/auth-client/package.json +15 -0
- package/templates/libs/auth-client/project.json +19 -0
- package/templates/libs/auth-client/src/index.ts +2 -0
- package/templates/libs/auth-client/src/lib/auth-client.module.ts +25 -0
- package/templates/libs/auth-client/src/lib/auth-client.service.ts +30 -0
- package/templates/libs/auth-client/tsconfig.json +24 -0
- package/templates/libs/auth-client/tsconfig.lib.json +26 -0
- package/templates/libs/auth-client/tsconfig.spec.json +22 -0
- package/templates/libs/auth-client/vitest.config.mts +22 -0
- package/templates/libs/auth-strategies/firebase/README.md +11 -0
- package/templates/libs/auth-strategies/firebase/eslint.config.mjs +22 -0
- package/templates/libs/auth-strategies/firebase/package.json +15 -0
- package/templates/libs/auth-strategies/firebase/project.json +19 -0
- package/templates/libs/auth-strategies/firebase/src/index.ts +4 -0
- package/templates/libs/auth-strategies/firebase/src/lib/__tests__/firebase-auth.contract.unit.test.ts +13 -0
- package/templates/libs/auth-strategies/firebase/src/lib/firebase-auth.strategy.ts +77 -0
- package/templates/libs/auth-strategies/firebase/src/lib/identity-toolkit.client.ts +72 -0
- package/templates/libs/auth-strategies/firebase/src/lib/testing/mock-admin-auth.ts +41 -0
- package/templates/libs/auth-strategies/firebase/src/lib/testing/mock-identity-toolkit.ts +76 -0
- package/templates/libs/auth-strategies/firebase/tsconfig.json +24 -0
- package/templates/libs/auth-strategies/firebase/tsconfig.lib.json +23 -0
- package/templates/libs/auth-strategies/firebase/tsconfig.spec.json +22 -0
- package/templates/libs/auth-strategies/firebase/vitest.config.mts +22 -0
- package/templates/libs/auth-strategies/supabase/README.md +11 -0
- package/templates/libs/auth-strategies/supabase/eslint.config.mjs +22 -0
- package/templates/libs/auth-strategies/supabase/package.json +16 -0
- package/templates/libs/auth-strategies/supabase/project.json +19 -0
- package/templates/libs/auth-strategies/supabase/src/index.ts +2 -0
- package/templates/libs/auth-strategies/supabase/src/lib/__tests__/supabase-auth.contract.unit.test.ts +8 -0
- package/templates/libs/auth-strategies/supabase/src/lib/supabase-auth.strategy.ts +79 -0
- package/templates/libs/auth-strategies/supabase/src/lib/testing/mock-supabase.ts +107 -0
- package/templates/libs/auth-strategies/supabase/tsconfig.json +24 -0
- package/templates/libs/auth-strategies/supabase/tsconfig.lib.json +23 -0
- package/templates/libs/auth-strategies/supabase/tsconfig.spec.json +22 -0
- package/templates/libs/auth-strategies/supabase/vitest.config.mts +22 -0
- package/templates/libs/shared/README.md +11 -0
- package/templates/libs/shared/eslint.config.mjs +24 -0
- package/templates/libs/shared/package.json +14 -0
- package/templates/libs/shared/project.json +19 -0
- package/templates/libs/shared/src/__tests__/transport.unit.test.ts +58 -0
- package/templates/libs/shared/src/abilities/__tests__/ability.unit.test.ts +28 -0
- package/templates/libs/shared/src/abilities/ability.ts +21 -0
- package/templates/libs/shared/src/abilities/index.ts +2 -0
- package/templates/libs/shared/src/abilities/subjects.ts +2 -0
- package/templates/libs/shared/src/index.ts +3 -0
- package/templates/libs/shared/src/strategies/__tests__/fake-auth.contract.unit.test.ts +4 -0
- package/templates/libs/shared/src/strategies/__tests__/fake-storage.contract.unit.test.ts +4 -0
- package/templates/libs/shared/src/strategies/auth.ts +21 -0
- package/templates/libs/shared/src/strategies/contract/auth-contract.ts +66 -0
- package/templates/libs/shared/src/strategies/contract/storage-contract.ts +58 -0
- package/templates/libs/shared/src/strategies/fakes/fake-auth.ts +73 -0
- package/templates/libs/shared/src/strategies/fakes/fake-storage.ts +51 -0
- package/templates/libs/shared/src/strategies/fakes/index.ts +2 -0
- package/templates/libs/shared/src/strategies/index.ts +5 -0
- package/templates/libs/shared/src/strategies/storage.ts +17 -0
- package/templates/libs/shared/src/transport.ts +55 -0
- package/templates/libs/shared/tsconfig.json +24 -0
- package/templates/libs/shared/tsconfig.lib.json +23 -0
- package/templates/libs/shared/tsconfig.spec.json +22 -0
- package/templates/libs/shared/vitest.config.mts +21 -0
- package/templates/libs/storage-strategies/cloudinary/README.md +11 -0
- package/templates/libs/storage-strategies/cloudinary/eslint.config.mjs +23 -0
- package/templates/libs/storage-strategies/cloudinary/package.json +15 -0
- package/templates/libs/storage-strategies/cloudinary/project.json +19 -0
- package/templates/libs/storage-strategies/cloudinary/src/index.ts +2 -0
- package/templates/libs/storage-strategies/cloudinary/src/lib/__tests__/cloudinary-storage.contract.unit.test.ts +8 -0
- package/templates/libs/storage-strategies/cloudinary/src/lib/cloudinary-storage.strategy.ts +75 -0
- package/templates/libs/storage-strategies/cloudinary/src/lib/testing/mock-cloudinary.ts +36 -0
- package/templates/libs/storage-strategies/cloudinary/tsconfig.json +24 -0
- package/templates/libs/storage-strategies/cloudinary/tsconfig.lib.json +23 -0
- package/templates/libs/storage-strategies/cloudinary/tsconfig.spec.json +22 -0
- package/templates/libs/storage-strategies/cloudinary/vitest.config.mts +22 -0
- package/templates/libs/storage-strategies/firebase/README.md +11 -0
- package/templates/libs/storage-strategies/firebase/eslint.config.mjs +23 -0
- package/templates/libs/storage-strategies/firebase/package.json +15 -0
- package/templates/libs/storage-strategies/firebase/project.json +19 -0
- package/templates/libs/storage-strategies/firebase/src/index.ts +2 -0
- package/templates/libs/storage-strategies/firebase/src/lib/__tests__/firebase-storage.contract.unit.test.ts +8 -0
- package/templates/libs/storage-strategies/firebase/src/lib/firebase-storage.strategy.ts +63 -0
- package/templates/libs/storage-strategies/firebase/src/lib/testing/mock-firebase-storage.ts +43 -0
- package/templates/libs/storage-strategies/firebase/tsconfig.json +24 -0
- package/templates/libs/storage-strategies/firebase/tsconfig.lib.json +23 -0
- package/templates/libs/storage-strategies/firebase/tsconfig.spec.json +22 -0
- package/templates/libs/storage-strategies/firebase/vitest.config.mts +22 -0
- package/templates/libs/storage-strategies/supabase/README.md +11 -0
- package/templates/libs/storage-strategies/supabase/eslint.config.mjs +22 -0
- package/templates/libs/storage-strategies/supabase/package.json +16 -0
- package/templates/libs/storage-strategies/supabase/project.json +19 -0
- package/templates/libs/storage-strategies/supabase/src/index.ts +2 -0
- package/templates/libs/storage-strategies/supabase/src/lib/__tests__/supabase-storage.contract.unit.test.ts +8 -0
- package/templates/libs/storage-strategies/supabase/src/lib/supabase-storage.strategy.ts +53 -0
- package/templates/libs/storage-strategies/supabase/src/lib/testing/mock-supabase-storage.ts +78 -0
- package/templates/libs/storage-strategies/supabase/tsconfig.json +24 -0
- package/templates/libs/storage-strategies/supabase/tsconfig.lib.json +23 -0
- package/templates/libs/storage-strategies/supabase/tsconfig.spec.json +22 -0
- package/templates/libs/storage-strategies/supabase/vitest.config.mts +22 -0
- package/templates/libs/template-shared/README.md +11 -0
- package/templates/libs/template-shared/eslint.config.mjs +23 -0
- package/templates/libs/template-shared/package.json +22 -0
- package/templates/libs/template-shared/project.json +19 -0
- package/templates/libs/template-shared/src/index.ts +9 -0
- package/templates/libs/template-shared/src/lib/abilities/ability-provider.tsx +19 -0
- package/templates/libs/template-shared/src/lib/api/create-api.ts +20 -0
- package/templates/libs/template-shared/src/lib/draft/index.ts +1 -0
- package/templates/libs/template-shared/src/lib/i18n/create-i18n.ts +42 -0
- package/templates/libs/template-shared/src/lib/i18n/keys.ts +30 -0
- package/templates/libs/template-shared/src/lib/landing/LandingPage.tsx +68 -0
- package/templates/libs/template-shared/src/lib/notify/use-notify.ts +26 -0
- package/templates/libs/template-shared/src/lib/stores/auth.store.ts +29 -0
- package/templates/libs/template-shared/src/lib/stores/loading.store.ts +13 -0
- package/templates/libs/template-shared/tsconfig.json +24 -0
- package/templates/libs/template-shared/tsconfig.lib.json +25 -0
- package/templates/libs/template-shared/tsconfig.spec.json +22 -0
- package/templates/libs/template-shared/vitest.config.mts +22 -0
- package/templates/libs/upload-client/README.md +11 -0
- package/templates/libs/upload-client/eslint.config.mjs +22 -0
- package/templates/libs/upload-client/package.json +15 -0
- package/templates/libs/upload-client/project.json +19 -0
- package/templates/libs/upload-client/src/index.ts +2 -0
- package/templates/libs/upload-client/src/lib/upload-client.module.ts +25 -0
- package/templates/libs/upload-client/src/lib/upload-client.service.ts +38 -0
- package/templates/libs/upload-client/tsconfig.json +24 -0
- package/templates/libs/upload-client/tsconfig.lib.json +26 -0
- package/templates/libs/upload-client/tsconfig.spec.json +22 -0
- package/templates/libs/upload-client/vitest.config.mts +22 -0
- package/templates/nx.json +113 -0
- package/templates/package.json +24 -0
- package/templates/tools/create-icore/_template-shell/package.json +24 -0
- package/templates/tsconfig.base.json +29 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
collectOptions: () => collectOptions,
|
|
34
|
+
scaffold: () => scaffold
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(src_exports);
|
|
37
|
+
|
|
38
|
+
// src/lib/scaffold.ts
|
|
39
|
+
var import_promises = require("fs/promises");
|
|
40
|
+
var import_node_path = require("path");
|
|
41
|
+
var import_node_child_process = require("child_process");
|
|
42
|
+
var IGNORE_TOP = /* @__PURE__ */ new Set([
|
|
43
|
+
".git",
|
|
44
|
+
"node_modules",
|
|
45
|
+
".yarn/cache",
|
|
46
|
+
".yarn/unplugged",
|
|
47
|
+
".yarn/install-state.gz",
|
|
48
|
+
".nx",
|
|
49
|
+
"dist",
|
|
50
|
+
"tmp",
|
|
51
|
+
"coverage",
|
|
52
|
+
".idea",
|
|
53
|
+
".vscode"
|
|
54
|
+
]);
|
|
55
|
+
async function copyTree(src, dest) {
|
|
56
|
+
await (0, import_promises.mkdir)(dest, { recursive: true });
|
|
57
|
+
const entries = await (0, import_promises.readdir)(src, { withFileTypes: true });
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
if (IGNORE_TOP.has(entry.name)) continue;
|
|
60
|
+
const s = (0, import_node_path.join)(src, entry.name);
|
|
61
|
+
const d = (0, import_node_path.join)(dest, entry.name);
|
|
62
|
+
if (entry.isDirectory()) await copyTree(s, d);
|
|
63
|
+
else if (entry.isFile()) await (0, import_promises.copyFile)(s, d);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function rewriteRootPackageJson(targetDir, opts) {
|
|
67
|
+
const pkgPath = (0, import_node_path.join)(targetDir, "package.json");
|
|
68
|
+
const raw = await (0, import_promises.readFile)(pkgPath, "utf8");
|
|
69
|
+
const pkg = JSON.parse(raw);
|
|
70
|
+
pkg["name"] = opts.projectName;
|
|
71
|
+
pkg["version"] = "0.0.1";
|
|
72
|
+
pkg["private"] = true;
|
|
73
|
+
delete pkg.description;
|
|
74
|
+
await (0, import_promises.writeFile)(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
75
|
+
}
|
|
76
|
+
async function writeAuthEnv(targetDir, opts) {
|
|
77
|
+
const envExample = (0, import_node_path.join)(targetDir, "apps/microservices/auth/.env.example");
|
|
78
|
+
const env = await (0, import_promises.readFile)(envExample, "utf8");
|
|
79
|
+
let next = env.replace(/^AUTH_PROVIDER=.*$/m, `AUTH_PROVIDER=${opts.authProvider}`).replace(/^AUTH_TRANSPORT=.*$/m, `AUTH_TRANSPORT=${opts.transport}`);
|
|
80
|
+
if (opts.transport !== "tcp") {
|
|
81
|
+
next = next.replace(/^# (AUTH_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
82
|
+
}
|
|
83
|
+
await (0, import_promises.writeFile)((0, import_node_path.join)(targetDir, "apps/microservices/auth/.env"), next);
|
|
84
|
+
}
|
|
85
|
+
async function writeUploadEnv(targetDir, opts) {
|
|
86
|
+
if (opts.upload === "none") return;
|
|
87
|
+
const envExample = (0, import_node_path.join)(targetDir, "apps/microservices/upload/.env.example");
|
|
88
|
+
const env = await (0, import_promises.readFile)(envExample, "utf8");
|
|
89
|
+
let next = env.replace(/^STORAGE_PROVIDER=.*$/m, `STORAGE_PROVIDER=${opts.upload}`).replace(/^UPLOAD_TRANSPORT=.*$/m, `UPLOAD_TRANSPORT=${opts.transport}`);
|
|
90
|
+
if (opts.transport !== "tcp") {
|
|
91
|
+
next = next.replace(/^# (UPLOAD_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
92
|
+
}
|
|
93
|
+
await (0, import_promises.writeFile)((0, import_node_path.join)(targetDir, "apps/microservices/upload/.env"), next);
|
|
94
|
+
}
|
|
95
|
+
async function writeGatewayEnv(targetDir, opts) {
|
|
96
|
+
const envExample = (0, import_node_path.join)(targetDir, "apps/api/.env.example");
|
|
97
|
+
const env = await (0, import_promises.readFile)(envExample, "utf8");
|
|
98
|
+
let next = env.replace(/^AUTH_TRANSPORT=.*$/m, `AUTH_TRANSPORT=${opts.transport}`).replace(/^UPLOAD_TRANSPORT=.*$/m, `UPLOAD_TRANSPORT=${opts.transport}`);
|
|
99
|
+
if (opts.transport !== "tcp") {
|
|
100
|
+
next = next.replace(/^# (AUTH_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (UPLOAD_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
101
|
+
}
|
|
102
|
+
await (0, import_promises.writeFile)((0, import_node_path.join)(targetDir, "apps/api/.env"), next);
|
|
103
|
+
}
|
|
104
|
+
async function removeUploadStack(targetDir) {
|
|
105
|
+
const paths = [
|
|
106
|
+
"apps/microservices/upload",
|
|
107
|
+
"apps/microservices/upload-e2e",
|
|
108
|
+
"libs/storage-strategies",
|
|
109
|
+
"libs/upload-client",
|
|
110
|
+
"apps/api/src/app/storage"
|
|
111
|
+
];
|
|
112
|
+
for (const p2 of paths) {
|
|
113
|
+
await (0, import_promises.rm)((0, import_node_path.join)(targetDir, p2), { recursive: true, force: true });
|
|
114
|
+
}
|
|
115
|
+
const appModulePath = (0, import_node_path.join)(targetDir, "apps/api/src/app/app.module.ts");
|
|
116
|
+
try {
|
|
117
|
+
const appModule = await (0, import_promises.readFile)(appModulePath, "utf8");
|
|
118
|
+
const next = appModule.replace(/^import \{ StorageModule \} from '\.\/storage\/storage\.module';\n/m, "").replace(/,\s*StorageModule/g, "");
|
|
119
|
+
await (0, import_promises.writeFile)(appModulePath, next);
|
|
120
|
+
} catch {
|
|
121
|
+
}
|
|
122
|
+
const gatewayEnv = (0, import_node_path.join)(targetDir, "apps/api/.env");
|
|
123
|
+
try {
|
|
124
|
+
const env = await (0, import_promises.readFile)(gatewayEnv, "utf8");
|
|
125
|
+
const next = env.split("\n").filter(
|
|
126
|
+
(line) => !line.startsWith("UPLOAD_") && !line.startsWith("# UPLOAD_") && !line.startsWith("MAX_FILE_SIZE_KB")
|
|
127
|
+
).join("\n");
|
|
128
|
+
await (0, import_promises.writeFile)(gatewayEnv, next);
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async function selectClientTemplate(targetDir, opts) {
|
|
133
|
+
const templatesRoot = (0, import_node_path.join)(targetDir, "apps/templates");
|
|
134
|
+
const chosen = (0, import_node_path.join)(templatesRoot, `client-${opts.ui}`);
|
|
135
|
+
const destClient = (0, import_node_path.join)(targetDir, "apps/client");
|
|
136
|
+
try {
|
|
137
|
+
const s = await (0, import_promises.stat)(chosen);
|
|
138
|
+
if (!s.isDirectory()) throw new Error("not a dir");
|
|
139
|
+
} catch {
|
|
140
|
+
await copyTree((0, import_node_path.join)(templatesRoot, "client-shadcn"), destClient);
|
|
141
|
+
await (0, import_promises.rm)(templatesRoot, { recursive: true, force: true });
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
await copyTree(chosen, destClient);
|
|
145
|
+
await (0, import_promises.rm)(templatesRoot, { recursive: true, force: true });
|
|
146
|
+
}
|
|
147
|
+
function gitInit(cwd, projectName) {
|
|
148
|
+
(0, import_node_child_process.spawnSync)("git", ["init"], { cwd, stdio: "inherit" });
|
|
149
|
+
(0, import_node_child_process.spawnSync)("git", ["add", "."], { cwd, stdio: "inherit" });
|
|
150
|
+
(0, import_node_child_process.spawnSync)(
|
|
151
|
+
"git",
|
|
152
|
+
["commit", "-m", `chore: bootstrap ${projectName} from @idevconn/create-icore`],
|
|
153
|
+
{ cwd, stdio: "inherit" }
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
function yarnInstall(cwd) {
|
|
157
|
+
(0, import_node_child_process.spawnSync)("yarn", ["install"], { cwd, stdio: "inherit" });
|
|
158
|
+
}
|
|
159
|
+
async function scaffold(opts, templatesDir) {
|
|
160
|
+
await copyTree(templatesDir, opts.targetDir);
|
|
161
|
+
await rewriteRootPackageJson(opts.targetDir, opts);
|
|
162
|
+
await writeAuthEnv(opts.targetDir, opts);
|
|
163
|
+
await writeUploadEnv(opts.targetDir, opts);
|
|
164
|
+
await writeGatewayEnv(opts.targetDir, opts);
|
|
165
|
+
await selectClientTemplate(opts.targetDir, opts);
|
|
166
|
+
if (opts.upload === "none") await removeUploadStack(opts.targetDir);
|
|
167
|
+
if (opts.install) yarnInstall(opts.targetDir);
|
|
168
|
+
if (opts.initGit) gitInit(opts.targetDir, opts.projectName);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// src/lib/prompts.ts
|
|
172
|
+
var p = __toESM(require("@clack/prompts"), 1);
|
|
173
|
+
var import_node_path2 = require("path");
|
|
174
|
+
function parseFlags(argv) {
|
|
175
|
+
const out = {};
|
|
176
|
+
for (let i = 0; i < argv.length; i++) {
|
|
177
|
+
const a = argv[i];
|
|
178
|
+
if (!a || !a.startsWith("--")) {
|
|
179
|
+
if (a && !out.projectName) out.projectName = a;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const parts = a.includes("=") ? a.split("=", 2) : [a, argv[++i]];
|
|
183
|
+
const k = parts[0] ?? "";
|
|
184
|
+
const vIn = parts[1];
|
|
185
|
+
const key = k.slice(2);
|
|
186
|
+
const v = vIn ?? "";
|
|
187
|
+
switch (key) {
|
|
188
|
+
case "auth":
|
|
189
|
+
out.authProvider = v;
|
|
190
|
+
break;
|
|
191
|
+
case "db":
|
|
192
|
+
out.dbProvider = v;
|
|
193
|
+
break;
|
|
194
|
+
case "upload":
|
|
195
|
+
out.upload = v;
|
|
196
|
+
break;
|
|
197
|
+
case "storage":
|
|
198
|
+
process.stderr.write("Warning: --storage is deprecated, use --upload\n");
|
|
199
|
+
out.upload = v;
|
|
200
|
+
break;
|
|
201
|
+
case "ui":
|
|
202
|
+
out.ui = v;
|
|
203
|
+
break;
|
|
204
|
+
case "transport":
|
|
205
|
+
out.transport = v;
|
|
206
|
+
break;
|
|
207
|
+
case "no-git":
|
|
208
|
+
out.initGit = false;
|
|
209
|
+
break;
|
|
210
|
+
case "no-install":
|
|
211
|
+
out.install = false;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
async function collectOptions({ argv, cwd }) {
|
|
218
|
+
const flags = parseFlags(argv);
|
|
219
|
+
p.intro("icore \u2014 bootstrap a new project");
|
|
220
|
+
const projectName = flags.projectName ?? await p.text({
|
|
221
|
+
message: "Project name",
|
|
222
|
+
placeholder: "my-app",
|
|
223
|
+
validate: (v) => v && /^[a-z0-9-]+$/i.test(v) ? void 0 : "Use letters, digits, hyphens"
|
|
224
|
+
});
|
|
225
|
+
if (p.isCancel(projectName)) throw new Error("cancelled");
|
|
226
|
+
const authProvider = flags.authProvider ?? await p.select({
|
|
227
|
+
message: "Auth provider",
|
|
228
|
+
options: [
|
|
229
|
+
{ value: "supabase", label: "Supabase" },
|
|
230
|
+
{ value: "firebase", label: "Firebase" }
|
|
231
|
+
]
|
|
232
|
+
});
|
|
233
|
+
if (p.isCancel(authProvider)) throw new Error("cancelled");
|
|
234
|
+
const dbProvider = flags.dbProvider ?? await p.select({
|
|
235
|
+
message: "Database backend",
|
|
236
|
+
options: [
|
|
237
|
+
{ value: "supabase", label: "Supabase Postgres" },
|
|
238
|
+
{ value: "firebase", label: "Firestore" }
|
|
239
|
+
],
|
|
240
|
+
initialValue: authProvider
|
|
241
|
+
});
|
|
242
|
+
if (p.isCancel(dbProvider)) throw new Error("cancelled");
|
|
243
|
+
if (dbProvider !== authProvider) {
|
|
244
|
+
p.log.info(
|
|
245
|
+
"Note: in v0.1.0 the DB choice mirrors auth; independent db swap arrives in Plan 8."
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
const upload = flags.upload ?? await p.select({
|
|
249
|
+
message: "File upload provider",
|
|
250
|
+
options: [
|
|
251
|
+
{ value: "supabase", label: "Supabase Storage" },
|
|
252
|
+
{ value: "firebase", label: "Firebase Cloud Storage" },
|
|
253
|
+
{ value: "cloudinary", label: "Cloudinary" },
|
|
254
|
+
{ value: "none", label: "None \u2014 skip the upload microservice" }
|
|
255
|
+
]
|
|
256
|
+
});
|
|
257
|
+
if (p.isCancel(upload)) throw new Error("cancelled");
|
|
258
|
+
const ui = flags.ui ?? await p.select({
|
|
259
|
+
message: "UI library",
|
|
260
|
+
options: [
|
|
261
|
+
{ value: "shadcn", label: "shadcn/ui + Tailwind" },
|
|
262
|
+
{
|
|
263
|
+
value: "antd",
|
|
264
|
+
label: "Ant Design (coming soon \u2014 falls back to shadcn)"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
value: "mui",
|
|
268
|
+
label: "MUI (coming soon \u2014 falls back to shadcn)"
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
initialValue: "shadcn"
|
|
272
|
+
});
|
|
273
|
+
if (p.isCancel(ui)) throw new Error("cancelled");
|
|
274
|
+
const transport = flags.transport ?? await p.select({
|
|
275
|
+
message: "Microservice transport",
|
|
276
|
+
options: [
|
|
277
|
+
{ value: "tcp", label: "TCP (default, no broker required)" },
|
|
278
|
+
{ value: "redis", label: "Redis" },
|
|
279
|
+
{ value: "nats", label: "NATS" }
|
|
280
|
+
],
|
|
281
|
+
initialValue: "tcp"
|
|
282
|
+
});
|
|
283
|
+
if (p.isCancel(transport)) throw new Error("cancelled");
|
|
284
|
+
const initGit = flags.initGit ?? !await p.confirm({ message: "Initialise git repo?", initialValue: true }) === false;
|
|
285
|
+
const install = flags.install ?? !await p.confirm({ message: "Run yarn install?", initialValue: true }) === false;
|
|
286
|
+
return {
|
|
287
|
+
projectName,
|
|
288
|
+
targetDir: (0, import_node_path2.resolve)(cwd, projectName),
|
|
289
|
+
authProvider,
|
|
290
|
+
dbProvider,
|
|
291
|
+
upload,
|
|
292
|
+
ui: ui === "shadcn" ? "shadcn" : "shadcn",
|
|
293
|
+
// antd/mui fall back to shadcn for v0.1.0
|
|
294
|
+
transport,
|
|
295
|
+
initGit,
|
|
296
|
+
install
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
300
|
+
0 && (module.exports = {
|
|
301
|
+
collectOptions,
|
|
302
|
+
scaffold
|
|
303
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type AuthProvider = 'supabase' | 'firebase';
|
|
2
|
+
type DbProvider = 'supabase' | 'firebase';
|
|
3
|
+
type UploadProvider = 'supabase' | 'firebase' | 'cloudinary' | 'none';
|
|
4
|
+
type UiLibrary = 'shadcn' | 'antd' | 'mui';
|
|
5
|
+
type MsTransport = 'tcp' | 'redis' | 'nats';
|
|
6
|
+
interface CreateIcoreOptions {
|
|
7
|
+
projectName: string;
|
|
8
|
+
targetDir: string;
|
|
9
|
+
authProvider: AuthProvider;
|
|
10
|
+
dbProvider: DbProvider;
|
|
11
|
+
upload: UploadProvider;
|
|
12
|
+
ui: UiLibrary;
|
|
13
|
+
transport: MsTransport;
|
|
14
|
+
initGit: boolean;
|
|
15
|
+
install: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare function scaffold(opts: CreateIcoreOptions, templatesDir: string): Promise<void>;
|
|
19
|
+
|
|
20
|
+
interface PromptInput {
|
|
21
|
+
argv: string[];
|
|
22
|
+
cwd: string;
|
|
23
|
+
}
|
|
24
|
+
declare function collectOptions({ argv, cwd }: PromptInput): Promise<CreateIcoreOptions>;
|
|
25
|
+
|
|
26
|
+
export { type AuthProvider, type CreateIcoreOptions, type DbProvider, type MsTransport, type UiLibrary, type UploadProvider, collectOptions, scaffold };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type AuthProvider = 'supabase' | 'firebase';
|
|
2
|
+
type DbProvider = 'supabase' | 'firebase';
|
|
3
|
+
type UploadProvider = 'supabase' | 'firebase' | 'cloudinary' | 'none';
|
|
4
|
+
type UiLibrary = 'shadcn' | 'antd' | 'mui';
|
|
5
|
+
type MsTransport = 'tcp' | 'redis' | 'nats';
|
|
6
|
+
interface CreateIcoreOptions {
|
|
7
|
+
projectName: string;
|
|
8
|
+
targetDir: string;
|
|
9
|
+
authProvider: AuthProvider;
|
|
10
|
+
dbProvider: DbProvider;
|
|
11
|
+
upload: UploadProvider;
|
|
12
|
+
ui: UiLibrary;
|
|
13
|
+
transport: MsTransport;
|
|
14
|
+
initGit: boolean;
|
|
15
|
+
install: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare function scaffold(opts: CreateIcoreOptions, templatesDir: string): Promise<void>;
|
|
19
|
+
|
|
20
|
+
interface PromptInput {
|
|
21
|
+
argv: string[];
|
|
22
|
+
cwd: string;
|
|
23
|
+
}
|
|
24
|
+
declare function collectOptions({ argv, cwd }: PromptInput): Promise<CreateIcoreOptions>;
|
|
25
|
+
|
|
26
|
+
export { type AuthProvider, type CreateIcoreOptions, type DbProvider, type MsTransport, type UiLibrary, type UploadProvider, collectOptions, scaffold };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// src/lib/scaffold.ts
|
|
2
|
+
import { copyFile, mkdir, readdir, readFile, stat, writeFile, rm } from "fs/promises";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { spawnSync } from "child_process";
|
|
5
|
+
var IGNORE_TOP = /* @__PURE__ */ new Set([
|
|
6
|
+
".git",
|
|
7
|
+
"node_modules",
|
|
8
|
+
".yarn/cache",
|
|
9
|
+
".yarn/unplugged",
|
|
10
|
+
".yarn/install-state.gz",
|
|
11
|
+
".nx",
|
|
12
|
+
"dist",
|
|
13
|
+
"tmp",
|
|
14
|
+
"coverage",
|
|
15
|
+
".idea",
|
|
16
|
+
".vscode"
|
|
17
|
+
]);
|
|
18
|
+
async function copyTree(src, dest) {
|
|
19
|
+
await mkdir(dest, { recursive: true });
|
|
20
|
+
const entries = await readdir(src, { withFileTypes: true });
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
if (IGNORE_TOP.has(entry.name)) continue;
|
|
23
|
+
const s = join(src, entry.name);
|
|
24
|
+
const d = join(dest, entry.name);
|
|
25
|
+
if (entry.isDirectory()) await copyTree(s, d);
|
|
26
|
+
else if (entry.isFile()) await copyFile(s, d);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function rewriteRootPackageJson(targetDir, opts) {
|
|
30
|
+
const pkgPath = join(targetDir, "package.json");
|
|
31
|
+
const raw = await readFile(pkgPath, "utf8");
|
|
32
|
+
const pkg = JSON.parse(raw);
|
|
33
|
+
pkg["name"] = opts.projectName;
|
|
34
|
+
pkg["version"] = "0.0.1";
|
|
35
|
+
pkg["private"] = true;
|
|
36
|
+
delete pkg.description;
|
|
37
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
38
|
+
}
|
|
39
|
+
async function writeAuthEnv(targetDir, opts) {
|
|
40
|
+
const envExample = join(targetDir, "apps/microservices/auth/.env.example");
|
|
41
|
+
const env = await readFile(envExample, "utf8");
|
|
42
|
+
let next = env.replace(/^AUTH_PROVIDER=.*$/m, `AUTH_PROVIDER=${opts.authProvider}`).replace(/^AUTH_TRANSPORT=.*$/m, `AUTH_TRANSPORT=${opts.transport}`);
|
|
43
|
+
if (opts.transport !== "tcp") {
|
|
44
|
+
next = next.replace(/^# (AUTH_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
45
|
+
}
|
|
46
|
+
await writeFile(join(targetDir, "apps/microservices/auth/.env"), next);
|
|
47
|
+
}
|
|
48
|
+
async function writeUploadEnv(targetDir, opts) {
|
|
49
|
+
if (opts.upload === "none") return;
|
|
50
|
+
const envExample = join(targetDir, "apps/microservices/upload/.env.example");
|
|
51
|
+
const env = await readFile(envExample, "utf8");
|
|
52
|
+
let next = env.replace(/^STORAGE_PROVIDER=.*$/m, `STORAGE_PROVIDER=${opts.upload}`).replace(/^UPLOAD_TRANSPORT=.*$/m, `UPLOAD_TRANSPORT=${opts.transport}`);
|
|
53
|
+
if (opts.transport !== "tcp") {
|
|
54
|
+
next = next.replace(/^# (UPLOAD_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
55
|
+
}
|
|
56
|
+
await writeFile(join(targetDir, "apps/microservices/upload/.env"), next);
|
|
57
|
+
}
|
|
58
|
+
async function writeGatewayEnv(targetDir, opts) {
|
|
59
|
+
const envExample = join(targetDir, "apps/api/.env.example");
|
|
60
|
+
const env = await readFile(envExample, "utf8");
|
|
61
|
+
let next = env.replace(/^AUTH_TRANSPORT=.*$/m, `AUTH_TRANSPORT=${opts.transport}`).replace(/^UPLOAD_TRANSPORT=.*$/m, `UPLOAD_TRANSPORT=${opts.transport}`);
|
|
62
|
+
if (opts.transport !== "tcp") {
|
|
63
|
+
next = next.replace(/^# (AUTH_(?:REDIS|NATS)_URL=)/m, "$1").replace(/^# (UPLOAD_(?:REDIS|NATS)_URL=)/m, "$1");
|
|
64
|
+
}
|
|
65
|
+
await writeFile(join(targetDir, "apps/api/.env"), next);
|
|
66
|
+
}
|
|
67
|
+
async function removeUploadStack(targetDir) {
|
|
68
|
+
const paths = [
|
|
69
|
+
"apps/microservices/upload",
|
|
70
|
+
"apps/microservices/upload-e2e",
|
|
71
|
+
"libs/storage-strategies",
|
|
72
|
+
"libs/upload-client",
|
|
73
|
+
"apps/api/src/app/storage"
|
|
74
|
+
];
|
|
75
|
+
for (const p2 of paths) {
|
|
76
|
+
await rm(join(targetDir, p2), { recursive: true, force: true });
|
|
77
|
+
}
|
|
78
|
+
const appModulePath = join(targetDir, "apps/api/src/app/app.module.ts");
|
|
79
|
+
try {
|
|
80
|
+
const appModule = await readFile(appModulePath, "utf8");
|
|
81
|
+
const next = appModule.replace(/^import \{ StorageModule \} from '\.\/storage\/storage\.module';\n/m, "").replace(/,\s*StorageModule/g, "");
|
|
82
|
+
await writeFile(appModulePath, next);
|
|
83
|
+
} catch {
|
|
84
|
+
}
|
|
85
|
+
const gatewayEnv = join(targetDir, "apps/api/.env");
|
|
86
|
+
try {
|
|
87
|
+
const env = await readFile(gatewayEnv, "utf8");
|
|
88
|
+
const next = env.split("\n").filter(
|
|
89
|
+
(line) => !line.startsWith("UPLOAD_") && !line.startsWith("# UPLOAD_") && !line.startsWith("MAX_FILE_SIZE_KB")
|
|
90
|
+
).join("\n");
|
|
91
|
+
await writeFile(gatewayEnv, next);
|
|
92
|
+
} catch {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function selectClientTemplate(targetDir, opts) {
|
|
96
|
+
const templatesRoot = join(targetDir, "apps/templates");
|
|
97
|
+
const chosen = join(templatesRoot, `client-${opts.ui}`);
|
|
98
|
+
const destClient = join(targetDir, "apps/client");
|
|
99
|
+
try {
|
|
100
|
+
const s = await stat(chosen);
|
|
101
|
+
if (!s.isDirectory()) throw new Error("not a dir");
|
|
102
|
+
} catch {
|
|
103
|
+
await copyTree(join(templatesRoot, "client-shadcn"), destClient);
|
|
104
|
+
await rm(templatesRoot, { recursive: true, force: true });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
await copyTree(chosen, destClient);
|
|
108
|
+
await rm(templatesRoot, { recursive: true, force: true });
|
|
109
|
+
}
|
|
110
|
+
function gitInit(cwd, projectName) {
|
|
111
|
+
spawnSync("git", ["init"], { cwd, stdio: "inherit" });
|
|
112
|
+
spawnSync("git", ["add", "."], { cwd, stdio: "inherit" });
|
|
113
|
+
spawnSync(
|
|
114
|
+
"git",
|
|
115
|
+
["commit", "-m", `chore: bootstrap ${projectName} from @idevconn/create-icore`],
|
|
116
|
+
{ cwd, stdio: "inherit" }
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function yarnInstall(cwd) {
|
|
120
|
+
spawnSync("yarn", ["install"], { cwd, stdio: "inherit" });
|
|
121
|
+
}
|
|
122
|
+
async function scaffold(opts, templatesDir) {
|
|
123
|
+
await copyTree(templatesDir, opts.targetDir);
|
|
124
|
+
await rewriteRootPackageJson(opts.targetDir, opts);
|
|
125
|
+
await writeAuthEnv(opts.targetDir, opts);
|
|
126
|
+
await writeUploadEnv(opts.targetDir, opts);
|
|
127
|
+
await writeGatewayEnv(opts.targetDir, opts);
|
|
128
|
+
await selectClientTemplate(opts.targetDir, opts);
|
|
129
|
+
if (opts.upload === "none") await removeUploadStack(opts.targetDir);
|
|
130
|
+
if (opts.install) yarnInstall(opts.targetDir);
|
|
131
|
+
if (opts.initGit) gitInit(opts.targetDir, opts.projectName);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/lib/prompts.ts
|
|
135
|
+
import * as p from "@clack/prompts";
|
|
136
|
+
import { resolve } from "path";
|
|
137
|
+
function parseFlags(argv) {
|
|
138
|
+
const out = {};
|
|
139
|
+
for (let i = 0; i < argv.length; i++) {
|
|
140
|
+
const a = argv[i];
|
|
141
|
+
if (!a || !a.startsWith("--")) {
|
|
142
|
+
if (a && !out.projectName) out.projectName = a;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const parts = a.includes("=") ? a.split("=", 2) : [a, argv[++i]];
|
|
146
|
+
const k = parts[0] ?? "";
|
|
147
|
+
const vIn = parts[1];
|
|
148
|
+
const key = k.slice(2);
|
|
149
|
+
const v = vIn ?? "";
|
|
150
|
+
switch (key) {
|
|
151
|
+
case "auth":
|
|
152
|
+
out.authProvider = v;
|
|
153
|
+
break;
|
|
154
|
+
case "db":
|
|
155
|
+
out.dbProvider = v;
|
|
156
|
+
break;
|
|
157
|
+
case "upload":
|
|
158
|
+
out.upload = v;
|
|
159
|
+
break;
|
|
160
|
+
case "storage":
|
|
161
|
+
process.stderr.write("Warning: --storage is deprecated, use --upload\n");
|
|
162
|
+
out.upload = v;
|
|
163
|
+
break;
|
|
164
|
+
case "ui":
|
|
165
|
+
out.ui = v;
|
|
166
|
+
break;
|
|
167
|
+
case "transport":
|
|
168
|
+
out.transport = v;
|
|
169
|
+
break;
|
|
170
|
+
case "no-git":
|
|
171
|
+
out.initGit = false;
|
|
172
|
+
break;
|
|
173
|
+
case "no-install":
|
|
174
|
+
out.install = false;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
async function collectOptions({ argv, cwd }) {
|
|
181
|
+
const flags = parseFlags(argv);
|
|
182
|
+
p.intro("icore \u2014 bootstrap a new project");
|
|
183
|
+
const projectName = flags.projectName ?? await p.text({
|
|
184
|
+
message: "Project name",
|
|
185
|
+
placeholder: "my-app",
|
|
186
|
+
validate: (v) => v && /^[a-z0-9-]+$/i.test(v) ? void 0 : "Use letters, digits, hyphens"
|
|
187
|
+
});
|
|
188
|
+
if (p.isCancel(projectName)) throw new Error("cancelled");
|
|
189
|
+
const authProvider = flags.authProvider ?? await p.select({
|
|
190
|
+
message: "Auth provider",
|
|
191
|
+
options: [
|
|
192
|
+
{ value: "supabase", label: "Supabase" },
|
|
193
|
+
{ value: "firebase", label: "Firebase" }
|
|
194
|
+
]
|
|
195
|
+
});
|
|
196
|
+
if (p.isCancel(authProvider)) throw new Error("cancelled");
|
|
197
|
+
const dbProvider = flags.dbProvider ?? await p.select({
|
|
198
|
+
message: "Database backend",
|
|
199
|
+
options: [
|
|
200
|
+
{ value: "supabase", label: "Supabase Postgres" },
|
|
201
|
+
{ value: "firebase", label: "Firestore" }
|
|
202
|
+
],
|
|
203
|
+
initialValue: authProvider
|
|
204
|
+
});
|
|
205
|
+
if (p.isCancel(dbProvider)) throw new Error("cancelled");
|
|
206
|
+
if (dbProvider !== authProvider) {
|
|
207
|
+
p.log.info(
|
|
208
|
+
"Note: in v0.1.0 the DB choice mirrors auth; independent db swap arrives in Plan 8."
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
const upload = flags.upload ?? await p.select({
|
|
212
|
+
message: "File upload provider",
|
|
213
|
+
options: [
|
|
214
|
+
{ value: "supabase", label: "Supabase Storage" },
|
|
215
|
+
{ value: "firebase", label: "Firebase Cloud Storage" },
|
|
216
|
+
{ value: "cloudinary", label: "Cloudinary" },
|
|
217
|
+
{ value: "none", label: "None \u2014 skip the upload microservice" }
|
|
218
|
+
]
|
|
219
|
+
});
|
|
220
|
+
if (p.isCancel(upload)) throw new Error("cancelled");
|
|
221
|
+
const ui = flags.ui ?? await p.select({
|
|
222
|
+
message: "UI library",
|
|
223
|
+
options: [
|
|
224
|
+
{ value: "shadcn", label: "shadcn/ui + Tailwind" },
|
|
225
|
+
{
|
|
226
|
+
value: "antd",
|
|
227
|
+
label: "Ant Design (coming soon \u2014 falls back to shadcn)"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
value: "mui",
|
|
231
|
+
label: "MUI (coming soon \u2014 falls back to shadcn)"
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
initialValue: "shadcn"
|
|
235
|
+
});
|
|
236
|
+
if (p.isCancel(ui)) throw new Error("cancelled");
|
|
237
|
+
const transport = flags.transport ?? await p.select({
|
|
238
|
+
message: "Microservice transport",
|
|
239
|
+
options: [
|
|
240
|
+
{ value: "tcp", label: "TCP (default, no broker required)" },
|
|
241
|
+
{ value: "redis", label: "Redis" },
|
|
242
|
+
{ value: "nats", label: "NATS" }
|
|
243
|
+
],
|
|
244
|
+
initialValue: "tcp"
|
|
245
|
+
});
|
|
246
|
+
if (p.isCancel(transport)) throw new Error("cancelled");
|
|
247
|
+
const initGit = flags.initGit ?? !await p.confirm({ message: "Initialise git repo?", initialValue: true }) === false;
|
|
248
|
+
const install = flags.install ?? !await p.confirm({ message: "Run yarn install?", initialValue: true }) === false;
|
|
249
|
+
return {
|
|
250
|
+
projectName,
|
|
251
|
+
targetDir: resolve(cwd, projectName),
|
|
252
|
+
authProvider,
|
|
253
|
+
dbProvider,
|
|
254
|
+
upload,
|
|
255
|
+
ui: ui === "shadcn" ? "shadcn" : "shadcn",
|
|
256
|
+
// antd/mui fall back to shadcn for v0.1.0
|
|
257
|
+
transport,
|
|
258
|
+
initGit,
|
|
259
|
+
install
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
export {
|
|
263
|
+
collectOptions,
|
|
264
|
+
scaffold
|
|
265
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@idevconn/create-icore",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Bootstrap a new project from the iCore scaffold (Nx + NestJS + React + Vite + shadcn/Tailwind, swappable auth + storage providers).",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "iDEVconn",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/iDEVconn/create-icore.git",
|
|
10
|
+
"directory": "tools/create-icore"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/iDEVconn/create-icore/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/iDEVconn/create-icore#readme",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"icore",
|
|
19
|
+
"scaffold",
|
|
20
|
+
"bootstrap",
|
|
21
|
+
"nestjs",
|
|
22
|
+
"react",
|
|
23
|
+
"vite",
|
|
24
|
+
"shadcn",
|
|
25
|
+
"tailwind",
|
|
26
|
+
"supabase",
|
|
27
|
+
"firebase",
|
|
28
|
+
"cloudinary",
|
|
29
|
+
"tanstack-router",
|
|
30
|
+
"create-app"
|
|
31
|
+
],
|
|
32
|
+
"main": "./dist/index.cjs",
|
|
33
|
+
"module": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"exports": {
|
|
36
|
+
".": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"import": "./dist/index.js",
|
|
39
|
+
"require": "./dist/index.cjs"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"bin": "./dist/cli.js",
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"templates",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=20"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup",
|
|
54
|
+
"dev": "tsup --watch",
|
|
55
|
+
"test": "vitest run",
|
|
56
|
+
"test:watch": "vitest",
|
|
57
|
+
"lint": "eslint src",
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
59
|
+
"prepublishOnly": "npm run typecheck && npm run test && npm run build"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@clack/prompts": "^0.7.0",
|
|
63
|
+
"kleur": "^4.1.5"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"tsup": "^8.3.0",
|
|
67
|
+
"vitest": "^4.0.0"
|
|
68
|
+
},
|
|
69
|
+
"publishConfig": {
|
|
70
|
+
"access": "public"
|
|
71
|
+
}
|
|
72
|
+
}
|