@skalfa/skalfa-api-core 1.0.2

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 (249) hide show
  1. package/.github/workflows/publish.yml +40 -0
  2. package/dist/auth/auth.d.ts +19 -0
  3. package/dist/auth/auth.js +227 -0
  4. package/dist/auth/auth.js.map +1 -0
  5. package/dist/auth/index.d.ts +1 -0
  6. package/dist/auth/index.js +2 -0
  7. package/dist/auth/index.js.map +1 -0
  8. package/dist/auth.util.d.ts +19 -0
  9. package/dist/auth.util.js +183 -0
  10. package/dist/auth.util.js.map +1 -0
  11. package/dist/commands/cli.d.ts +1 -0
  12. package/dist/commands/cli.js +78 -0
  13. package/dist/commands/cli.js.map +1 -0
  14. package/dist/commands/make/basic-controller.d.ts +2 -0
  15. package/dist/commands/make/basic-controller.js +40 -0
  16. package/dist/commands/make/basic-controller.js.map +1 -0
  17. package/dist/commands/make/basic-migration.d.ts +5 -0
  18. package/dist/commands/make/basic-migration.js +60 -0
  19. package/dist/commands/make/basic-migration.js.map +1 -0
  20. package/dist/commands/make/basic-model.d.ts +2 -0
  21. package/dist/commands/make/basic-model.js +25 -0
  22. package/dist/commands/make/basic-model.js.map +1 -0
  23. package/dist/commands/make/basic-seeder.d.ts +3 -0
  24. package/dist/commands/make/basic-seeder.js +32 -0
  25. package/dist/commands/make/basic-seeder.js.map +1 -0
  26. package/dist/commands/make/blueprint.d.ts +2 -0
  27. package/dist/commands/make/blueprint.js +29 -0
  28. package/dist/commands/make/blueprint.js.map +1 -0
  29. package/dist/commands/make/da-migration.d.ts +5 -0
  30. package/dist/commands/make/da-migration.js +60 -0
  31. package/dist/commands/make/da-migration.js.map +1 -0
  32. package/dist/commands/make/light-controller.d.ts +3 -0
  33. package/dist/commands/make/light-controller.js +54 -0
  34. package/dist/commands/make/light-controller.js.map +1 -0
  35. package/dist/commands/make/light-model.d.ts +3 -0
  36. package/dist/commands/make/light-model.js +50 -0
  37. package/dist/commands/make/light-model.js.map +1 -0
  38. package/dist/commands/make/mail.d.ts +2 -0
  39. package/dist/commands/make/mail.js +41 -0
  40. package/dist/commands/make/mail.js.map +1 -0
  41. package/dist/commands/make/notification.d.ts +2 -0
  42. package/dist/commands/make/notification.js +33 -0
  43. package/dist/commands/make/notification.js.map +1 -0
  44. package/dist/commands/make/queue.d.ts +2 -0
  45. package/dist/commands/make/queue.js +35 -0
  46. package/dist/commands/make/queue.js.map +1 -0
  47. package/dist/commands/runner/barrels.d.ts +3 -0
  48. package/dist/commands/runner/barrels.js +78 -0
  49. package/dist/commands/runner/barrels.js.map +1 -0
  50. package/dist/commands/runner/blueprint/controller-generation.d.ts +1 -0
  51. package/dist/commands/runner/blueprint/controller-generation.js +147 -0
  52. package/dist/commands/runner/blueprint/controller-generation.js.map +1 -0
  53. package/dist/commands/runner/blueprint/documentation-generation.d.ts +6 -0
  54. package/dist/commands/runner/blueprint/documentation-generation.js +337 -0
  55. package/dist/commands/runner/blueprint/documentation-generation.js.map +1 -0
  56. package/dist/commands/runner/blueprint/migration-generation.d.ts +1 -0
  57. package/dist/commands/runner/blueprint/migration-generation.js +120 -0
  58. package/dist/commands/runner/blueprint/migration-generation.js.map +1 -0
  59. package/dist/commands/runner/blueprint/model-generation.d.ts +1 -0
  60. package/dist/commands/runner/blueprint/model-generation.js +122 -0
  61. package/dist/commands/runner/blueprint/model-generation.js.map +1 -0
  62. package/dist/commands/runner/blueprint/runner.d.ts +23 -0
  63. package/dist/commands/runner/blueprint/runner.js +139 -0
  64. package/dist/commands/runner/blueprint/runner.js.map +1 -0
  65. package/dist/commands/runner/blueprint/seeder-generation.d.ts +1 -0
  66. package/dist/commands/runner/blueprint/seeder-generation.js +40 -0
  67. package/dist/commands/runner/blueprint/seeder-generation.js.map +1 -0
  68. package/dist/commands/runner/da-migration.d.ts +39 -0
  69. package/dist/commands/runner/da-migration.js +262 -0
  70. package/dist/commands/runner/da-migration.js.map +1 -0
  71. package/dist/commands/runner/migration.d.ts +11 -0
  72. package/dist/commands/runner/migration.js +188 -0
  73. package/dist/commands/runner/migration.js.map +1 -0
  74. package/dist/commands/runner/seeder.d.ts +3 -0
  75. package/dist/commands/runner/seeder.js +40 -0
  76. package/dist/commands/runner/seeder.js.map +1 -0
  77. package/dist/commands/stubs/index.d.ts +14 -0
  78. package/dist/commands/stubs/index.js +277 -0
  79. package/dist/commands/stubs/index.js.map +1 -0
  80. package/dist/context/context.d.ts +7 -0
  81. package/dist/context/context.js +11 -0
  82. package/dist/context/context.js.map +1 -0
  83. package/dist/context/index.d.ts +1 -0
  84. package/dist/context/index.js +2 -0
  85. package/dist/context/index.js.map +1 -0
  86. package/dist/context.util.d.ts +7 -0
  87. package/dist/context.util.js +11 -0
  88. package/dist/context.util.js.map +1 -0
  89. package/dist/controller/controller.d.ts +118 -0
  90. package/dist/controller/controller.js +147 -0
  91. package/dist/controller/controller.js.map +1 -0
  92. package/dist/controller/index.d.ts +1 -0
  93. package/dist/controller/index.js +2 -0
  94. package/dist/controller/index.js.map +1 -0
  95. package/dist/controller.util.d.ts +118 -0
  96. package/dist/controller.util.js +144 -0
  97. package/dist/controller.util.js.map +1 -0
  98. package/dist/conversion/conversion.d.ts +8 -0
  99. package/dist/conversion/conversion.js +52 -0
  100. package/dist/conversion/conversion.js.map +1 -0
  101. package/dist/conversion/index.d.ts +1 -0
  102. package/dist/conversion/index.js +2 -0
  103. package/dist/conversion/index.js.map +1 -0
  104. package/dist/conversion.util.d.ts +8 -0
  105. package/dist/conversion.util.js +52 -0
  106. package/dist/conversion.util.js.map +1 -0
  107. package/dist/db/db.d.ts +84 -0
  108. package/dist/db/db.js +177 -0
  109. package/dist/db/db.js.map +1 -0
  110. package/dist/db/index.d.ts +1 -0
  111. package/dist/db/index.js +2 -0
  112. package/dist/db/index.js.map +1 -0
  113. package/dist/db.util.d.ts +84 -0
  114. package/dist/db.util.js +177 -0
  115. package/dist/db.util.js.map +1 -0
  116. package/dist/index.d.ts +21 -0
  117. package/dist/index.js +14 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/logger/index.d.ts +1 -0
  120. package/dist/logger/index.js +2 -0
  121. package/dist/logger/index.js.map +1 -0
  122. package/dist/logger/logger.d.ts +30 -0
  123. package/dist/logger/logger.js +126 -0
  124. package/dist/logger/logger.js.map +1 -0
  125. package/dist/logger.util.d.ts +30 -0
  126. package/dist/logger.util.js +126 -0
  127. package/dist/logger.util.js.map +1 -0
  128. package/dist/mail/index.d.ts +1 -0
  129. package/dist/mail/index.js +2 -0
  130. package/dist/mail/index.js.map +1 -0
  131. package/dist/mail/mail.d.ts +21 -0
  132. package/dist/mail/mail.js +53 -0
  133. package/dist/mail/mail.js.map +1 -0
  134. package/dist/mail.util.d.ts +21 -0
  135. package/dist/mail.util.js +53 -0
  136. package/dist/mail.util.js.map +1 -0
  137. package/dist/middleware/index.d.ts +1 -0
  138. package/dist/middleware/index.js +2 -0
  139. package/dist/middleware/index.js.map +1 -0
  140. package/dist/middleware/middleware.d.ts +263 -0
  141. package/dist/middleware/middleware.js +233 -0
  142. package/dist/middleware/middleware.js.map +1 -0
  143. package/dist/middleware.util.d.ts +263 -0
  144. package/dist/middleware.util.js +233 -0
  145. package/dist/middleware.util.js.map +1 -0
  146. package/dist/model/index.d.ts +3 -0
  147. package/dist/model/index.js +4 -0
  148. package/dist/model/index.js.map +1 -0
  149. package/dist/model/model.d.ts +204 -0
  150. package/dist/model/model.js +1495 -0
  151. package/dist/model/model.js.map +1 -0
  152. package/dist/model.util.d.ts +204 -0
  153. package/dist/model.util.js +1495 -0
  154. package/dist/model.util.js.map +1 -0
  155. package/dist/permission/index.d.ts +1 -0
  156. package/dist/permission/index.js +2 -0
  157. package/dist/permission/index.js.map +1 -0
  158. package/dist/permission/permission.d.ts +38 -0
  159. package/dist/permission/permission.js +91 -0
  160. package/dist/permission/permission.js.map +1 -0
  161. package/dist/permission.util.d.ts +38 -0
  162. package/dist/permission.util.js +91 -0
  163. package/dist/permission.util.js.map +1 -0
  164. package/dist/registry/index.d.ts +1 -0
  165. package/dist/registry/index.js +2 -0
  166. package/dist/registry/index.js.map +1 -0
  167. package/dist/registry/registry.d.ts +28 -0
  168. package/dist/registry/registry.js +19 -0
  169. package/dist/registry/registry.js.map +1 -0
  170. package/dist/registry.util.d.ts +28 -0
  171. package/dist/registry.util.js +19 -0
  172. package/dist/registry.util.js.map +1 -0
  173. package/dist/route/index.d.ts +1 -0
  174. package/dist/route/index.js +2 -0
  175. package/dist/route/index.js.map +1 -0
  176. package/dist/route/route.d.ts +1 -0
  177. package/dist/route/route.js +12 -0
  178. package/dist/route/route.js.map +1 -0
  179. package/dist/route.util.d.ts +1 -0
  180. package/dist/route.util.js +12 -0
  181. package/dist/route.util.js.map +1 -0
  182. package/dist/storage/index.d.ts +1 -0
  183. package/dist/storage/index.js +2 -0
  184. package/dist/storage/index.js.map +1 -0
  185. package/dist/storage/storage.d.ts +56 -0
  186. package/dist/storage/storage.js +86 -0
  187. package/dist/storage/storage.js.map +1 -0
  188. package/dist/storage.util.d.ts +56 -0
  189. package/dist/storage.util.js +82 -0
  190. package/dist/storage.util.js.map +1 -0
  191. package/dist/validation/index.d.ts +1 -0
  192. package/dist/validation/index.js +2 -0
  193. package/dist/validation/index.js.map +1 -0
  194. package/dist/validation/validation.d.ts +7 -0
  195. package/dist/validation/validation.js +245 -0
  196. package/dist/validation/validation.js.map +1 -0
  197. package/dist/validation.util.d.ts +7 -0
  198. package/dist/validation.util.js +237 -0
  199. package/dist/validation.util.js.map +1 -0
  200. package/package.json +34 -0
  201. package/src/auth/auth.ts +282 -0
  202. package/src/auth/index.ts +1 -0
  203. package/src/commands/cli.ts +89 -0
  204. package/src/commands/make/basic-controller.ts +49 -0
  205. package/src/commands/make/basic-migration.ts +89 -0
  206. package/src/commands/make/basic-model.ts +32 -0
  207. package/src/commands/make/basic-seeder.ts +38 -0
  208. package/src/commands/make/blueprint.ts +36 -0
  209. package/src/commands/make/da-migration.ts +90 -0
  210. package/src/commands/make/light-controller.ts +67 -0
  211. package/src/commands/make/light-model.ts +61 -0
  212. package/src/commands/make/mail.ts +51 -0
  213. package/src/commands/make/notification.ts +43 -0
  214. package/src/commands/make/queue.ts +45 -0
  215. package/src/commands/runner/barrels.ts +85 -0
  216. package/src/commands/runner/blueprint/controller-generation.ts +194 -0
  217. package/src/commands/runner/blueprint/documentation-generation.ts +463 -0
  218. package/src/commands/runner/blueprint/migration-generation.ts +153 -0
  219. package/src/commands/runner/blueprint/model-generation.ts +149 -0
  220. package/src/commands/runner/blueprint/runner.ts +181 -0
  221. package/src/commands/runner/blueprint/seeder-generation.ts +55 -0
  222. package/src/commands/runner/da-migration.ts +333 -0
  223. package/src/commands/runner/migration.ts +245 -0
  224. package/src/commands/runner/seeder.ts +44 -0
  225. package/src/commands/stubs/index.ts +289 -0
  226. package/src/context/context.ts +17 -0
  227. package/src/context/index.ts +1 -0
  228. package/src/controller/controller.ts +240 -0
  229. package/src/controller/index.ts +1 -0
  230. package/src/conversion/conversion.ts +65 -0
  231. package/src/conversion/index.ts +1 -0
  232. package/src/index.ts +22 -0
  233. package/src/logger/index.ts +1 -0
  234. package/src/logger/logger.ts +177 -0
  235. package/src/mail/index.ts +1 -0
  236. package/src/mail/mail.ts +86 -0
  237. package/src/middleware/index.ts +1 -0
  238. package/src/middleware/middleware.ts +289 -0
  239. package/src/permission/index.ts +1 -0
  240. package/src/permission/permission.ts +136 -0
  241. package/src/registry/index.ts +1 -0
  242. package/src/registry/registry.ts +37 -0
  243. package/src/route/index.ts +1 -0
  244. package/src/route/route.ts +12 -0
  245. package/src/storage/index.ts +1 -0
  246. package/src/storage/storage.ts +107 -0
  247. package/src/validation/index.ts +1 -0
  248. package/src/validation/validation.ts +346 -0
  249. package/tsconfig.json +23 -0
@@ -0,0 +1,149 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { conversion } from "@utils";
4
+ import { resolveBlueprintPath } from "./runner";
5
+ import { lightModelStub } from "../../stubs";
6
+
7
+ // ============================>
8
+ // ## Command: blueprint model generation
9
+ // ============================>
10
+ export async function modelGeneration(
11
+ model: string,
12
+ schema: Record<string, string> = {},
13
+ relations: Record<string, string> = {},
14
+ marker: string
15
+ ): Promise<boolean> {
16
+ const resolvePath = resolveBlueprintPath(model, "model");
17
+ if (!resolvePath) { return false; }
18
+
19
+ const { name, folder, basePath, filePath } = resolvePath;
20
+ const modelName = conversion.strPascal(name);
21
+
22
+ let imports: string[] = [];
23
+ let importUtils: string[] = ["Field"];
24
+
25
+ // ? Fields
26
+ const fields: string[] = [];
27
+
28
+ for (const [name, def] of Object.entries(schema)) {
29
+ const flags: string[] = [];
30
+ const typeMatch = /type:(\w+),?(\d+)?/.exec(def);
31
+ const type = typeMatch?.[1] ?? "string";
32
+
33
+ let columnType = "any";
34
+ switch (type) {
35
+ case "bigInt":
36
+ case "bigint":
37
+ case "bigInteger":
38
+ case "int":
39
+ case "integer":
40
+ case "float":
41
+ columnType = "number";
42
+ break;
43
+ case "string":
44
+ case "text":
45
+ case "time":
46
+ columnType = "string";
47
+ break;
48
+ case "date":
49
+ case "timestamp":
50
+ columnType = "Date";
51
+ break;
52
+ case "json":
53
+ columnType = "Record<string,any>";
54
+ break;
55
+ case "boolean":
56
+ columnType = "boolean";
57
+ break;
58
+ default:
59
+ columnType = "any";
60
+ break;
61
+ }
62
+
63
+ if (def.includes("fillable")) flags.push("fillable");
64
+ if (def.includes("searchable")) flags.push("searchable");
65
+ if (def.includes("selectable")) flags.push("selectable");
66
+ if (def.includes("hidden")) flags.push("hidden");
67
+
68
+ const decorator = flags.length ? `@Field(${JSON.stringify(flags)})` : "";
69
+
70
+ fields.push([
71
+ ` ${decorator}`,
72
+ ` ${name}!: ${columnType}`
73
+ ].join("\n"));
74
+ }
75
+
76
+ // ? Relations
77
+ const relationFields: string[] = [];
78
+
79
+ let importRelations: string[] = [];
80
+
81
+ for (const [name, def] of Object.entries(relations)) {
82
+ let type = "BelongsTo";
83
+ let target = conversion.strPascal(def.replace(/\[\]|\[1\]|:/g, "").split(" ")[0].split(",")[0]);
84
+ const fk = def.split(" ")[0].split(",")[1] || null;
85
+
86
+ if (def.startsWith("[]:")) type = "BelongsToMany";
87
+ else if (def.startsWith("[]")) type = "HasMany";
88
+ else if (def.startsWith("[1]")) type = "HasOne";
89
+
90
+ !importUtils.includes(type) && importUtils.push(type);
91
+ !importRelations.includes(target) && importRelations.push(`${target}`);
92
+
93
+ const isMany = type === "HasMany" || type === "BelongsToMany";
94
+
95
+ relationFields.push([
96
+ ...(type === "BelongsTo" ? [` ${fk ? fk : conversion.strSnake(target) + "_id"}!: number\n`] : []),
97
+ ` @${type}(() => ${target}${fk ? `, { foreignKey: "${fk}" }` : ""})`,
98
+ ` ${name}!: ${isMany ? `${target}[]` : target}`
99
+ ].join("\n"));
100
+ }
101
+
102
+ if (importRelations.length) {
103
+ imports.push(`import { ${importRelations.join(", ")} } from '@models'`);
104
+ }
105
+
106
+ let stub = lightModelStub;
107
+ const strImportUtils = importUtils?.length ? ", " + importUtils.join(", ") : "";
108
+
109
+ stub = stub
110
+ .replace(/{{\s*marker\s*}}/g, marker)
111
+ .replace(/{{\s*name\s*}}/g, modelName)
112
+ .replace(/{{\s*fields\s*}}/g, fields.join("\n\n"))
113
+ .replace(/{{\s*relations\s*}}/g, relationFields.join("\n\n"))
114
+ .replace(/{{\s*attributes\s*}}/g, "")
115
+ .replace(/{{\s*import\s*}}/g, imports.join("\n"))
116
+ .replace(/{{\s*import_utils\s*}}/g, strImportUtils);
117
+
118
+ fs.writeFileSync(filePath, stub, "utf-8");
119
+
120
+ for (const def of Object.values(relations)) {
121
+ if (!def.startsWith("[]:")) continue;
122
+
123
+ const target = def.replace("[]:", "").trim();
124
+ generatePivotModel(model, target, marker, basePath);
125
+ }
126
+
127
+ return true;
128
+ }
129
+
130
+ function generatePivotModel(sourceModel: string, targetModel: string, marker: string, basePath: string) {
131
+ if (sourceModel > targetModel) return;
132
+
133
+ const a = sourceModel.split("/").pop()!;
134
+ const b = targetModel.split("/").pop()!;
135
+
136
+ const pivotModelName = conversion.strPascal(a) + "Has" + conversion.strPascal(b);
137
+
138
+ const pivotRelations: Record<string, string> = {
139
+ [conversion.strSnake(a)]: a,
140
+ [conversion.strSnake(b)]: b
141
+ };
142
+
143
+ modelGeneration(
144
+ `${basePath}/${conversion.strSlug(pivotModelName)}`,
145
+ {},
146
+ pivotRelations,
147
+ marker
148
+ );
149
+ }
@@ -0,0 +1,181 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { Command } from "commander";
4
+ import { conversion, logger } from "@utils";
5
+ import { modelGeneration } from "./model-generation";
6
+ import { migrationGeneration } from "./migration-generation";
7
+ import { controllerGeneration } from "./controller-generation";
8
+ import { seederGeneration } from "./seeder-generation";
9
+ import { generateDrawioEntityDocumentation, generateMermaidEntityDocumentation, generatePostmanAPIDocumentation } from "./documentation-generation";
10
+ import { exec as execCb } from "child_process";
11
+ import { promisify } from "util";
12
+
13
+ const exec = promisify(execCb);
14
+
15
+ export interface BlueprintSchema {
16
+ model: string;
17
+ schema?: Record<string, string>;
18
+ relations?: Record<string, string>;
19
+ controllers?: Record<string, string> | false;
20
+ seeders?: any[][];
21
+ migrations?: boolean;
22
+ postman?: boolean;
23
+ mermaid?: boolean;
24
+ }
25
+
26
+ const blueprintMarker = `// ============================================
27
+ // ## file THIS FILE IS AUTO-GENERATED BY BLUEPRINT
28
+ // ?? Blueprint : {{ blueprint }}
29
+ // !! If this comment is removed, blueprint engine WILL NOT override this file.
30
+ // ============================================
31
+
32
+
33
+ `;
34
+
35
+ // =====================================>
36
+ // ## Command: blueprint
37
+ // =====================================>
38
+ export const blueprintCommand = new Command("blueprint")
39
+ .option("-o, --only <names...>", "Run only specific blueprints")
40
+ .description("Run blueprints")
41
+ .action(async (opts) => {
42
+ await runBlueprints({ only: opts.only });
43
+
44
+ logger.info("Success run all blueprints!");
45
+
46
+ await exec("bunx barrelsby -c barrels.json", { cwd: path.resolve() });
47
+
48
+ logger.info("Success generate auto import all modules!");
49
+
50
+ process.exit(0);
51
+ });
52
+
53
+ // =======================>
54
+ // ## Command: Blueprint engine
55
+ // =======================>
56
+ export async function runBlueprints(options?: { only?: string[] }) {
57
+ const loaded = loadBlueprintFiles();
58
+ const postmanSchemas: any[] = [];
59
+
60
+ for (const file of loaded) {
61
+ const name = file.file.replace(".blueprint.json", "");
62
+
63
+ if (options?.only && !options.only.includes(name)) continue;
64
+
65
+ const marker = blueprintMarker.replace(/{{ blueprint }}/g, file.file);
66
+
67
+ for (const struct of file.blueprints) {
68
+ const schema = struct.schema ?? {};
69
+ const relations = struct.relations ?? {};
70
+ const seeders = struct.seeders ?? [];
71
+ const controllers = struct.controllers ?? [];
72
+
73
+ await modelGeneration(struct.model, schema, relations, marker);
74
+
75
+ if (struct.migrations !== false) {
76
+ await migrationGeneration(struct.model, schema, relations, marker);
77
+ }
78
+
79
+ if (controllers !== false) {
80
+ if (Array.isArray(controllers) && !!controllers.length) {
81
+ controllers.map(async (item: string) => {
82
+ const [controller, route, permission] = item.split(" ");
83
+ await controllerGeneration(struct.model, schema, relations, controller, route || controller, permission, marker);
84
+ });
85
+ } else {
86
+ const permission = Math.floor(Math.random() * 1000).toString().padStart(3, "0");
87
+ await controllerGeneration(struct.model, schema, relations, struct.model, struct.model, permission, marker);
88
+ }
89
+
90
+ if (struct.postman !== false) {
91
+ const controllerRoutes = Array.isArray(controllers) && controllers.length ? controllers.map(c => {
92
+ const [controller, route] = c.split(" ");
93
+ return route || controller;
94
+ }) : [struct.model];
95
+
96
+ postmanSchemas.push({
97
+ model: struct.model,
98
+ schema,
99
+ controllers: controllerRoutes
100
+ });
101
+ }
102
+ }
103
+
104
+ if (seeders.length) {
105
+ await seederGeneration(struct.model, schema, seeders, marker);
106
+ }
107
+
108
+ if (struct.mermaid !== false) {
109
+ await generateMermaidEntityDocumentation(file.file, file.blueprints);
110
+ }
111
+ }
112
+ }
113
+
114
+ await generateDrawioEntityDocumentation(loaded);
115
+ await generatePostmanAPIDocumentation(postmanSchemas);
116
+ }
117
+
118
+ // =======================>
119
+ // ## Command: Blueprint load json files
120
+ // =======================>
121
+ function loadBlueprintFiles(dir = "blueprints") {
122
+ const basePath = path.join(process.cwd(), dir);
123
+
124
+ if (!fs.existsSync(basePath)) {
125
+ throw new Error("Blueprint folder not found");
126
+ }
127
+
128
+ return fs.readdirSync(basePath)
129
+ .filter(f => f.endsWith(".blueprint.json"))
130
+ .map(file => {
131
+ const fullPath = path.join(basePath, file);
132
+ const content = JSON.parse(fs.readFileSync(fullPath, "utf-8"));
133
+
134
+ if (!Array.isArray(content)) {
135
+ throw new Error(`${file} must export array of blueprints`);
136
+ }
137
+
138
+ return {
139
+ file,
140
+ blueprints: content
141
+ };
142
+ });
143
+ }
144
+
145
+ type BlueprintFileType = "model" | "controller";
146
+
147
+ const TYPE_MAP: Record<BlueprintFileType, { root: string; suffix: string }> = {
148
+ model: {
149
+ root: "src/models",
150
+ suffix: ".model",
151
+ },
152
+ controller: {
153
+ root: "src/controllers",
154
+ suffix: ".controller",
155
+ },
156
+ };
157
+
158
+ export function resolveBlueprintPath(blueprintPath: string, type: BlueprintFileType) {
159
+ const parts = blueprintPath.split("/").filter(Boolean);
160
+ const name = parts.pop()!;
161
+ const folder = parts.join("/");
162
+ const config = TYPE_MAP[type];
163
+
164
+ const basePath = path.join(process.cwd(), config.root, folder);
165
+ const filePath = path.join(basePath, `${conversion.strSlug(name)}${config.suffix}.ts`);
166
+
167
+ if (fs.existsSync(filePath)) {
168
+ const content = fs.readFileSync(filePath, "utf-8");
169
+
170
+ if (!content.includes("AUTO-GENERATED BY BLUEPRINT")) {
171
+ logger.info(`Skip overridden file: ${filePath}`);
172
+ return null;
173
+ }
174
+ }
175
+
176
+ if (!fs.existsSync(basePath)) {
177
+ fs.mkdirSync(basePath, { recursive: true });
178
+ }
179
+
180
+ return { name, folder, basePath, filePath };
181
+ }
@@ -0,0 +1,55 @@
1
+ import { conversion, logger } from "@utils";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { lightSeederStub } from "../../stubs";
5
+
6
+ // =================================>
7
+ // ## Command: Blueprint seeder generation
8
+ // =================================>
9
+ export async function seederGeneration(
10
+ model: string,
11
+ schema: Record<string, string> = {},
12
+ data: any[][] = [],
13
+ marker: string
14
+ ): Promise<boolean> {
15
+ const modelName = conversion.strPascal(model?.split("/")?.pop() || "");
16
+ const name = modelName + "Seeder";
17
+ const basePath = path.join(process.cwd(), "src", "database", "seeders");
18
+ const filename = conversion.strSlug(modelName);
19
+ const filePath = path.join(basePath, `${filename}.seeder.ts`);
20
+
21
+ if (fs.existsSync(filePath)) {
22
+ const content = fs.readFileSync(filePath, "utf-8");
23
+
24
+ if (!content.includes("AUTO-GENERATED BY BLUEPRINT")) {
25
+ logger.info(`Skip overridden file: ${filePath}`);
26
+ return false;
27
+ }
28
+ }
29
+
30
+ const schemaKeys = Object.keys(schema);
31
+
32
+ const seeders = data.map((row) =>
33
+ ` {${row
34
+ .map((val, idx) => {
35
+ const col = schemaKeys[idx];
36
+ return `"${col}": ${isNaN(val as any) ? `"${val}"` : val}`;
37
+ })
38
+ .join(", ")}}`).join(",\n ");
39
+
40
+ let stub = lightSeederStub;
41
+
42
+ stub = stub
43
+ .replace(/{{\s*marker\s*}}/g, marker)
44
+ .replace(/{{\s*name\s*}}/g, name)
45
+ .replace(/{{\s*model\s*}}/g, modelName)
46
+ .replace(/{{\s*seeders\s*}}/g, seeders);
47
+
48
+ if (!fs.existsSync(basePath)) {
49
+ fs.mkdirSync(basePath, { recursive: true });
50
+ }
51
+
52
+ fs.writeFileSync(filePath, stub, "utf-8");
53
+
54
+ return true;
55
+ }