@forinda/kickjs-cli 0.7.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
@@ -1051,11 +1051,35 @@ var __dirname = dirname2(fileURLToPath(import.meta.url));
1051
1051
  var cliPkg = JSON.parse(readFileSync(join8(__dirname, "..", "package.json"), "utf-8"));
1052
1052
  var KICKJS_VERSION = `^${cliPkg.version}`;
1053
1053
  async function initProject(options) {
1054
- const { name, directory, packageManager = "pnpm" } = options;
1054
+ const { name, directory, packageManager = "pnpm", template = "rest" } = options;
1055
1055
  const dir = directory;
1056
1056
  console.log(`
1057
1057
  Creating KickJS project: ${name}
1058
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
+ }
1059
1083
  await writeFileSafe(join8(dir, "package.json"), JSON.stringify({
1060
1084
  name,
1061
1085
  version: cliPkg.version,
@@ -1071,17 +1095,7 @@ async function initProject(options) {
1071
1095
  lint: "eslint src/",
1072
1096
  format: "prettier --write src/"
1073
1097
  },
1074
- dependencies: {
1075
- "@forinda/kickjs-core": KICKJS_VERSION,
1076
- "@forinda/kickjs-http": KICKJS_VERSION,
1077
- "@forinda/kickjs-config": KICKJS_VERSION,
1078
- "@forinda/kickjs-swagger": KICKJS_VERSION,
1079
- express: "^5.1.0",
1080
- "reflect-metadata": "^0.2.2",
1081
- zod: "^4.3.6",
1082
- pino: "^10.3.1",
1083
- "pino-pretty": "^13.1.3"
1084
- },
1098
+ dependencies: baseDeps,
1085
1099
  devDependencies: {
1086
1100
  "@forinda/kickjs-cli": KICKJS_VERSION,
1087
1101
  "@swc/core": "^1.7.28",
@@ -1172,27 +1186,18 @@ NODE_ENV=development
1172
1186
  await writeFileSafe(join8(dir, ".env.example"), `PORT=3000
1173
1187
  NODE_ENV=development
1174
1188
  `);
1175
- await writeFileSafe(join8(dir, "src/index.ts"), `import 'reflect-metadata'
1176
- import { bootstrap } from '@forinda/kickjs-http'
1177
- import { SwaggerAdapter } from '@forinda/kickjs-swagger'
1178
- import { modules } from './modules'
1179
-
1180
- bootstrap({
1181
- modules,
1182
- adapters: [
1183
- new SwaggerAdapter({
1184
- info: { title: '${name}', version: '${cliPkg.version}' },
1185
- }),
1186
- ],
1187
- })
1188
- `);
1189
+ await writeFileSafe(join8(dir, "src/index.ts"), getEntryFile(name, template));
1189
1190
  await writeFileSafe(join8(dir, "src/modules/index.ts"), `import type { AppModuleClass } from '@forinda/kickjs-core'
1190
1191
 
1191
1192
  export const modules: AppModuleClass[] = []
1192
1193
  `);
1194
+ if (template === "graphql") {
1195
+ await writeFileSafe(join8(dir, "src/resolvers/.gitkeep"), "");
1196
+ }
1193
1197
  await writeFileSafe(join8(dir, "kick.config.ts"), `import { defineConfig } from '@forinda/kickjs-cli'
1194
1198
 
1195
1199
  export default defineConfig({
1200
+ pattern: '${template}',
1196
1201
  modulesDir: 'src/modules',
1197
1202
  defaultRepo: 'inmemory',
1198
1203
 
@@ -1273,17 +1278,103 @@ export default defineConfig({
1273
1278
  console.log(" Next steps:");
1274
1279
  if (needsCd) console.log(` cd ${name}`);
1275
1280
  if (!options.installDeps) console.log(` ${packageManager} install`);
1276
- 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}`);
1277
1289
  console.log(" kick dev");
1278
1290
  console.log();
1279
1291
  console.log(" Commands:");
1280
1292
  console.log(" kick dev Start dev server with Vite HMR");
1281
1293
  console.log(" kick build Production build via Vite");
1282
1294
  console.log(" kick start Run production build");
1283
- 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");
1284
1298
  console.log();
1285
1299
  }
1286
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");
1287
1378
 
1288
1379
  // src/config.ts
1289
1380
  import { readFile as readFile3, access as access2 } from "fs/promises";