@wild-framework/cli 0.1.1 → 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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +109 -5
- package/dist/cli.js.map +1 -1
- package/dist/client/codegen.d.ts +32 -0
- package/dist/client/codegen.d.ts.map +1 -0
- package/dist/client/codegen.js +94 -0
- package/dist/client/codegen.js.map +1 -0
- package/dist/client/command.d.ts +29 -0
- package/dist/client/command.d.ts.map +1 -0
- package/dist/client/command.js +95 -0
- package/dist/client/command.js.map +1 -0
- package/dist/client/contract.d.ts +86 -0
- package/dist/client/contract.d.ts.map +1 -0
- package/dist/client/contract.js +12 -0
- package/dist/client/contract.js.map +1 -0
- package/dist/client/core.d.ts +80 -0
- package/dist/client/core.d.ts.map +1 -0
- package/dist/client/core.js +52 -0
- package/dist/client/core.js.map +1 -0
- package/dist/client/fs-writer.d.ts +13 -0
- package/dist/client/fs-writer.d.ts.map +1 -0
- package/dist/client/fs-writer.js +24 -0
- package/dist/client/fs-writer.js.map +1 -0
- package/dist/client/inspector.d.ts +19 -0
- package/dist/client/inspector.d.ts.map +1 -0
- package/dist/client/inspector.js +71 -0
- package/dist/client/inspector.js.map +1 -0
- package/dist/client/spec.d.ts +13 -0
- package/dist/client/spec.d.ts.map +1 -0
- package/dist/client/spec.js +235 -0
- package/dist/client/spec.js.map +1 -0
- package/dist/client/targets/index.d.ts +9 -0
- package/dist/client/targets/index.d.ts.map +1 -0
- package/dist/client/targets/index.js +11 -0
- package/dist/client/targets/index.js.map +1 -0
- package/dist/client/targets/react.d.ts +20 -0
- package/dist/client/targets/react.d.ts.map +1 -0
- package/dist/client/targets/react.js +519 -0
- package/dist/client/targets/react.js.map +1 -0
- package/dist/commands/ci.d.ts +5 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +254 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/db.d.ts +13 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +104 -0
- package/dist/commands/db.js.map +1 -0
- package/dist/commands/docker.d.ts +9 -0
- package/dist/commands/docker.d.ts.map +1 -0
- package/dist/commands/docker.js +175 -0
- package/dist/commands/docker.js.map +1 -0
- package/dist/commands/graph.d.ts +9 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +36 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/make.d.ts +1 -1
- package/dist/commands/make.d.ts.map +1 -1
- package/dist/commands/make.js +51 -0
- package/dist/commands/make.js.map +1 -1
- package/dist/commands/new.d.ts +24 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +374 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/resource.d.ts +33 -0
- package/dist/commands/resource.d.ts.map +1 -0
- package/dist/commands/resource.js +291 -0
- package/dist/commands/resource.js.map +1 -0
- package/dist/frontend/codegen.d.ts +27 -0
- package/dist/frontend/codegen.d.ts.map +1 -0
- package/dist/frontend/codegen.js +97 -0
- package/dist/frontend/codegen.js.map +1 -0
- package/dist/frontend/command.d.ts +22 -0
- package/dist/frontend/command.d.ts.map +1 -0
- package/dist/frontend/command.js +57 -0
- package/dist/frontend/command.js.map +1 -0
- package/dist/frontend/react.d.ts +14 -0
- package/dist/frontend/react.d.ts.map +1 -0
- package/dist/frontend/react.js +156 -0
- package/dist/frontend/react.js.map +1 -0
- package/dist/frontend/scaffold.d.ts +20 -0
- package/dist/frontend/scaffold.d.ts.map +1 -0
- package/dist/frontend/scaffold.js +157 -0
- package/dist/frontend/scaffold.js.map +1 -0
- package/dist/frontend/spec.d.ts +33 -0
- package/dist/frontend/spec.d.ts.map +1 -0
- package/dist/frontend/spec.js +74 -0
- package/dist/frontend/spec.js.map +1 -0
- package/dist/templates/resource-slice.d.ts +87 -0
- package/dist/templates/resource-slice.d.ts.map +1 -0
- package/dist/templates/resource-slice.js +513 -0
- package/dist/templates/resource-slice.js.map +1 -0
- package/package.json +8 -2
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { createInterface } from "node:readline";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { findProjectSrc, toKebabCase, writeFiles } from "./make.js";
|
|
4
|
+
import { pluralize } from "../client/codegen.js";
|
|
5
|
+
import { renderResourceSlice, } from "../templates/resource-slice.js";
|
|
6
|
+
/**
|
|
7
|
+
* Run `wild resource <Name>` — generate a full vertical slice.
|
|
8
|
+
*
|
|
9
|
+
* Non-interactive:
|
|
10
|
+
* wild resource Product --field name:string --field price:number
|
|
11
|
+
*
|
|
12
|
+
* Interactive (no name): guided multi-step wizard asking for the name and
|
|
13
|
+
* fields.
|
|
14
|
+
*/
|
|
15
|
+
export async function runResource(args, deps) {
|
|
16
|
+
const print = deps?.print ?? console.log;
|
|
17
|
+
// Parse --field name:type[:rule=value…] flags and --with addons
|
|
18
|
+
const fields = [];
|
|
19
|
+
const addons = {};
|
|
20
|
+
const positional = [];
|
|
21
|
+
for (let i = 0; i < args.length; i++) {
|
|
22
|
+
const arg = args[i];
|
|
23
|
+
if (!arg)
|
|
24
|
+
continue;
|
|
25
|
+
if (arg === "--field" || arg === "-f") {
|
|
26
|
+
const raw = args[i + 1];
|
|
27
|
+
if (raw) {
|
|
28
|
+
fields.push(parseField(raw));
|
|
29
|
+
i++;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (arg.startsWith("--field=")) {
|
|
33
|
+
fields.push(parseField(arg.slice("--field=".length)));
|
|
34
|
+
}
|
|
35
|
+
else if (arg === "--with") {
|
|
36
|
+
const value = args[i + 1];
|
|
37
|
+
if (value) {
|
|
38
|
+
markAddon(addons, value);
|
|
39
|
+
i++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (arg.startsWith("--with=")) {
|
|
43
|
+
markAddon(addons, arg.slice("--with=".length));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
positional.push(arg);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
let name = positional[0];
|
|
50
|
+
if (!name) {
|
|
51
|
+
if (deps?.ask) {
|
|
52
|
+
const result = await runResourceWizard({ ask: deps.ask, print });
|
|
53
|
+
if (!result)
|
|
54
|
+
return 0;
|
|
55
|
+
name = result.name;
|
|
56
|
+
fields.push(...result.fields);
|
|
57
|
+
Object.assign(addons, result.addons);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
print('wild: resource requires a name, e.g. "wild resource Product --field name:string"');
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (fields.length === 0) {
|
|
65
|
+
// A bare `wild resource Product` still produces a working slice.
|
|
66
|
+
fields.push({ name: "name", type: "string" });
|
|
67
|
+
}
|
|
68
|
+
if (!/^[A-Z][A-Za-z0-9]*$/.test(name)) {
|
|
69
|
+
print(`wild: "${name}" is not a valid resource name. Use PascalCase singular, e.g. "Product".`);
|
|
70
|
+
return 1;
|
|
71
|
+
}
|
|
72
|
+
const kebabSingular = toKebabCase(name);
|
|
73
|
+
const kebabPlural = pluralize(kebabSingular);
|
|
74
|
+
const spec = { name, kebabSingular, kebabPlural, fields, addons };
|
|
75
|
+
const srcRoot = findProjectSrc(process.cwd());
|
|
76
|
+
const prefix = timestamp();
|
|
77
|
+
const files = renderResourceSlice(spec, prefix).map((f) => ({
|
|
78
|
+
path: f.path.startsWith("migrations/")
|
|
79
|
+
? join(process.cwd(), f.path)
|
|
80
|
+
: join(srcRoot, f.path),
|
|
81
|
+
content: f.content,
|
|
82
|
+
}));
|
|
83
|
+
print(`\nGenerating resource slice: ${name} (${kebabPlural})\n`);
|
|
84
|
+
const written = writeFiles(files);
|
|
85
|
+
if (written === 0) {
|
|
86
|
+
print("\nNothing to do — all files already exist.");
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
print(`\nDone. ${written} file(s) created.`);
|
|
90
|
+
print(`Routes: GET/POST /${kebabPlural}, GET/PUT/DELETE /${kebabPlural}/:id`);
|
|
91
|
+
print(`Register the provider: app.register(${name}Provider);`);
|
|
92
|
+
print(`Wire migrations: DatabaseProvider.migrations = loadMigrations("./migrations");`);
|
|
93
|
+
print("ℹ️ New migration(s) detected — run `wild db:migrate` to apply them.");
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
/** Interactive wizard for the resource command (ACF-style: fields + rules + add-ons). */
|
|
98
|
+
export async function runResourceWizard(deps) {
|
|
99
|
+
const { ask, print } = deps;
|
|
100
|
+
if (!ask)
|
|
101
|
+
return null; // non-interactive, caller handles missing name
|
|
102
|
+
print("\n🐺 Wild Framework — resource wizard\n");
|
|
103
|
+
const name = (await ask("Resource name (PascalCase singular, e.g. Product): ")).trim();
|
|
104
|
+
if (!name) {
|
|
105
|
+
print("No name given — aborting.");
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
if (!/^[A-Z][A-Za-z0-9]*$/.test(name)) {
|
|
109
|
+
print(`"${name}" is not a valid resource name. Use PascalCase singular, e.g. "Product".`);
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
print("\nFields — enter `name:type` (type = string | text | email | url | uuid | date |");
|
|
113
|
+
print("datetime | time | int | float | boolean | enum | json).");
|
|
114
|
+
print("Append rules with `:key=value`, e.g. `price:float:min=0` or `status:enum:options=draft|published`.");
|
|
115
|
+
print("Leave blank when done. e.g. name:string, then price:float:min=0, then <blank>\n");
|
|
116
|
+
const fields = [];
|
|
117
|
+
while (true) {
|
|
118
|
+
const raw = (await ask(`Field ${fields.length + 1}: `)).trim();
|
|
119
|
+
if (!raw)
|
|
120
|
+
break;
|
|
121
|
+
try {
|
|
122
|
+
fields.push(parseField(raw));
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
print(` ${error instanceof Error ? error.message : String(error)}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (fields.length === 0) {
|
|
129
|
+
print("No fields given — generating with a single `name` field.");
|
|
130
|
+
fields.push({ name: "name", type: "string" });
|
|
131
|
+
}
|
|
132
|
+
// Optional add-ons → more bindings
|
|
133
|
+
const addons = {};
|
|
134
|
+
if (await askYesNo(ask, "Add an event class?"))
|
|
135
|
+
addons.event = true;
|
|
136
|
+
if (await askYesNo(ask, "Add a listener (bound in the provider)?"))
|
|
137
|
+
addons.listener = true;
|
|
138
|
+
if (await askYesNo(ask, "Add a queued job (bound in the provider)?"))
|
|
139
|
+
addons.job = true;
|
|
140
|
+
if (await askYesNo(ask, "Add a policy (auth guard)?"))
|
|
141
|
+
addons.policy = true;
|
|
142
|
+
print(`\nCreating resource ${name} with fields: ${fields.map((f) => `${f.name}:${f.type}`).join(", ")}\n`);
|
|
143
|
+
return { name, fields, addons };
|
|
144
|
+
}
|
|
145
|
+
async function askYesNo(ask, question) {
|
|
146
|
+
const answer = (await ask(`${question} (y/N): `)).trim().toLowerCase();
|
|
147
|
+
return answer === "y" || answer === "yes";
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Parse `name:type[:rule=value…]` into a field.
|
|
151
|
+
*
|
|
152
|
+
* Examples:
|
|
153
|
+
* name:string
|
|
154
|
+
* price:float:min=0:max=100
|
|
155
|
+
* email:string:required=false
|
|
156
|
+
* status:enum:options=draft|published
|
|
157
|
+
*/
|
|
158
|
+
function parseField(raw) {
|
|
159
|
+
const parts = raw.trim().split(":");
|
|
160
|
+
const name = (parts[0] ?? "").trim();
|
|
161
|
+
if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(name)) {
|
|
162
|
+
throw new Error(`"${raw}" is not a valid field (expected name:type[:rule=value…]).`);
|
|
163
|
+
}
|
|
164
|
+
const type = normalizeType(parts[1]);
|
|
165
|
+
const rules = parseRules(parts.slice(2));
|
|
166
|
+
return { name, type, ...(rules ? { rules } : {}) };
|
|
167
|
+
}
|
|
168
|
+
function normalizeType(type) {
|
|
169
|
+
const t = (type ?? "string").trim().toLowerCase();
|
|
170
|
+
switch (t) {
|
|
171
|
+
case "text":
|
|
172
|
+
return "text";
|
|
173
|
+
case "email":
|
|
174
|
+
return "email";
|
|
175
|
+
case "url":
|
|
176
|
+
return "url";
|
|
177
|
+
case "uuid":
|
|
178
|
+
return "uuid";
|
|
179
|
+
case "date":
|
|
180
|
+
return "date";
|
|
181
|
+
case "datetime":
|
|
182
|
+
return "datetime";
|
|
183
|
+
case "time":
|
|
184
|
+
return "time";
|
|
185
|
+
case "int":
|
|
186
|
+
case "integer":
|
|
187
|
+
return "int";
|
|
188
|
+
case "number":
|
|
189
|
+
case "float":
|
|
190
|
+
return "float";
|
|
191
|
+
case "boolean":
|
|
192
|
+
case "bool":
|
|
193
|
+
return "boolean";
|
|
194
|
+
case "enum":
|
|
195
|
+
return "enum";
|
|
196
|
+
case "json":
|
|
197
|
+
return "json";
|
|
198
|
+
default:
|
|
199
|
+
return "string";
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/** Parse `key=value` rule segments into a FieldRules object. */
|
|
203
|
+
function parseRules(parts) {
|
|
204
|
+
const rules = {};
|
|
205
|
+
for (const part of parts) {
|
|
206
|
+
if (!part)
|
|
207
|
+
continue;
|
|
208
|
+
const eq = part.indexOf("=");
|
|
209
|
+
const key = (eq === -1 ? part : part.slice(0, eq)).trim();
|
|
210
|
+
const value = eq === -1 ? "" : part.slice(eq + 1);
|
|
211
|
+
switch (key) {
|
|
212
|
+
case "required":
|
|
213
|
+
rules.required = value.toLowerCase() !== "false";
|
|
214
|
+
break;
|
|
215
|
+
case "min":
|
|
216
|
+
rules.min = Number(value);
|
|
217
|
+
break;
|
|
218
|
+
case "max":
|
|
219
|
+
rules.max = Number(value);
|
|
220
|
+
break;
|
|
221
|
+
case "minLength":
|
|
222
|
+
case "minlength":
|
|
223
|
+
rules.minLength = Number(value);
|
|
224
|
+
break;
|
|
225
|
+
case "maxLength":
|
|
226
|
+
case "maxlength":
|
|
227
|
+
rules.maxLength = Number(value);
|
|
228
|
+
break;
|
|
229
|
+
case "pattern":
|
|
230
|
+
case "regex":
|
|
231
|
+
rules.pattern = value;
|
|
232
|
+
break;
|
|
233
|
+
case "options":
|
|
234
|
+
rules.options = value.split("|").filter(Boolean);
|
|
235
|
+
break;
|
|
236
|
+
case "default":
|
|
237
|
+
rules.default = coerceDefault(value);
|
|
238
|
+
break;
|
|
239
|
+
case "array":
|
|
240
|
+
rules.array = value.toLowerCase() !== "false";
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return Object.keys(rules).length > 0 ? rules : undefined;
|
|
245
|
+
}
|
|
246
|
+
/** Coerce a `default=` string into a number/boolean/string. */
|
|
247
|
+
function coerceDefault(value) {
|
|
248
|
+
if (value === "true")
|
|
249
|
+
return true;
|
|
250
|
+
if (value === "false")
|
|
251
|
+
return false;
|
|
252
|
+
if (value !== "" && !Number.isNaN(Number(value)))
|
|
253
|
+
return Number(value);
|
|
254
|
+
return value;
|
|
255
|
+
}
|
|
256
|
+
/** Mark an add-on by name (aliases allowed). */
|
|
257
|
+
function markAddon(addons, value) {
|
|
258
|
+
const v = value.trim().toLowerCase();
|
|
259
|
+
if (v === "event" || v === "events")
|
|
260
|
+
addons.event = true;
|
|
261
|
+
else if (v === "listener" || v === "listeners")
|
|
262
|
+
addons.listener = true;
|
|
263
|
+
else if (v === "job" || v === "jobs" || v === "queue")
|
|
264
|
+
addons.job = true;
|
|
265
|
+
else if (v === "policy" || v === "policies")
|
|
266
|
+
addons.policy = true;
|
|
267
|
+
}
|
|
268
|
+
/** `YYYYMMDDHHMMSS` — sorts migrations by creation time. */
|
|
269
|
+
function timestamp() {
|
|
270
|
+
const d = new Date();
|
|
271
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
272
|
+
return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Run `wild resource` with real stdin/stdout.
|
|
276
|
+
*/
|
|
277
|
+
export async function runResourceCli(args) {
|
|
278
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
279
|
+
const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
|
|
280
|
+
try {
|
|
281
|
+
const code = await runResource(args, { ask, print: console.log });
|
|
282
|
+
rl.close();
|
|
283
|
+
return code;
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
rl.close();
|
|
287
|
+
console.error(`wild: ${error instanceof Error ? error.message : String(error)}`);
|
|
288
|
+
return 1;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/commands/resource.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SpecOperation } from "./spec.js";
|
|
2
|
+
/**
|
|
3
|
+
* Convert an OpenAPI path param to a TS string interpolation key.
|
|
4
|
+
* "/users/{id}" with param "id" → "id" (used as `encodeURIComponent(String(id))`)
|
|
5
|
+
*/
|
|
6
|
+
export declare function pathParamKeys(path: string): string[];
|
|
7
|
+
/** Convert a schema name to a TypeScript type name. */
|
|
8
|
+
export declare function schemaToTsType(name: string | undefined, fallback?: string): string;
|
|
9
|
+
/** PascalCase → camelCase ("CreateUserRequest" → "createUserRequest"). */
|
|
10
|
+
export declare function camelCase(name: string): string;
|
|
11
|
+
/** Uppercase the first character. */
|
|
12
|
+
export declare function capitalize(name: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Derive a function name from an operation.
|
|
15
|
+
*
|
|
16
|
+
* Prefers method+path (deterministic, descriptive: `getProducts`,
|
|
17
|
+
* `postOrders`). Uses a custom operationId only when it's a clean
|
|
18
|
+
* identifier (no dot — e.g. "listProducts" from a hand-written spec).
|
|
19
|
+
* Auto-generated operationIds look like "ProductController.index",
|
|
20
|
+
* which we ignore in favour of the method+path name.
|
|
21
|
+
*/
|
|
22
|
+
export declare function functionName(op: SpecOperation): string;
|
|
23
|
+
/** Derive a hook name from a function name. */
|
|
24
|
+
export declare function hookName(fn: string): string;
|
|
25
|
+
/** Convert a JSON Schema object to a TS type string. */
|
|
26
|
+
export declare function jsonSchemaToTs(schema: Record<string, unknown> | undefined, schemas: Record<string, Record<string, unknown>>, depth?: number): string;
|
|
27
|
+
//# sourceMappingURL=codegen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/frontend/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,WAAW,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQpD;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAY,GAAG,MAAM,CAGrF;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,qCAAqC;AACrC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CActD;AAED,+CAA+C;AAC/C,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,SAAI,GAAG,MAAM,CAuC/I"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert an OpenAPI path param to a TS string interpolation key.
|
|
3
|
+
* "/users/{id}" with param "id" → "id" (used as `encodeURIComponent(String(id))`)
|
|
4
|
+
*/
|
|
5
|
+
export function pathParamKeys(path) {
|
|
6
|
+
const keys = [];
|
|
7
|
+
const re = /\{([^}]+)\}/g;
|
|
8
|
+
let m;
|
|
9
|
+
while ((m = re.exec(path)) !== null) {
|
|
10
|
+
keys.push(m[1]);
|
|
11
|
+
}
|
|
12
|
+
return keys;
|
|
13
|
+
}
|
|
14
|
+
/** Convert a schema name to a TypeScript type name. */
|
|
15
|
+
export function schemaToTsType(name, fallback = "unknown") {
|
|
16
|
+
if (!name)
|
|
17
|
+
return fallback;
|
|
18
|
+
return name;
|
|
19
|
+
}
|
|
20
|
+
/** PascalCase → camelCase ("CreateUserRequest" → "createUserRequest"). */
|
|
21
|
+
export function camelCase(name) {
|
|
22
|
+
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
23
|
+
}
|
|
24
|
+
/** Uppercase the first character. */
|
|
25
|
+
export function capitalize(name) {
|
|
26
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Derive a function name from an operation.
|
|
30
|
+
*
|
|
31
|
+
* Prefers method+path (deterministic, descriptive: `getProducts`,
|
|
32
|
+
* `postOrders`). Uses a custom operationId only when it's a clean
|
|
33
|
+
* identifier (no dot — e.g. "listProducts" from a hand-written spec).
|
|
34
|
+
* Auto-generated operationIds look like "ProductController.index",
|
|
35
|
+
* which we ignore in favour of the method+path name.
|
|
36
|
+
*/
|
|
37
|
+
export function functionName(op) {
|
|
38
|
+
if (op.operationId && !op.operationId.includes(".")) {
|
|
39
|
+
return camelCase(op.operationId);
|
|
40
|
+
}
|
|
41
|
+
const method = op.method;
|
|
42
|
+
const segments = op.path.split("/").filter(Boolean);
|
|
43
|
+
let last = segments.pop() ?? "resource";
|
|
44
|
+
// If the last segment is a param, use the resource name before it
|
|
45
|
+
if (/\{[^}]+\}/.test(last)) {
|
|
46
|
+
const base = segments.pop() ?? "resource";
|
|
47
|
+
last = `${base}ById`;
|
|
48
|
+
}
|
|
49
|
+
const plural = last.replace(/\{[^}]+\}/g, "ById");
|
|
50
|
+
return `${method}${capitalize(plural)}`;
|
|
51
|
+
}
|
|
52
|
+
/** Derive a hook name from a function name. */
|
|
53
|
+
export function hookName(fn) {
|
|
54
|
+
return `use${capitalize(fn)}`;
|
|
55
|
+
}
|
|
56
|
+
/** Convert a JSON Schema object to a TS type string. */
|
|
57
|
+
export function jsonSchemaToTs(schema, schemas, depth = 0) {
|
|
58
|
+
if (!schema)
|
|
59
|
+
return "unknown";
|
|
60
|
+
if (depth > 6)
|
|
61
|
+
return "unknown";
|
|
62
|
+
if (schema.$ref) {
|
|
63
|
+
return String(schema.$ref).replace("#/components/schemas/", "");
|
|
64
|
+
}
|
|
65
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
66
|
+
return schema.allOf.map((s) => jsonSchemaToTs(s, schemas, depth + 1)).join(" & ");
|
|
67
|
+
}
|
|
68
|
+
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
69
|
+
return schema.oneOf.map((s) => jsonSchemaToTs(s, schemas, depth + 1)).join(" | ");
|
|
70
|
+
}
|
|
71
|
+
const type = schema.type;
|
|
72
|
+
if (type === "string")
|
|
73
|
+
return "string";
|
|
74
|
+
if (type === "number" || type === "integer")
|
|
75
|
+
return "number";
|
|
76
|
+
if (type === "boolean")
|
|
77
|
+
return "boolean";
|
|
78
|
+
if (type === "null")
|
|
79
|
+
return "null";
|
|
80
|
+
if (type === "array" || Array.isArray(schema.items)) {
|
|
81
|
+
const items = schema.items;
|
|
82
|
+
return `${jsonSchemaToTs(items, schemas, depth + 1)}[]`;
|
|
83
|
+
}
|
|
84
|
+
if (type === "object" || schema.properties) {
|
|
85
|
+
const props = (schema.properties ?? {});
|
|
86
|
+
const required = (schema.required ?? []);
|
|
87
|
+
const lines = Object.entries(props).map(([key, propSchema]) => {
|
|
88
|
+
const isRequired = required.includes(key) || !schema.required;
|
|
89
|
+
const propType = jsonSchemaToTs(propSchema, schemas, depth + 1);
|
|
90
|
+
const optional = isRequired ? "" : "?";
|
|
91
|
+
return ` ${key}${optional}: ${propType};`;
|
|
92
|
+
});
|
|
93
|
+
return `{\n${lines.join("\n")}\n}`;
|
|
94
|
+
}
|
|
95
|
+
return "unknown";
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=codegen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/frontend/codegen.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for the `wild frontend` command.
|
|
3
|
+
*/
|
|
4
|
+
export interface FrontendOptions {
|
|
5
|
+
/** OpenAPI spec source: URL or file path. Default "./openapi.json". */
|
|
6
|
+
spec?: string;
|
|
7
|
+
/** Where to generate the frontend. Default "./frontend". */
|
|
8
|
+
path?: string;
|
|
9
|
+
/** Frontend target. Only "react" is supported for now. */
|
|
10
|
+
target?: string;
|
|
11
|
+
/** Base URL the generated client calls. */
|
|
12
|
+
baseUrl?: string;
|
|
13
|
+
/** Print what would be generated, write nothing. */
|
|
14
|
+
dryRun?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Run the `wild frontend` generator.
|
|
18
|
+
*
|
|
19
|
+
* @returns true on success, false on error (error already printed)
|
|
20
|
+
*/
|
|
21
|
+
export declare function runFrontend(options: FrontendOptions): Promise<boolean>;
|
|
22
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/frontend/command.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAiD5E"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { resolve, relative } from "node:path";
|
|
2
|
+
import { loadSpec, parseSpec } from "./spec.js";
|
|
3
|
+
import { buildReactFrontend, writeFrontend } from "./scaffold.js";
|
|
4
|
+
/**
|
|
5
|
+
* Run the `wild frontend` generator.
|
|
6
|
+
*
|
|
7
|
+
* @returns true on success, false on error (error already printed)
|
|
8
|
+
*/
|
|
9
|
+
export async function runFrontend(options) {
|
|
10
|
+
const specSource = options.spec ?? "./openapi.json";
|
|
11
|
+
const target = options.target ?? "react";
|
|
12
|
+
if (target !== "react") {
|
|
13
|
+
console.error(`wild: frontend target "${target}" is not supported yet. Available: react`);
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
console.log(`\nLoading OpenAPI spec from ${specSource}...`);
|
|
17
|
+
let raw;
|
|
18
|
+
try {
|
|
19
|
+
raw = await loadSpec(specSource);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
console.error(`wild: ${error instanceof Error ? error.message : String(error)}`);
|
|
23
|
+
console.error("\nHint: start your app (so /openapi.json is served) or pass --spec <file>.");
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const spec = parseSpec(raw);
|
|
27
|
+
console.log(` ${spec.title} v${spec.version} — ${spec.operations.length} operation(s)`);
|
|
28
|
+
// Default base URL: derive from spec URL host, or from --baseUrl.
|
|
29
|
+
const baseUrl = options.baseUrl ?? deriveBaseUrl(specSource);
|
|
30
|
+
const outRoot = resolve(options.path ?? "./frontend");
|
|
31
|
+
const files = buildReactFrontend(spec, { baseUrl, title: spec.title });
|
|
32
|
+
if (options.dryRun) {
|
|
33
|
+
console.log(`\nDry-run — would generate ${files.length} file(s) under ${relative(process.cwd(), outRoot)}:\n`);
|
|
34
|
+
for (const f of files) {
|
|
35
|
+
console.log(` ${f.path}`);
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
console.log(`\nGenerating frontend under ${relative(process.cwd(), outRoot)}...\n`);
|
|
40
|
+
const written = writeFrontend(files, outRoot);
|
|
41
|
+
if (written === 0) {
|
|
42
|
+
console.log("\nNothing to do — all files already exist.");
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log(`\nDone. ${written} file(s) generated.`);
|
|
46
|
+
console.log("\nNext steps:");
|
|
47
|
+
console.log(` cd ${relative(process.cwd(), outRoot)}`);
|
|
48
|
+
console.log(" npm install");
|
|
49
|
+
console.log(" npm run dev");
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
function deriveBaseUrl(specSource) {
|
|
54
|
+
const m = specSource.match(/^https?:\/\/([^/]+)/);
|
|
55
|
+
return m ? `${m[0]}/` : "http://localhost:3000";
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/frontend/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ParsedSpec } from "./spec.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate the TypeScript types file from the spec's component schemas.
|
|
4
|
+
*/
|
|
5
|
+
export declare function generateTypes(spec: ParsedSpec): string;
|
|
6
|
+
/**
|
|
7
|
+
* Generate the typed fetch client (api.ts).
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateApiClient(spec: ParsedSpec, baseUrl: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Generate TanStack Query hooks (hooks.ts).
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateHooks(spec: ParsedSpec): string;
|
|
14
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/frontend/react.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAG3D;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAwBtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA0B3E;AAqCD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAmEtD"}
|