@forinda/kickjs-cli 0.6.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -51,12 +51,14 @@ interface GenerateDtoOptions {
51
51
  }
52
52
  declare function generateDto(options: GenerateDtoOptions): Promise<string[]>;
53
53
 
54
+ type ProjectTemplate = 'rest' | 'graphql' | 'ddd' | 'microservice' | 'minimal';
54
55
  interface InitProjectOptions {
55
56
  name: string;
56
57
  directory: string;
57
58
  packageManager?: 'pnpm' | 'npm' | 'yarn';
58
59
  initGit?: boolean;
59
60
  installDeps?: boolean;
61
+ template?: ProjectTemplate;
60
62
  }
61
63
  /** Scaffold a new KickJS project */
62
64
  declare function initProject(options: InitProjectOptions): Promise<void>;
@@ -79,14 +81,42 @@ interface KickCommandDefinition {
79
81
  /** Optional aliases (e.g. ['migrate'] for 'db:migrate') */
80
82
  aliases?: string[];
81
83
  }
84
+ /** Project pattern — controls what generators produce and which deps are installed */
85
+ type ProjectPattern = 'rest' | 'graphql' | 'ddd' | 'microservice' | 'minimal';
82
86
  /** Configuration for the kick.config.ts file */
83
87
  interface KickConfig {
88
+ /**
89
+ * Project pattern — controls default generator behavior.
90
+ * - 'rest' — Express + Swagger (default)
91
+ * - 'graphql' — GraphQL + GraphiQL
92
+ * - 'ddd' — Full DDD modules with use cases, entities, value objects
93
+ * - 'microservice' — REST + queue workers
94
+ * - 'minimal' — Bare Express with no scaffolding
95
+ */
96
+ pattern?: ProjectPattern;
84
97
  /** Where modules live (default: 'src/modules') */
85
98
  modulesDir?: string;
86
99
  /** Default repository implementation for generators */
87
100
  defaultRepo?: 'drizzle' | 'inmemory' | 'prisma';
88
101
  /** Drizzle schema output directory */
89
102
  schemaDir?: string;
103
+ /**
104
+ * Directories to copy to dist/ after build.
105
+ * Useful for EJS templates, email templates, static assets, etc.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * copyDirs: [
110
+ * 'src/views', // copies to dist/src/views
111
+ * { src: 'src/views', dest: 'dist/views' }, // custom dest
112
+ * 'src/emails',
113
+ * ]
114
+ * ```
115
+ */
116
+ copyDirs?: Array<string | {
117
+ src: string;
118
+ dest?: string;
119
+ }>;
90
120
  /** Custom commands that extend the CLI */
91
121
  commands?: KickCommandDefinition[];
92
122
  /** Code style overrides (auto-detected from prettier when possible) */
package/dist/index.js CHANGED
@@ -1043,17 +1043,46 @@ export type ${pascal}DTO = z.infer<typeof ${camel}Schema>
1043
1043
  __name(generateDto, "generateDto");
1044
1044
 
1045
1045
  // src/generators/project.ts
1046
- import { join as join8 } from "path";
1046
+ import { join as join8, dirname as dirname2 } from "path";
1047
1047
  import { execSync } from "child_process";
1048
+ import { readFileSync } from "fs";
1049
+ import { fileURLToPath } from "url";
1050
+ var __dirname = dirname2(fileURLToPath(import.meta.url));
1051
+ var cliPkg = JSON.parse(readFileSync(join8(__dirname, "..", "package.json"), "utf-8"));
1052
+ var KICKJS_VERSION = `^${cliPkg.version}`;
1048
1053
  async function initProject(options) {
1049
- const { name, directory, packageManager = "pnpm" } = options;
1054
+ const { name, directory, packageManager = "pnpm", template = "rest" } = options;
1050
1055
  const dir = directory;
1051
1056
  console.log(`
1052
1057
  Creating KickJS project: ${name}
1053
1058
  `);
1059
+ const baseDeps = {
1060
+ "@forinda/kickjs-core": KICKJS_VERSION,
1061
+ "@forinda/kickjs-http": KICKJS_VERSION,
1062
+ "@forinda/kickjs-config": KICKJS_VERSION,
1063
+ express: "^5.1.0",
1064
+ "reflect-metadata": "^0.2.2",
1065
+ zod: "^4.3.6",
1066
+ pino: "^10.3.1",
1067
+ "pino-pretty": "^13.1.3"
1068
+ };
1069
+ if (template !== "minimal") {
1070
+ baseDeps["@forinda/kickjs-swagger"] = KICKJS_VERSION;
1071
+ }
1072
+ if (template === "graphql") {
1073
+ baseDeps["@forinda/kickjs-graphql"] = KICKJS_VERSION;
1074
+ baseDeps["graphql"] = "^16.11.0";
1075
+ }
1076
+ if (template === "microservice") {
1077
+ baseDeps["@forinda/kickjs-queue"] = KICKJS_VERSION;
1078
+ baseDeps["@forinda/kickjs-otel"] = KICKJS_VERSION;
1079
+ }
1080
+ if (template === "ddd") {
1081
+ baseDeps["@forinda/kickjs-swagger"] = KICKJS_VERSION;
1082
+ }
1054
1083
  await writeFileSafe(join8(dir, "package.json"), JSON.stringify({
1055
1084
  name,
1056
- version: "0.1.0",
1085
+ version: cliPkg.version,
1057
1086
  type: "module",
1058
1087
  scripts: {
1059
1088
  dev: "kick dev",
@@ -1066,19 +1095,9 @@ async function initProject(options) {
1066
1095
  lint: "eslint src/",
1067
1096
  format: "prettier --write src/"
1068
1097
  },
1069
- dependencies: {
1070
- "@forinda/kickjs-core": "^0.1.0",
1071
- "@forinda/kickjs-http": "^0.1.0",
1072
- "@forinda/kickjs-config": "^0.1.0",
1073
- "@forinda/kickjs-swagger": "^0.1.0",
1074
- express: "^5.1.0",
1075
- "reflect-metadata": "^0.2.2",
1076
- zod: "^4.3.6",
1077
- pino: "^10.3.1",
1078
- "pino-pretty": "^13.1.3"
1079
- },
1098
+ dependencies: baseDeps,
1080
1099
  devDependencies: {
1081
- "@forinda/kickjs-cli": "^0.1.0",
1100
+ "@forinda/kickjs-cli": KICKJS_VERSION,
1082
1101
  "@swc/core": "^1.7.28",
1083
1102
  "@types/express": "^5.0.6",
1084
1103
  "@types/node": "^24.5.2",
@@ -1167,27 +1186,18 @@ NODE_ENV=development
1167
1186
  await writeFileSafe(join8(dir, ".env.example"), `PORT=3000
1168
1187
  NODE_ENV=development
1169
1188
  `);
1170
- await writeFileSafe(join8(dir, "src/index.ts"), `import 'reflect-metadata'
1171
- import { bootstrap } from '@forinda/kickjs-http'
1172
- import { SwaggerAdapter } from '@forinda/kickjs-swagger'
1173
- import { modules } from './modules'
1174
-
1175
- bootstrap({
1176
- modules,
1177
- adapters: [
1178
- new SwaggerAdapter({
1179
- info: { title: '${name}', version: '0.1.0' },
1180
- }),
1181
- ],
1182
- })
1183
- `);
1189
+ await writeFileSafe(join8(dir, "src/index.ts"), getEntryFile(name, template));
1184
1190
  await writeFileSafe(join8(dir, "src/modules/index.ts"), `import type { AppModuleClass } from '@forinda/kickjs-core'
1185
1191
 
1186
1192
  export const modules: AppModuleClass[] = []
1187
1193
  `);
1194
+ if (template === "graphql") {
1195
+ await writeFileSafe(join8(dir, "src/resolvers/.gitkeep"), "");
1196
+ }
1188
1197
  await writeFileSafe(join8(dir, "kick.config.ts"), `import { defineConfig } from '@forinda/kickjs-cli'
1189
1198
 
1190
1199
  export default defineConfig({
1200
+ pattern: '${template}',
1191
1201
  modulesDir: 'src/modules',
1192
1202
  defaultRepo: 'inmemory',
1193
1203
 
@@ -1268,17 +1278,103 @@ export default defineConfig({
1268
1278
  console.log(" Next steps:");
1269
1279
  if (needsCd) console.log(` cd ${name}`);
1270
1280
  if (!options.installDeps) console.log(` ${packageManager} install`);
1271
- console.log(" kick g module user");
1281
+ const genHint = {
1282
+ rest: "kick g module user",
1283
+ graphql: "kick g resolver user",
1284
+ ddd: "kick g module user --repo drizzle",
1285
+ microservice: "kick g module user && kick g job email",
1286
+ minimal: "# add your routes to src/index.ts"
1287
+ };
1288
+ console.log(` ${genHint[template] ?? genHint.rest}`);
1272
1289
  console.log(" kick dev");
1273
1290
  console.log();
1274
1291
  console.log(" Commands:");
1275
1292
  console.log(" kick dev Start dev server with Vite HMR");
1276
1293
  console.log(" kick build Production build via Vite");
1277
1294
  console.log(" kick start Run production build");
1278
- console.log(" kick g module X Generate a DDD module");
1295
+ console.log(` kick g module X Generate a DDD module`);
1296
+ if (template === "graphql") console.log(" kick g resolver X Generate a GraphQL resolver");
1297
+ if (template === "microservice") console.log(" kick g job X Generate a queue job processor");
1279
1298
  console.log();
1280
1299
  }
1281
1300
  __name(initProject, "initProject");
1301
+ function getEntryFile(name, template) {
1302
+ switch (template) {
1303
+ case "graphql":
1304
+ return `import 'reflect-metadata'
1305
+ import { bootstrap } from '@forinda/kickjs-http'
1306
+ import { DevToolsAdapter } from '@forinda/kickjs-http/devtools'
1307
+ import { GraphQLAdapter } from '@forinda/kickjs-graphql'
1308
+ import { modules } from './modules'
1309
+
1310
+ // Import your resolvers here
1311
+ // import { UserResolver } from './resolvers/user.resolver'
1312
+
1313
+ bootstrap({
1314
+ modules,
1315
+ adapters: [
1316
+ new DevToolsAdapter(),
1317
+ new GraphQLAdapter({
1318
+ resolvers: [/* UserResolver */],
1319
+ // Add custom type definitions here:
1320
+ // typeDefs: userTypeDefs,
1321
+ }),
1322
+ ],
1323
+ })
1324
+ `;
1325
+ case "microservice":
1326
+ return `import 'reflect-metadata'
1327
+ import { bootstrap } from '@forinda/kickjs-http'
1328
+ import { DevToolsAdapter } from '@forinda/kickjs-http/devtools'
1329
+ import { SwaggerAdapter } from '@forinda/kickjs-swagger'
1330
+ import { OtelAdapter } from '@forinda/kickjs-otel'
1331
+ // import { QueueAdapter, BullMQProvider } from '@forinda/kickjs-queue'
1332
+ import { modules } from './modules'
1333
+
1334
+ bootstrap({
1335
+ modules,
1336
+ adapters: [
1337
+ new OtelAdapter({ serviceName: '${name}' }),
1338
+ new DevToolsAdapter(),
1339
+ new SwaggerAdapter({
1340
+ info: { title: '${name}', version: '${cliPkg.version}' },
1341
+ }),
1342
+ // Uncomment when Redis is available:
1343
+ // new QueueAdapter({
1344
+ // provider: new BullMQProvider({ host: 'localhost', port: 6379 }),
1345
+ // }),
1346
+ ],
1347
+ })
1348
+ `;
1349
+ case "minimal":
1350
+ return `import 'reflect-metadata'
1351
+ import { bootstrap } from '@forinda/kickjs-http'
1352
+ import { modules } from './modules'
1353
+
1354
+ bootstrap({ modules })
1355
+ `;
1356
+ case "ddd":
1357
+ case "rest":
1358
+ default:
1359
+ return `import 'reflect-metadata'
1360
+ import { bootstrap } from '@forinda/kickjs-http'
1361
+ import { DevToolsAdapter } from '@forinda/kickjs-http/devtools'
1362
+ import { SwaggerAdapter } from '@forinda/kickjs-swagger'
1363
+ import { modules } from './modules'
1364
+
1365
+ bootstrap({
1366
+ modules,
1367
+ adapters: [
1368
+ new DevToolsAdapter(),
1369
+ new SwaggerAdapter({
1370
+ info: { title: '${name}', version: '${cliPkg.version}' },
1371
+ }),
1372
+ ],
1373
+ })
1374
+ `;
1375
+ }
1376
+ }
1377
+ __name(getEntryFile, "getEntryFile");
1282
1378
 
1283
1379
  // src/config.ts
1284
1380
  import { readFile as readFile3, access as access2 } from "fs/promises";