@wild-framework/cli 0.1.1 → 0.2.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.
- 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/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 +9 -3
|
@@ -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,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource slice templates — a full vertical feature.
|
|
3
|
+
*
|
|
4
|
+
* `wild resource Product` generates, under `features/products/`:
|
|
5
|
+
* products-provider.ts — DI bindings + routes
|
|
6
|
+
* product-service.ts — business logic (in-memory CRUD)
|
|
7
|
+
* product-controller.ts — thin HTTP handlers
|
|
8
|
+
* create-product-request.ts — Zod validators (create + update)
|
|
9
|
+
* product-resource.ts — response shaping
|
|
10
|
+
* products.test.ts — service test
|
|
11
|
+
* plus a `migrations/<ts>_create_products.sql` + `.down.sql` pair.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Field types. Rich, ACF-inspired set — each maps to a TS type, a Zod
|
|
15
|
+
* validator, and a SQL column.
|
|
16
|
+
*/
|
|
17
|
+
export type FieldType = "string" | "text" | "email" | "url" | "uuid" | "date" | "datetime" | "time" | "int" | "float" | "boolean" | "enum" | "json";
|
|
18
|
+
/**
|
|
19
|
+
* Validation rules for a field — the ACF-style "define fields with rules"
|
|
20
|
+
* model. Everything is optional; sensible defaults apply when absent.
|
|
21
|
+
*/
|
|
22
|
+
export interface FieldRules {
|
|
23
|
+
/** Required in create input. Defaults to true. */
|
|
24
|
+
required?: boolean;
|
|
25
|
+
/** Numeric minimum (int/float). */
|
|
26
|
+
min?: number;
|
|
27
|
+
/** Numeric maximum (int/float). */
|
|
28
|
+
max?: number;
|
|
29
|
+
/** String minimum length (string/text/email/url/uuid). */
|
|
30
|
+
minLength?: number;
|
|
31
|
+
/** String maximum length. */
|
|
32
|
+
maxLength?: number;
|
|
33
|
+
/** Regex pattern (string-like types). */
|
|
34
|
+
pattern?: string;
|
|
35
|
+
/** Allowed values (enum). */
|
|
36
|
+
options?: string[];
|
|
37
|
+
/** Default value (applied in validator + SQL). */
|
|
38
|
+
default?: string | number | boolean;
|
|
39
|
+
/** Make the field an array of the base type (e.g. `tags:string:array=true`). */
|
|
40
|
+
array?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** A user-declared field on the resource. */
|
|
43
|
+
export interface ResourceField {
|
|
44
|
+
name: string;
|
|
45
|
+
type: FieldType;
|
|
46
|
+
rules?: FieldRules;
|
|
47
|
+
}
|
|
48
|
+
/** Optional add-ons that add more bindings to the slice. */
|
|
49
|
+
export interface ResourceAddons {
|
|
50
|
+
event?: boolean;
|
|
51
|
+
listener?: boolean;
|
|
52
|
+
job?: boolean;
|
|
53
|
+
policy?: boolean;
|
|
54
|
+
}
|
|
55
|
+
/** Everything the generator needs to render a slice. */
|
|
56
|
+
export interface ResourceSpec {
|
|
57
|
+
/** PascalCase singular, e.g. "Product". */
|
|
58
|
+
name: string;
|
|
59
|
+
/** kebab plural (feature folder + URL segment), e.g. "products". */
|
|
60
|
+
kebabPlural: string;
|
|
61
|
+
/** kebab singular, e.g. "product". */
|
|
62
|
+
kebabSingular: string;
|
|
63
|
+
/** Fields (always include an `id` implicitly). */
|
|
64
|
+
fields: ResourceField[];
|
|
65
|
+
/** Optional add-ons. */
|
|
66
|
+
addons?: ResourceAddons;
|
|
67
|
+
}
|
|
68
|
+
/** A generated file (path relative to src root or project root). */
|
|
69
|
+
export interface SliceFile {
|
|
70
|
+
path: string;
|
|
71
|
+
content: string;
|
|
72
|
+
}
|
|
73
|
+
/** The TypeScript type for a field, e.g. `string`, `number`, `"a" | "b"`, `string[]`. */
|
|
74
|
+
export declare function tsType(field: ResourceField): string;
|
|
75
|
+
/** The TS interface line for a field, e.g. `email: string;` / `nickname?: string;`. */
|
|
76
|
+
export declare function interfaceLine(field: ResourceField): string;
|
|
77
|
+
/** The full Zod chain for a field, e.g. `z.string().email().optional()`. */
|
|
78
|
+
export declare function zodChain(field: ResourceField): string;
|
|
79
|
+
/** The SQL column definition for a field, e.g. `name TEXT NOT NULL`. */
|
|
80
|
+
export declare function sqlColumn(field: ResourceField): string;
|
|
81
|
+
/**
|
|
82
|
+
* Render every file for a resource slice.
|
|
83
|
+
*
|
|
84
|
+
* @returns files grouped by prefix (`src/…` for feature files, `migrations/…`).
|
|
85
|
+
*/
|
|
86
|
+
export declare function renderResourceSlice(spec: ResourceSpec, migrationPrefix: string): SliceFile[];
|
|
87
|
+
//# sourceMappingURL=resource-slice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-slice.d.ts","sourceRoot":"","sources":["../../src/templates/resource-slice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;GAGG;AACH,MAAM,MAAM,SAAS,GACf,QAAQ,GACR,MAAM,GACN,OAAO,GACP,KAAK,GACL,MAAM,GACN,MAAM,GACN,UAAU,GACV,MAAM,GACN,KAAK,GACL,OAAO,GACP,SAAS,GACT,MAAM,GACN,MAAM,CAAC;AAEb;;;GAGG;AACH,MAAM,WAAW,UAAU;IACvB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACpC,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wDAAwD;AACxD,MAAM,WAAW,YAAY;IACzB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,wBAAwB;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,oEAAoE;AACpE,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAWD,yFAAyF;AACzF,wBAAgB,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAOnD;AAmBD,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAG1D;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAWrD;AAqCD,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CA8BtD;AAmXD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,GAAG,SAAS,EAAE,CA8B5F"}
|