@skalfa/skalfa-api-core 1.0.7 → 1.0.8

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.
Files changed (39) hide show
  1. package/dist/commands/cli.js +16 -27
  2. package/dist/commands/cli.js.map +1 -1
  3. package/dist/commands/make/resource.js +4 -4
  4. package/dist/commands/make/resource.js.map +1 -1
  5. package/dist/commands/make/skalfa-controller.d.ts +2 -2
  6. package/dist/commands/make/skalfa-controller.js +7 -7
  7. package/dist/commands/make/skalfa-controller.js.map +1 -1
  8. package/dist/commands/make/skalfa-model.d.ts +2 -2
  9. package/dist/commands/make/skalfa-model.js +9 -9
  10. package/dist/commands/make/skalfa-model.js.map +1 -1
  11. package/dist/commands/runner/blueprint/controller-generation.js +2 -2
  12. package/dist/commands/runner/blueprint/controller-generation.js.map +1 -1
  13. package/dist/commands/runner/blueprint/migration-generation.js +2 -2
  14. package/dist/commands/runner/blueprint/migration-generation.js.map +1 -1
  15. package/dist/commands/runner/blueprint/model-generation.js +2 -2
  16. package/dist/commands/runner/blueprint/model-generation.js.map +1 -1
  17. package/dist/commands/runner/blueprint/runner.js +5 -6
  18. package/dist/commands/runner/blueprint/runner.js.map +1 -1
  19. package/dist/commands/runner/blueprint/seeder-generation.js +2 -2
  20. package/dist/commands/runner/blueprint/seeder-generation.js.map +1 -1
  21. package/dist/commands/runner/generate-docs.d.ts +2 -0
  22. package/dist/commands/runner/generate-docs.js +400 -0
  23. package/dist/commands/runner/generate-docs.js.map +1 -0
  24. package/dist/commands/stubs/index.d.ts +4 -4
  25. package/dist/commands/stubs/index.js +4 -4
  26. package/dist/commands/stubs/index.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/commands/cli.ts +17 -29
  29. package/src/commands/make/basic-controller.ts +1 -1
  30. package/src/commands/make/resource.ts +4 -4
  31. package/src/commands/make/skalfa-controller.ts +7 -7
  32. package/src/commands/make/skalfa-model.ts +9 -9
  33. package/src/commands/runner/blueprint/controller-generation.ts +2 -2
  34. package/src/commands/runner/blueprint/migration-generation.ts +2 -2
  35. package/src/commands/runner/blueprint/model-generation.ts +2 -2
  36. package/src/commands/runner/blueprint/runner.ts +5 -6
  37. package/src/commands/runner/blueprint/seeder-generation.ts +2 -2
  38. package/src/commands/runner/generate-docs.ts +495 -0
  39. package/src/commands/stubs/index.ts +4 -4
@@ -0,0 +1,400 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { Command } from "commander";
4
+ // Helper to recursively find files with specific extensions
5
+ function getFiles(dir, extList) {
6
+ let results = [];
7
+ if (!fs.existsSync(dir))
8
+ return results;
9
+ const list = fs.readdirSync(dir);
10
+ for (const file of list) {
11
+ const filePath = path.join(dir, file);
12
+ const stat = fs.statSync(filePath);
13
+ if (stat.isDirectory()) {
14
+ if (file !== "node_modules" && file !== ".next" && file !== ".git") {
15
+ results = results.concat(getFiles(filePath, extList));
16
+ }
17
+ }
18
+ else {
19
+ if (extList.includes(path.extname(file))) {
20
+ results.push(filePath);
21
+ }
22
+ }
23
+ }
24
+ return results;
25
+ }
26
+ // Simple parser for object literal string (e.g. c.validation block)
27
+ function parseObjectLiteral(str) {
28
+ const result = {};
29
+ // Strip single-line and multi-line comments
30
+ const cleanStr = str
31
+ .replace(/\/\*[\s\S]*?\*\//g, "")
32
+ .replace(/\/\/.*$/gm, "");
33
+ // Regex to match key: value
34
+ const regex = /(?:(\w+)|["']([^"']+)["'])\s*:\s*([^,}\n]+)/g;
35
+ let match;
36
+ while ((match = regex.exec(cleanStr)) !== null) {
37
+ const key = match[1] || match[2];
38
+ const val = match[3].trim().replace(/['"\[\]]/g, "").replace(/\s+/g, " ");
39
+ result[key] = val;
40
+ }
41
+ return result;
42
+ }
43
+ export const generateDocsCommand = new Command("generate:docs")
44
+ .description("Generate API Markdown documentation from routes, controllers, and models")
45
+ .option("-p, --path <path>", "Filter by specific route path (e.g. --path=/users)")
46
+ .action(async (options) => {
47
+ const projectRoot = process.cwd();
48
+ const filterPath = options.path;
49
+ console.log(`🔍 Scanning project in: ${projectRoot}`);
50
+ if (filterPath) {
51
+ console.log(`Filter path: ${filterPath}`);
52
+ }
53
+ // 1. Parse Models
54
+ const modelFiles = getFiles(path.join(projectRoot, "app", "models"), [".ts"]);
55
+ const models = {};
56
+ for (const file of modelFiles) {
57
+ const content = fs.readFileSync(file, "utf8");
58
+ // Find class User extends Model
59
+ const classMatch = /class\s+(\w+)\s+extends\s+Model/g.exec(content);
60
+ if (!classMatch)
61
+ continue;
62
+ const modelName = classMatch[1];
63
+ const fields = [];
64
+ const relations = [];
65
+ // Parse fields: @Field(["fillable", "selectable", "searchable"]) name!: string
66
+ const fieldRegex = /@Field\(\s*\[([\s\S]*?)\]\s*\)\s*(\w+)\s*!?:?\s*(\w+)/g;
67
+ let fieldMatch;
68
+ while ((fieldMatch = fieldRegex.exec(content)) !== null) {
69
+ const decorators = fieldMatch[1]
70
+ .split(",")
71
+ .map((d) => d.trim().replace(/['"]/g, ""))
72
+ .filter(Boolean);
73
+ fields.push({
74
+ name: fieldMatch[2],
75
+ type: fieldMatch[3],
76
+ decorators,
77
+ });
78
+ }
79
+ // Parse relations: @HasMany(() => Role, "user_id") roles!: Role[]
80
+ const relationRegex = /@(HasMany|HasOne|BelongsTo)\(\s*\(\s*\)\s*=>\s*(\w+)[^]*?\)\s*(\w+)/g;
81
+ let relationMatch;
82
+ while ((relationMatch = relationRegex.exec(content)) !== null) {
83
+ relations.push({
84
+ type: relationMatch[1],
85
+ targetModel: relationMatch[2],
86
+ name: relationMatch[3],
87
+ });
88
+ }
89
+ models[modelName] = {
90
+ name: modelName,
91
+ fields,
92
+ relations,
93
+ };
94
+ }
95
+ // 2. Parse Controllers
96
+ const controllerFiles = getFiles(path.join(projectRoot, "app", "controllers"), [".ts"]);
97
+ const controllers = {};
98
+ for (const file of controllerFiles) {
99
+ const content = fs.readFileSync(file, "utf8");
100
+ const classMatch = /class\s+(\w+)/g.exec(content);
101
+ if (!classMatch)
102
+ continue;
103
+ const controllerName = classMatch[1];
104
+ const methods = {};
105
+ // Simple method splitter by looking for static async or static methods
106
+ const methodRegex = /static\s+(?:async\s+)?(\w+)\s*\(\s*c\s*:\s*(\w+|any)\s*\)\s*\{([\s\S]*?)(?=\s+static|\s+\/\/|\s*\}\s*$)/g;
107
+ let methodMatch;
108
+ while ((methodMatch = methodRegex.exec(content)) !== null) {
109
+ const methodName = methodMatch[1];
110
+ const body = methodMatch[3];
111
+ const isMagicResolve = body.includes(".resolve(c)");
112
+ const isMagicPump = body.includes(".pump(");
113
+ // Parse c.validation<ModelName>({ ... })
114
+ let validationModel;
115
+ let validationRules = {};
116
+ const valRegex = /c\.validation(?:<(\w+)>)?\(\s*(\{[\s\S]*?\})\s*\)/g;
117
+ const valMatch = valRegex.exec(body);
118
+ if (valMatch) {
119
+ validationModel = valMatch[1];
120
+ validationRules = parseObjectLiteral(valMatch[2]);
121
+ }
122
+ // Parse custom query parameters: c.getQuery.field, c.query.field, or destructuring
123
+ const customQueryParams = [];
124
+ const queryFieldRegex = /\bc\.(?:getQuery|query)\.(\w+)\b/g;
125
+ let qfMatch;
126
+ while ((qfMatch = queryFieldRegex.exec(body)) !== null) {
127
+ customQueryParams.push(qfMatch[1]);
128
+ }
129
+ // Destructuring: const { a, b } = c.getQuery
130
+ const queryDestructRegex = /const\s*\{\s*([\w\s,]+)\s*\}\s*=\s*c\.(?:getQuery|query)/g;
131
+ let qdMatch;
132
+ while ((qdMatch = queryDestructRegex.exec(body)) !== null) {
133
+ qdMatch[1].split(",").forEach((p) => {
134
+ const trimmed = p.trim();
135
+ if (trimmed)
136
+ customQueryParams.push(trimmed);
137
+ });
138
+ }
139
+ // Parse custom payload fields: c.payload.field, c.body.field, or destructuring
140
+ const customPayloadFields = [];
141
+ const payloadFieldRegex = /\bc\.(?:payload|body)\.(\w+)\b/g;
142
+ let pfMatch;
143
+ while ((pfMatch = payloadFieldRegex.exec(body)) !== null) {
144
+ customPayloadFields.push(pfMatch[1]);
145
+ }
146
+ const payloadDestructRegex = /const\s*\{\s*([\w\s,]+)\s*\}\s*=\s*c\.(?:payload|body)/g;
147
+ let pdMatch;
148
+ while ((pdMatch = payloadDestructRegex.exec(body)) !== null) {
149
+ pdMatch[1].split(",").forEach((p) => {
150
+ const trimmed = p.trim();
151
+ if (trimmed)
152
+ customPayloadFields.push(trimmed);
153
+ });
154
+ }
155
+ methods[methodName] = {
156
+ methodName,
157
+ isMagicResolve,
158
+ isMagicPump,
159
+ validationModel,
160
+ validationRules,
161
+ customQueryParams: Array.from(new Set(customQueryParams)),
162
+ customPayloadFields: Array.from(new Set(customPayloadFields)),
163
+ };
164
+ }
165
+ controllers[controllerName] = {
166
+ name: controllerName,
167
+ methods,
168
+ };
169
+ }
170
+ // 3. Parse Routes
171
+ const routeFiles = getFiles(path.join(projectRoot, "app", "routes"), [".ts"]);
172
+ const routesList = [];
173
+ for (const file of routeFiles) {
174
+ const content = fs.readFileSync(file, "utf8");
175
+ const filename = path.basename(file);
176
+ // We want to find Elysia route registrations and api() helper registrations
177
+ // Group: app.group('/api', (route) => { ... })
178
+ // Let's capture the group path
179
+ const groupRegex = /\.group\(\s*['"]([^'"]+)['"]/g;
180
+ let groupPrefix = "";
181
+ const groupMatch = groupRegex.exec(content);
182
+ if (groupMatch) {
183
+ groupPrefix = groupMatch[1]; // e.g. "/api"
184
+ }
185
+ // 1. Standard routes: route.get('/path', Controller.method)
186
+ const routeRegex = /route\.(\w+)\(\s*['"]([^'"]+)['"]\s*,\s*(\w+)\.(\w+)\)/g;
187
+ let rMatch;
188
+ while ((rMatch = routeRegex.exec(content)) !== null) {
189
+ routesList.push({
190
+ method: rMatch[1].toUpperCase(),
191
+ path: `${groupPrefix}${rMatch[2]}`.replace(/\/+/g, "/"),
192
+ controllerName: rMatch[3],
193
+ methodName: rMatch[4],
194
+ routesFile: filename,
195
+ });
196
+ }
197
+ // 2. Resource routes: api(route, "/users", UserController)
198
+ const resourceRegex = /api\(\s*\w+\s*,\s*['"]([^'"]+)['"]\s*,\s*(\w+)\)/g;
199
+ let resMatch;
200
+ while ((resMatch = resourceRegex.exec(content)) !== null) {
201
+ const basePath = `${groupPrefix}${resMatch[1]}`.replace(/\/+/g, "/");
202
+ const controllerName = resMatch[2];
203
+ // Standard RESTful mappings for api()
204
+ const resourceMethods = [
205
+ { method: "GET", path: basePath, methodName: "index" },
206
+ { method: "POST", path: basePath, methodName: "store" },
207
+ { method: "PUT", path: `${basePath}/:id`.replace(/\/+/g, "/"), methodName: "update" },
208
+ { method: "DELETE", path: `${basePath}/:id`.replace(/\/+/g, "/"), methodName: "destroy" },
209
+ ];
210
+ for (const rm of resourceMethods) {
211
+ routesList.push({
212
+ method: rm.method,
213
+ path: rm.path,
214
+ controllerName,
215
+ methodName: rm.methodName,
216
+ routesFile: filename,
217
+ });
218
+ }
219
+ }
220
+ }
221
+ // 4. Generate Markdown Documentation
222
+ let generatedCount = 0;
223
+ const docsDir = path.join(projectRoot, "docs");
224
+ if (!fs.existsSync(docsDir)) {
225
+ fs.mkdirSync(docsDir, { recursive: true });
226
+ }
227
+ for (const route of routesList) {
228
+ const fullPath = route.path;
229
+ // Filter by path if requested
230
+ if (filterPath && !fullPath.startsWith(filterPath)) {
231
+ continue;
232
+ }
233
+ const controller = controllers[route.controllerName];
234
+ if (!controller)
235
+ continue;
236
+ const methodInfo = controller.methods[route.methodName];
237
+ if (!methodInfo)
238
+ continue;
239
+ // Find associated model
240
+ // First check if validation specified a model, otherwise guess from controller name or model usages
241
+ let modelName = methodInfo.validationModel;
242
+ if (!modelName) {
243
+ // Guess from controller name (e.g., UserController -> User)
244
+ const guessed = route.controllerName.replace("Controller", "");
245
+ if (models[guessed]) {
246
+ modelName = guessed;
247
+ }
248
+ }
249
+ const model = modelName ? models[modelName] : undefined;
250
+ // Determine output directory based on routes file and path
251
+ // If routesFile is not "base.routes.ts", prefix folder with routesFile prefix (e.g. admin.routes.ts -> admin)
252
+ let modulePrefix = "";
253
+ if (route.routesFile !== "base.routes.ts") {
254
+ modulePrefix = route.routesFile.replace(".routes.ts", "");
255
+ }
256
+ // First path segment after the group/api prefix
257
+ const cleanPath = fullPath.replace(/^\/(api|v1)\//, "").replace(/^\//, "");
258
+ const firstSegment = cleanPath.split("/")[0] || "general";
259
+ const targetFolder = modulePrefix
260
+ ? path.join(docsDir, modulePrefix, firstSegment)
261
+ : path.join(docsDir, firstSegment);
262
+ if (!fs.existsSync(targetFolder)) {
263
+ fs.mkdirSync(targetFolder, { recursive: true });
264
+ }
265
+ // File Naming: [METHOD]_[SAFE_PATH].md
266
+ // Replace :param with [param], and other unsafe chars with _
267
+ const safePathName = fullPath
268
+ .replace(/:(\w+)/g, "[$1]") // replace :id with [id]
269
+ .replace(/^\//, "")
270
+ .replace(/\/+/g, "_"); // replace slashes with underscore
271
+ const fileName = `${route.method}_${safePathName}.md`;
272
+ const filePath = path.join(targetFolder, fileName);
273
+ // Start building Markdown content
274
+ let md = `# ${route.method} ${fullPath}\n\n`;
275
+ md += `* **Controller**: \`${route.controllerName}.${route.methodName}\`\n`;
276
+ if (model) {
277
+ md += `* **Model**: \`${model.name}\`\n`;
278
+ }
279
+ md += `* **Features**: ${[
280
+ methodInfo.isMagicResolve ? "**[Magic Resolve]**" : "",
281
+ methodInfo.isMagicPump ? "**[Magic Pump]**" : "",
282
+ ]
283
+ .filter(Boolean)
284
+ .join(", ") || "None"}\n\n`;
285
+ // 1. Headers Table (Only if GET and supports option mode, or custom headers)
286
+ if (route.method === "GET" && methodInfo.isMagicResolve) {
287
+ md += `## Request Headers (Optional)\n\n`;
288
+ md += `| Key | Example Value |\n`;
289
+ md += `| :--- | :--- |\n`;
290
+ md += `| \`x-option\` | \`"true"\` |\n\n`;
291
+ }
292
+ // 2. Query Parameters Table
293
+ const queryParams = [];
294
+ if (route.method === "GET" && methodInfo.isMagicResolve) {
295
+ queryParams.push({ key: "isOption", example: "true", desc: "Alternative to activate **Dropdown/Option Mode**." }, { key: "option[]", example: '["id", "name"]', desc: "Customizes the columns mapped to `value` and `label` in Option Mode." }, { key: "page", example: "1", desc: "The page number for pagination." }, { key: "paginate", example: "15", desc: "Number of records per page." }, { key: "search", example: '"john"', desc: "Performs a global search across `searchable` fields in the model." }, { key: "filter[column]", example: '"active"', desc: "Filters records by a specific column value." });
296
+ // Add expandable relations
297
+ if (model && model.relations.length > 0) {
298
+ const relationNames = model.relations.map((r) => `\`"${r.name}"\``).join(", ");
299
+ queryParams.push({
300
+ key: "expand",
301
+ example: `"${model.relations[0].name}"`,
302
+ desc: `Eager-loads related models. Available relations: ${relationNames}. Can also be passed as \`expand[]\`.`,
303
+ });
304
+ }
305
+ queryParams.push({ key: "sort", example: '"-created_at"', desc: "Sorts by a column. Prefix with `-` for descending order." });
306
+ }
307
+ // Add custom query parameters found in controller
308
+ for (const customQ of methodInfo.customQueryParams) {
309
+ // Skip if already in standard params
310
+ if (["page", "paginate", "search", "filter", "expand", "sort", "isOption", "option"].includes(customQ))
311
+ continue;
312
+ queryParams.push({
313
+ key: customQ,
314
+ example: `"value"`,
315
+ desc: "Custom query parameter extracted from controller logic.",
316
+ });
317
+ }
318
+ if (queryParams.length > 0) {
319
+ md += `## Query Parameters\n\n`;
320
+ md += `| Key | Example Value |\n`;
321
+ md += `| :--- | :--- |\n`;
322
+ for (const q of queryParams) {
323
+ md += `| \`${q.key}\` | \`${q.example}\` |\n`;
324
+ }
325
+ md += `\n`;
326
+ }
327
+ // 3. Payload Table (For POST/PUT/PATCH)
328
+ if (["POST", "PUT", "PATCH"].includes(route.method)) {
329
+ md += `## Payload (JSON Body)\n\n`;
330
+ md += `| Key | Example Value | Required | Validation |\n`;
331
+ md += `| :--- | :--- | :--- | :--- |\n`;
332
+ const payloadFieldsSet = new Set();
333
+ // First add fields from validation rules
334
+ for (const [field, rule] of Object.entries(methodInfo.validationRules)) {
335
+ payloadFieldsSet.add(field);
336
+ const isRequired = rule.includes("required") ? "Yes" : "No";
337
+ md += `| \`${field}\` | \`""\` | ${isRequired} | \`${rule}\` |\n`;
338
+ }
339
+ // Add other fillable fields from Model if not already in validation
340
+ if (model) {
341
+ for (const f of model.fields) {
342
+ if (f.decorators.includes("fillable") && !payloadFieldsSet.has(f.name)) {
343
+ payloadFieldsSet.add(f.name);
344
+ md += `| \`${f.name}\` | \`""\` | No | \`None\` |\n`;
345
+ }
346
+ }
347
+ // Add pumpable relations
348
+ if (methodInfo.isMagicPump) {
349
+ for (const r of model.relations) {
350
+ if (!payloadFieldsSet.has(r.name)) {
351
+ payloadFieldsSet.add(r.name);
352
+ const isArray = r.type === "HasMany" ? "[]" : "";
353
+ md += `| \`${r.name}\` | \`${r.type === "HasMany" ? "[]" : "{}"}\` | No | \`Relation (${r.type})\` |\n`;
354
+ }
355
+ }
356
+ }
357
+ }
358
+ // Add custom payload fields found in controller
359
+ for (const customP of methodInfo.customPayloadFields) {
360
+ if (!payloadFieldsSet.has(customP)) {
361
+ payloadFieldsSet.add(customP);
362
+ md += `| \`${customP}\` | \`""\` | No | \`Custom\` |\n`;
363
+ }
364
+ }
365
+ md += `\n`;
366
+ }
367
+ // 4. Response Table
368
+ md += `## Response\n\n`;
369
+ md += `| Key | Example Result |\n`;
370
+ md += `| :--- | :--- |\n`;
371
+ if (route.method === "GET" && methodInfo.isMagicResolve) {
372
+ md += `| \`data\` | \`[]\` |\n`;
373
+ md += `| \`total\` | \`0\` |\n`;
374
+ }
375
+ else if (model) {
376
+ // Show selectable fields of the model
377
+ for (const f of model.fields) {
378
+ if (f.decorators.includes("selectable")) {
379
+ let exampleVal = `""`;
380
+ if (f.type === "number")
381
+ exampleVal = `0`;
382
+ else if (f.type === "boolean")
383
+ exampleVal = `true`;
384
+ else if (f.type === "Date")
385
+ exampleVal = `"${new Date().toISOString()}"`;
386
+ md += `| \`${f.name}\` | \`${exampleVal}\` |\n`;
387
+ }
388
+ }
389
+ }
390
+ else {
391
+ md += `| \`success\` | \`true\` |\n`;
392
+ }
393
+ md += `\n`;
394
+ fs.writeFileSync(filePath, md, "utf8");
395
+ console.log(`Generated: docs/${path.relative(docsDir, filePath)}`);
396
+ generatedCount++;
397
+ }
398
+ console.log(`🎉 API Documentation generated successfully! Total files: ${generatedCount}`);
399
+ });
400
+ //# sourceMappingURL=generate-docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-docs.js","sourceRoot":"","sources":["../../../src/commands/runner/generate-docs.ts"],"names":[],"mappings":"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"}
@@ -4,10 +4,10 @@ export declare const basicModelStub = "import { Model } from '@utils'\n\nexport
4
4
  export declare const basicSeederStub = "import { {{ model }} } from \"@models\";\n\nexport default async function {{ name }}() {\n // =========================>\n // ## Seed the application's database\n // =========================>\n \n await {{ model }}.query().insert([]);\n}\n";
5
5
  export declare const blueprintStub = "[\n {\n \"model\" : \"\",\n \"schema\" : {},\n \"relations\": {},\n \"controllers\": {},\n \"migrations\" : true,\n \"seeders\" : [],\n \"documentation\": true\n }\n]";
6
6
  export declare const daMigrationStub = "import { DAMigration } from \"@utils\"\n\nexport default class {{ className }} extends DAMigration {\n async up() { \n await this.createTable(\"{{ tableName }}\",(table) => {\n table.uuid()\n }, {\n engine: \"MergeTree\",\n })\n }\n}\n";
7
- export declare const lightControllerStub = "{{ marker }}\nimport type { ControllerContext } from \"elysia\"\nimport { permission } from '@utils'\nimport { {{ model }} } from '@models'\n\n\n\n// ========================================>\n// ## Permission of the resource.\n// ========================================>\nconst p = permission.register({\n \"{{ permission_code }}\": {\n name: \"{{ permission_name }}\",\n accesses: {\n \"00\": \"Melihat\",\n \"01\": \"Membuat\",\n \"02\": \"Mengubah\",\n \"03\": \"Menghapus\",\n }\n }\n})\n\n\n\nexport class {{ name }} {\n // ========================================>\n // ## Display a listing of the resource.\n // ========================================>\n static async index(c: ControllerContext) {\n p.have(\"{{ permission_code }}.00\").guard(c)\n\n const { data, total } = await {{ model }}.query().resolve(c)\n \n c.responseData(data, total)\n }\n\n\n // =============================================>\n // ## Store a newly created resource.\n // =============================================>\n static async store(c: ControllerContext) {\n p.have(\"{{ permission_code }}.01\").guard(c)\n\n c.validation<{{ model }}>({{{ validations }}})\n\n let record = {}\n\n try {\n record = await (new {{ model }}).pump(c.payload) \n } catch (err) {\n c.responseError(err as Error, \"Create {{ model }}\")\n }\n\n c.responseSaved(record)\n }\n\n\n // ============================================>\n // ## Update the specified resource.\n // ============================================>\n static async update(c: ControllerContext) {\n p.have(\"{{ permission_code }}.02\").guard(c)\n\n const record = await {{ model }}.query().findOrNotFound(c.params.id)\n\n c.validation<{{ model }}>({{{ validations }}})\n\n try {\n await record.pump(c.payload)\n } catch (err) {\n c.responseError(err as Error, \"Update {{ model }}\")\n }\n \n c.responseSaved(record)\n }\n\n\n // ===============================================>\n // ## Remove the specified resource.\n // ===============================================>\n static async destroy(c: ControllerContext) {\n p.have(\"{{ permission_code }}.03\").guard(c)\n\n const record = await {{ model }}.query().findOrNotFound(c.params.id)\n \n try {\n await record.delete()\n } catch (err) {\n c.responseError(err as Error, \"Delete {{ model }}\")\n }\n\n c.responseSuccess(record)\n }\n}\n";
8
- export declare const lightMigrationStub = "{{ marker }}\nimport type { Knex } from \"knex\"\n\nexport async function up(knex: Knex): Promise<void> {\n await knex.schema.createTable(\"{{ tableName }}\", (table) => {\n table.bigIncrements('id').primary()\n{{ schemas }}\n table.timestamps(true, true)\n table.softDelete()\n })\n\n{{ pivot }}\n}";
9
- export declare const lightModelStub = "{{ marker }}\nimport { Model, SoftDelete{{ import_utils }} } from '@utils'\n{{ import }}\n\nexport class {{ name }} extends Model {\n // =====================>\n // ## Field\n // =====================>\n{{ fields }}\n\n @SoftDelete()\n deleted_at!: Date\n\n\n // =========================>\n // ## Relations\n // =========================>\n{{ relations }}\n\n\n // =====================>\n // ## Attribute\n // =====================>\n{{ attributes }}\n\n\n // =====================>\n // ## Hook\n // =====================>\n\n}\n";
10
- export declare const lightSeederStub = "{{ marker }}\nimport { {{ model }} } from \"@models\";\n\nexport default async function {{ name }}Seeder() {\n // =========================>\n // ## Seed the application's database\n // =========================>\n \n await (new {{ model }}).pump([\n {{ seeders }}\n ]);\n}\n";
7
+ export declare const skalfaControllerStub = "{{ marker }}\nimport type { ControllerContext } from \"elysia\"\nimport { permission } from '@utils'\nimport { {{ model }} } from '@models'\n\n\n\n// ========================================>\n// ## Permission of the resource.\n// ========================================>\nconst p = permission.register({\n \"{{ permission_code }}\": {\n name: \"{{ permission_name }}\",\n accesses: {\n \"00\": \"Melihat\",\n \"01\": \"Membuat\",\n \"02\": \"Mengubah\",\n \"03\": \"Menghapus\",\n }\n }\n})\n\n\n\nexport class {{ name }} {\n // ========================================>\n // ## Display a listing of the resource.\n // ========================================>\n static async index(c: ControllerContext) {\n p.have(\"{{ permission_code }}.00\").guard(c)\n\n const { data, total } = await {{ model }}.query().resolve(c)\n \n c.responseData(data, total)\n }\n\n\n // =============================================>\n // ## Store a newly created resource.\n // =============================================>\n static async store(c: ControllerContext) {\n p.have(\"{{ permission_code }}.01\").guard(c)\n\n c.validation<{{ model }}>({{{ validations }}})\n\n let record = {}\n\n try {\n record = await (new {{ model }}).pump(c.payload) \n } catch (err) {\n c.responseError(err as Error, \"Create {{ model }}\")\n }\n\n c.responseSaved(record)\n }\n\n\n // ============================================>\n // ## Update the specified resource.\n // ============================================>\n static async update(c: ControllerContext) {\n p.have(\"{{ permission_code }}.02\").guard(c)\n\n const record = await {{ model }}.query().findOrNotFound(c.params.id)\n\n c.validation<{{ model }}>({{{ validations }}})\n\n try {\n await record.pump(c.payload)\n } catch (err) {\n c.responseError(err as Error, \"Update {{ model }}\")\n }\n \n c.responseSaved(record)\n }\n\n\n // ===============================================>\n // ## Remove the specified resource.\n // ===============================================>\n static async destroy(c: ControllerContext) {\n p.have(\"{{ permission_code }}.03\").guard(c)\n\n const record = await {{ model }}.query().findOrNotFound(c.params.id)\n \n try {\n await record.delete()\n } catch (err) {\n c.responseError(err as Error, \"Delete {{ model }}\")\n }\n\n c.responseSuccess(record)\n }\n}\n";
8
+ export declare const skalfaMigrationStub = "{{ marker }}\nimport type { Knex } from \"knex\"\n\nexport async function up(knex: Knex): Promise<void> {\n await knex.schema.createTable(\"{{ tableName }}\", (table) => {\n table.bigIncrements('id').primary()\n{{ schemas }}\n table.timestamps(true, true)\n table.softDelete()\n })\n\n{{ pivot }}\n}";
9
+ export declare const skalfaModelStub = "{{ marker }}\nimport { Model, SoftDelete{{ import_utils }} } from '@utils'\n{{ import }}\n\nexport class {{ name }} extends Model {\n // =====================>\n // ## Field\n // =====================>\n{{ fields }}\n\n @SoftDelete()\n deleted_at!: Date\n\n\n // =========================>\n // ## Relations\n // =========================>\n{{ relations }}\n\n\n // =====================>\n // ## Attribute\n // =====================>\n{{ attributes }}\n\n\n // =====================>\n // ## Hook\n // =====================>\n\n}\n";
10
+ export declare const skalfaSeederStub = "{{ marker }}\nimport { {{ model }} } from \"@models\";\n\nexport default async function {{ name }}Seeder() {\n // =========================>\n // ## Seed the application's database\n // =========================>\n \n await (new {{ model }}).pump([\n {{ seeders }}\n ]);\n}\n";
11
11
  export declare const mailStub = "import { renderMailTemplate, sendMail } from \"@utils\"\n\nexport async function {{ name }}Mail(to: string) {\n const content = renderMailTemplate(\"{{ name }}\", {\n title: \"{{ title }}\",\n })\n\n const send = await sendMail({\n subject: \"{{ title }}\",\n to: to,\n content: content\n })\n \n return send;\n}\n";
12
12
  export declare const notificationStub = "import { queue } from \"@utils\";\n\nexport async function {{ name }}Notification(payload: Record<string,any>) {\n await queue.add('notification', { payload })\n}\n";
13
13
  export declare const queueStub = "import { queue } from '@utils'\n\nexport const {{ name }}QueueWorker = () => {\n queue.worker(\"{{ worker_name }}\", async (payload) => {\n \n })\n}\n";
@@ -80,7 +80,7 @@ export default class {{ className }} extends DAMigration {
80
80
  }
81
81
  }
82
82
  `;
83
- export const lightControllerStub = `{{ marker }}
83
+ export const skalfaControllerStub = `{{ marker }}
84
84
  import type { ControllerContext } from "elysia"
85
85
  import { permission } from '@utils'
86
86
  import { {{ model }} } from '@models'
@@ -175,7 +175,7 @@ export class {{ name }} {
175
175
  }
176
176
  }
177
177
  `;
178
- export const lightMigrationStub = `{{ marker }}
178
+ export const skalfaMigrationStub = `{{ marker }}
179
179
  import type { Knex } from "knex"
180
180
 
181
181
  export async function up(knex: Knex): Promise<void> {
@@ -188,7 +188,7 @@ export async function up(knex: Knex): Promise<void> {
188
188
 
189
189
  {{ pivot }}
190
190
  }`;
191
- export const lightModelStub = `{{ marker }}
191
+ export const skalfaModelStub = `{{ marker }}
192
192
  import { Model, SoftDelete{{ import_utils }} } from '@utils'
193
193
  {{ import }}
194
194
 
@@ -220,7 +220,7 @@ export class {{ name }} extends Model {
220
220
 
221
221
  }
222
222
  `;
223
- export const lightSeederStub = `{{ marker }}
223
+ export const skalfaSeederStub = `{{ marker }}
224
224
  import { {{ model }} } from "@models";
225
225
 
226
226
  export default async function {{ name }}Seeder() {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/stubs/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCjC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;EAShC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;EAI5B,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;CAS9B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;EAU3B,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;CAW9B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8FlC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;EAYhC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B7B,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;CAY9B,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;CAevB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;CAK/B,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;CAOxB,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;CAUxB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/stubs/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCjC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;EAShC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;EAI5B,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;CAS9B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;EAU3B,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;CAW9B,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8FnC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;EAYjC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B9B,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;CAY/B,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;CAevB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;CAK/B,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;CAOxB,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;CAUxB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skalfa/skalfa-api-core",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Core framework engine and foundational utilities for the Skalfa API backend.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -2,23 +2,19 @@ import fs from "fs";
2
2
  import path from "path";
3
3
  import { Command } from "commander";
4
4
 
5
- // Basic commands (always available)
6
5
  import { makeControllerCommand } from "./make/basic-controller";
7
- import { makeLightControllerCommand } from "./make/skalfa-controller";
6
+ import { makeSkalfaControllerCommand } from "./make/skalfa-controller";
8
7
  import { barrelsCommand, watchBarrelsCommand } from "./runner/barrels";
9
-
10
- // ORM commands (optional)
11
8
  import { makeModelCommand } from "./make/basic-model";
12
9
  import { makeSeederCommand } from "./make/basic-seeder";
13
10
  import { makeMigrationCommand } from "./make/basic-migration";
14
- import { makeLightModelCommand } from "./make/skalfa-model";
11
+ import { makeSkalfaModelCommand } from "./make/skalfa-model";
15
12
  import { makeBlueprintCommand } from "./make/blueprint";
16
13
  import { makeResourceCommand } from "./make/resource";
17
14
  import { migrateCommand, migrateFreshCommand } from "./runner/migration";
18
15
  import { seederCommand } from "./runner/seeder";
19
16
  import { blueprintCommand } from "./runner/blueprint/runner";
20
-
21
- // Extension-specific commands
17
+ import { generateDocsCommand } from "./runner/generate-docs";
22
18
  import { makeQueueCommand } from "./make/queue";
23
19
  import { makeMailCommand } from "./make/mail";
24
20
  import { makeNotificationCommand } from "./make/notification";
@@ -26,7 +22,6 @@ import { makeDaMigrationCommand } from "./make/da-migration";
26
22
  import { daMigrateCommand, daMigrateFreshCommand } from "./runner/da-migration";
27
23
 
28
24
  export function runCli() {
29
- // Read package.json to dynamically detect installed extensions
30
25
  let dependencies: Record<string, string> = {};
31
26
  try {
32
27
  const pkgPath = path.join(process.cwd(), "package.json");
@@ -36,7 +31,6 @@ export function runCli() {
36
31
  }
37
32
  } catch {}
38
33
 
39
- const hasOrm = !!dependencies["@skalfa/skalfa-orm"];
40
34
  const hasMail = !!dependencies["@skalfa/mail"] || !!dependencies["skalfa-mail"];
41
35
  const hasNotification = !!dependencies["@skalfa/notification"] || !!dependencies["skalfa-notification"];
42
36
  const hasQueue = !!dependencies["@skalfa/queue"] || !!dependencies["@skalfa/redis"] || !!dependencies["skalfa-queue"] || !!dependencies["skalfa-redis"];
@@ -45,42 +39,36 @@ export function runCli() {
45
39
  const program = new Command();
46
40
  program.name("skalfa").description("Skalfa-api CLI").version("1.0.0");
47
41
 
48
- // 1. Add Core / Basic commands
49
- program.addCommand(makeControllerCommand);
50
- program.addCommand(makeLightControllerCommand);
51
42
  program.addCommand(barrelsCommand);
43
+
44
+ program.addCommand(makeControllerCommand);
45
+ program.addCommand(makeSkalfaControllerCommand);
52
46
  program.addCommand(watchBarrelsCommand);
47
+ program.addCommand(makeModelCommand);
48
+ program.addCommand(makeMigrationCommand);
49
+ program.addCommand(makeSeederCommand);
50
+ program.addCommand(makeSkalfaModelCommand);
51
+ program.addCommand(makeBlueprintCommand);
52
+ program.addCommand(makeResourceCommand);
53
53
 
54
- // 2. Add ORM commands if installed
55
- if (hasOrm) {
56
- program.addCommand(makeModelCommand);
57
- program.addCommand(makeMigrationCommand);
58
- program.addCommand(makeSeederCommand);
59
- program.addCommand(makeLightModelCommand);
60
- program.addCommand(makeBlueprintCommand);
61
- program.addCommand(makeResourceCommand);
62
- program.addCommand(migrateCommand);
63
- program.addCommand(migrateFreshCommand);
64
- program.addCommand(seederCommand);
65
- program.addCommand(blueprintCommand);
66
- }
54
+ program.addCommand(migrateCommand);
55
+ program.addCommand(migrateFreshCommand);
56
+ program.addCommand(seederCommand);
57
+ program.addCommand(blueprintCommand);
58
+ program.addCommand(generateDocsCommand);
67
59
 
68
- // 3. Add Mail commands if installed
69
60
  if (hasMail) {
70
61
  program.addCommand(makeMailCommand);
71
62
  }
72
63
 
73
- // 4. Add Notification commands if installed
74
64
  if (hasNotification) {
75
65
  program.addCommand(makeNotificationCommand);
76
66
  }
77
67
 
78
- // 5. Add Queue commands if installed
79
68
  if (hasQueue) {
80
69
  program.addCommand(makeQueueCommand);
81
70
  }
82
71
 
83
- // 6. Add Data Analytics / OLAP commands if installed
84
72
  if (hasDa) {
85
73
  program.addCommand(makeDaMigrationCommand);
86
74
  program.addCommand(daMigrateCommand);
@@ -43,7 +43,7 @@ export const makeControllerCommand = new Command("make:controller")
43
43
 
44
44
  let content = basicControllerStub;
45
45
  content = content.replace(/{{\s*name\s*}}/g, name || "");
46
-
46
+
47
47
  writeFileSync(filePath, content);
48
48
 
49
49
  logger.info(`Controller ${controllerName} created!`);
@@ -1,6 +1,6 @@
1
1
  import { Command } from "commander";
2
- import { makeLightModel } from "./skalfa-model";
3
- import { makeLightController } from "./skalfa-controller";
2
+ import { makeSkalfaModel } from "./skalfa-model";
3
+ import { makeSkalfaController } from "./skalfa-controller";
4
4
  import { makeMigration } from "./basic-migration";
5
5
  import { makeSeeder } from "./basic-seeder";
6
6
 
@@ -13,8 +13,8 @@ export const makeResourceCommand = new Command("make:resource")
13
13
  .argument("<name>", "Name of resource")
14
14
  .description("Create a new model, migration, seeder, and controller for a resource")
15
15
  .action((name) => {
16
- makeLightModel(name);
17
- makeLightController(name);
16
+ makeSkalfaModel(name);
17
+ makeSkalfaController(name);
18
18
  makeMigration("create_" + name, { init: true });
19
19
  makeSeeder(name);
20
20
  process.exit(0);