@idealyst/cli 1.0.32 → 1.0.34
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/generators/api.js +28 -25
- package/dist/generators/api.js.map +1 -1
- package/dist/generators/index.js +33 -16
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/native.js +51 -48
- package/dist/generators/native.js.map +1 -1
- package/dist/generators/shared.js +25 -22
- package/dist/generators/shared.js.map +1 -1
- package/dist/generators/utils.js +146 -118
- package/dist/generators/utils.js.map +1 -1
- package/dist/generators/web.js +33 -30
- package/dist/generators/web.js.map +1 -1
- package/dist/generators/workspace.js +24 -21
- package/dist/generators/workspace.js.map +1 -1
- package/dist/index.js +82 -44
- package/dist/index.js.map +1 -1
- package/dist/templates/api/README.md +207 -0
- package/dist/templates/api/__tests__/api.test.ts +26 -0
- package/dist/templates/api/env.example +12 -0
- package/dist/templates/api/jest.config.js +23 -0
- package/dist/templates/api/jest.setup.js +9 -0
- package/dist/templates/api/package.json +62 -0
- package/dist/templates/api/prisma/schema.prisma +21 -0
- package/dist/templates/api/src/context.ts +23 -0
- package/dist/templates/api/src/controllers/UserController.ts +102 -0
- package/dist/templates/api/src/index.ts +14 -0
- package/dist/templates/api/src/lib/controller.ts +90 -0
- package/dist/templates/api/src/lib/middleware.ts +170 -0
- package/dist/templates/api/src/middleware/auth.ts +75 -0
- package/dist/templates/api/src/middleware/common.ts +103 -0
- package/dist/templates/api/src/router/index.ts +130 -0
- package/dist/templates/api/src/server.ts +50 -0
- package/dist/templates/api/src/trpc.ts +28 -0
- package/dist/templates/api/tsconfig.json +44 -0
- package/dist/templates/native/.yarnrc.yml +19 -0
- package/dist/templates/native/App.tsx +23 -0
- package/dist/templates/native/README.md +86 -0
- package/dist/templates/native/__tests__/App.test.tsx +156 -0
- package/dist/templates/native/__tests__/components.test.tsx +300 -0
- package/dist/templates/native/app.json +5 -0
- package/dist/templates/native/babel.config.js +10 -0
- package/dist/templates/native/index.js +6 -0
- package/dist/templates/native/jest.config.js +21 -0
- package/dist/templates/native/jest.setup.js +12 -0
- package/dist/templates/native/metro.config.js +27 -0
- package/dist/templates/native/package.json +44 -0
- package/dist/templates/native/src/App-with-trpc.tsx +59 -0
- package/dist/templates/native/src/utils/trpc.ts +127 -0
- package/dist/templates/native/tsconfig.json +30 -0
- package/dist/templates/shared/README.md +109 -0
- package/dist/templates/shared/__tests__/shared.test.ts +39 -0
- package/dist/templates/shared/jest.config.js +22 -0
- package/dist/templates/shared/package.json +50 -0
- package/dist/templates/shared/rollup.config.js +43 -0
- package/dist/templates/shared/src/index.ts +1 -0
- package/dist/templates/shared/tsconfig.json +25 -0
- package/dist/templates/web/README.md +90 -0
- package/dist/templates/web/__tests__/App.test.tsx +342 -0
- package/dist/templates/web/__tests__/components.test.tsx +564 -0
- package/dist/templates/web/index.html +13 -0
- package/dist/templates/web/jest.config.js +27 -0
- package/dist/templates/web/jest.setup.js +24 -0
- package/dist/templates/web/package.json +66 -0
- package/dist/templates/web/src/App-with-trpc.tsx +67 -0
- package/dist/templates/web/src/App.tsx +15 -0
- package/dist/templates/web/src/main.tsx +25 -0
- package/dist/templates/web/src/utils/trpc.ts +93 -0
- package/dist/templates/web/tsconfig.json +27 -0
- package/dist/templates/web/vite.config.ts +69 -0
- package/dist/templates/workspace/.devcontainer/devcontainer.json +140 -0
- package/dist/templates/workspace/.devcontainer/docker-compose.yml +74 -0
- package/dist/templates/workspace/.devcontainer/post-create.sh +89 -0
- package/dist/templates/workspace/.dockerignore +151 -0
- package/dist/templates/workspace/.env.example +36 -0
- package/dist/templates/workspace/.env.production +56 -0
- package/dist/templates/workspace/.yarnrc.yml +26 -0
- package/dist/templates/workspace/DOCKER.md +0 -0
- package/dist/templates/workspace/Dockerfile +93 -0
- package/dist/templates/workspace/README.md +179 -0
- package/dist/templates/workspace/docker/nginx/prod.conf +238 -0
- package/dist/templates/workspace/docker/nginx.conf +131 -0
- package/dist/templates/workspace/docker/postgres/init.sql +41 -0
- package/dist/templates/workspace/docker/prometheus/prometheus.yml +52 -0
- package/dist/templates/workspace/docker-compose.prod.yml +146 -0
- package/dist/templates/workspace/docker-compose.yml +144 -0
- package/dist/templates/workspace/jest.config.js +20 -0
- package/dist/templates/workspace/package.json +35 -0
- package/dist/templates/workspace/scripts/docker/db-backup.sh +230 -0
- package/dist/templates/workspace/scripts/docker/deploy.sh +212 -0
- package/dist/templates/workspace/scripts/docker-build.sh +151 -0
- package/dist/templates/workspace/scripts/test-runner.js +120 -0
- package/dist/templates/workspace/setup.sh +205 -0
- package/dist/types.js +2 -1
- package/package.json +3 -3
package/dist/generators/web.js
CHANGED
|
@@ -1,43 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateWebProject = generateWebProject;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
async function generateWebProject(options) {
|
|
8
11
|
const { name, directory, skipInstall, withTrpc } = options;
|
|
9
|
-
if (!validateProjectName(name)) {
|
|
12
|
+
if (!(0, utils_1.validateProjectName)(name)) {
|
|
10
13
|
throw new Error(`Invalid project name: ${name}`);
|
|
11
14
|
}
|
|
12
|
-
console.log(
|
|
13
|
-
const { projectPath, workspacePath, workspaceScope } = await resolveProjectPath(name, directory);
|
|
14
|
-
const templatePath =
|
|
15
|
-
const templateData = getTemplateData(name, `React web app built with Idealyst Framework`, undefined, workspaceScope || undefined);
|
|
16
|
-
await copyTemplate(templatePath, projectPath, templateData);
|
|
15
|
+
console.log(chalk_1.default.blue(`🌐 Creating React Web project: ${name}`));
|
|
16
|
+
const { projectPath, workspacePath, workspaceScope } = await (0, utils_1.resolveProjectPath)(name, directory);
|
|
17
|
+
const templatePath = path_1.default.join(__dirname, '..', 'templates', 'web');
|
|
18
|
+
const templateData = (0, utils_1.getTemplateData)(name, `React web app built with Idealyst Framework`, undefined, workspaceScope || undefined);
|
|
19
|
+
await (0, utils_1.copyTemplate)(templatePath, projectPath, templateData);
|
|
17
20
|
// Handle tRPC setup
|
|
18
21
|
if (withTrpc) {
|
|
19
|
-
await copyTrpcFiles(templatePath, projectPath, templateData);
|
|
20
|
-
await copyTrpcAppComponent(templatePath, projectPath, templateData);
|
|
22
|
+
await (0, utils_1.copyTrpcFiles)(templatePath, projectPath, templateData);
|
|
23
|
+
await (0, utils_1.copyTrpcAppComponent)(templatePath, projectPath, templateData);
|
|
21
24
|
}
|
|
22
25
|
else {
|
|
23
26
|
// Remove tRPC dependencies if not requested
|
|
24
|
-
await removeTrpcDependencies(projectPath);
|
|
27
|
+
await (0, utils_1.removeTrpcDependencies)(projectPath);
|
|
25
28
|
}
|
|
26
|
-
await installDependencies(projectPath, skipInstall);
|
|
27
|
-
await updateWorkspacePackageJson(workspacePath, directory);
|
|
28
|
-
console.log(
|
|
29
|
-
console.log(
|
|
30
|
-
console.log(
|
|
31
|
-
console.log(
|
|
32
|
-
console.log(
|
|
33
|
-
console.log(
|
|
34
|
-
console.log(
|
|
35
|
-
console.log(
|
|
36
|
-
console.log(
|
|
29
|
+
await (0, utils_1.installDependencies)(projectPath, skipInstall);
|
|
30
|
+
await (0, utils_1.updateWorkspacePackageJson)(workspacePath, directory);
|
|
31
|
+
console.log(chalk_1.default.green('✅ React Web project created successfully!'));
|
|
32
|
+
console.log(chalk_1.default.blue('📋 Project includes:'));
|
|
33
|
+
console.log(chalk_1.default.white(' • React 19.1'));
|
|
34
|
+
console.log(chalk_1.default.white(' • Vite build system'));
|
|
35
|
+
console.log(chalk_1.default.white(' • Idealyst Components'));
|
|
36
|
+
console.log(chalk_1.default.white(' • Idealyst Navigation'));
|
|
37
|
+
console.log(chalk_1.default.white(' • Idealyst Theme'));
|
|
38
|
+
console.log(chalk_1.default.white(' • TypeScript configuration'));
|
|
39
|
+
console.log(chalk_1.default.white(' • React Router'));
|
|
37
40
|
if (withTrpc) {
|
|
38
|
-
console.log(
|
|
39
|
-
console.log(
|
|
40
|
-
console.log(
|
|
41
|
+
console.log(chalk_1.default.white(' • tRPC client setup and utilities'));
|
|
42
|
+
console.log(chalk_1.default.white(' • React Query integration'));
|
|
43
|
+
console.log(chalk_1.default.white(' • Pre-configured tRPC provider'));
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
//# sourceMappingURL=web.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/generators/web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/generators/web.ts"],"names":[],"mappings":";;;;;AAKA,gDA0CC;AA/CD,gDAAwB;AACxB,kDAA0B;AAE1B,mCAA+M;AAExM,KAAK,UAAU,kBAAkB,CAAC,OAA+B;IACtE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE3D,IAAI,CAAC,IAAA,2BAAmB,EAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC,CAAC;IAElE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,MAAM,IAAA,0BAAkB,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjG,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;IAEpE,MAAM,YAAY,GAAG,IAAA,uBAAe,EAAC,IAAI,EAAE,6CAA6C,EAAE,SAAS,EAAE,cAAc,IAAI,SAAS,CAAC,CAAC;IAElI,MAAM,IAAA,oBAAY,EAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAE5D,oBAAoB;IACpB,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,IAAA,qBAAa,EAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;QAC7D,MAAM,IAAA,4BAAoB,EAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IACtE,CAAC;SAAM,CAAC;QACN,4CAA4C;QAC5C,MAAM,IAAA,8BAAsB,EAAC,WAAW,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,IAAA,2BAAmB,EAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACpD,MAAM,IAAA,kCAA0B,EAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAE3D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC7C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC"}
|
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateWorkspace = generateWorkspace;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
async function generateWorkspace(options) {
|
|
8
11
|
const { name, directory, skipInstall } = options;
|
|
9
|
-
if (!validateProjectName(name)) {
|
|
12
|
+
if (!(0, utils_1.validateProjectName)(name)) {
|
|
10
13
|
throw new Error(`Invalid project name: ${name}`);
|
|
11
14
|
}
|
|
12
|
-
console.log(
|
|
13
|
-
const projectPath =
|
|
14
|
-
const templatePath =
|
|
15
|
-
const templateData = getTemplateData(name, `Idealyst Framework monorepo workspace`);
|
|
16
|
-
await copyTemplate(templatePath, projectPath, templateData);
|
|
17
|
-
await installDependencies(projectPath, skipInstall);
|
|
18
|
-
console.log(
|
|
19
|
-
console.log(
|
|
20
|
-
console.log(
|
|
21
|
-
console.log(
|
|
22
|
-
console.log(
|
|
23
|
-
console.log(
|
|
24
|
-
console.log(
|
|
15
|
+
console.log(chalk_1.default.blue(`🏗️ Creating Idealyst workspace: ${name}`));
|
|
16
|
+
const projectPath = path_1.default.join(directory, name);
|
|
17
|
+
const templatePath = path_1.default.join(__dirname, '..', 'templates', 'workspace');
|
|
18
|
+
const templateData = (0, utils_1.getTemplateData)(name, `Idealyst Framework monorepo workspace`);
|
|
19
|
+
await (0, utils_1.copyTemplate)(templatePath, projectPath, templateData);
|
|
20
|
+
await (0, utils_1.installDependencies)(projectPath, skipInstall);
|
|
21
|
+
console.log(chalk_1.default.green('✅ Workspace created successfully!'));
|
|
22
|
+
console.log(chalk_1.default.blue('📋 Workspace includes:'));
|
|
23
|
+
console.log(chalk_1.default.white(' • Yarn workspace configuration'));
|
|
24
|
+
console.log(chalk_1.default.white(' • Idealyst packages (theme, components, navigation)'));
|
|
25
|
+
console.log(chalk_1.default.white(' • TypeScript configuration'));
|
|
26
|
+
console.log(chalk_1.default.white(' • Build scripts'));
|
|
27
|
+
console.log(chalk_1.default.white(' • Version management scripts'));
|
|
25
28
|
}
|
|
26
29
|
//# sourceMappingURL=workspace.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/generators/workspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/generators/workspace.ts"],"names":[],"mappings":";;;;;AAKA,8CAwBC;AA7BD,gDAAwB;AACxB,kDAA0B;AAE1B,mCAAkG;AAE3F,KAAK,UAAU,iBAAiB,CAAC,OAA+B;IACrE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAEjD,IAAI,CAAC,IAAA,2BAAmB,EAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEpE,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAE1E,MAAM,YAAY,GAAG,IAAA,uBAAe,EAAC,IAAI,EAAE,uCAAuC,CAAC,CAAC;IAEpF,MAAM,IAAA,oBAAY,EAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAC5D,MAAM,IAAA,2BAAmB,EAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAEpD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;AAC7D,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const index_1 = require("./generators/index");
|
|
43
|
+
const utils_1 = require("./generators/utils");
|
|
44
|
+
const program = new commander_1.Command();
|
|
7
45
|
program
|
|
8
46
|
.name('idealyst')
|
|
9
47
|
.description('CLI tool for generating Idealyst Framework projects')
|
|
@@ -20,14 +58,14 @@ program
|
|
|
20
58
|
try {
|
|
21
59
|
// Prompt for project name if not provided
|
|
22
60
|
if (!projectName) {
|
|
23
|
-
projectName = await promptForProjectName();
|
|
61
|
+
projectName = await (0, utils_1.promptForProjectName)();
|
|
24
62
|
}
|
|
25
63
|
else {
|
|
26
64
|
// Validate provided project name
|
|
27
|
-
const { validateProjectName } = await
|
|
65
|
+
const { validateProjectName } = await Promise.resolve().then(() => __importStar(require('./generators/utils')));
|
|
28
66
|
if (!validateProjectName(projectName.toLowerCase())) {
|
|
29
|
-
console.error(
|
|
30
|
-
console.error(
|
|
67
|
+
console.error(chalk_1.default.red(`Invalid project name: ${projectName}`));
|
|
68
|
+
console.error(chalk_1.default.yellow('Project name must be a valid npm package name (lowercase, no spaces)'));
|
|
31
69
|
process.exit(1);
|
|
32
70
|
}
|
|
33
71
|
projectName = projectName.toLowerCase();
|
|
@@ -35,25 +73,25 @@ program
|
|
|
35
73
|
// Prompt for project type if not provided
|
|
36
74
|
let projectType = options.type;
|
|
37
75
|
if (!projectType) {
|
|
38
|
-
projectType = await promptForProjectType();
|
|
76
|
+
projectType = await (0, utils_1.promptForProjectType)();
|
|
39
77
|
}
|
|
40
78
|
const validTypes = ['native', 'web', 'shared', 'api'];
|
|
41
79
|
if (!validTypes.includes(projectType)) {
|
|
42
|
-
console.error(
|
|
43
|
-
console.error(
|
|
80
|
+
console.error(chalk_1.default.red(`Invalid project type: ${projectType}`));
|
|
81
|
+
console.error(chalk_1.default.yellow(`Valid types are: ${validTypes.join(', ')}`));
|
|
44
82
|
process.exit(1);
|
|
45
83
|
}
|
|
46
84
|
// Prompt for app name if it's a native project and app name not provided
|
|
47
85
|
let appName = options.appName;
|
|
48
86
|
if (projectType === 'native' && !appName) {
|
|
49
|
-
appName = await promptForAppName(projectName);
|
|
87
|
+
appName = await (0, utils_1.promptForAppName)(projectName);
|
|
50
88
|
}
|
|
51
89
|
// Prompt for tRPC integration if it's a web/native project and flag not provided
|
|
52
90
|
let withTrpc = options.withTrpc;
|
|
53
91
|
if ((projectType === 'web' || projectType === 'native') && withTrpc === undefined) {
|
|
54
|
-
withTrpc = await promptForTrpcIntegration();
|
|
92
|
+
withTrpc = await (0, utils_1.promptForTrpcIntegration)();
|
|
55
93
|
}
|
|
56
|
-
await generateProject({
|
|
94
|
+
await (0, index_1.generateProject)({
|
|
57
95
|
name: projectName,
|
|
58
96
|
type: projectType,
|
|
59
97
|
directory: options.directory,
|
|
@@ -61,33 +99,33 @@ program
|
|
|
61
99
|
appName,
|
|
62
100
|
withTrpc: withTrpc || false
|
|
63
101
|
});
|
|
64
|
-
console.log(
|
|
65
|
-
console.log(
|
|
102
|
+
console.log(chalk_1.default.green(`✨ Successfully created ${projectName}!`));
|
|
103
|
+
console.log(chalk_1.default.blue(`📁 Project created in: ${options.directory}/packages/${projectName}`));
|
|
66
104
|
if (projectType === 'native') {
|
|
67
|
-
console.log(
|
|
68
|
-
console.log(
|
|
69
|
-
console.log(
|
|
105
|
+
console.log(chalk_1.default.yellow('\n📱 Next steps for React Native:'));
|
|
106
|
+
console.log(chalk_1.default.white(' cd packages/' + projectName));
|
|
107
|
+
console.log(chalk_1.default.white(' yarn android # or yarn ios'));
|
|
70
108
|
}
|
|
71
109
|
else if (projectType === 'web') {
|
|
72
|
-
console.log(
|
|
73
|
-
console.log(
|
|
74
|
-
console.log(
|
|
110
|
+
console.log(chalk_1.default.yellow('\n🌐 Next steps for React Web:'));
|
|
111
|
+
console.log(chalk_1.default.white(' cd packages/' + projectName));
|
|
112
|
+
console.log(chalk_1.default.white(' yarn dev'));
|
|
75
113
|
}
|
|
76
114
|
else if (projectType === 'api') {
|
|
77
|
-
console.log(
|
|
78
|
-
console.log(
|
|
79
|
-
console.log(
|
|
80
|
-
console.log(
|
|
81
|
-
console.log(
|
|
115
|
+
console.log(chalk_1.default.yellow('\n🚀 Next steps for API Server:'));
|
|
116
|
+
console.log(chalk_1.default.white(' cd packages/' + projectName));
|
|
117
|
+
console.log(chalk_1.default.white(' yarn dev # Start development server'));
|
|
118
|
+
console.log(chalk_1.default.white(' yarn db:push # Push database schema'));
|
|
119
|
+
console.log(chalk_1.default.white(' yarn db:studio # Open Prisma Studio'));
|
|
82
120
|
}
|
|
83
121
|
else {
|
|
84
|
-
console.log(
|
|
85
|
-
console.log(
|
|
86
|
-
console.log(
|
|
122
|
+
console.log(chalk_1.default.yellow('\n📦 Next steps for Shared Library:'));
|
|
123
|
+
console.log(chalk_1.default.white(' cd packages/' + projectName));
|
|
124
|
+
console.log(chalk_1.default.white(' yarn build'));
|
|
87
125
|
}
|
|
88
126
|
}
|
|
89
127
|
catch (error) {
|
|
90
|
-
console.error(
|
|
128
|
+
console.error(chalk_1.default.red('❌ Error creating project:'), error);
|
|
91
129
|
process.exit(1);
|
|
92
130
|
}
|
|
93
131
|
});
|
|
@@ -100,33 +138,33 @@ program
|
|
|
100
138
|
try {
|
|
101
139
|
// Prompt for project name if not provided
|
|
102
140
|
if (!projectName) {
|
|
103
|
-
projectName = await promptForProjectName();
|
|
141
|
+
projectName = await (0, utils_1.promptForProjectName)();
|
|
104
142
|
}
|
|
105
143
|
else {
|
|
106
144
|
// Validate provided project name
|
|
107
|
-
const { validateProjectName } = await
|
|
145
|
+
const { validateProjectName } = await Promise.resolve().then(() => __importStar(require('./generators/utils')));
|
|
108
146
|
if (!validateProjectName(projectName.toLowerCase())) {
|
|
109
|
-
console.error(
|
|
110
|
-
console.error(
|
|
147
|
+
console.error(chalk_1.default.red(`Invalid project name: ${projectName}`));
|
|
148
|
+
console.error(chalk_1.default.yellow('Project name must be a valid npm package name (lowercase, no spaces)'));
|
|
111
149
|
process.exit(1);
|
|
112
150
|
}
|
|
113
151
|
projectName = projectName.toLowerCase();
|
|
114
152
|
}
|
|
115
|
-
await generateProject({
|
|
153
|
+
await (0, index_1.generateProject)({
|
|
116
154
|
name: projectName,
|
|
117
155
|
type: 'workspace',
|
|
118
156
|
directory: options.directory,
|
|
119
157
|
skipInstall: options.skipInstall || false
|
|
120
158
|
});
|
|
121
|
-
console.log(
|
|
122
|
-
console.log(
|
|
123
|
-
console.log(
|
|
124
|
-
console.log(
|
|
125
|
-
console.log(
|
|
126
|
-
console.log(
|
|
159
|
+
console.log(chalk_1.default.green('✨ Successfully initialized Idealyst workspace!'));
|
|
160
|
+
console.log(chalk_1.default.blue(`📁 Workspace created in: ${options.directory}/${projectName}`));
|
|
161
|
+
console.log(chalk_1.default.yellow('\n🚀 Next steps:'));
|
|
162
|
+
console.log(chalk_1.default.white(` cd ${projectName}`));
|
|
163
|
+
console.log(chalk_1.default.white(' idealyst create my-app --type native'));
|
|
164
|
+
console.log(chalk_1.default.white(' idealyst create my-web-app --type web'));
|
|
127
165
|
}
|
|
128
166
|
catch (error) {
|
|
129
|
-
console.error(
|
|
167
|
+
console.error(chalk_1.default.red('❌ Error initializing workspace:'), error);
|
|
130
168
|
process.exit(1);
|
|
131
169
|
}
|
|
132
170
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
{{description}}
|
|
4
|
+
|
|
5
|
+
This API project is built with:
|
|
6
|
+
- **tRPC** - End-to-end typesafe APIs
|
|
7
|
+
- **Prisma** - Modern database toolkit
|
|
8
|
+
- **Zod** - TypeScript-first schema validation
|
|
9
|
+
- **Express.js** - Web framework for Node.js
|
|
10
|
+
- **TypeScript** - Type-safe JavaScript
|
|
11
|
+
|
|
12
|
+
## Quick Start
|
|
13
|
+
|
|
14
|
+
1. **Setup environment variables:**
|
|
15
|
+
```bash
|
|
16
|
+
cp env.example .env
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. **Install dependencies:**
|
|
20
|
+
```bash
|
|
21
|
+
yarn install
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3. **Setup database:**
|
|
25
|
+
```bash
|
|
26
|
+
# Generate Prisma client
|
|
27
|
+
yarn db:generate
|
|
28
|
+
|
|
29
|
+
# Push schema to database (for development)
|
|
30
|
+
yarn db:push
|
|
31
|
+
|
|
32
|
+
# Or run migrations (for production)
|
|
33
|
+
yarn db:migrate
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
4. **Start development server:**
|
|
37
|
+
```bash
|
|
38
|
+
yarn dev
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The API will be available at `http://localhost:3000`
|
|
42
|
+
|
|
43
|
+
## Available Scripts
|
|
44
|
+
|
|
45
|
+
- `yarn dev` - Start development server with hot reload
|
|
46
|
+
- `yarn build` - Build for production
|
|
47
|
+
- `yarn start` - Start production server
|
|
48
|
+
- `yarn db:generate` - Generate Prisma client
|
|
49
|
+
- `yarn db:push` - Push schema changes to database
|
|
50
|
+
- `yarn db:studio` - Open Prisma Studio (database GUI)
|
|
51
|
+
- `yarn db:migrate` - Run database migrations
|
|
52
|
+
- `yarn db:reset` - Reset database and run all migrations
|
|
53
|
+
- `yarn lint` - Run ESLint
|
|
54
|
+
- `yarn type-check` - Run TypeScript type checking
|
|
55
|
+
|
|
56
|
+
## API Endpoints
|
|
57
|
+
|
|
58
|
+
### tRPC Routes
|
|
59
|
+
|
|
60
|
+
All tRPC routes are available at `/trpc/[procedure]`
|
|
61
|
+
|
|
62
|
+
#### Example Routes
|
|
63
|
+
- `hello` - Simple greeting endpoint (accepts optional name parameter)
|
|
64
|
+
- `health` - API health check with timestamp
|
|
65
|
+
|
|
66
|
+
### REST Endpoints
|
|
67
|
+
- `GET /` - API information
|
|
68
|
+
- `GET /health` - Health check
|
|
69
|
+
|
|
70
|
+
## Database
|
|
71
|
+
|
|
72
|
+
This project uses SQLite by default for development. You can switch to PostgreSQL or MySQL by updating the `DATABASE_URL` in your `.env` file and the `provider` in `prisma/schema.prisma`.
|
|
73
|
+
|
|
74
|
+
### Database Schema
|
|
75
|
+
|
|
76
|
+
The schema starts empty - you can add your own models in `prisma/schema.prisma`. Example model structure is provided in comments.
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
### Adding New Routes
|
|
81
|
+
|
|
82
|
+
You can add routes in two ways:
|
|
83
|
+
|
|
84
|
+
#### 1. Simple tRPC Procedures (Traditional)
|
|
85
|
+
1. Create a new router file in `src/router/`
|
|
86
|
+
2. Define your procedures with Zod schemas for validation
|
|
87
|
+
3. Export the router and add it to `src/router/index.ts`
|
|
88
|
+
|
|
89
|
+
#### 2. Controller & Middleware System (Recommended)
|
|
90
|
+
This template includes a powerful controller and middleware system:
|
|
91
|
+
|
|
92
|
+
1. **Create a Controller:**
|
|
93
|
+
```typescript
|
|
94
|
+
// src/controllers/PostController.ts
|
|
95
|
+
import { z } from 'zod';
|
|
96
|
+
import { BaseController, controllerToRouter } from '../lib/controller.js';
|
|
97
|
+
import { requireAuth, requireAdmin } from '../middleware/auth.js';
|
|
98
|
+
import { logger, rateLimit } from '../middleware/common.js';
|
|
99
|
+
|
|
100
|
+
const createPostSchema = z.object({
|
|
101
|
+
title: z.string().min(1),
|
|
102
|
+
content: z.string(),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
export class PostController extends BaseController {
|
|
106
|
+
// Public endpoint
|
|
107
|
+
getAll = this.createQuery(
|
|
108
|
+
z.object({ published: z.boolean().optional() }),
|
|
109
|
+
async (input, ctx) => {
|
|
110
|
+
return ctx.prisma.post.findMany({
|
|
111
|
+
where: { published: input.published }
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// Protected endpoint with middleware
|
|
117
|
+
create = this.createMutationWithMiddleware(
|
|
118
|
+
createPostSchema,
|
|
119
|
+
[logger, rateLimit(5, 60000), requireAuth],
|
|
120
|
+
async (input, ctx) => {
|
|
121
|
+
return ctx.prisma.post.create({ data: input });
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// Admin-only endpoint
|
|
126
|
+
delete = this.createMutationWithMiddleware(
|
|
127
|
+
z.object({ id: z.string() }),
|
|
128
|
+
[requireAuth, requireAdmin],
|
|
129
|
+
async (input, ctx) => {
|
|
130
|
+
return ctx.prisma.post.delete({ where: { id: input.id } });
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export const postRouter = controllerToRouter({
|
|
136
|
+
getAll: new PostController({} as any).getAll,
|
|
137
|
+
create: new PostController({} as any).create,
|
|
138
|
+
delete: new PostController({} as any).delete,
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
2. **Add to Main Router:**
|
|
143
|
+
```typescript
|
|
144
|
+
// src/router/index.ts
|
|
145
|
+
import { postRouter } from '../controllers/PostController.js';
|
|
146
|
+
|
|
147
|
+
export const appRouter = router({
|
|
148
|
+
posts: postRouter,
|
|
149
|
+
// ... other routes
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Available Middleware
|
|
154
|
+
|
|
155
|
+
#### Authentication
|
|
156
|
+
- `requireAuth` - Requires Bearer token authentication
|
|
157
|
+
- `requireRole(role)` - Requires specific user role
|
|
158
|
+
- `requireAdmin` - Requires admin role
|
|
159
|
+
|
|
160
|
+
#### Utility Middleware
|
|
161
|
+
- `logger` - Request/response logging with timing
|
|
162
|
+
- `rateLimit(maxRequests, windowMs)` - Rate limiting per IP
|
|
163
|
+
- `responseTime` - Adds X-Response-Time header
|
|
164
|
+
- `requestId` - Adds unique X-Request-ID header
|
|
165
|
+
- `errorHandler` - Centralized error handling
|
|
166
|
+
|
|
167
|
+
### Example tRPC Client Usage
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
|
171
|
+
import type { AppRouter } from './path/to/your/api';
|
|
172
|
+
|
|
173
|
+
const client = createTRPCProxyClient<AppRouter>({
|
|
174
|
+
links: [
|
|
175
|
+
httpBatchLink({
|
|
176
|
+
url: 'http://localhost:3000/trpc',
|
|
177
|
+
}),
|
|
178
|
+
],
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Use the client
|
|
182
|
+
const greeting = await client.hello.query({ name: 'John' });
|
|
183
|
+
const healthStatus = await client.health.query();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Environment Variables
|
|
187
|
+
|
|
188
|
+
Copy `env.example` to `.env` and configure:
|
|
189
|
+
|
|
190
|
+
- `DATABASE_URL` - Database connection string
|
|
191
|
+
- `PORT` - Server port (default: 3000)
|
|
192
|
+
- `NODE_ENV` - Environment (development/production)
|
|
193
|
+
- `CORS_ORIGIN` - CORS origin for client requests
|
|
194
|
+
|
|
195
|
+
## Deployment
|
|
196
|
+
|
|
197
|
+
1. Build the project: `yarn build`
|
|
198
|
+
2. Set up your production database
|
|
199
|
+
3. Run migrations: `yarn db:migrate`
|
|
200
|
+
4. Start the server: `yarn start`
|
|
201
|
+
|
|
202
|
+
## Learn More
|
|
203
|
+
|
|
204
|
+
- [tRPC Documentation](https://trpc.io/)
|
|
205
|
+
- [Prisma Documentation](https://www.prisma.io/docs/)
|
|
206
|
+
- [Zod Documentation](https://zod.dev/)
|
|
207
|
+
- [Express.js Documentation](https://expressjs.com/)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, it, expect } from '@jest/globals';
|
|
2
|
+
import { appRouter } from '../src/router/index.js';
|
|
3
|
+
|
|
4
|
+
describe('API Router', () => {
|
|
5
|
+
it('should have a valid router configuration', () => {
|
|
6
|
+
expect(appRouter).toBeDefined();
|
|
7
|
+
expect(typeof appRouter).toBe('object');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('should export the expected router structure', () => {
|
|
11
|
+
// Test that the router has the expected structure
|
|
12
|
+
expect(appRouter._def).toBeDefined();
|
|
13
|
+
expect(appRouter._def.router).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('Sample API Test', () => {
|
|
18
|
+
it('should pass a basic test', () => {
|
|
19
|
+
expect(1 + 1).toBe(2);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should handle async operations', async () => {
|
|
23
|
+
const result = await Promise.resolve('test');
|
|
24
|
+
expect(result).toBe('test');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Database
|
|
2
|
+
DATABASE_URL="file:./dev.db"
|
|
3
|
+
|
|
4
|
+
# Server
|
|
5
|
+
PORT=3000
|
|
6
|
+
NODE_ENV=development
|
|
7
|
+
|
|
8
|
+
# CORS
|
|
9
|
+
CORS_ORIGIN="http://localhost:3000"
|
|
10
|
+
|
|
11
|
+
# Optional: Database for production (uncomment and configure as needed)
|
|
12
|
+
# DATABASE_URL="postgresql://username:password@localhost:5432/{{projectName}}"
|