@anu8151/adonisjs-blueprint 0.2.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/LICENSE.md +9 -0
- package/README.md +131 -0
- package/build/configure.d.ts +2 -0
- package/build/configure.js +7 -0
- package/build/index.d.ts +16 -0
- package/build/index.js +9 -0
- package/build/init-TjAcOVVP.js +64 -0
- package/build/main-1fZp_M_R.js +8 -0
- package/build/parser-DJB5DEck.js +5832 -0
- package/build/src/commands/build.d.ts +14 -0
- package/build/src/commands/build.js +177 -0
- package/build/src/commands/erase.d.ts +6 -0
- package/build/src/commands/erase.js +23 -0
- package/build/src/commands/init.d.ts +6 -0
- package/build/src/commands/main.d.ts +1 -0
- package/build/src/commands/main.js +10 -0
- package/build/src/commands/stubs.d.ts +6 -0
- package/build/src/commands/stubs.js +16 -0
- package/build/src/commands/trace.d.ts +6 -0
- package/build/src/commands/trace.js +60 -0
- package/build/src/generators/base_generator.d.ts +12 -0
- package/build/src/generators/base_generator.js +31 -0
- package/build/src/generators/channel_generator.d.ts +4 -0
- package/build/src/generators/channel_generator.js +25 -0
- package/build/src/generators/class_generator.d.ts +4 -0
- package/build/src/generators/class_generator.js +11 -0
- package/build/src/generators/controller_generator.d.ts +5 -0
- package/build/src/generators/controller_generator.js +355 -0
- package/build/src/generators/enum_generator.d.ts +4 -0
- package/build/src/generators/enum_generator.js +17 -0
- package/build/src/generators/event_generator.d.ts +4 -0
- package/build/src/generators/event_generator.js +10 -0
- package/build/src/generators/factory_generator.d.ts +4 -0
- package/build/src/generators/factory_generator.js +50 -0
- package/build/src/generators/job_generator.d.ts +4 -0
- package/build/src/generators/job_generator.js +10 -0
- package/build/src/generators/mail_generator.d.ts +4 -0
- package/build/src/generators/mail_generator.js +10 -0
- package/build/src/generators/middleware_generator.d.ts +4 -0
- package/build/src/generators/middleware_generator.js +10 -0
- package/build/src/generators/migration_generator.d.ts +5 -0
- package/build/src/generators/migration_generator.js +46 -0
- package/build/src/generators/model_generator.d.ts +4 -0
- package/build/src/generators/model_generator.js +57 -0
- package/build/src/generators/notification_generator.d.ts +4 -0
- package/build/src/generators/notification_generator.js +10 -0
- package/build/src/generators/openapi_generator.d.ts +8 -0
- package/build/src/generators/openapi_generator.js +200 -0
- package/build/src/generators/policy_generator.d.ts +4 -0
- package/build/src/generators/policy_generator.js +29 -0
- package/build/src/generators/route_generator.d.ts +4 -0
- package/build/src/generators/route_generator.js +34 -0
- package/build/src/generators/seeder_generator.d.ts +4 -0
- package/build/src/generators/seeder_generator.js +16 -0
- package/build/src/generators/service_generator.d.ts +4 -0
- package/build/src/generators/service_generator.js +14 -0
- package/build/src/generators/test_generator.d.ts +5 -0
- package/build/src/generators/test_generator.js +38 -0
- package/build/src/generators/validator_generator.d.ts +4 -0
- package/build/src/generators/validator_generator.js +70 -0
- package/build/src/generators/view_generator.d.ts +4 -0
- package/build/src/generators/view_generator.js +23 -0
- package/build/src/parser.d.ts +7 -0
- package/build/src/parser.js +2 -0
- package/build/src/statements/index.d.ts +1 -0
- package/build/src/statements_registry.d.ts +47 -0
- package/build/src/types.d.ts +50 -0
- package/build/statements_registry-DzyxAiKP.js +19 -0
- package/build/stubs/config.stub +32 -0
- package/build/stubs/main.d.ts +5 -0
- package/build/stubs/make/controller/main.stub +47 -0
- package/build/stubs/make/enum/main.stub +10 -0
- package/build/stubs/make/event/main.stub +12 -0
- package/build/stubs/make/factory/main.stub +25 -0
- package/build/stubs/make/job/main.stub +12 -0
- package/build/stubs/make/mail/main.stub +23 -0
- package/build/stubs/make/middleware/main.stub +16 -0
- package/build/stubs/make/migration/main.stub +25 -0
- package/build/stubs/make/model/main.stub +19 -0
- package/build/stubs/make/notification/main.stub +28 -0
- package/build/stubs/make/policy/main.stub +17 -0
- package/build/stubs/make/seeder/main.stub +21 -0
- package/build/stubs/make/service/main.stub +8 -0
- package/build/stubs/make/test/controller.stub +23 -0
- package/build/stubs/make/validator/main.stub +22 -0
- package/build/stubs/make/view/edge.stub +65 -0
- package/build/stubs/make/view/react.stub +57 -0
- package/build/stubs/make/view/svelte.stub +67 -0
- package/build/stubs/make/view/vue.stub +74 -0
- package/package.json +151 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import { t as statementsRegistry } from "../../statements_registry-DzyxAiKP.js";
|
|
2
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
3
|
+
import { EventGenerator } from "./event_generator.js";
|
|
4
|
+
import { MailGenerator } from "./mail_generator.js";
|
|
5
|
+
import { JobGenerator } from "./job_generator.js";
|
|
6
|
+
import { NotificationGenerator } from "./notification_generator.js";
|
|
7
|
+
import { ServiceGenerator } from "./service_generator.js";
|
|
8
|
+
import string from "@adonisjs/core/helpers/string";
|
|
9
|
+
//#region src/statements/index.ts
|
|
10
|
+
statementsRegistry.register("query", (value, { entity, pluralName, singularName }) => {
|
|
11
|
+
const parts = value.split(",").map((p) => p.trim());
|
|
12
|
+
const queryPart = parts[0];
|
|
13
|
+
const preloads = [];
|
|
14
|
+
for (const part of parts.slice(1)) if (part.startsWith("with:")) {
|
|
15
|
+
const relations = part.replace("with:", "").split(",").map((r) => r.trim());
|
|
16
|
+
preloads.push(...relations);
|
|
17
|
+
} else preloads.push(part);
|
|
18
|
+
const queryParts = queryPart.split(":");
|
|
19
|
+
const queryType = queryParts[0];
|
|
20
|
+
const variableName = queryType === "all" || queryType === "paginate" ? pluralName : singularName;
|
|
21
|
+
const logicLines = [];
|
|
22
|
+
const context = [];
|
|
23
|
+
let queryChain = `${entity.className}.query()`;
|
|
24
|
+
for (const relation of preloads) if (relation) queryChain += `.preload('${string.camelCase(relation)}')`;
|
|
25
|
+
if (queryType === "all") logicLines.push(`const ${variableName} = await ${queryChain}`);
|
|
26
|
+
else if (queryType === "paginate") {
|
|
27
|
+
const limit = queryParts[1] || "20";
|
|
28
|
+
logicLines.push(`const ${variableName} = await ${queryChain}.paginate(request.input('page', 1), ${limit})`);
|
|
29
|
+
} else if (queryType === "find") {
|
|
30
|
+
logicLines.push(`const ${variableName} = await ${queryChain}.where('id', params.id).firstOrFail()`);
|
|
31
|
+
context.push("params");
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
logicLines,
|
|
35
|
+
imports: { models: [entity.className] },
|
|
36
|
+
context
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
statementsRegistry.register("authorize", (value, { entity }) => {
|
|
40
|
+
const authParts = value.split(",");
|
|
41
|
+
const action = authParts[0].trim();
|
|
42
|
+
const modelArg = authParts[1] ? `, ${authParts[1].trim()}` : "";
|
|
43
|
+
const policyName = `${entity.className}Policy`;
|
|
44
|
+
return {
|
|
45
|
+
logicLines: [`await bouncer.with(${policyName}).authorize('${action}'${modelArg})`],
|
|
46
|
+
imports: { policies: [policyName] },
|
|
47
|
+
context: ["bouncer"]
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
statementsRegistry.register("validate", (value, { actionName, entity }) => {
|
|
51
|
+
const validatorName = actionName === "store" || actionName === "update" ? `${actionName === "store" ? "create" : "update"}${entity.className}Validator` : "validator";
|
|
52
|
+
let meta = "";
|
|
53
|
+
if (actionName === "update") meta = ", { meta: { id: params.id } }";
|
|
54
|
+
if (typeof value === "string" && value !== "all") return {
|
|
55
|
+
logicLines: [`const payload = await request.validateUsing(${validatorName}.pick(['${value.split(",").map((f) => f.trim()).join("', '")}'])${meta})`],
|
|
56
|
+
imports: { validators: [validatorName] },
|
|
57
|
+
context: actionName === "update" ? ["params"] : []
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
logicLines: [`const payload = await request.validateUsing(${validatorName}${meta})`],
|
|
61
|
+
imports: { validators: [validatorName] },
|
|
62
|
+
context: actionName === "update" ? ["params"] : []
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
statementsRegistry.register("save", (value, { entity }) => {
|
|
66
|
+
const logicLines = [];
|
|
67
|
+
const parts = typeof value === "string" ? value.split(",").map((p) => p.trim()) : [];
|
|
68
|
+
const relationships = [];
|
|
69
|
+
for (const part of parts.slice(1)) if (part.startsWith("with:")) {
|
|
70
|
+
const relations = part.replace("with:", "").split(",").map((r) => r.trim());
|
|
71
|
+
relationships.push(...relations);
|
|
72
|
+
} else relationships.push(part);
|
|
73
|
+
if (relationships.length > 0) {
|
|
74
|
+
logicLines.push(`const model = await ${entity.className}.create(payload)`);
|
|
75
|
+
for (const rel of relationships) if (rel) {
|
|
76
|
+
const singularRel = string.singular(rel);
|
|
77
|
+
logicLines.push(`await model.related('${string.camelCase(rel)}').sync(payload.${string.snakeCase(singularRel)}_ids)`);
|
|
78
|
+
}
|
|
79
|
+
} else logicLines.push(`await ${entity.className}.create(payload)`);
|
|
80
|
+
return {
|
|
81
|
+
logicLines,
|
|
82
|
+
imports: { models: [entity.className] }
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
statementsRegistry.register("delete", (_value, { entity, models }) => {
|
|
86
|
+
const modelDef = models ? models[entity.className] : null;
|
|
87
|
+
const isSoftDelete = modelDef && modelDef.softDeletes;
|
|
88
|
+
return {
|
|
89
|
+
logicLines: [`const model = await ${entity.className}.findOrFail(params.id)`, `await model.${isSoftDelete ? "delete()" : "delete()"}`],
|
|
90
|
+
imports: { models: [entity.className] },
|
|
91
|
+
context: ["params"]
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
statementsRegistry.register("fire", async (value, { generators }) => {
|
|
95
|
+
const eventName = value;
|
|
96
|
+
await generators.event.generate(eventName);
|
|
97
|
+
return {
|
|
98
|
+
logicLines: [`emitter.emit(new ${eventName}(payload))`],
|
|
99
|
+
imports: { events: [eventName] },
|
|
100
|
+
context: ["emitter"]
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
statementsRegistry.register("send", async (value, { generators }) => {
|
|
104
|
+
const mailName = value;
|
|
105
|
+
await generators.mail.generate(mailName);
|
|
106
|
+
return {
|
|
107
|
+
logicLines: [`await mail.sendLater(new ${mailName}(payload))`],
|
|
108
|
+
imports: { mails: [mailName] },
|
|
109
|
+
context: ["mail"]
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
statementsRegistry.register("dispatch", async (value, { generators }) => {
|
|
113
|
+
const jobName = value;
|
|
114
|
+
await generators.job.generate(jobName);
|
|
115
|
+
return {
|
|
116
|
+
logicLines: [`await new ${jobName}(payload).handle()`],
|
|
117
|
+
imports: { jobs: [jobName] }
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
statementsRegistry.register("notify", async (value, { generators }) => {
|
|
121
|
+
const notifyParts = value.split(", ");
|
|
122
|
+
const target = notifyParts[0].trim();
|
|
123
|
+
const notificationName = notifyParts[1].trim();
|
|
124
|
+
await generators.notification.generate(notificationName);
|
|
125
|
+
return {
|
|
126
|
+
logicLines: [`await ${target}.notify(new ${notificationName}(payload))`],
|
|
127
|
+
imports: { notifications: [notificationName] }
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
statementsRegistry.register("upload", (value) => {
|
|
131
|
+
const parts = value.split(", ");
|
|
132
|
+
const uploadParts = parts[0].split(" to: ");
|
|
133
|
+
const field = uploadParts[0].trim();
|
|
134
|
+
const disk = uploadParts[1] ? `, '${uploadParts[1].trim()}'` : "";
|
|
135
|
+
let size = "2mb";
|
|
136
|
+
let extnames = "['jpg', 'png', 'pdf']";
|
|
137
|
+
for (const part of parts.slice(1)) if (part.startsWith("size:")) size = part.replace("size:", "").trim();
|
|
138
|
+
else if (part.startsWith("ext:")) extnames = `['${part.replace("ext:", "").trim().split(",").join("', '")}']`;
|
|
139
|
+
return { logicLines: [`const ${field}File = request.file('${field}', { size: '${size}', extnames: ${extnames} })!`, `await ${field}File.moveToDisk(''${disk})`] };
|
|
140
|
+
});
|
|
141
|
+
statementsRegistry.register("auth", (_value) => {
|
|
142
|
+
return {
|
|
143
|
+
logicLines: [`const user = auth.user!`],
|
|
144
|
+
context: ["auth"]
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
statementsRegistry.register("render", (value, { actionName, isApi, useInertia }) => {
|
|
148
|
+
const parts = value.split(" with: ");
|
|
149
|
+
const viewPath = parts[0];
|
|
150
|
+
const logicLines = [];
|
|
151
|
+
const context = [];
|
|
152
|
+
if (isApi || viewPath === "json") {
|
|
153
|
+
const responseData = parts[1] ? parts[1] : actionName === "store" || actionName === "update" ? "payload" : "data";
|
|
154
|
+
logicLines.push(`return response.json({ ${responseData} })`);
|
|
155
|
+
} else if (useInertia) {
|
|
156
|
+
const data = parts[1] ? `, { ${parts[1]} }` : "";
|
|
157
|
+
logicLines.push(`return inertia.render('${viewPath}'${data})`);
|
|
158
|
+
context.push("inertia");
|
|
159
|
+
} else {
|
|
160
|
+
const data = parts[1] ? `, { ${parts[1]} }` : "";
|
|
161
|
+
logicLines.push(`return view.render('${viewPath}'${data})`);
|
|
162
|
+
context.push("view");
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
logicLines,
|
|
166
|
+
context
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
statementsRegistry.register("redirect", (value) => {
|
|
170
|
+
return { logicLines: [`return response.redirect().toRoute('${value}')`] };
|
|
171
|
+
});
|
|
172
|
+
statementsRegistry.register("flash", (value) => {
|
|
173
|
+
return {
|
|
174
|
+
logicLines: [`session.flash('${value}', 'Success!')`],
|
|
175
|
+
context: ["session"]
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
statementsRegistry.register("service", async (value, { generators }) => {
|
|
179
|
+
const parts = value.split(".");
|
|
180
|
+
const serviceClass = parts[0];
|
|
181
|
+
const method = parts[1] || "handle";
|
|
182
|
+
await generators.service.generate(serviceClass);
|
|
183
|
+
return {
|
|
184
|
+
logicLines: [`await ${serviceClass}.${method}(payload)`],
|
|
185
|
+
imports: { services: [serviceClass] }
|
|
186
|
+
};
|
|
187
|
+
});
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region src/generators/controller_generator.ts
|
|
190
|
+
var ControllerGenerator = class extends BaseGenerator {
|
|
191
|
+
async generate(name, definition, useInertia = false, isApi = false, models) {
|
|
192
|
+
const nameParts = name.split(/[\/.]/);
|
|
193
|
+
const baseName = nameParts.pop();
|
|
194
|
+
const entity = this.app.generators.createEntity(baseName);
|
|
195
|
+
if (nameParts.length > 0) entity.path = nameParts.map((p) => string.snakeCase(p)).join("/");
|
|
196
|
+
const eventGenerator = new EventGenerator(this.app, this.logger, this.manifest);
|
|
197
|
+
const mailGenerator = new MailGenerator(this.app, this.logger, this.manifest);
|
|
198
|
+
const jobGenerator = new JobGenerator(this.app, this.logger, this.manifest);
|
|
199
|
+
const notificationGenerator = new NotificationGenerator(this.app, this.logger, this.manifest);
|
|
200
|
+
const serviceGenerator = new ServiceGenerator(this.app, this.logger, this.manifest);
|
|
201
|
+
const actions = [];
|
|
202
|
+
const imports = {
|
|
203
|
+
models: /* @__PURE__ */ new Set(),
|
|
204
|
+
validators: /* @__PURE__ */ new Set(),
|
|
205
|
+
events: /* @__PURE__ */ new Set(),
|
|
206
|
+
policies: /* @__PURE__ */ new Set(),
|
|
207
|
+
mails: /* @__PURE__ */ new Set(),
|
|
208
|
+
jobs: /* @__PURE__ */ new Set(),
|
|
209
|
+
notifications: /* @__PURE__ */ new Set(),
|
|
210
|
+
services: /* @__PURE__ */ new Map()
|
|
211
|
+
};
|
|
212
|
+
const middleware = definition.middleware || [];
|
|
213
|
+
const pluralName = string.plural(string.camelCase(entity.name));
|
|
214
|
+
const singularName = string.camelCase(entity.name);
|
|
215
|
+
let normalizedDefinition = definition;
|
|
216
|
+
if (definition.resource) normalizedDefinition = isApi ? {
|
|
217
|
+
index: {
|
|
218
|
+
query: "all",
|
|
219
|
+
render: "json"
|
|
220
|
+
},
|
|
221
|
+
store: {
|
|
222
|
+
validate: "all",
|
|
223
|
+
save: true,
|
|
224
|
+
render: "json"
|
|
225
|
+
},
|
|
226
|
+
show: {
|
|
227
|
+
query: "find",
|
|
228
|
+
render: "json"
|
|
229
|
+
},
|
|
230
|
+
update: {
|
|
231
|
+
validate: "all",
|
|
232
|
+
save: true,
|
|
233
|
+
render: "json"
|
|
234
|
+
},
|
|
235
|
+
destroy: {
|
|
236
|
+
delete: true,
|
|
237
|
+
render: "json"
|
|
238
|
+
}
|
|
239
|
+
} : {
|
|
240
|
+
index: { render: `${pluralName}/index` },
|
|
241
|
+
create: { render: `${pluralName}/create` },
|
|
242
|
+
store: {
|
|
243
|
+
validate: "all",
|
|
244
|
+
save: true,
|
|
245
|
+
redirect: `${pluralName}.index`
|
|
246
|
+
},
|
|
247
|
+
show: { render: `${pluralName}/show` },
|
|
248
|
+
edit: { render: `${pluralName}/edit` },
|
|
249
|
+
update: {
|
|
250
|
+
validate: "all",
|
|
251
|
+
save: true,
|
|
252
|
+
redirect: `${pluralName}.index`
|
|
253
|
+
},
|
|
254
|
+
destroy: {
|
|
255
|
+
delete: true,
|
|
256
|
+
redirect: `${pluralName}.index`
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const generators = {
|
|
260
|
+
event: eventGenerator,
|
|
261
|
+
mail: mailGenerator,
|
|
262
|
+
job: jobGenerator,
|
|
263
|
+
notification: notificationGenerator,
|
|
264
|
+
service: serviceGenerator
|
|
265
|
+
};
|
|
266
|
+
for (const [actionName, actionDef] of Object.entries(normalizedDefinition)) {
|
|
267
|
+
if (actionName === "resource" || actionName === "middleware" || actionName === "stub") continue;
|
|
268
|
+
const contextItems = new Set(["request", "response"]);
|
|
269
|
+
let logicLines = [];
|
|
270
|
+
if (typeof actionDef === "object" && actionDef !== null) {
|
|
271
|
+
const typedDef = actionDef;
|
|
272
|
+
const order = [
|
|
273
|
+
"auth",
|
|
274
|
+
"authorize",
|
|
275
|
+
"validate",
|
|
276
|
+
"query",
|
|
277
|
+
"save",
|
|
278
|
+
"delete",
|
|
279
|
+
"fire",
|
|
280
|
+
"send",
|
|
281
|
+
"dispatch",
|
|
282
|
+
"notify",
|
|
283
|
+
"upload",
|
|
284
|
+
"flash",
|
|
285
|
+
"render",
|
|
286
|
+
"redirect"
|
|
287
|
+
];
|
|
288
|
+
const keys = Object.keys(typedDef).sort((a, b) => {
|
|
289
|
+
const idxA = order.indexOf(a);
|
|
290
|
+
const idxB = order.indexOf(b);
|
|
291
|
+
if (idxA === -1 && idxB === -1) return 0;
|
|
292
|
+
if (idxA === -1) return 1;
|
|
293
|
+
if (idxB === -1) return -1;
|
|
294
|
+
return idxA - idxB;
|
|
295
|
+
});
|
|
296
|
+
for (const key of keys) {
|
|
297
|
+
const handler = statementsRegistry.get(key);
|
|
298
|
+
if (handler) {
|
|
299
|
+
const result = await handler(typedDef[key], {
|
|
300
|
+
actionName,
|
|
301
|
+
actionDef,
|
|
302
|
+
entity,
|
|
303
|
+
isApi,
|
|
304
|
+
useInertia,
|
|
305
|
+
pluralName,
|
|
306
|
+
singularName,
|
|
307
|
+
generators,
|
|
308
|
+
models
|
|
309
|
+
});
|
|
310
|
+
logicLines.push(...result.logicLines);
|
|
311
|
+
if (result.imports) {
|
|
312
|
+
if (result.imports.models) result.imports.models.forEach((i) => imports.models.add(i));
|
|
313
|
+
if (result.imports.validators) result.imports.validators.forEach((i) => imports.validators.add(i));
|
|
314
|
+
if (result.imports.events) result.imports.events.forEach((i) => imports.events.add(i));
|
|
315
|
+
if (result.imports.policies) result.imports.policies.forEach((i) => imports.policies.add(i));
|
|
316
|
+
if (result.imports.mails) result.imports.mails.forEach((i) => imports.mails.add(i));
|
|
317
|
+
if (result.imports.jobs) result.imports.jobs.forEach((i) => imports.jobs.add(i));
|
|
318
|
+
if (result.imports.notifications) result.imports.notifications.forEach((i) => imports.notifications.add(i));
|
|
319
|
+
if (result.imports.services) result.imports.services.forEach((serviceName) => {
|
|
320
|
+
const servicePath = string.snakeCase(serviceName.replace("Service", "")) + "_service";
|
|
321
|
+
imports.services.set(serviceName, servicePath);
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
if (result.context) result.context.forEach((c) => contextItems.add(c));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
actions.push({
|
|
329
|
+
name: actionName,
|
|
330
|
+
context: Array.from(contextItems).join(", "),
|
|
331
|
+
logic: logicLines.join("\n ") || "// Action logic here"
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
await this.generateStub("make/controller/main.stub", {
|
|
335
|
+
entity,
|
|
336
|
+
actions,
|
|
337
|
+
middleware,
|
|
338
|
+
imports: {
|
|
339
|
+
models: Array.from(imports.models),
|
|
340
|
+
validators: Array.from(imports.validators),
|
|
341
|
+
events: Array.from(imports.events),
|
|
342
|
+
policies: Array.from(imports.policies),
|
|
343
|
+
mails: Array.from(imports.mails),
|
|
344
|
+
jobs: Array.from(imports.jobs),
|
|
345
|
+
notifications: Array.from(imports.notifications),
|
|
346
|
+
services: Array.from(imports.services.entries()).map(([serviceName, path]) => ({
|
|
347
|
+
name: serviceName,
|
|
348
|
+
path
|
|
349
|
+
}))
|
|
350
|
+
}
|
|
351
|
+
}, definition.stub);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
//#endregion
|
|
355
|
+
export { ControllerGenerator };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
//#region src/generators/enum_generator.ts
|
|
3
|
+
var EnumGenerator = class extends BaseGenerator {
|
|
4
|
+
async generate(name, definition) {
|
|
5
|
+
const entity = this.app.generators.createEntity(name);
|
|
6
|
+
const values = definition.values.map((val) => ({
|
|
7
|
+
key: val.toUpperCase(),
|
|
8
|
+
value: val
|
|
9
|
+
}));
|
|
10
|
+
await this.generateStub("make/enum/main.stub", {
|
|
11
|
+
entity,
|
|
12
|
+
values
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { EnumGenerator };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
//#region src/generators/event_generator.ts
|
|
3
|
+
var EventGenerator = class extends BaseGenerator {
|
|
4
|
+
async generate(name, _definition) {
|
|
5
|
+
const entity = this.app.generators.createEntity(name);
|
|
6
|
+
await this.generateStub("make/event/main.stub", { entity });
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { EventGenerator };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
import string from "@adonisjs/core/helpers/string";
|
|
3
|
+
//#region src/generators/factory_generator.ts
|
|
4
|
+
var FactoryGenerator = class extends BaseGenerator {
|
|
5
|
+
async generate(name, definition) {
|
|
6
|
+
const entity = this.app.generators.createEntity(name);
|
|
7
|
+
const attributes = [];
|
|
8
|
+
const relationships = [];
|
|
9
|
+
const factoryImports = /* @__PURE__ */ new Set();
|
|
10
|
+
if (definition.attributes) for (const [attrName, attrType] of Object.entries(definition.attributes)) {
|
|
11
|
+
let fakerMethod = "lorem.word";
|
|
12
|
+
const typeStr = typeof attrType === "string" ? attrType : attrType.type || "string";
|
|
13
|
+
if (typeStr.includes("faker:")) fakerMethod = typeStr.split("faker:")[1].split(":")[0];
|
|
14
|
+
else if (attrName.includes("first_name")) fakerMethod = "person.firstName";
|
|
15
|
+
else if (attrName.includes("last_name")) fakerMethod = "person.lastName";
|
|
16
|
+
else if (attrName.includes("full_name") || attrName === "name") fakerMethod = "person.fullName";
|
|
17
|
+
else if (attrName === "email") fakerMethod = "internet.email";
|
|
18
|
+
else if (attrName.includes("password")) fakerMethod = "internet.password";
|
|
19
|
+
else if (attrName.includes("phone")) fakerMethod = "phone.number";
|
|
20
|
+
else if (attrName.includes("city")) fakerMethod = "location.city";
|
|
21
|
+
else if (attrName.includes("country")) fakerMethod = "location.country";
|
|
22
|
+
else if (attrName.includes("address")) fakerMethod = "location.streetAddress";
|
|
23
|
+
else if (typeStr.startsWith("string") || typeStr.startsWith("text")) fakerMethod = "lorem.sentence";
|
|
24
|
+
else if (typeStr.startsWith("integer") || typeStr.startsWith("number")) fakerMethod = "number.int";
|
|
25
|
+
else if (typeStr.startsWith("boolean")) fakerMethod = "datatype.boolean";
|
|
26
|
+
else if (typeStr.startsWith("timestamp") || typeStr.startsWith("datetime")) fakerMethod = "date.recent";
|
|
27
|
+
attributes.push({
|
|
28
|
+
name: attrName,
|
|
29
|
+
fakerMethod
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (definition.relationships) for (const [relName, relType] of Object.entries(definition.relationships)) {
|
|
33
|
+
const relatedModel = string.pascalCase(string.singular(relName));
|
|
34
|
+
relationships.push({
|
|
35
|
+
name: relName,
|
|
36
|
+
type: relType,
|
|
37
|
+
model: relatedModel
|
|
38
|
+
});
|
|
39
|
+
if (relType === "hasMany" || relType === "belongsToMany") factoryImports.add(`${relatedModel}Factory`);
|
|
40
|
+
}
|
|
41
|
+
await this.generateStub("make/factory/main.stub", {
|
|
42
|
+
entity,
|
|
43
|
+
attributes,
|
|
44
|
+
relationships,
|
|
45
|
+
factoryImports: Array.from(factoryImports)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { FactoryGenerator };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
//#region src/generators/job_generator.ts
|
|
3
|
+
var JobGenerator = class extends BaseGenerator {
|
|
4
|
+
async generate(name, _definition) {
|
|
5
|
+
const entity = this.app.generators.createEntity(name);
|
|
6
|
+
await this.generateStub("make/job/main.stub", { entity });
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { JobGenerator };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
//#region src/generators/mail_generator.ts
|
|
3
|
+
var MailGenerator = class extends BaseGenerator {
|
|
4
|
+
async generate(name, _definition) {
|
|
5
|
+
const entity = this.app.generators.createEntity(name);
|
|
6
|
+
await this.generateStub("make/mail/main.stub", { entity });
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { MailGenerator };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
//#region src/generators/middleware_generator.ts
|
|
3
|
+
var MiddlewareGenerator = class extends BaseGenerator {
|
|
4
|
+
async generate(name, _definition) {
|
|
5
|
+
const entity = this.app.generators.createEntity(name);
|
|
6
|
+
await this.generateStub("make/middleware/main.stub", { entity });
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { MiddlewareGenerator };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
import string from "@adonisjs/core/helpers/string";
|
|
3
|
+
//#region src/generators/migration_generator.ts
|
|
4
|
+
var MigrationGenerator = class extends BaseGenerator {
|
|
5
|
+
async generate(name, definition) {
|
|
6
|
+
const entity = this.app.generators.createEntity(name);
|
|
7
|
+
const attributes = [];
|
|
8
|
+
const processedAttributes = /* @__PURE__ */ new Set();
|
|
9
|
+
if (definition.attributes) for (const [attrName, attrType] of Object.entries(definition.attributes)) {
|
|
10
|
+
let migrationLine = "";
|
|
11
|
+
if (typeof attrType === "string") if (attrType === "foreign") migrationLine = `table.integer('${attrName}').unsigned().references('id').inTable('${string.plural(attrName.replace("_id", ""))}')`;
|
|
12
|
+
else if (attrType.startsWith("enum:")) migrationLine = `table.enum('${attrName}', [${attrType.split(":")[1].split(",").map((v) => `'${v.trim()}'`).join(", ")}])`;
|
|
13
|
+
else migrationLine = `table.${attrType}('${attrName}')`;
|
|
14
|
+
attributes.push({ migrationLine });
|
|
15
|
+
processedAttributes.add(attrName);
|
|
16
|
+
}
|
|
17
|
+
if (definition.relationships) {
|
|
18
|
+
for (const [relName, relType] of Object.entries(definition.relationships)) if (relType === "belongsTo" && !processedAttributes.has(`${relName}_id`)) attributes.push({ migrationLine: `table.integer('${relName}_id').unsigned().references('id').inTable('${string.plural(relName)}').onDelete('CASCADE')` });
|
|
19
|
+
}
|
|
20
|
+
if (definition.softDeletes) attributes.push({ migrationLine: `table.timestamp('deleted_at')` });
|
|
21
|
+
await this.generateStub("make/migration/main.stub", {
|
|
22
|
+
entity: {
|
|
23
|
+
...entity,
|
|
24
|
+
tableName: string.plural(string.snakeCase(entity.name))
|
|
25
|
+
},
|
|
26
|
+
attributes
|
|
27
|
+
});
|
|
28
|
+
if (definition.relationships) {
|
|
29
|
+
for (const [relName, relType] of Object.entries(definition.relationships)) if (relType === "belongsToMany") await this.generatePivotMigration(entity.name, relName);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async generatePivotMigration(modelA, modelB) {
|
|
33
|
+
const models = [string.snakeCase(modelA), string.snakeCase(modelB)].sort();
|
|
34
|
+
const tableName = `${models[0]}_${models[1]}`;
|
|
35
|
+
const entity = this.app.generators.createEntity(tableName);
|
|
36
|
+
await this.generateStub("make/migration/main.stub", {
|
|
37
|
+
entity: {
|
|
38
|
+
...entity,
|
|
39
|
+
tableName
|
|
40
|
+
},
|
|
41
|
+
attributes: [{ migrationLine: `table.integer('${models[0]}_id').unsigned().references('id').inTable('${string.plural(models[0])}').onDelete('CASCADE')` }, { migrationLine: `table.integer('${models[1]}_id').unsigned().references('id').inTable('${string.plural(models[1])}').onDelete('CASCADE')` }]
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
export { MigrationGenerator };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
import string from "@adonisjs/core/helpers/string";
|
|
3
|
+
//#region src/generators/model_generator.ts
|
|
4
|
+
var ModelGenerator = class extends BaseGenerator {
|
|
5
|
+
async generate(name, definition) {
|
|
6
|
+
const entity = this.app.generators.createEntity(name);
|
|
7
|
+
const relationships = [];
|
|
8
|
+
const attributes = [];
|
|
9
|
+
const processedAttributes = /* @__PURE__ */ new Set();
|
|
10
|
+
let modelImports = `import { DateTime } from 'luxon'\nimport { column } from '@adonisjs/lucid/orm'\nimport { BaseModel } from '@adonisjs/lucid/orm'`;
|
|
11
|
+
let modelSignature = `export default class ${entity.className} extends BaseModel {`;
|
|
12
|
+
if (definition.softDeletes) {
|
|
13
|
+
modelImports = `import { DateTime } from 'luxon'\nimport { column } from '@adonisjs/lucid/orm'\nimport { BaseModel } from '@adonisjs/lucid/orm'\nimport { compose } from '@adonisjs/core/helpers'\nimport { withSoftDeletes } from '@adonisjs/lucid-soft-deletes'`;
|
|
14
|
+
modelSignature = `export default class ${entity.className} extends compose(BaseModel, withSoftDeletes) {`;
|
|
15
|
+
}
|
|
16
|
+
if (definition.attributes) for (const [attrName, attrType] of Object.entries(definition.attributes)) {
|
|
17
|
+
let tsType = "string";
|
|
18
|
+
let columnDecorator = "@column()";
|
|
19
|
+
const baseType = (typeof attrType === "string" ? attrType : attrType.type || "string").split(":")[0];
|
|
20
|
+
if (baseType === "number" || baseType === "integer") tsType = "number";
|
|
21
|
+
else if (baseType === "boolean") tsType = "boolean";
|
|
22
|
+
else if (baseType === "timestamp" || baseType === "datetime") {
|
|
23
|
+
tsType = "DateTime";
|
|
24
|
+
columnDecorator = "@column.dateTime({ autoCreate: true, autoUpdate: true })";
|
|
25
|
+
} else if (baseType === "enum") tsType = "any";
|
|
26
|
+
attributes.push({ line: `${columnDecorator}\ndeclare ${attrName}: ${tsType}` });
|
|
27
|
+
processedAttributes.add(attrName);
|
|
28
|
+
}
|
|
29
|
+
if (definition.relationships) for (const [relName, relType] of Object.entries(definition.relationships)) {
|
|
30
|
+
const relatedModelName = string.pascalCase(string.singular(relName));
|
|
31
|
+
let relationshipLine = `@${relType}(() => ${relatedModelName})\ndeclare ${relName}: ${relType.charAt(0).toUpperCase() + relType.slice(1)}<typeof ${relatedModelName}>`;
|
|
32
|
+
if (relType === "belongsToMany") relationshipLine = `@${relType}(() => ${relatedModelName}, { pivotTable: '${[entity.className, relatedModelName].sort().map((m) => string.snakeCase(m)).join("_")}' })\ndeclare ${relName}: ${relType.charAt(0).toUpperCase() + relType.slice(1)}<typeof ${relatedModelName}>`;
|
|
33
|
+
if (relType === "belongsTo") {
|
|
34
|
+
const foreignKey = `${string.camelCase(relName)}Id`;
|
|
35
|
+
if (!processedAttributes.has(foreignKey)) {
|
|
36
|
+
attributes.push({ line: `@column()\ndeclare ${foreignKey}: number` });
|
|
37
|
+
processedAttributes.add(foreignKey);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
relationships.push({
|
|
41
|
+
importLine: `import { ${relType} } from '@adonisjs/lucid/orm'\nimport type { ${relType.charAt(0).toUpperCase() + relType.slice(1)} } from '@adonisjs/lucid/types'\nimport ${relatedModelName} from '#models/${string.snakeCase(relatedModelName)}'`,
|
|
42
|
+
line: relationshipLine
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (!processedAttributes.has("createdAt")) attributes.push({ line: "@column.dateTime({ autoCreate: true })\ndeclare createdAt: DateTime" });
|
|
46
|
+
if (!processedAttributes.has("updatedAt")) attributes.push({ line: "@column.dateTime({ autoCreate: true, autoUpdate: true })\ndeclare updatedAt: DateTime" });
|
|
47
|
+
await this.generateStub("make/model/main.stub", {
|
|
48
|
+
entity,
|
|
49
|
+
attributes,
|
|
50
|
+
relationships,
|
|
51
|
+
modelImports,
|
|
52
|
+
modelSignature
|
|
53
|
+
}, definition.stub);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
export { ModelGenerator };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseGenerator } from "./base_generator.js";
|
|
2
|
+
//#region src/generators/notification_generator.ts
|
|
3
|
+
var NotificationGenerator = class extends BaseGenerator {
|
|
4
|
+
async generate(name, _definition) {
|
|
5
|
+
const entity = this.app.generators.createEntity(name);
|
|
6
|
+
await this.generateStub("make/notification/main.stub", { entity });
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { NotificationGenerator };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BaseGenerator } from './base_generator.js';
|
|
2
|
+
import type { BlueprintSchema } from '../types.js';
|
|
3
|
+
export declare class OpenAPIGenerator extends BaseGenerator {
|
|
4
|
+
generate(_name: string, blueprint: BlueprintSchema): Promise<void>;
|
|
5
|
+
private mapToOpenAPIType;
|
|
6
|
+
private normalizeDefinition;
|
|
7
|
+
private inferRoute;
|
|
8
|
+
}
|