@ghentcdh/crouton-api 0.0.1-alpha.40 → 0.0.1-alpha.41
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/index.cjs +1249 -611
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -16
- package/dist/index.d.ts +49 -16
- package/dist/index.js +1103 -465
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -59,7 +59,7 @@ __export(index_exports, {
|
|
|
59
59
|
});
|
|
60
60
|
module.exports = __toCommonJS(index_exports);
|
|
61
61
|
|
|
62
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.58.8_@types+node@26.
|
|
62
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.58.8_@types+node@26.4.0__@swc+core@1.16.1_@swc+he_53e7170f1cd8909962d4b3404cf3712f/node_modules/tsup/assets/cjs_shims.js
|
|
63
63
|
var getImportMetaUrl = /* @__PURE__ */ __name(() => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href, "getImportMetaUrl");
|
|
64
64
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
65
65
|
|
|
@@ -1395,6 +1395,14 @@ var RulesetSchema = import_zod19.z.object({
|
|
|
1395
1395
|
sharedEnums: import_zod19.z.boolean().default(true),
|
|
1396
1396
|
defaultOperations: JsonOperationsSchema.default(JsonOperationsSchema.parse({}))
|
|
1397
1397
|
});
|
|
1398
|
+
var I18nConfigSchema = import_zod19.z.object({
|
|
1399
|
+
/** Default / fallback language. */
|
|
1400
|
+
defaultLanguage: import_zod19.z.string().default("en"),
|
|
1401
|
+
/** All supported language codes. */
|
|
1402
|
+
languages: import_zod19.z.array(import_zod19.z.string()).min(1),
|
|
1403
|
+
/** Directory containing `<lang>.json` bundles, relative to project root. */
|
|
1404
|
+
translationsDir: import_zod19.z.string().default("translations")
|
|
1405
|
+
});
|
|
1398
1406
|
var CroutonConfigSchema = import_zod19.z.object({
|
|
1399
1407
|
/**
|
|
1400
1408
|
* Application title served to the frontend via `GET /_app/layout`.
|
|
@@ -1424,7 +1432,9 @@ var CroutonConfigSchema = import_zod19.z.object({
|
|
|
1424
1432
|
* Whether form fields are saved automatically as the user edits them.
|
|
1425
1433
|
* @default true
|
|
1426
1434
|
*/
|
|
1427
|
-
autoSave: import_zod19.z.boolean().default(true)
|
|
1435
|
+
autoSave: import_zod19.z.boolean().default(true),
|
|
1436
|
+
/** Optional i18n / translation configuration. */
|
|
1437
|
+
i18n: I18nConfigSchema.optional()
|
|
1428
1438
|
});
|
|
1429
1439
|
|
|
1430
1440
|
// ../crouton-core/src/lib/config/readConfig.ts
|
|
@@ -2153,26 +2163,128 @@ var ViewConfigSchema = import_zod22.z.object({
|
|
|
2153
2163
|
defaultSort: import_zod22.z.string().optional()
|
|
2154
2164
|
});
|
|
2155
2165
|
|
|
2166
|
+
// ../crouton-core/src/lib/i18n/Translations.schema.ts
|
|
2167
|
+
var import_zod23 = require("zod");
|
|
2168
|
+
var NestedStringRecord = import_zod23.z.lazy(() => import_zod23.z.record(import_zod23.z.string(), import_zod23.z.union([
|
|
2169
|
+
import_zod23.z.string(),
|
|
2170
|
+
NestedStringRecord
|
|
2171
|
+
])));
|
|
2172
|
+
var TranslationBundleSchema = import_zod23.z.object({
|
|
2173
|
+
app: import_zod23.z.object({
|
|
2174
|
+
title: import_zod23.z.string().optional()
|
|
2175
|
+
}).optional(),
|
|
2176
|
+
sidebarGroups: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.string()).optional(),
|
|
2177
|
+
resources: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.object({
|
|
2178
|
+
title: import_zod23.z.string().optional(),
|
|
2179
|
+
sidebar: import_zod23.z.string().optional(),
|
|
2180
|
+
columns: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.string()).optional(),
|
|
2181
|
+
actions: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.string()).optional(),
|
|
2182
|
+
subResources: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.object({
|
|
2183
|
+
title: import_zod23.z.string().optional(),
|
|
2184
|
+
columns: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.string()).optional()
|
|
2185
|
+
}).optional()).optional()
|
|
2186
|
+
}).optional()).optional(),
|
|
2187
|
+
enums: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.record(import_zod23.z.string(), import_zod23.z.string())).optional(),
|
|
2188
|
+
ui: NestedStringRecord.optional(),
|
|
2189
|
+
validation: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.string()).optional()
|
|
2190
|
+
}).passthrough();
|
|
2191
|
+
|
|
2192
|
+
// ../crouton-core/src/lib/i18n/translation-keys.ts
|
|
2193
|
+
var resourceTitleKey = /* @__PURE__ */ __name((resource) => `resources.${resource}.title`, "resourceTitleKey");
|
|
2194
|
+
var resourceSidebarKey = /* @__PURE__ */ __name((resource) => `resources.${resource}.sidebar`, "resourceSidebarKey");
|
|
2195
|
+
var columnKey = /* @__PURE__ */ __name((resource, column) => `resources.${resource}.columns.${column}`, "columnKey");
|
|
2196
|
+
var actionKey = /* @__PURE__ */ __name((resource, action) => `resources.${resource}.actions.${action}`, "actionKey");
|
|
2197
|
+
var subResourceTitleKey = /* @__PURE__ */ __name((resource, sub) => `resources.${resource}.subResources.${sub}.title`, "subResourceTitleKey");
|
|
2198
|
+
var subResourceColumnKey = /* @__PURE__ */ __name((resource, sub, column) => `resources.${resource}.subResources.${sub}.columns.${column}`, "subResourceColumnKey");
|
|
2199
|
+
var enumKey = /* @__PURE__ */ __name((enumName, value) => `enums.${enumName}.${value}`, "enumKey");
|
|
2200
|
+
var sidebarGroupKey = /* @__PURE__ */ __name((group) => `sidebarGroups.${group}`, "sidebarGroupKey");
|
|
2201
|
+
var validationKey = /* @__PURE__ */ __name((code) => `validation.${code}`, "validationKey");
|
|
2202
|
+
|
|
2203
|
+
// ../crouton-core/src/lib/i18n/translator.ts
|
|
2204
|
+
var getNestedValue = /* @__PURE__ */ __name((obj, path) => {
|
|
2205
|
+
const keys = path.split(".");
|
|
2206
|
+
let current = obj;
|
|
2207
|
+
for (const key of keys) {
|
|
2208
|
+
if (current == null || typeof current !== "object") return void 0;
|
|
2209
|
+
current = current[key];
|
|
2210
|
+
}
|
|
2211
|
+
if (typeof current === "string" && current !== "") return current;
|
|
2212
|
+
return void 0;
|
|
2213
|
+
}, "getNestedValue");
|
|
2214
|
+
var createTranslator = /* @__PURE__ */ __name((bundles, language, defaultLanguage = "en") => {
|
|
2215
|
+
const langBundle = bundles[language];
|
|
2216
|
+
const defaultBundle = language !== defaultLanguage ? bundles[defaultLanguage] : void 0;
|
|
2217
|
+
return (path, fallback) => {
|
|
2218
|
+
if (langBundle) {
|
|
2219
|
+
const value = getNestedValue(langBundle, path);
|
|
2220
|
+
if (value !== void 0) return value;
|
|
2221
|
+
}
|
|
2222
|
+
if (defaultBundle) {
|
|
2223
|
+
const value = getNestedValue(defaultBundle, path);
|
|
2224
|
+
if (value !== void 0) return value;
|
|
2225
|
+
}
|
|
2226
|
+
return fallback ?? path;
|
|
2227
|
+
};
|
|
2228
|
+
}, "createTranslator");
|
|
2229
|
+
|
|
2230
|
+
// ../crouton-core/src/lib/i18n/negotiate.ts
|
|
2231
|
+
var parseAcceptLanguage = /* @__PURE__ */ __name((header) => {
|
|
2232
|
+
const entries = [];
|
|
2233
|
+
for (const part of header.split(",")) {
|
|
2234
|
+
const trimmed = part.trim();
|
|
2235
|
+
if (!trimmed) continue;
|
|
2236
|
+
const [tag, ...params] = trimmed.split(";");
|
|
2237
|
+
let q = 1;
|
|
2238
|
+
for (const param of params) {
|
|
2239
|
+
const match = param.trim().match(/^q\s*=\s*([0-9.]+)$/);
|
|
2240
|
+
if (match) {
|
|
2241
|
+
q = parseFloat(match[1]);
|
|
2242
|
+
if (isNaN(q)) q = 0;
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
entries.push({
|
|
2246
|
+
tag: tag.trim().toLowerCase(),
|
|
2247
|
+
q
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
return entries.sort((a, b) => b.q - a.q);
|
|
2251
|
+
}, "parseAcceptLanguage");
|
|
2252
|
+
var resolveLanguage = /* @__PURE__ */ __name((acceptLanguage, supported, defaultLanguage) => {
|
|
2253
|
+
if (!acceptLanguage) return defaultLanguage;
|
|
2254
|
+
const supportedLower = supported.map((s) => s.toLowerCase());
|
|
2255
|
+
const entries = parseAcceptLanguage(acceptLanguage);
|
|
2256
|
+
for (const { tag, q } of entries) {
|
|
2257
|
+
if (q <= 0) continue;
|
|
2258
|
+
if (tag === "*") return defaultLanguage;
|
|
2259
|
+
const exactIdx = supportedLower.indexOf(tag);
|
|
2260
|
+
if (exactIdx !== -1) return supported[exactIdx];
|
|
2261
|
+
const base = tag.split("-")[0];
|
|
2262
|
+
const baseIdx = supportedLower.indexOf(base);
|
|
2263
|
+
if (baseIdx !== -1) return supported[baseIdx];
|
|
2264
|
+
}
|
|
2265
|
+
return defaultLanguage;
|
|
2266
|
+
}, "resolveLanguage");
|
|
2267
|
+
|
|
2156
2268
|
// src/lib/crouton-api.module.ts
|
|
2157
|
-
var
|
|
2269
|
+
var import_common22 = require("@nestjs/common");
|
|
2158
2270
|
var import_core = require("@nestjs/core");
|
|
2159
2271
|
|
|
2160
2272
|
// src/lib/crud/app-layout/app-layout.types.ts
|
|
2161
|
-
var
|
|
2162
|
-
var SidebarLeafSchema =
|
|
2163
|
-
kind:
|
|
2164
|
-
id:
|
|
2165
|
-
label:
|
|
2166
|
-
position:
|
|
2273
|
+
var import_zod24 = require("zod");
|
|
2274
|
+
var SidebarLeafSchema = import_zod24.z.object({
|
|
2275
|
+
kind: import_zod24.z.literal("item").default("item"),
|
|
2276
|
+
id: import_zod24.z.string(),
|
|
2277
|
+
label: import_zod24.z.string(),
|
|
2278
|
+
position: import_zod24.z.number().optional()
|
|
2167
2279
|
});
|
|
2168
|
-
var SidebarGroupSchema2 =
|
|
2169
|
-
kind:
|
|
2170
|
-
id:
|
|
2171
|
-
label:
|
|
2172
|
-
position:
|
|
2173
|
-
children:
|
|
2280
|
+
var SidebarGroupSchema2 = import_zod24.z.object({
|
|
2281
|
+
kind: import_zod24.z.literal("group").default("group"),
|
|
2282
|
+
id: import_zod24.z.string(),
|
|
2283
|
+
label: import_zod24.z.string(),
|
|
2284
|
+
position: import_zod24.z.number().optional(),
|
|
2285
|
+
children: import_zod24.z.array(SidebarLeafSchema).default([])
|
|
2174
2286
|
});
|
|
2175
|
-
var SidebarNodeSchema =
|
|
2287
|
+
var SidebarNodeSchema = import_zod24.z.discriminatedUnion("kind", [
|
|
2176
2288
|
SidebarLeafSchema,
|
|
2177
2289
|
SidebarGroupSchema2
|
|
2178
2290
|
]);
|
|
@@ -2252,15 +2364,311 @@ var IS_DEV = parseBooleanEnv(process.env["CROUTON_SCHEMA_EDITOR"]);
|
|
|
2252
2364
|
|
|
2253
2365
|
// src/lib/crud/resource-config.registry.ts
|
|
2254
2366
|
var import_common = require("@nestjs/common");
|
|
2367
|
+
|
|
2368
|
+
// src/lib/crud/resource/ReadResourceJson.ts
|
|
2369
|
+
var import_node_fs = require("fs");
|
|
2370
|
+
var import_node_path = require("path");
|
|
2371
|
+
var readResourceJson = /* @__PURE__ */ __name((jsonPath) => {
|
|
2372
|
+
if (!(0, import_node_fs.existsSync)(jsonPath)) return void 0;
|
|
2373
|
+
let fileContent;
|
|
2374
|
+
try {
|
|
2375
|
+
fileContent = JSON.parse((0, import_node_fs.readFileSync)(jsonPath, "utf-8"));
|
|
2376
|
+
} catch (err) {
|
|
2377
|
+
return {
|
|
2378
|
+
success: false,
|
|
2379
|
+
error: `Invalid JSON in ${jsonPath}: ${err.message}`
|
|
2380
|
+
};
|
|
2381
|
+
}
|
|
2382
|
+
const resource = ResourceJsonSchema.safeParse(fileContent);
|
|
2383
|
+
if (resource.error) {
|
|
2384
|
+
return {
|
|
2385
|
+
success: false,
|
|
2386
|
+
error: `Resource cannot be parsed ${jsonPath}: ${resource.error.message}`
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
return {
|
|
2390
|
+
success: true,
|
|
2391
|
+
data: {
|
|
2392
|
+
json: resource.data,
|
|
2393
|
+
dir: (0, import_node_path.dirname)(jsonPath)
|
|
2394
|
+
}
|
|
2395
|
+
};
|
|
2396
|
+
}, "readResourceJson");
|
|
2397
|
+
|
|
2398
|
+
// src/lib/crud/adapter/resource-resolver.ts
|
|
2399
|
+
var import_node_fs2 = require("fs");
|
|
2400
|
+
var import_node_path2 = require("path");
|
|
2401
|
+
var resolveChildResourceDetailed = /* @__PURE__ */ __name((resourcePath, parentDir) => {
|
|
2402
|
+
const attempted = [];
|
|
2403
|
+
try {
|
|
2404
|
+
if (resourcePath.endsWith(".json")) {
|
|
2405
|
+
const directPath = (0, import_node_path2.resolve)(parentDir, resourcePath);
|
|
2406
|
+
attempted.push(directPath);
|
|
2407
|
+
if ((0, import_node_fs2.existsSync)(directPath)) {
|
|
2408
|
+
const result2 = readResourceJson(directPath);
|
|
2409
|
+
if (result2?.success) return {
|
|
2410
|
+
ok: true,
|
|
2411
|
+
value: result2.data
|
|
2412
|
+
};
|
|
2413
|
+
return {
|
|
2414
|
+
ok: false,
|
|
2415
|
+
reason: "invalid",
|
|
2416
|
+
error: result2?.error ?? `Could not read ${directPath}`
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
const childName = resourcePath.replace(/^\.\//, "").replace(/\.resource$/, "");
|
|
2421
|
+
const childJsonPath = (0, import_node_path2.resolve)((0, import_node_path2.dirname)(parentDir), childName, "resource.json");
|
|
2422
|
+
attempted.push(childJsonPath);
|
|
2423
|
+
const result = readResourceJson(childJsonPath);
|
|
2424
|
+
if (result?.success) return {
|
|
2425
|
+
ok: true,
|
|
2426
|
+
value: result.data
|
|
2427
|
+
};
|
|
2428
|
+
if (result) return {
|
|
2429
|
+
ok: false,
|
|
2430
|
+
reason: "invalid",
|
|
2431
|
+
error: result.error
|
|
2432
|
+
};
|
|
2433
|
+
return {
|
|
2434
|
+
ok: false,
|
|
2435
|
+
reason: "missing",
|
|
2436
|
+
attempted
|
|
2437
|
+
};
|
|
2438
|
+
} catch (err) {
|
|
2439
|
+
return {
|
|
2440
|
+
ok: false,
|
|
2441
|
+
reason: "invalid",
|
|
2442
|
+
error: err.message
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
}, "resolveChildResourceDetailed");
|
|
2446
|
+
var resolveChildResource = /* @__PURE__ */ __name((resourcePath, parentDir) => {
|
|
2447
|
+
const resolution = resolveChildResourceDetailed(resourcePath, parentDir);
|
|
2448
|
+
return resolution.ok ? resolution.value : void 0;
|
|
2449
|
+
}, "resolveChildResource");
|
|
2450
|
+
|
|
2451
|
+
// src/lib/crud/adapter/column-transforms.ts
|
|
2452
|
+
var expandExtendColumns = /* @__PURE__ */ __name((columns, dirPath) => {
|
|
2453
|
+
if (!dirPath) return columns;
|
|
2454
|
+
const result = [];
|
|
2455
|
+
for (const col of columns) {
|
|
2456
|
+
if (!col.extend) {
|
|
2457
|
+
result.push(col);
|
|
2458
|
+
continue;
|
|
2459
|
+
}
|
|
2460
|
+
const resolved = resolveChildResource(col.extend, dirPath);
|
|
2461
|
+
if (!resolved) {
|
|
2462
|
+
console.warn(`[extend] Could not resolve "${col.extend}" for column "${col.id}" \u2014 keeping as-is`);
|
|
2463
|
+
result.push(col);
|
|
2464
|
+
continue;
|
|
2465
|
+
}
|
|
2466
|
+
const refColumns = resolved.json.columns;
|
|
2467
|
+
const parentColumnKey = col.column ?? col.id;
|
|
2468
|
+
for (const refCol of refColumns) {
|
|
2469
|
+
if (refCol.idField) continue;
|
|
2470
|
+
const virtualId = `${col.id}_${refCol.id}`;
|
|
2471
|
+
const displayKey = refCol.displayKey ? `${refCol.id}.${refCol.displayKey}` : refCol.id;
|
|
2472
|
+
const hiddenInTable = col.hiddenInTable === true || refCol.hiddenInTable === true ? true : col.hiddenInTable ?? refCol.hiddenInTable;
|
|
2473
|
+
const hiddenInForm = col.hiddenInForm === true || refCol.hiddenInForm === true ? true : col.hiddenInForm ?? refCol.hiddenInForm;
|
|
2474
|
+
const hiddenInView = col.hiddenInView === true || refCol.hiddenInView === true ? true : col.hiddenInView ?? refCol.hiddenInView;
|
|
2475
|
+
const override = col.columns?.[virtualId] ?? col.columns?.[refCol.id] ?? {};
|
|
2476
|
+
const virtualCol = {
|
|
2477
|
+
id: virtualId,
|
|
2478
|
+
column: parentColumnKey,
|
|
2479
|
+
displayKey,
|
|
2480
|
+
label: refCol.label ?? refCol.id,
|
|
2481
|
+
columnType: "object",
|
|
2482
|
+
...hiddenInTable !== void 0 && {
|
|
2483
|
+
hiddenInTable
|
|
2484
|
+
},
|
|
2485
|
+
...hiddenInForm !== void 0 && {
|
|
2486
|
+
hiddenInForm
|
|
2487
|
+
},
|
|
2488
|
+
...hiddenInView !== void 0 && {
|
|
2489
|
+
hiddenInView
|
|
2490
|
+
},
|
|
2491
|
+
...refCol.sortable != null && {
|
|
2492
|
+
sortable: refCol.sortable
|
|
2493
|
+
},
|
|
2494
|
+
...refCol.fieldInput && {
|
|
2495
|
+
fieldInput: refCol.fieldInput
|
|
2496
|
+
},
|
|
2497
|
+
...override
|
|
2498
|
+
};
|
|
2499
|
+
result.push(virtualCol);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
return result;
|
|
2503
|
+
}, "expandExtendColumns");
|
|
2504
|
+
var buildValueLabelColumns = /* @__PURE__ */ __name((columns) => (columns ?? []).flatMap((c) => {
|
|
2505
|
+
const opts = c.fieldInput?.options;
|
|
2506
|
+
if (!opts?.emitObject || !Array.isArray(opts.values)) return [];
|
|
2507
|
+
return [
|
|
2508
|
+
{
|
|
2509
|
+
field: c.column ?? c.id,
|
|
2510
|
+
values: opts.values,
|
|
2511
|
+
...c.enum && {
|
|
2512
|
+
enumName: c.enum
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
];
|
|
2516
|
+
}), "buildValueLabelColumns");
|
|
2517
|
+
var applyRelationFormatDefault = /* @__PURE__ */ __name((cols) => cols?.map((col) => {
|
|
2518
|
+
const fi = col.fieldInput;
|
|
2519
|
+
if (fi && fi.resource && !fi.format && !fi.type) {
|
|
2520
|
+
return {
|
|
2521
|
+
...col,
|
|
2522
|
+
fieldInput: {
|
|
2523
|
+
...fi,
|
|
2524
|
+
format: "relation"
|
|
2525
|
+
}
|
|
2526
|
+
};
|
|
2527
|
+
}
|
|
2528
|
+
return col;
|
|
2529
|
+
}), "applyRelationFormatDefault");
|
|
2530
|
+
var resolveColumnFieldVariants = /* @__PURE__ */ __name((cols) => cols?.map((col) => {
|
|
2531
|
+
const fieldView = resolveViewField(col);
|
|
2532
|
+
const fieldTable = resolveTableField(col);
|
|
2533
|
+
return {
|
|
2534
|
+
...col,
|
|
2535
|
+
...fieldView && {
|
|
2536
|
+
fieldView
|
|
2537
|
+
},
|
|
2538
|
+
...fieldTable && {
|
|
2539
|
+
fieldTable
|
|
2540
|
+
}
|
|
2541
|
+
};
|
|
2542
|
+
}), "resolveColumnFieldVariants");
|
|
2543
|
+
|
|
2544
|
+
// src/lib/crud/translation/localize-resource.ts
|
|
2545
|
+
var clone = /* @__PURE__ */ __name((obj) => JSON.parse(JSON.stringify(obj)), "clone");
|
|
2546
|
+
var translateEnumOptions = /* @__PURE__ */ __name((columns, t) => {
|
|
2547
|
+
if (!columns) return;
|
|
2548
|
+
for (const col of columns) {
|
|
2549
|
+
if (!col.enum) continue;
|
|
2550
|
+
const opts = col.fieldInput?.options;
|
|
2551
|
+
if (!Array.isArray(opts?.values)) continue;
|
|
2552
|
+
for (const entry of opts.values) {
|
|
2553
|
+
entry.label = t(enumKey(col.enum, String(entry.value)), entry.label);
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
}, "translateEnumOptions");
|
|
2557
|
+
var translateValueLabelEntries = /* @__PURE__ */ __name((vlCols, t) => {
|
|
2558
|
+
if (!vlCols) return;
|
|
2559
|
+
for (const vlc of vlCols) {
|
|
2560
|
+
if (!vlc.enumName) continue;
|
|
2561
|
+
for (const entry of vlc.values) {
|
|
2562
|
+
entry.label = t(enumKey(vlc.enumName, String(entry.value)), entry.label);
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
}, "translateValueLabelEntries");
|
|
2566
|
+
var patchViewTitles = /* @__PURE__ */ __name((views, columnLabels) => {
|
|
2567
|
+
if (!views) return views;
|
|
2568
|
+
const patched = {};
|
|
2569
|
+
for (const [viewName, view] of Object.entries(views)) {
|
|
2570
|
+
const patchedView = clone(view);
|
|
2571
|
+
const props = patchedView.json_schema?.properties;
|
|
2572
|
+
if (props && typeof props === "object") {
|
|
2573
|
+
for (const [key, prop] of Object.entries(props)) {
|
|
2574
|
+
const translated = columnLabels.get(key);
|
|
2575
|
+
if (translated && prop && typeof prop === "object") {
|
|
2576
|
+
prop.title = translated;
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
if (patchedView.columns) {
|
|
2581
|
+
patchedView.columns = patchedView.columns.map((vc) => {
|
|
2582
|
+
const translated = columnLabels.get(vc.id);
|
|
2583
|
+
return translated ? {
|
|
2584
|
+
...vc,
|
|
2585
|
+
label: translated
|
|
2586
|
+
} : vc;
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
2589
|
+
patched[viewName] = patchedView;
|
|
2590
|
+
}
|
|
2591
|
+
return patched;
|
|
2592
|
+
}, "patchViewTitles");
|
|
2593
|
+
var localizeResource = /* @__PURE__ */ __name((config, t) => {
|
|
2594
|
+
const name = config.name;
|
|
2595
|
+
const localized = clone(config);
|
|
2596
|
+
localized.title = t(resourceTitleKey(name), config.title ?? config.tag);
|
|
2597
|
+
if (localized.sidebar) {
|
|
2598
|
+
const sidebarTranslation = t(resourceSidebarKey(name), config.sidebar?.label);
|
|
2599
|
+
if (sidebarTranslation !== resourceSidebarKey(name)) {
|
|
2600
|
+
localized.sidebar = {
|
|
2601
|
+
...localized.sidebar,
|
|
2602
|
+
label: sidebarTranslation
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
const columnLabels = /* @__PURE__ */ new Map();
|
|
2607
|
+
const columns = localized.columns;
|
|
2608
|
+
if (columns) {
|
|
2609
|
+
for (const col of columns) {
|
|
2610
|
+
const translated = t(columnKey(name, col.id), col.label ?? col.id);
|
|
2611
|
+
col.label = translated;
|
|
2612
|
+
columnLabels.set(col.id, translated);
|
|
2613
|
+
}
|
|
2614
|
+
translateEnumOptions(columns, t);
|
|
2615
|
+
localized.valueLabelColumns = buildValueLabelColumns(columns);
|
|
2616
|
+
}
|
|
2617
|
+
if (localized.views) {
|
|
2618
|
+
localized.views = patchViewTitles(localized.views, columnLabels);
|
|
2619
|
+
}
|
|
2620
|
+
if (localized.actions) {
|
|
2621
|
+
for (const a of localized.actions) {
|
|
2622
|
+
a.label = t(actionKey(name, a.id), a.label);
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
if (localized.tableActions) {
|
|
2626
|
+
for (const a of localized.tableActions) {
|
|
2627
|
+
a.label = t(actionKey(name, a.id), a.label);
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
if (localized.subResources) {
|
|
2631
|
+
for (const sub of localized.subResources) {
|
|
2632
|
+
const subName = sub.name ?? sub.childRoute;
|
|
2633
|
+
sub.title = t(subResourceTitleKey(name, subName), sub.title ?? subName);
|
|
2634
|
+
const subColumnLabels = /* @__PURE__ */ new Map();
|
|
2635
|
+
if (sub.views) {
|
|
2636
|
+
for (const view of Object.values(sub.views)) {
|
|
2637
|
+
if (view.columns) {
|
|
2638
|
+
for (const vc of view.columns) {
|
|
2639
|
+
const translated = t(subResourceColumnKey(name, subName, vc.id), vc.label ?? vc.id);
|
|
2640
|
+
vc.label = translated;
|
|
2641
|
+
subColumnLabels.set(vc.id, translated);
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
sub.views = patchViewTitles(sub.views, subColumnLabels);
|
|
2646
|
+
}
|
|
2647
|
+
translateValueLabelEntries(sub.valueLabelColumns, t);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
return localized;
|
|
2651
|
+
}, "localizeResource");
|
|
2652
|
+
|
|
2653
|
+
// src/lib/crud/resource-config.registry.ts
|
|
2255
2654
|
function _ts_decorate(decorators, target, key, desc2) {
|
|
2256
2655
|
var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
|
|
2257
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
2258
|
-
|
|
2656
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2657
|
+
r = Reflect.decorate(decorators, target, key, desc2);
|
|
2658
|
+
} else {
|
|
2659
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2660
|
+
if (d = decorators[i]) {
|
|
2661
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2259
2665
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2260
2666
|
}
|
|
2261
2667
|
__name(_ts_decorate, "_ts_decorate");
|
|
2262
|
-
function _ts_metadata(
|
|
2263
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
2668
|
+
function _ts_metadata(metadataKey, metadataValue) {
|
|
2669
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
2670
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
2671
|
+
}
|
|
2264
2672
|
}
|
|
2265
2673
|
__name(_ts_metadata, "_ts_metadata");
|
|
2266
2674
|
var ResourceConfigRegistry = class {
|
|
@@ -2269,21 +2677,45 @@ var ResourceConfigRegistry = class {
|
|
|
2269
2677
|
}
|
|
2270
2678
|
loader;
|
|
2271
2679
|
configs;
|
|
2680
|
+
translationRegistry;
|
|
2681
|
+
/**
|
|
2682
|
+
* Per-language memo: `Map<language, Map<route, Resource>>`.
|
|
2683
|
+
* Cleared whenever the underlying configs reload (dev mode).
|
|
2684
|
+
*/
|
|
2685
|
+
localizedCache = /* @__PURE__ */ new Map();
|
|
2272
2686
|
constructor(loader, initialConfigs) {
|
|
2273
2687
|
this.loader = loader;
|
|
2274
2688
|
this.configs = initialConfigs;
|
|
2275
2689
|
}
|
|
2276
|
-
|
|
2690
|
+
setTranslationRegistry(registry) {
|
|
2691
|
+
this.translationRegistry = registry;
|
|
2692
|
+
}
|
|
2693
|
+
async getAll(language) {
|
|
2277
2694
|
if (IS_DEV) {
|
|
2278
2695
|
this.configs = await this.loader.loadAll();
|
|
2696
|
+
this.localizedCache.clear();
|
|
2697
|
+
}
|
|
2698
|
+
if (!language || !this.translationRegistry?.active) {
|
|
2699
|
+
return this.configs;
|
|
2279
2700
|
}
|
|
2280
|
-
return this.configs;
|
|
2701
|
+
return this.configs.map((c) => this.getLocalized(c, language));
|
|
2281
2702
|
}
|
|
2282
|
-
async getByRoute(route) {
|
|
2703
|
+
async getByRoute(route, language) {
|
|
2283
2704
|
if (IS_DEV) {
|
|
2284
|
-
|
|
2705
|
+
const fresh = await this.loader.loadByRoute(route);
|
|
2706
|
+
this.localizedCache.clear();
|
|
2707
|
+
if (!fresh) return void 0;
|
|
2708
|
+
if (language && this.translationRegistry?.active) {
|
|
2709
|
+
return this.localize(fresh, language);
|
|
2710
|
+
}
|
|
2711
|
+
return fresh;
|
|
2285
2712
|
}
|
|
2286
|
-
|
|
2713
|
+
const config = this.configs.find((c) => c.route === route);
|
|
2714
|
+
if (!config) return void 0;
|
|
2715
|
+
if (language && this.translationRegistry?.active) {
|
|
2716
|
+
return this.getLocalized(config, language);
|
|
2717
|
+
}
|
|
2718
|
+
return config;
|
|
2287
2719
|
}
|
|
2288
2720
|
/**
|
|
2289
2721
|
* On-disk directory containing `route`'s `resource.json`, if known.
|
|
@@ -2294,6 +2726,24 @@ var ResourceConfigRegistry = class {
|
|
|
2294
2726
|
getResourceDir(route) {
|
|
2295
2727
|
return this.loader.getResourceDir(route);
|
|
2296
2728
|
}
|
|
2729
|
+
getLocalized(config, language) {
|
|
2730
|
+
let langMap = this.localizedCache.get(language);
|
|
2731
|
+
if (!langMap) {
|
|
2732
|
+
langMap = /* @__PURE__ */ new Map();
|
|
2733
|
+
this.localizedCache.set(language, langMap);
|
|
2734
|
+
}
|
|
2735
|
+
let localized = langMap.get(config.route);
|
|
2736
|
+
if (!localized) {
|
|
2737
|
+
localized = this.localize(config, language);
|
|
2738
|
+
langMap.set(config.route, localized);
|
|
2739
|
+
}
|
|
2740
|
+
return localized;
|
|
2741
|
+
}
|
|
2742
|
+
localize(config, language) {
|
|
2743
|
+
if (!this.translationRegistry) return config;
|
|
2744
|
+
const t = this.translationRegistry.translatorFor(language);
|
|
2745
|
+
return localizeResource(config, t);
|
|
2746
|
+
}
|
|
2297
2747
|
};
|
|
2298
2748
|
ResourceConfigRegistry = _ts_decorate([
|
|
2299
2749
|
(0, import_common.Injectable)(),
|
|
@@ -2304,19 +2754,34 @@ ResourceConfigRegistry = _ts_decorate([
|
|
|
2304
2754
|
])
|
|
2305
2755
|
], ResourceConfigRegistry);
|
|
2306
2756
|
|
|
2757
|
+
// src/lib/crud/translation/language.context.ts
|
|
2758
|
+
var import_node_async_hooks = require("async_hooks");
|
|
2759
|
+
var languageStore = new import_node_async_hooks.AsyncLocalStorage();
|
|
2760
|
+
var runWithLanguage = /* @__PURE__ */ __name((language, fn) => languageStore.run(language, fn), "runWithLanguage");
|
|
2761
|
+
var getRequestLanguage = /* @__PURE__ */ __name((defaultLanguage = "en") => languageStore.getStore() ?? defaultLanguage, "getRequestLanguage");
|
|
2762
|
+
|
|
2307
2763
|
// src/lib/crud/app-layout/app-layout.controller.ts
|
|
2308
2764
|
function _ts_decorate2(decorators, target, key, desc2) {
|
|
2309
2765
|
var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
|
|
2310
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
2311
|
-
|
|
2766
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2767
|
+
r = Reflect.decorate(decorators, target, key, desc2);
|
|
2768
|
+
} else {
|
|
2769
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2770
|
+
if (d = decorators[i]) {
|
|
2771
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2312
2775
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2313
2776
|
}
|
|
2314
2777
|
__name(_ts_decorate2, "_ts_decorate");
|
|
2315
|
-
function _ts_metadata2(
|
|
2316
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
2778
|
+
function _ts_metadata2(metadataKey, metadataValue) {
|
|
2779
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
2780
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
2781
|
+
}
|
|
2317
2782
|
}
|
|
2318
2783
|
__name(_ts_metadata2, "_ts_metadata");
|
|
2319
|
-
var createAppLayoutController = /* @__PURE__ */ __name((configs, sidebarGroups = {}, title, autoSave = true) => {
|
|
2784
|
+
var createAppLayoutController = /* @__PURE__ */ __name((configs, sidebarGroups = {}, title, autoSave = true, translationRegistry, i18nConfig) => {
|
|
2320
2785
|
const layoutPayload = buildLayoutPayload(configs, sidebarGroups, title, autoSave, IS_DEV);
|
|
2321
2786
|
let AppLayoutController = class AppLayoutController {
|
|
2322
2787
|
static {
|
|
@@ -2327,11 +2792,44 @@ var createAppLayoutController = /* @__PURE__ */ __name((configs, sidebarGroups =
|
|
|
2327
2792
|
this.configRegistry = configRegistry;
|
|
2328
2793
|
}
|
|
2329
2794
|
async getLayout() {
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2795
|
+
const language = getRequestLanguage();
|
|
2796
|
+
let payload;
|
|
2797
|
+
if (IS_DEV || language) {
|
|
2798
|
+
const fresh = await this.configRegistry.getAll(language);
|
|
2799
|
+
payload = buildLayoutPayload(fresh, language ? translateSidebarGroups(sidebarGroups, language, translationRegistry) : sidebarGroups, language ? translateTitle(title, language, translationRegistry) : title, autoSave, IS_DEV);
|
|
2800
|
+
} else {
|
|
2801
|
+
payload = layoutPayload;
|
|
2333
2802
|
}
|
|
2334
|
-
|
|
2803
|
+
if (translationRegistry?.active && i18nConfig) {
|
|
2804
|
+
const lang = language ?? i18nConfig.defaultLanguage;
|
|
2805
|
+
const bundle = translationRegistry.bundleFor(lang);
|
|
2806
|
+
return {
|
|
2807
|
+
...payload,
|
|
2808
|
+
i18n: {
|
|
2809
|
+
languages: i18nConfig.languages,
|
|
2810
|
+
defaultLanguage: i18nConfig.defaultLanguage,
|
|
2811
|
+
current: lang
|
|
2812
|
+
},
|
|
2813
|
+
...bundle.ui && {
|
|
2814
|
+
ui: bundle.ui
|
|
2815
|
+
}
|
|
2816
|
+
};
|
|
2817
|
+
}
|
|
2818
|
+
return payload;
|
|
2819
|
+
}
|
|
2820
|
+
getTranslations() {
|
|
2821
|
+
if (!translationRegistry?.active || !i18nConfig) {
|
|
2822
|
+
return {
|
|
2823
|
+
ui: {},
|
|
2824
|
+
validation: {}
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
const language = getRequestLanguage() ?? i18nConfig.defaultLanguage;
|
|
2828
|
+
const bundle = translationRegistry.bundleFor(language);
|
|
2829
|
+
return {
|
|
2830
|
+
ui: bundle.ui ?? {},
|
|
2831
|
+
validation: bundle.validation ?? {}
|
|
2832
|
+
};
|
|
2335
2833
|
}
|
|
2336
2834
|
};
|
|
2337
2835
|
_ts_decorate2([
|
|
@@ -2347,6 +2845,19 @@ var createAppLayoutController = /* @__PURE__ */ __name((configs, sidebarGroups =
|
|
|
2347
2845
|
_ts_metadata2("design:paramtypes", []),
|
|
2348
2846
|
_ts_metadata2("design:returntype", Promise)
|
|
2349
2847
|
], AppLayoutController.prototype, "getLayout", null);
|
|
2848
|
+
_ts_decorate2([
|
|
2849
|
+
(0, import_common2.Get)("translations"),
|
|
2850
|
+
(0, import_swagger.ApiOperation)({
|
|
2851
|
+
summary: "Get ui + validation translation dictionaries"
|
|
2852
|
+
}),
|
|
2853
|
+
(0, import_swagger.ApiResponse)({
|
|
2854
|
+
status: 200,
|
|
2855
|
+
description: "Translation dictionaries for the current language"
|
|
2856
|
+
}),
|
|
2857
|
+
_ts_metadata2("design:type", Function),
|
|
2858
|
+
_ts_metadata2("design:paramtypes", []),
|
|
2859
|
+
_ts_metadata2("design:returntype", void 0)
|
|
2860
|
+
], AppLayoutController.prototype, "getTranslations", null);
|
|
2350
2861
|
AppLayoutController = _ts_decorate2([
|
|
2351
2862
|
(0, import_common2.Controller)("_app"),
|
|
2352
2863
|
(0, import_swagger.ApiTags)("App"),
|
|
@@ -2360,10 +2871,28 @@ var createAppLayoutController = /* @__PURE__ */ __name((configs, sidebarGroups =
|
|
|
2360
2871
|
], AppLayoutController);
|
|
2361
2872
|
return AppLayoutController;
|
|
2362
2873
|
}, "createAppLayoutController");
|
|
2874
|
+
var translateSidebarGroups = /* @__PURE__ */ __name((groups, language, registry) => {
|
|
2875
|
+
if (!registry?.active) return groups;
|
|
2876
|
+
const t = registry.translatorFor(language);
|
|
2877
|
+
const translated = {};
|
|
2878
|
+
for (const [slug, cfg] of Object.entries(groups)) {
|
|
2879
|
+
const label = t(sidebarGroupKey(slug), cfg.label);
|
|
2880
|
+
translated[slug] = label !== cfg.label ? {
|
|
2881
|
+
...cfg,
|
|
2882
|
+
label
|
|
2883
|
+
} : cfg;
|
|
2884
|
+
}
|
|
2885
|
+
return translated;
|
|
2886
|
+
}, "translateSidebarGroups");
|
|
2887
|
+
var translateTitle = /* @__PURE__ */ __name((title, language, registry) => {
|
|
2888
|
+
if (!title || !registry?.active) return title;
|
|
2889
|
+
const t = registry.translatorFor(language);
|
|
2890
|
+
return t("app.title", title);
|
|
2891
|
+
}, "translateTitle");
|
|
2363
2892
|
|
|
2364
2893
|
// src/lib/crud/config/read.ts
|
|
2365
2894
|
var import_promises = require("fs/promises");
|
|
2366
|
-
var
|
|
2895
|
+
var import_node_path3 = require("path");
|
|
2367
2896
|
var fileExists = /* @__PURE__ */ __name(async (p) => {
|
|
2368
2897
|
try {
|
|
2369
2898
|
await (0, import_promises.access)(p);
|
|
@@ -2373,19 +2902,19 @@ var fileExists = /* @__PURE__ */ __name(async (p) => {
|
|
|
2373
2902
|
}
|
|
2374
2903
|
}, "fileExists");
|
|
2375
2904
|
var findConfigPath = /* @__PURE__ */ __name(async (cwd) => {
|
|
2376
|
-
let dir = (0,
|
|
2905
|
+
let dir = (0, import_node_path3.resolve)(cwd);
|
|
2377
2906
|
while (true) {
|
|
2378
2907
|
for (const name of CONFIG_FILES) {
|
|
2379
|
-
const candidate = (0,
|
|
2908
|
+
const candidate = (0, import_node_path3.join)(dir, name);
|
|
2380
2909
|
if (await fileExists(candidate)) return candidate;
|
|
2381
2910
|
}
|
|
2382
|
-
const parent = (0,
|
|
2911
|
+
const parent = (0, import_node_path3.dirname)(dir);
|
|
2383
2912
|
if (parent === dir) return void 0;
|
|
2384
2913
|
dir = parent;
|
|
2385
2914
|
}
|
|
2386
2915
|
}, "findConfigPath");
|
|
2387
2916
|
var loadConfig = /* @__PURE__ */ __name(async () => {
|
|
2388
|
-
const cwd = (0,
|
|
2917
|
+
const cwd = (0, import_node_path3.resolve)(process.cwd());
|
|
2389
2918
|
const path = await findConfigPath(cwd);
|
|
2390
2919
|
if (!path) {
|
|
2391
2920
|
throw new Error(`No crouton config found (looked for ${CONFIG_FILES.join(", ")} up from ${cwd}).`);
|
|
@@ -2415,77 +2944,187 @@ var CroutonValidationError = class extends Error {
|
|
|
2415
2944
|
}
|
|
2416
2945
|
};
|
|
2417
2946
|
|
|
2947
|
+
// src/lib/crud/translation/translation.loader.ts
|
|
2948
|
+
var import_node_fs3 = require("fs");
|
|
2949
|
+
var import_node_path4 = require("path");
|
|
2950
|
+
var loadTranslationBundles = /* @__PURE__ */ __name((translationsDir) => {
|
|
2951
|
+
if (!(0, import_node_fs3.existsSync)(translationsDir)) return {};
|
|
2952
|
+
const bundles = {};
|
|
2953
|
+
const entries = (0, import_node_fs3.readdirSync)(translationsDir, {
|
|
2954
|
+
withFileTypes: true
|
|
2955
|
+
});
|
|
2956
|
+
for (const entry of entries) {
|
|
2957
|
+
if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
|
|
2958
|
+
const lang = entry.name.replace(/\.json$/, "");
|
|
2959
|
+
try {
|
|
2960
|
+
bundles[lang] = JSON.parse((0, import_node_fs3.readFileSync)((0, import_node_path4.join)(translationsDir, entry.name), "utf-8"));
|
|
2961
|
+
} catch {
|
|
2962
|
+
}
|
|
2963
|
+
}
|
|
2964
|
+
return bundles;
|
|
2965
|
+
}, "loadTranslationBundles");
|
|
2966
|
+
|
|
2967
|
+
// src/lib/crud/translation/translation.registry.ts
|
|
2968
|
+
var TranslationRegistry2 = class {
|
|
2969
|
+
static {
|
|
2970
|
+
__name(this, "TranslationRegistry");
|
|
2971
|
+
}
|
|
2972
|
+
translationsDir;
|
|
2973
|
+
i18nConfig;
|
|
2974
|
+
bundles;
|
|
2975
|
+
constructor(translationsDir, i18nConfig) {
|
|
2976
|
+
this.translationsDir = translationsDir;
|
|
2977
|
+
this.i18nConfig = i18nConfig;
|
|
2978
|
+
this.bundles = loadTranslationBundles(translationsDir);
|
|
2979
|
+
}
|
|
2980
|
+
get languages() {
|
|
2981
|
+
return this.i18nConfig.languages;
|
|
2982
|
+
}
|
|
2983
|
+
get defaultLanguage() {
|
|
2984
|
+
return this.i18nConfig.defaultLanguage;
|
|
2985
|
+
}
|
|
2986
|
+
/** Whether i18n is active (at least one bundle loaded). */
|
|
2987
|
+
get active() {
|
|
2988
|
+
return Object.keys(this.bundles).length > 0;
|
|
2989
|
+
}
|
|
2990
|
+
translatorFor(language) {
|
|
2991
|
+
if (IS_DEV) {
|
|
2992
|
+
this.bundles = loadTranslationBundles(this.translationsDir);
|
|
2993
|
+
}
|
|
2994
|
+
return createTranslator(this.bundles, language, this.i18nConfig.defaultLanguage);
|
|
2995
|
+
}
|
|
2996
|
+
/** Raw bundle for a language (falls back to default). */
|
|
2997
|
+
bundleFor(language) {
|
|
2998
|
+
if (IS_DEV) {
|
|
2999
|
+
this.bundles = loadTranslationBundles(this.translationsDir);
|
|
3000
|
+
}
|
|
3001
|
+
return this.bundles[language] ?? this.bundles[this.i18nConfig.defaultLanguage] ?? {};
|
|
3002
|
+
}
|
|
3003
|
+
};
|
|
3004
|
+
|
|
2418
3005
|
// src/lib/crud/crouton-validation.filter.ts
|
|
2419
3006
|
function _ts_decorate3(decorators, target, key, desc2) {
|
|
2420
3007
|
var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
|
|
2421
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
2422
|
-
|
|
3008
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
3009
|
+
r = Reflect.decorate(decorators, target, key, desc2);
|
|
3010
|
+
} else {
|
|
3011
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
3012
|
+
if (d = decorators[i]) {
|
|
3013
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
2423
3017
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2424
3018
|
}
|
|
2425
3019
|
__name(_ts_decorate3, "_ts_decorate");
|
|
3020
|
+
function _ts_metadata3(metadataKey, metadataValue) {
|
|
3021
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
3022
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
3026
|
+
function _ts_param(paramIndex, decorator) {
|
|
3027
|
+
return function(target, key) {
|
|
3028
|
+
decorator(target, key, paramIndex);
|
|
3029
|
+
};
|
|
3030
|
+
}
|
|
3031
|
+
__name(_ts_param, "_ts_param");
|
|
2426
3032
|
var CroutonValidationExceptionFilter = class {
|
|
2427
3033
|
static {
|
|
2428
3034
|
__name(this, "CroutonValidationExceptionFilter");
|
|
2429
3035
|
}
|
|
3036
|
+
translationRegistry;
|
|
3037
|
+
constructor(translationRegistry) {
|
|
3038
|
+
this.translationRegistry = translationRegistry;
|
|
3039
|
+
}
|
|
2430
3040
|
catch(exception, host) {
|
|
2431
3041
|
const res = host.switchToHttp().getResponse();
|
|
3042
|
+
const errors = this.translateErrors(exception.errors);
|
|
2432
3043
|
res.status(400).json({
|
|
2433
3044
|
statusCode: 400,
|
|
2434
|
-
message:
|
|
3045
|
+
message: errors,
|
|
2435
3046
|
error: "Bad Request"
|
|
2436
3047
|
});
|
|
2437
3048
|
}
|
|
3049
|
+
translateErrors(errors) {
|
|
3050
|
+
if (!this.translationRegistry) return errors;
|
|
3051
|
+
const language = getRequestLanguage();
|
|
3052
|
+
if (!language) return errors;
|
|
3053
|
+
const t = this.translationRegistry.translatorFor(language);
|
|
3054
|
+
return errors.map(({ field, message, code }) => {
|
|
3055
|
+
if (!code) return {
|
|
3056
|
+
field,
|
|
3057
|
+
message
|
|
3058
|
+
};
|
|
3059
|
+
const key = validationKey(code);
|
|
3060
|
+
const translated = t(key, "");
|
|
3061
|
+
if (!translated) return {
|
|
3062
|
+
field,
|
|
3063
|
+
message
|
|
3064
|
+
};
|
|
3065
|
+
return {
|
|
3066
|
+
field,
|
|
3067
|
+
message: translated.replace(/\{field\}/g, field)
|
|
3068
|
+
};
|
|
3069
|
+
});
|
|
3070
|
+
}
|
|
2438
3071
|
};
|
|
2439
3072
|
CroutonValidationExceptionFilter = _ts_decorate3([
|
|
2440
|
-
(0, import_common3.Catch)(CroutonValidationError)
|
|
3073
|
+
(0, import_common3.Catch)(CroutonValidationError),
|
|
3074
|
+
_ts_param(0, (0, import_common3.Optional)()),
|
|
3075
|
+
_ts_param(0, (0, import_common3.Inject)(TranslationRegistry2)),
|
|
3076
|
+
_ts_metadata3("design:type", Function),
|
|
3077
|
+
_ts_metadata3("design:paramtypes", [
|
|
3078
|
+
typeof TranslationRegistry2 === "undefined" ? Object : TranslationRegistry2
|
|
3079
|
+
])
|
|
2441
3080
|
], CroutonValidationExceptionFilter);
|
|
2442
3081
|
|
|
2443
3082
|
// src/lib/crud/crud-controller.factory.ts
|
|
2444
|
-
var
|
|
3083
|
+
var import_common19 = require("@nestjs/common");
|
|
2445
3084
|
var import_swagger11 = require("@nestjs/swagger");
|
|
2446
3085
|
|
|
2447
3086
|
// src/lib/crud/action/action.types.ts
|
|
2448
|
-
var
|
|
2449
|
-
var ActionMetadataSchema =
|
|
3087
|
+
var import_zod25 = require("zod");
|
|
3088
|
+
var ActionMetadataSchema = import_zod25.z.object({
|
|
2450
3089
|
/** URL segment used in the endpoint. */
|
|
2451
|
-
id:
|
|
3090
|
+
id: import_zod25.z.string(),
|
|
2452
3091
|
/** Human-readable label shown as a button. */
|
|
2453
|
-
label:
|
|
3092
|
+
label: import_zod25.z.string().optional(),
|
|
2454
3093
|
/** MDI icon name, e.g. `"mdi:open-in-new"`. */
|
|
2455
|
-
icon:
|
|
3094
|
+
icon: import_zod25.z.string().optional(),
|
|
2456
3095
|
/** Tooltip text. Falls back to `label` when omitted. */
|
|
2457
|
-
tooltip:
|
|
3096
|
+
tooltip: import_zod25.z.string().optional(),
|
|
2458
3097
|
/** Per-row condition — button is hidden when false. */
|
|
2459
|
-
condition:
|
|
3098
|
+
condition: import_zod25.z.custom().optional()
|
|
2460
3099
|
});
|
|
2461
3100
|
var ResourceLinkActionSchema = ActionMetadataSchema.extend({
|
|
2462
|
-
type:
|
|
3101
|
+
type: import_zod25.z.literal("link"),
|
|
2463
3102
|
/** URL to open. May contain `{id}` or `{env.VAR}` placeholders. */
|
|
2464
|
-
href:
|
|
3103
|
+
href: import_zod25.z.string()
|
|
2465
3104
|
});
|
|
2466
3105
|
var ResourceRowProcedureActionSchema = ActionMetadataSchema.extend({
|
|
2467
|
-
type:
|
|
3106
|
+
type: import_zod25.z.literal("procedure").optional(),
|
|
2468
3107
|
/** HTTP method for the endpoint. Defaults to `"post"`. */
|
|
2469
|
-
method:
|
|
3108
|
+
method: import_zod25.z.string().optional(),
|
|
2470
3109
|
/** Static data payload merged into the request body by the frontend. */
|
|
2471
|
-
data:
|
|
3110
|
+
data: import_zod25.z.record(import_zod25.z.string(), import_zod25.z.unknown()).optional(),
|
|
2472
3111
|
/** Procedure called with `(prisma, recordId)`. */
|
|
2473
|
-
procedure:
|
|
3112
|
+
procedure: import_zod25.z.custom((v) => typeof v === "function")
|
|
2474
3113
|
});
|
|
2475
3114
|
var ResourceTableProcedureActionSchema = ActionMetadataSchema.extend({
|
|
2476
|
-
type:
|
|
3115
|
+
type: import_zod25.z.literal("procedure").optional(),
|
|
2477
3116
|
/** HTTP method for the endpoint. Defaults to `"post"`. */
|
|
2478
|
-
method:
|
|
3117
|
+
method: import_zod25.z.string().optional(),
|
|
2479
3118
|
/** Static data payload merged into the request body by the frontend. */
|
|
2480
|
-
data:
|
|
3119
|
+
data: import_zod25.z.record(import_zod25.z.string(), import_zod25.z.unknown()).optional(),
|
|
2481
3120
|
/** Procedure called with `(prisma)` — no record id. */
|
|
2482
|
-
procedure:
|
|
3121
|
+
procedure: import_zod25.z.custom((v) => typeof v === "function")
|
|
2483
3122
|
});
|
|
2484
|
-
var ResourceRowActionSchema =
|
|
3123
|
+
var ResourceRowActionSchema = import_zod25.z.union([
|
|
2485
3124
|
ResourceRowProcedureActionSchema,
|
|
2486
3125
|
ResourceLinkActionSchema
|
|
2487
3126
|
]);
|
|
2488
|
-
var ResourceTableActionSchema =
|
|
3127
|
+
var ResourceTableActionSchema = import_zod25.z.union([
|
|
2489
3128
|
ResourceTableProcedureActionSchema,
|
|
2490
3129
|
ResourceLinkActionSchema
|
|
2491
3130
|
]);
|
|
@@ -2493,17 +3132,17 @@ var isRowProcedureAction = /* @__PURE__ */ __name((action) => action.type !== "l
|
|
|
2493
3132
|
var isTableProcedureAction = /* @__PURE__ */ __name((action) => action.type !== "link", "isTableProcedureAction");
|
|
2494
3133
|
|
|
2495
3134
|
// src/lib/crud/loader/module.loader.ts
|
|
2496
|
-
var
|
|
3135
|
+
var import_node_fs4 = require("fs");
|
|
2497
3136
|
var import_node_module = require("module");
|
|
2498
|
-
var
|
|
3137
|
+
var import_node_path5 = require("path");
|
|
2499
3138
|
var _require = (0, import_node_module.createRequire)(importMetaUrl ?? __filename);
|
|
2500
3139
|
var findModule = /* @__PURE__ */ __name((dir, name) => {
|
|
2501
3140
|
for (const ext of [
|
|
2502
3141
|
".ts",
|
|
2503
3142
|
".js"
|
|
2504
3143
|
]) {
|
|
2505
|
-
const p = (0,
|
|
2506
|
-
if ((0,
|
|
3144
|
+
const p = (0, import_node_path5.join)(dir, `${name}${ext}`);
|
|
3145
|
+
if ((0, import_node_fs4.existsSync)(p)) return p;
|
|
2507
3146
|
}
|
|
2508
3147
|
return void 0;
|
|
2509
3148
|
}, "findModule");
|
|
@@ -2526,7 +3165,7 @@ var importDefault = /* @__PURE__ */ __name(async (filePath, onError) => {
|
|
|
2526
3165
|
}, "importDefault");
|
|
2527
3166
|
|
|
2528
3167
|
// src/lib/crud/action/action.loader.ts
|
|
2529
|
-
var
|
|
3168
|
+
var import_node_path6 = require("path");
|
|
2530
3169
|
var loadActions = /* @__PURE__ */ __name(async (jsonActions, basePath, scope) => {
|
|
2531
3170
|
const tag = scope === "row" ? "actions" : "tableActions";
|
|
2532
3171
|
const results = [];
|
|
@@ -2535,7 +3174,7 @@ var loadActions = /* @__PURE__ */ __name(async (jsonActions, basePath, scope) =>
|
|
|
2535
3174
|
results.push(action);
|
|
2536
3175
|
continue;
|
|
2537
3176
|
}
|
|
2538
|
-
const file = findModule((0,
|
|
3177
|
+
const file = findModule((0, import_node_path6.join)(basePath, "actions"), action.procedure);
|
|
2539
3178
|
if (!file) {
|
|
2540
3179
|
console.warn(`[${tag}] Procedure file not found for "${action.id}" in ${basePath}/actions/`);
|
|
2541
3180
|
continue;
|
|
@@ -2567,7 +3206,7 @@ var schemaFor = /* @__PURE__ */ __name((def2, op) => {
|
|
|
2567
3206
|
var upsertOnFor = /* @__PURE__ */ __name((def2) => def2.upsert?.upsertOn, "upsertOnFor");
|
|
2568
3207
|
|
|
2569
3208
|
// src/lib/crud/custom-repository/custom-repository.types.ts
|
|
2570
|
-
var
|
|
3209
|
+
var import_zod26 = require("zod");
|
|
2571
3210
|
var CUSTOM_OPS = [
|
|
2572
3211
|
"findAll",
|
|
2573
3212
|
"findOne",
|
|
@@ -2584,7 +3223,7 @@ var PARENT_METHOD = {
|
|
|
2584
3223
|
patch: "patchByParent",
|
|
2585
3224
|
delete: "deleteByParent"
|
|
2586
3225
|
};
|
|
2587
|
-
var CustomRepositorySchema =
|
|
3226
|
+
var CustomRepositorySchema = import_zod26.z.custom((value) => typeof value === "object" && value !== null);
|
|
2588
3227
|
|
|
2589
3228
|
// src/lib/crud/resource/resource-load-errors.registry.ts
|
|
2590
3229
|
var ResourceLoadErrorsRegistry = class ResourceLoadErrorsRegistry2 {
|
|
@@ -2650,7 +3289,7 @@ var loadSubResourceRepositories = /* @__PURE__ */ __name(async (subResources, pa
|
|
|
2650
3289
|
}, "loadSubResourceRepositories");
|
|
2651
3290
|
|
|
2652
3291
|
// src/lib/crud/custom-repository/custom-repository.adapter.ts
|
|
2653
|
-
var
|
|
3292
|
+
var import_common5 = require("@nestjs/common");
|
|
2654
3293
|
|
|
2655
3294
|
// src/lib/crud/constants.ts
|
|
2656
3295
|
var PRISMA_NOT_FOUND_CODE = "P2025";
|
|
@@ -2658,33 +3297,33 @@ var DEFAULT_ID_TYPE = "string";
|
|
|
2658
3297
|
var DEFAULT_ID_FIELD = "id";
|
|
2659
3298
|
|
|
2660
3299
|
// src/lib/crud/hooks/hooks.types.ts
|
|
2661
|
-
var
|
|
2662
|
-
var WriteOpSchema =
|
|
3300
|
+
var import_zod27 = require("zod");
|
|
3301
|
+
var WriteOpSchema = import_zod27.z.enum([
|
|
2663
3302
|
"create",
|
|
2664
3303
|
"update",
|
|
2665
3304
|
"patch",
|
|
2666
3305
|
"upsert",
|
|
2667
3306
|
"delete"
|
|
2668
3307
|
]);
|
|
2669
|
-
var ReadOpSchema =
|
|
3308
|
+
var ReadOpSchema = import_zod27.z.enum([
|
|
2670
3309
|
"findAll",
|
|
2671
3310
|
"findOne"
|
|
2672
3311
|
]);
|
|
2673
|
-
var ResourceHooksSchema =
|
|
2674
|
-
beforeWrite:
|
|
2675
|
-
afterWrite:
|
|
2676
|
-
afterRead:
|
|
3312
|
+
var ResourceHooksSchema = import_zod27.z.object({
|
|
3313
|
+
beforeWrite: import_zod27.z.custom().optional(),
|
|
3314
|
+
afterWrite: import_zod27.z.custom().optional(),
|
|
3315
|
+
afterRead: import_zod27.z.custom().optional()
|
|
2677
3316
|
});
|
|
2678
3317
|
|
|
2679
3318
|
// src/lib/crud/hooks/hooks.loader.ts
|
|
2680
|
-
var
|
|
3319
|
+
var import_node_path7 = require("path");
|
|
2681
3320
|
var loadResourceHooks = /* @__PURE__ */ __name(async (basePath) => {
|
|
2682
3321
|
const file = findModule(basePath, "hooks");
|
|
2683
3322
|
return file ? importDefault(file) : void 0;
|
|
2684
3323
|
}, "loadResourceHooks");
|
|
2685
3324
|
var loadSubResourceHooks = /* @__PURE__ */ __name(async (subResources, basePath) => {
|
|
2686
3325
|
for (const sub of subResources) {
|
|
2687
|
-
const file = (sub.name ? findModule((0,
|
|
3326
|
+
const file = (sub.name ? findModule((0, import_node_path7.join)(basePath, "hooks"), sub.name) : void 0) ?? (sub.childDir ? findModule(sub.childDir, "hooks") : void 0);
|
|
2688
3327
|
if (!file) continue;
|
|
2689
3328
|
const hooks = await importDefault(file);
|
|
2690
3329
|
if (hooks) sub.hooks = hooks;
|
|
@@ -2764,12 +3403,73 @@ var postWrite = /* @__PURE__ */ __name(async (result, op, target, prisma, id, re
|
|
|
2764
3403
|
}) : result;
|
|
2765
3404
|
}, "postWrite");
|
|
2766
3405
|
|
|
3406
|
+
// src/lib/crud/translation/language.interceptor.ts
|
|
3407
|
+
var import_common4 = require("@nestjs/common");
|
|
3408
|
+
function _ts_decorate4(decorators, target, key, desc2) {
|
|
3409
|
+
var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
|
|
3410
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
3411
|
+
r = Reflect.decorate(decorators, target, key, desc2);
|
|
3412
|
+
} else {
|
|
3413
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
3414
|
+
if (d = decorators[i]) {
|
|
3415
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3420
|
+
}
|
|
3421
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
3422
|
+
function _ts_metadata4(metadataKey, metadataValue) {
|
|
3423
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
3424
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
3428
|
+
var LanguageInterceptor = class {
|
|
3429
|
+
static {
|
|
3430
|
+
__name(this, "LanguageInterceptor");
|
|
3431
|
+
}
|
|
3432
|
+
registry;
|
|
3433
|
+
constructor(registry) {
|
|
3434
|
+
this.registry = registry;
|
|
3435
|
+
}
|
|
3436
|
+
intercept(context, next) {
|
|
3437
|
+
const http = context.switchToHttp();
|
|
3438
|
+
const request = http.getRequest();
|
|
3439
|
+
const response = http.getResponse();
|
|
3440
|
+
const acceptLanguage = request.headers["accept-language"];
|
|
3441
|
+
const resolved = resolveLanguage(acceptLanguage, this.registry.languages, this.registry.defaultLanguage);
|
|
3442
|
+
response.setHeader("Vary", "Accept-Language");
|
|
3443
|
+
response.setHeader("Content-Language", resolved);
|
|
3444
|
+
return runWithLanguage(resolved, () => next.handle());
|
|
3445
|
+
}
|
|
3446
|
+
};
|
|
3447
|
+
LanguageInterceptor = _ts_decorate4([
|
|
3448
|
+
(0, import_common4.Injectable)(),
|
|
3449
|
+
_ts_metadata4("design:type", Function),
|
|
3450
|
+
_ts_metadata4("design:paramtypes", [
|
|
3451
|
+
typeof TranslationRegistry === "undefined" ? Object : TranslationRegistry
|
|
3452
|
+
])
|
|
3453
|
+
], LanguageInterceptor);
|
|
3454
|
+
|
|
3455
|
+
// src/lib/crud/translation/resolve-value-labels.ts
|
|
3456
|
+
var resolveValueLabelColumns = /* @__PURE__ */ __name(async (route, bootTimeCols, configRegistry, childRoute) => {
|
|
3457
|
+
if (!configRegistry) return bootTimeCols;
|
|
3458
|
+
const language = getRequestLanguage();
|
|
3459
|
+
if (!language) return bootTimeCols;
|
|
3460
|
+
const localized = await configRegistry.getByRoute(route, language);
|
|
3461
|
+
if (!localized) return bootTimeCols;
|
|
3462
|
+
if (!childRoute) return localized.valueLabelColumns ?? bootTimeCols;
|
|
3463
|
+
const sub = (localized.subResources ?? []).find((s) => s.childRoute === childRoute);
|
|
3464
|
+
return sub?.valueLabelColumns ?? bootTimeCols;
|
|
3465
|
+
}, "resolveValueLabelColumns");
|
|
3466
|
+
|
|
2767
3467
|
// src/lib/crud/custom-repository/custom-repository.adapter.ts
|
|
2768
3468
|
var unsupported = /* @__PURE__ */ __name((config, op) => {
|
|
2769
3469
|
const method = config.parent ? PARENT_METHOD[op] : op;
|
|
2770
|
-
throw new
|
|
3470
|
+
throw new import_common5.NotImplementedException(`Resource "${config.name}" enables "${op}" but its repository.ts does not implement "${method}".`);
|
|
2771
3471
|
}, "unsupported");
|
|
2772
|
-
var createCustomRepository = /* @__PURE__ */ __name((prisma, config, dataSources, repository) => {
|
|
3472
|
+
var createCustomRepository = /* @__PURE__ */ __name((prisma, config, dataSources, repository, configRegistry) => {
|
|
2773
3473
|
const repo = repository ?? {};
|
|
2774
3474
|
const idField = config.idField ?? DEFAULT_ID_FIELD;
|
|
2775
3475
|
const toId = /* @__PURE__ */ __name((id) => (config.idType ?? DEFAULT_ID_TYPE) === "number" ? +id : String(id), "toId");
|
|
@@ -2777,7 +3477,7 @@ var createCustomRepository = /* @__PURE__ */ __name((prisma, config, dataSources
|
|
|
2777
3477
|
const parentIdFrom = /* @__PURE__ */ __name((request) => {
|
|
2778
3478
|
const raw = request?.params?.[parentRef.param];
|
|
2779
3479
|
if (raw === void 0 || raw === null || raw === "") {
|
|
2780
|
-
throw new
|
|
3480
|
+
throw new import_common5.BadRequestException(`Resource "${config.name}" is nested under "${parentRef.route}" but no "${parentRef.param}" was supplied.`);
|
|
2781
3481
|
}
|
|
2782
3482
|
return (parentRef.idType ?? "string") === "number" ? +raw : String(raw);
|
|
2783
3483
|
}, "parentIdFrom");
|
|
@@ -2824,7 +3524,12 @@ var createCustomRepository = /* @__PURE__ */ __name((prisma, config, dataSources
|
|
|
2824
3524
|
if (!repo.findAll) unsupported(config, "findAll");
|
|
2825
3525
|
result = await repo.findAll(params, ctx("findAll", params, void 0, request));
|
|
2826
3526
|
}
|
|
2827
|
-
const
|
|
3527
|
+
const vlCols = await resolveValueLabelColumns(config.route, config.valueLabelColumns, configRegistry);
|
|
3528
|
+
const target = vlCols === config.valueLabelColumns ? config : {
|
|
3529
|
+
hooks: config.hooks,
|
|
3530
|
+
valueLabelColumns: vlCols
|
|
3531
|
+
};
|
|
3532
|
+
const data = await decorateRows(result?.data ?? [], "findAll", target, prisma, request, parentHookCtx(request));
|
|
2828
3533
|
return {
|
|
2829
3534
|
data,
|
|
2830
3535
|
count: result?.count ?? data.length
|
|
@@ -2844,7 +3549,7 @@ var createCustomRepository = /* @__PURE__ */ __name((prisma, config, dataSources
|
|
|
2844
3549
|
row = await repo.findOne(toId(id), ctx("findOne", void 0, id, request));
|
|
2845
3550
|
}
|
|
2846
3551
|
if (row === null || row === void 0) {
|
|
2847
|
-
throw new
|
|
3552
|
+
throw new import_common5.NotFoundException(`${config.name} with id ${id} not found`);
|
|
2848
3553
|
}
|
|
2849
3554
|
return decorateRow(row, "findOne", config, prisma, request, parentHookCtx(request));
|
|
2850
3555
|
}, "findOne");
|
|
@@ -2871,7 +3576,7 @@ var createCustomRepository = /* @__PURE__ */ __name((prisma, config, dataSources
|
|
|
2871
3576
|
return postWrite(result, op, config, prisma, coercedId, request, parentHookCtx(request));
|
|
2872
3577
|
}, "write");
|
|
2873
3578
|
const notAChildRepository = /* @__PURE__ */ __name(async () => {
|
|
2874
|
-
throw new
|
|
3579
|
+
throw new import_common5.NotImplementedException(`Resource "${config.name}" is a custom resource; nested sub-resource routes are not supported. Expose the child collection as its own resource instead.`);
|
|
2875
3580
|
}, "notAChildRepository");
|
|
2876
3581
|
return {
|
|
2877
3582
|
prisma,
|
|
@@ -2906,10 +3611,10 @@ var createCustomRepository = /* @__PURE__ */ __name((prisma, config, dataSources
|
|
|
2906
3611
|
return postWrite(result, "delete", config, prisma, coercedId, request, parentHookCtx(request));
|
|
2907
3612
|
}, "delete"),
|
|
2908
3613
|
upsert: /* @__PURE__ */ __name(async () => {
|
|
2909
|
-
throw new
|
|
3614
|
+
throw new import_common5.NotImplementedException(`Resource "${config.name}" is a custom resource; upsert is not part of the repository contract.`);
|
|
2910
3615
|
}, "upsert"),
|
|
2911
3616
|
upsertMany: /* @__PURE__ */ __name(async () => {
|
|
2912
|
-
throw new
|
|
3617
|
+
throw new import_common5.NotImplementedException(`Resource "${config.name}" is a custom resource; upsert is not part of the repository contract.`);
|
|
2913
3618
|
}, "upsertMany"),
|
|
2914
3619
|
findAllByParent: notAChildRepository,
|
|
2915
3620
|
findOneChild: notAChildRepository,
|
|
@@ -2938,19 +3643,19 @@ var validateCustomRepository = /* @__PURE__ */ __name((config, repository) => {
|
|
|
2938
3643
|
}, "validateCustomRepository");
|
|
2939
3644
|
|
|
2940
3645
|
// src/lib/crud/read.repository.ts
|
|
2941
|
-
var
|
|
3646
|
+
var import_common7 = require("@nestjs/common");
|
|
2942
3647
|
|
|
2943
3648
|
// src/lib/crud/custom-repository/child-delegate.ts
|
|
2944
|
-
var
|
|
3649
|
+
var import_common6 = require("@nestjs/common");
|
|
2945
3650
|
var childRepositoryFn = /* @__PURE__ */ __name((sub, op, parentName) => {
|
|
2946
3651
|
const repo = sub.repository;
|
|
2947
3652
|
const method = PARENT_METHOD[op];
|
|
2948
3653
|
if (!repo) {
|
|
2949
|
-
throw new
|
|
3654
|
+
throw new import_common6.NotImplementedException(`Sub-resource "${sub.childRoute}" of "${parentName}" is a custom resource but no repository.ts was loaded for it.`);
|
|
2950
3655
|
}
|
|
2951
3656
|
const fn = repo[method] ?? (op === "patch" ? repo[PARENT_METHOD.update] : void 0);
|
|
2952
3657
|
if (typeof fn !== "function") {
|
|
2953
|
-
throw new
|
|
3658
|
+
throw new import_common6.NotImplementedException(`Sub-resource "${sub.childRoute}" of "${parentName}" does not implement "${method}" in its repository.ts.`);
|
|
2954
3659
|
}
|
|
2955
3660
|
return fn.bind(repo);
|
|
2956
3661
|
}, "childRepositoryFn");
|
|
@@ -3247,12 +3952,14 @@ var ReadRepository = class {
|
|
|
3247
3952
|
config;
|
|
3248
3953
|
listSelect;
|
|
3249
3954
|
oneSelect;
|
|
3250
|
-
|
|
3955
|
+
configRegistry;
|
|
3956
|
+
constructor(prismaModel, prisma, config, listSelect, oneSelect, configRegistry) {
|
|
3251
3957
|
this.prismaModel = prismaModel;
|
|
3252
3958
|
this.prisma = prisma;
|
|
3253
3959
|
this.config = config;
|
|
3254
3960
|
this.listSelect = listSelect;
|
|
3255
3961
|
this.oneSelect = oneSelect;
|
|
3962
|
+
this.configRegistry = configRegistry;
|
|
3256
3963
|
}
|
|
3257
3964
|
/**
|
|
3258
3965
|
* Physical table name for raw SQL (calculated columns).
|
|
@@ -3298,7 +4005,12 @@ var ReadRepository = class {
|
|
|
3298
4005
|
};
|
|
3299
4006
|
}
|
|
3300
4007
|
async decorate(rows, op, request) {
|
|
3301
|
-
|
|
4008
|
+
const vlCols = await resolveValueLabelColumns(this.config.route, this.config.valueLabelColumns, this.configRegistry);
|
|
4009
|
+
const target = vlCols === this.config.valueLabelColumns ? this.config : {
|
|
4010
|
+
hooks: this.config.hooks,
|
|
4011
|
+
valueLabelColumns: vlCols
|
|
4012
|
+
};
|
|
4013
|
+
return decorateRows(rows, op, target, this.prisma, request);
|
|
3302
4014
|
}
|
|
3303
4015
|
async decorateOne(row, op, request) {
|
|
3304
4016
|
return decorateRow(row, op, this.config, this.prisma, request);
|
|
@@ -3310,11 +4022,12 @@ var ReadRepository = class {
|
|
|
3310
4022
|
async findAll(params, request) {
|
|
3311
4023
|
const subResources = this.config.subResources ?? [];
|
|
3312
4024
|
const projection = this.projection("findAll");
|
|
4025
|
+
const vlCols = await resolveValueLabelColumns(this.config.route, this.config.valueLabelColumns, this.configRegistry);
|
|
3313
4026
|
const query = {
|
|
3314
4027
|
where: this.buildWhere(params.filter),
|
|
3315
4028
|
take: params.pageSize,
|
|
3316
4029
|
skip: offsetOf(params),
|
|
3317
|
-
orderBy: this.safeSort(sanitizeValueLabelSort(params.sort,
|
|
4030
|
+
orderBy: this.safeSort(sanitizeValueLabelSort(params.sort, vlCols), params.sortDir)
|
|
3318
4031
|
};
|
|
3319
4032
|
const prismaSubResources = subResources.filter((s) => s.childKind !== "custom");
|
|
3320
4033
|
const oneToManySubResources = prismaSubResources.filter((s) => s.relationType !== "manyToOne");
|
|
@@ -3402,7 +4115,7 @@ var ReadRepository = class {
|
|
|
3402
4115
|
}
|
|
3403
4116
|
}
|
|
3404
4117
|
const record = await this.prismaModel.findUnique(query);
|
|
3405
|
-
if (!record) throw new
|
|
4118
|
+
if (!record) throw new import_common7.NotFoundException(`${this.config.name} with id ${id} not found`);
|
|
3406
4119
|
const [withCalc] = await mergeCalculatedColumnsForRows([
|
|
3407
4120
|
record
|
|
3408
4121
|
], this.config.calculatedColumns ?? [], this.tableName, this.prisma, this.config.idField ?? "id");
|
|
@@ -3444,7 +4157,8 @@ var ReadRepository = class {
|
|
|
3444
4157
|
request,
|
|
3445
4158
|
parent: this.parentHookContext(parentId2)
|
|
3446
4159
|
}))) : rows;
|
|
3447
|
-
const
|
|
4160
|
+
const subVlCols2 = await resolveValueLabelColumns(this.config.route, sub.valueLabelColumns, this.configRegistry, sub.childRoute);
|
|
4161
|
+
const labeled2 = subVlCols2?.length ? decorated2.map((r) => applyValueLabelColumns(r, subVlCols2)) : decorated2;
|
|
3448
4162
|
return {
|
|
3449
4163
|
data: labeled2,
|
|
3450
4164
|
count: result?.count ?? labeled2.length
|
|
@@ -3457,7 +4171,8 @@ var ReadRepository = class {
|
|
|
3457
4171
|
[sub.foreignKey]: this.toId(parentId2)
|
|
3458
4172
|
};
|
|
3459
4173
|
const includeClause = buildIncludeClause(sub.include);
|
|
3460
|
-
const
|
|
4174
|
+
const subVlCols = await resolveValueLabelColumns(this.config.route, sub.valueLabelColumns, this.configRegistry, sub.childRoute);
|
|
4175
|
+
const childSort = orderableChildSort(sanitizeValueLabelSort(params.sort, subVlCols), childModel, sub);
|
|
3461
4176
|
const [data, count] = await Promise.all([
|
|
3462
4177
|
childModel.findMany({
|
|
3463
4178
|
where,
|
|
@@ -3479,7 +4194,7 @@ var ReadRepository = class {
|
|
|
3479
4194
|
request,
|
|
3480
4195
|
parent: this.parentHookContext(parentId2)
|
|
3481
4196
|
}))) : withCalc;
|
|
3482
|
-
const labeled =
|
|
4197
|
+
const labeled = subVlCols?.length ? decorated.map((r) => applyValueLabelColumns(r, subVlCols)) : decorated;
|
|
3483
4198
|
return {
|
|
3484
4199
|
data: labeled,
|
|
3485
4200
|
count
|
|
@@ -3492,7 +4207,7 @@ var ReadRepository = class {
|
|
|
3492
4207
|
async findOneChild(sub, childId, parentId2, request) {
|
|
3493
4208
|
if (sub.childKind === "custom") {
|
|
3494
4209
|
if (parentId2 === void 0) {
|
|
3495
|
-
throw new
|
|
4210
|
+
throw new import_common7.BadRequestException(`Sub-resource "${sub.childRoute}" of "${this.config.name}" requires a parent id.`);
|
|
3496
4211
|
}
|
|
3497
4212
|
const findOne = childRepositoryFn(sub, "findOne", this.config.name);
|
|
3498
4213
|
const row = await findOne(this.toId(parentId2), (sub.idType ?? "string") === "number" ? +childId : String(childId), childCtx({
|
|
@@ -3504,7 +4219,7 @@ var ReadRepository = class {
|
|
|
3504
4219
|
request
|
|
3505
4220
|
}));
|
|
3506
4221
|
if (row === null || row === void 0) {
|
|
3507
|
-
throw new
|
|
4222
|
+
throw new import_common7.NotFoundException(`${sub.childRoute} with id ${childId} not found`);
|
|
3508
4223
|
}
|
|
3509
4224
|
return sub.hooks?.afterRead ? sub.hooks.afterRead(row, {
|
|
3510
4225
|
prisma: this.prisma,
|
|
@@ -3528,7 +4243,7 @@ var ReadRepository = class {
|
|
|
3528
4243
|
include: includeClause
|
|
3529
4244
|
}
|
|
3530
4245
|
});
|
|
3531
|
-
if (!record) throw new
|
|
4246
|
+
if (!record) throw new import_common7.NotFoundException(`${sub.childRoute} with id ${childId} not found`);
|
|
3532
4247
|
const [withCalc] = sub.calculatedColumns?.length ? await mergeCalculatedColumnsForRows([
|
|
3533
4248
|
record
|
|
3534
4249
|
], sub.calculatedColumns, sub.childModel, this.prisma, sub.idField ?? "id") : [
|
|
@@ -3545,9 +4260,9 @@ var ReadRepository = class {
|
|
|
3545
4260
|
};
|
|
3546
4261
|
|
|
3547
4262
|
// src/lib/crud/schema.utils.ts
|
|
3548
|
-
var
|
|
4263
|
+
var import_zod28 = require("zod");
|
|
3549
4264
|
function isZodSchema(schema) {
|
|
3550
|
-
return schema instanceof
|
|
4265
|
+
return schema instanceof import_zod28.ZodObject;
|
|
3551
4266
|
}
|
|
3552
4267
|
__name(isZodSchema, "isZodSchema");
|
|
3553
4268
|
var isNullableProperty2 = /* @__PURE__ */ __name((property) => {
|
|
@@ -3561,7 +4276,7 @@ var dropNullableFromRequired2 = /* @__PURE__ */ __name((jsonSchema) => {
|
|
|
3561
4276
|
}, "dropNullableFromRequired");
|
|
3562
4277
|
function toJsonSchema(schema) {
|
|
3563
4278
|
if (isZodSchema(schema)) {
|
|
3564
|
-
const jsonSchema = (0,
|
|
4279
|
+
const jsonSchema = (0, import_zod28.toJSONSchema)(schema, {
|
|
3565
4280
|
target: "openApi3",
|
|
3566
4281
|
...jsonSchemaOpts
|
|
3567
4282
|
});
|
|
@@ -3614,7 +4329,7 @@ function toSelectFields(schema) {
|
|
|
3614
4329
|
__name(toSelectFields, "toSelectFields");
|
|
3615
4330
|
|
|
3616
4331
|
// src/lib/crud/write.repository.ts
|
|
3617
|
-
var
|
|
4332
|
+
var import_common8 = require("@nestjs/common");
|
|
3618
4333
|
var includeRelationNames = /* @__PURE__ */ __name((include) => new Set((include ?? []).map((e) => typeof e === "string" ? e : e.relation)), "includeRelationNames");
|
|
3619
4334
|
var PRISMA_RELATION_WRITE_KEYS = /* @__PURE__ */ new Set([
|
|
3620
4335
|
"connect",
|
|
@@ -3649,7 +4364,7 @@ var WriteRepository = class {
|
|
|
3649
4364
|
return (this.config.idType ?? "string") === "number" ? +id : String(id);
|
|
3650
4365
|
}
|
|
3651
4366
|
notFound(id) {
|
|
3652
|
-
return new
|
|
4367
|
+
return new import_common8.NotFoundException(`${this.config.name} with id ${id} not found`);
|
|
3653
4368
|
}
|
|
3654
4369
|
stripSubResourceKeys(data) {
|
|
3655
4370
|
if (!data || typeof data !== "object" || Array.isArray(data)) return data;
|
|
@@ -3685,7 +4400,7 @@ var WriteRepository = class {
|
|
|
3685
4400
|
}
|
|
3686
4401
|
upsertWhere(data) {
|
|
3687
4402
|
const keys = upsertOnFor(resolveDefinition(this.config));
|
|
3688
|
-
if (!keys) throw new
|
|
4403
|
+
if (!keys) throw new import_common8.BadRequestException(`${this.config.name} has no upsertOn configured`);
|
|
3689
4404
|
if (typeof keys === "string") return {
|
|
3690
4405
|
[keys]: data[keys]
|
|
3691
4406
|
};
|
|
@@ -3777,7 +4492,7 @@ var WriteRepository = class {
|
|
|
3777
4492
|
*/
|
|
3778
4493
|
async delegateChildWrite(sub, op, parentId1, childId, data, request) {
|
|
3779
4494
|
if (parentId1 === void 0) {
|
|
3780
|
-
throw new
|
|
4495
|
+
throw new import_common8.BadRequestException(`Sub-resource "${sub.childRoute}" of "${this.config.name}" requires a parent id.`);
|
|
3781
4496
|
}
|
|
3782
4497
|
const fn = childRepositoryFn(sub, op, this.config.name);
|
|
3783
4498
|
const id = childId === void 0 ? void 0 : (sub.idType ?? "string") === "number" ? +childId : String(childId);
|
|
@@ -3888,7 +4603,7 @@ var WriteRepository = class {
|
|
|
3888
4603
|
request
|
|
3889
4604
|
}) : result;
|
|
3890
4605
|
} catch (e) {
|
|
3891
|
-
if (e?.code === PRISMA_NOT_FOUND_CODE) throw new
|
|
4606
|
+
if (e?.code === PRISMA_NOT_FOUND_CODE) throw new import_common8.NotFoundException(`${sub.childRoute} with id ${childId} not found`);
|
|
3892
4607
|
throw e;
|
|
3893
4608
|
}
|
|
3894
4609
|
}
|
|
@@ -3913,7 +4628,7 @@ var WriteRepository = class {
|
|
|
3913
4628
|
const result = await childModel.deleteMany({
|
|
3914
4629
|
where
|
|
3915
4630
|
});
|
|
3916
|
-
if (result.count === 0) throw new
|
|
4631
|
+
if (result.count === 0) throw new import_common8.NotFoundException(`${sub.childRoute} with id ${childId} not found`);
|
|
3917
4632
|
return sub.hooks?.afterWrite ? sub.hooks.afterWrite(result, {
|
|
3918
4633
|
prisma: this.prisma,
|
|
3919
4634
|
op: "delete",
|
|
@@ -3921,19 +4636,19 @@ var WriteRepository = class {
|
|
|
3921
4636
|
request
|
|
3922
4637
|
}) : result;
|
|
3923
4638
|
} catch (e) {
|
|
3924
|
-
if (e?.code === PRISMA_NOT_FOUND_CODE) throw new
|
|
4639
|
+
if (e?.code === PRISMA_NOT_FOUND_CODE) throw new import_common8.NotFoundException(`${sub.childRoute} with id ${childId} not found`);
|
|
3925
4640
|
throw e;
|
|
3926
4641
|
}
|
|
3927
4642
|
}
|
|
3928
4643
|
};
|
|
3929
4644
|
|
|
3930
4645
|
// src/lib/crud/crud-repository.factory.ts
|
|
3931
|
-
function createCrudRepository(prisma, config, dataSources) {
|
|
4646
|
+
function createCrudRepository(prisma, config, dataSources, configRegistry) {
|
|
3932
4647
|
if (config.kind === "custom") {
|
|
3933
4648
|
return createCustomRepository(prisma, config, dataSources ?? {
|
|
3934
4649
|
resolve: /* @__PURE__ */ __name(() => prisma, "resolve"),
|
|
3935
4650
|
entries: /* @__PURE__ */ __name(() => [], "entries")
|
|
3936
|
-
}, config.repository);
|
|
4651
|
+
}, config.repository, configRegistry);
|
|
3937
4652
|
}
|
|
3938
4653
|
if (!config.model) {
|
|
3939
4654
|
throw new Error(`Resource "${config.name}" has no "model". A prisma-backed resource must name its Prisma model; set "kind": "custom" for a resource with no model.`);
|
|
@@ -3947,7 +4662,7 @@ function createCrudRepository(prisma, config, dataSources) {
|
|
|
3947
4662
|
const oneSchema = schemaFor(definition, "findOne");
|
|
3948
4663
|
const listSelect = listSchema ? toSelectFields(listSchema) : void 0;
|
|
3949
4664
|
const oneSelect = oneSchema ? toSelectFields(oneSchema) : listSelect;
|
|
3950
|
-
const reader = new ReadRepository(model, prisma, config, listSelect, oneSelect);
|
|
4665
|
+
const reader = new ReadRepository(model, prisma, config, listSelect, oneSelect, configRegistry);
|
|
3951
4666
|
const writer = new WriteRepository(model, prisma, config);
|
|
3952
4667
|
return {
|
|
3953
4668
|
prisma,
|
|
@@ -3970,18 +4685,27 @@ function createCrudRepository(prisma, config, dataSources) {
|
|
|
3970
4685
|
__name(createCrudRepository, "createCrudRepository");
|
|
3971
4686
|
|
|
3972
4687
|
// src/lib/crud/data-source/data-source.registry.ts
|
|
3973
|
-
var
|
|
3974
|
-
function
|
|
4688
|
+
var import_common9 = require("@nestjs/common");
|
|
4689
|
+
function _ts_decorate5(decorators, target, key, desc2) {
|
|
3975
4690
|
var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
|
|
3976
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
3977
|
-
|
|
4691
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
4692
|
+
r = Reflect.decorate(decorators, target, key, desc2);
|
|
4693
|
+
} else {
|
|
4694
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
4695
|
+
if (d = decorators[i]) {
|
|
4696
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4697
|
+
}
|
|
4698
|
+
}
|
|
4699
|
+
}
|
|
3978
4700
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3979
4701
|
}
|
|
3980
|
-
__name(
|
|
3981
|
-
function
|
|
3982
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
4702
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
4703
|
+
function _ts_metadata5(metadataKey, metadataValue) {
|
|
4704
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
4705
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
4706
|
+
}
|
|
3983
4707
|
}
|
|
3984
|
-
__name(
|
|
4708
|
+
__name(_ts_metadata5, "_ts_metadata");
|
|
3985
4709
|
var DataSourceRegistry = class {
|
|
3986
4710
|
static {
|
|
3987
4711
|
__name(this, "DataSourceRegistry");
|
|
@@ -4040,31 +4764,31 @@ var DataSourceRegistry = class {
|
|
|
4040
4764
|
}
|
|
4041
4765
|
}
|
|
4042
4766
|
};
|
|
4043
|
-
DataSourceRegistry =
|
|
4044
|
-
(0,
|
|
4045
|
-
|
|
4046
|
-
|
|
4767
|
+
DataSourceRegistry = _ts_decorate5([
|
|
4768
|
+
(0, import_common9.Injectable)(),
|
|
4769
|
+
_ts_metadata5("design:type", Function),
|
|
4770
|
+
_ts_metadata5("design:paramtypes", [
|
|
4047
4771
|
Array
|
|
4048
4772
|
])
|
|
4049
4773
|
], DataSourceRegistry);
|
|
4050
4774
|
|
|
4051
4775
|
// src/lib/crud/data-source/data-source.loader.ts
|
|
4052
|
-
var
|
|
4053
|
-
var
|
|
4776
|
+
var import_node_fs5 = require("fs");
|
|
4777
|
+
var import_node_path8 = require("path");
|
|
4054
4778
|
var loadDataSourcesFromDir = /* @__PURE__ */ __name(async (dirPath) => {
|
|
4055
|
-
if (!(0,
|
|
4056
|
-
const entries = (0,
|
|
4779
|
+
if (!(0, import_node_fs5.existsSync)(dirPath)) return [];
|
|
4780
|
+
const entries = (0, import_node_fs5.readdirSync)(dirPath, {
|
|
4057
4781
|
withFileTypes: true
|
|
4058
4782
|
});
|
|
4059
4783
|
const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
4060
4784
|
const results = [];
|
|
4061
4785
|
for (const dir of dirs) {
|
|
4062
|
-
const basePath = (0,
|
|
4063
|
-
const jsonFile = (0,
|
|
4064
|
-
if (!(0,
|
|
4786
|
+
const basePath = (0, import_node_path8.join)(dirPath, dir);
|
|
4787
|
+
const jsonFile = (0, import_node_path8.join)(basePath, "data-source.json");
|
|
4788
|
+
if (!(0, import_node_fs5.existsSync)(jsonFile)) continue;
|
|
4065
4789
|
let _config;
|
|
4066
4790
|
try {
|
|
4067
|
-
_config = JSON.parse((0,
|
|
4791
|
+
_config = JSON.parse((0, import_node_fs5.readFileSync)(jsonFile, "utf-8"));
|
|
4068
4792
|
} catch (err) {
|
|
4069
4793
|
resourceLoadErrorsRegistry.record({
|
|
4070
4794
|
name: dir,
|
|
@@ -4100,14 +4824,14 @@ var findModule2 = /* @__PURE__ */ __name((dir, name) => {
|
|
|
4100
4824
|
".ts",
|
|
4101
4825
|
".js"
|
|
4102
4826
|
]) {
|
|
4103
|
-
const p = (0,
|
|
4104
|
-
if ((0,
|
|
4827
|
+
const p = (0, import_node_path8.join)(dir, `${name}${ext}`);
|
|
4828
|
+
if ((0, import_node_fs5.existsSync)(p)) return p;
|
|
4105
4829
|
}
|
|
4106
4830
|
return void 0;
|
|
4107
4831
|
}, "findModule");
|
|
4108
4832
|
|
|
4109
4833
|
// src/lib/crud/operations/register-actions.ts
|
|
4110
|
-
var
|
|
4834
|
+
var import_common10 = require("@nestjs/common");
|
|
4111
4835
|
var import_swagger2 = require("@nestjs/swagger");
|
|
4112
4836
|
|
|
4113
4837
|
// src/lib/crud/operations/decorator.utils.ts
|
|
@@ -4131,8 +4855,8 @@ var registerActionRoutes = /* @__PURE__ */ __name((ctx) => {
|
|
|
4131
4855
|
return action.procedure(this.repo.prisma, recordId);
|
|
4132
4856
|
});
|
|
4133
4857
|
const d = desc(cls, methodName);
|
|
4134
|
-
(0,
|
|
4135
|
-
(0,
|
|
4858
|
+
(0, import_common10.Post)(`procedure/${action.id}/:recordId`)(cls.prototype, methodName, d);
|
|
4859
|
+
(0, import_common10.Param)("recordId")(cls.prototype, methodName, 0);
|
|
4136
4860
|
(0, import_swagger2.ApiOperation)({
|
|
4137
4861
|
summary: `Execute action "${action.label}" on a ${name}`
|
|
4138
4862
|
})(cls.prototype, methodName, d);
|
|
@@ -4156,7 +4880,7 @@ var registerTableActionRoutes = /* @__PURE__ */ __name((ctx) => {
|
|
|
4156
4880
|
return action.procedure(this.repo.prisma);
|
|
4157
4881
|
});
|
|
4158
4882
|
const d = desc(cls, methodName);
|
|
4159
|
-
(0,
|
|
4883
|
+
(0, import_common10.Post)(`table-action/${action.id}`)(cls.prototype, methodName, d);
|
|
4160
4884
|
(0, import_swagger2.ApiOperation)({
|
|
4161
4885
|
summary: `Execute table action "${action.label ?? action.id}" on ${name}`
|
|
4162
4886
|
})(cls.prototype, methodName, d);
|
|
@@ -4168,7 +4892,7 @@ var registerTableActionRoutes = /* @__PURE__ */ __name((ctx) => {
|
|
|
4168
4892
|
}, "registerTableActionRoutes");
|
|
4169
4893
|
|
|
4170
4894
|
// src/lib/crud/operations/register-create.ts
|
|
4171
|
-
var
|
|
4895
|
+
var import_common11 = require("@nestjs/common");
|
|
4172
4896
|
var import_swagger3 = require("@nestjs/swagger");
|
|
4173
4897
|
var defaultCreate = /* @__PURE__ */ __name((ctx) => {
|
|
4174
4898
|
if (!isOperationEnabled(ctx.definition, "create")) return null;
|
|
@@ -4185,7 +4909,7 @@ var defaultCreate = /* @__PURE__ */ __name((ctx) => {
|
|
|
4185
4909
|
bodyDecorator(createSchema, {
|
|
4186
4910
|
coerceNullableUndefinedToNull: true
|
|
4187
4911
|
})(cls.prototype, methodName, 0);
|
|
4188
|
-
(0,
|
|
4912
|
+
(0, import_common11.Req)()(cls.prototype, methodName, 1);
|
|
4189
4913
|
}, "decorators")
|
|
4190
4914
|
};
|
|
4191
4915
|
}, "defaultCreate");
|
|
@@ -4197,9 +4921,9 @@ var childCreate = /* @__PURE__ */ __name((sub) => (ctx) => {
|
|
|
4197
4921
|
return this.repo.createChild(id, sub, body, req);
|
|
4198
4922
|
}, "createFn");
|
|
4199
4923
|
const decorators = /* @__PURE__ */ __name(() => {
|
|
4200
|
-
(0,
|
|
4201
|
-
(0,
|
|
4202
|
-
(0,
|
|
4924
|
+
(0, import_common11.Param)("id")(cls.prototype, methodName, 0);
|
|
4925
|
+
(0, import_common11.Body)()(cls.prototype, methodName, 1);
|
|
4926
|
+
(0, import_common11.Req)()(cls.prototype, methodName, 2);
|
|
4203
4927
|
}, "decorators");
|
|
4204
4928
|
return {
|
|
4205
4929
|
route: `:id/${sub.childRoute}`,
|
|
@@ -4217,7 +4941,7 @@ var registerCreate = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4217
4941
|
const { cls } = ctx;
|
|
4218
4942
|
def(cls, methodName, properties.createFn);
|
|
4219
4943
|
const d = desc(cls, methodName);
|
|
4220
|
-
(0,
|
|
4944
|
+
(0, import_common11.Post)(route)(cls.prototype, methodName, d);
|
|
4221
4945
|
(0, import_swagger3.ApiOperation)({
|
|
4222
4946
|
summary: `Create a ${name}`
|
|
4223
4947
|
})(cls.prototype, methodName, d);
|
|
@@ -4229,7 +4953,7 @@ var registerCreate = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4229
4953
|
}, "registerCreate");
|
|
4230
4954
|
|
|
4231
4955
|
// src/lib/crud/operations/register-delete.ts
|
|
4232
|
-
var
|
|
4956
|
+
var import_common12 = require("@nestjs/common");
|
|
4233
4957
|
var import_swagger4 = require("@nestjs/swagger");
|
|
4234
4958
|
var defaultDelete = /* @__PURE__ */ __name((ctx) => {
|
|
4235
4959
|
if (!isOperationEnabled(ctx.definition, "delete")) return null;
|
|
@@ -4255,9 +4979,9 @@ var deleteChild = /* @__PURE__ */ __name((sub) => (ctx) => {
|
|
|
4255
4979
|
return this.repo.deleteChild(sub, childId, parentId2, req);
|
|
4256
4980
|
}, "deleteFn");
|
|
4257
4981
|
const decorators = /* @__PURE__ */ __name(() => {
|
|
4258
|
-
(0,
|
|
4259
|
-
(0,
|
|
4260
|
-
(0,
|
|
4982
|
+
(0, import_common12.Param)("childId")(cls.prototype, methodName, 0);
|
|
4983
|
+
(0, import_common12.Param)("id")(cls.prototype, methodName, 1);
|
|
4984
|
+
(0, import_common12.Req)()(cls.prototype, methodName, 2);
|
|
4261
4985
|
}, "decorators");
|
|
4262
4986
|
return {
|
|
4263
4987
|
route: `:id/${sub.childRoute}/:childId`,
|
|
@@ -4275,8 +4999,8 @@ var registerDelete = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4275
4999
|
const { methodName, route, name } = properties;
|
|
4276
5000
|
def(cls, methodName, properties.deleteFn);
|
|
4277
5001
|
const d = desc(cls, methodName);
|
|
4278
|
-
(0,
|
|
4279
|
-
(0,
|
|
5002
|
+
(0, import_common12.Delete)(route)(cls.prototype, methodName, d);
|
|
5003
|
+
(0, import_common12.Param)("id")(cls.prototype, methodName, 0);
|
|
4280
5004
|
(0, import_swagger4.ApiOperation)({
|
|
4281
5005
|
summary: `Delete ${name} record`
|
|
4282
5006
|
})(cls.prototype, methodName, d);
|
|
@@ -4285,11 +5009,11 @@ var registerDelete = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4285
5009
|
status: 200
|
|
4286
5010
|
})(cls.prototype, methodName, d);
|
|
4287
5011
|
properties.decorators();
|
|
4288
|
-
if (!sub) (0,
|
|
5012
|
+
if (!sub) (0, import_common12.Req)()(cls.prototype, methodName, 1);
|
|
4289
5013
|
}, "registerDelete");
|
|
4290
5014
|
|
|
4291
5015
|
// src/lib/crud/operations/register-findall.ts
|
|
4292
|
-
var
|
|
5016
|
+
var import_common13 = require("@nestjs/common");
|
|
4293
5017
|
var import_swagger5 = require("@nestjs/swagger");
|
|
4294
5018
|
|
|
4295
5019
|
// src/lib/crud/request.dto.ts
|
|
@@ -4366,7 +5090,8 @@ var ZodValidationPipe = class {
|
|
|
4366
5090
|
formatErrors(error) {
|
|
4367
5091
|
return error.issues.map((e) => ({
|
|
4368
5092
|
field: e.path.join("."),
|
|
4369
|
-
message: e.message
|
|
5093
|
+
message: e.message,
|
|
5094
|
+
code: e.code
|
|
4370
5095
|
}));
|
|
4371
5096
|
}
|
|
4372
5097
|
};
|
|
@@ -4444,8 +5169,8 @@ var childFindAll = /* @__PURE__ */ __name((sub) => (ctx) => {
|
|
|
4444
5169
|
return findAllByParent(this.repo, id, sub.childRoute, params, req);
|
|
4445
5170
|
}, "findAll");
|
|
4446
5171
|
const decorators = /* @__PURE__ */ __name(() => {
|
|
4447
|
-
(0,
|
|
4448
|
-
(0,
|
|
5172
|
+
(0, import_common13.Param)("id")(cls.prototype, methodName, 2);
|
|
5173
|
+
(0, import_common13.Req)()(cls.prototype, methodName, 3);
|
|
4449
5174
|
}, "decorators");
|
|
4450
5175
|
return {
|
|
4451
5176
|
name: sub.childRoute,
|
|
@@ -4464,10 +5189,10 @@ var registerFindAll = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4464
5189
|
const { cls } = ctx;
|
|
4465
5190
|
def(cls, methodName, properties.findAll);
|
|
4466
5191
|
const d = desc(cls, methodName);
|
|
4467
|
-
(0,
|
|
4468
|
-
(0,
|
|
4469
|
-
(0,
|
|
4470
|
-
if (!sub) (0,
|
|
5192
|
+
(0, import_common13.Get)(route)(cls.prototype, methodName, d);
|
|
5193
|
+
(0, import_common13.Query)(new ZodValidationPipe(RequestDtoNoOffset.zodSchema))(cls.prototype, methodName, 0);
|
|
5194
|
+
(0, import_common13.Query)("q")(cls.prototype, methodName, 1);
|
|
5195
|
+
if (!sub) (0, import_common13.Req)()(cls.prototype, methodName, 2);
|
|
4471
5196
|
(0, import_swagger5.ApiOperation)({
|
|
4472
5197
|
summary: `List all ${name}s`
|
|
4473
5198
|
})(cls.prototype, methodName, d);
|
|
@@ -4485,7 +5210,7 @@ var registerFindAll = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4485
5210
|
}, "registerFindAll");
|
|
4486
5211
|
|
|
4487
5212
|
// src/lib/crud/operations/register-findone.ts
|
|
4488
|
-
var
|
|
5213
|
+
var import_common14 = require("@nestjs/common");
|
|
4489
5214
|
var import_swagger6 = require("@nestjs/swagger");
|
|
4490
5215
|
var defaultFindOne = /* @__PURE__ */ __name((ctx) => {
|
|
4491
5216
|
if (!isOperationEnabled(ctx.definition, "findOne")) return null;
|
|
@@ -4499,8 +5224,8 @@ var defaultFindOne = /* @__PURE__ */ __name((ctx) => {
|
|
|
4499
5224
|
return this.repo.findOne(id, req);
|
|
4500
5225
|
}, "findOneFn"),
|
|
4501
5226
|
decorators: /* @__PURE__ */ __name(() => {
|
|
4502
|
-
(0,
|
|
4503
|
-
(0,
|
|
5227
|
+
(0, import_common14.Param)("id")(cls.prototype, methodName, 0);
|
|
5228
|
+
(0, import_common14.Req)()(cls.prototype, methodName, 1);
|
|
4504
5229
|
}, "decorators")
|
|
4505
5230
|
};
|
|
4506
5231
|
}, "defaultFindOne");
|
|
@@ -4512,9 +5237,9 @@ var childFindOne = /* @__PURE__ */ __name((sub) => (ctx) => {
|
|
|
4512
5237
|
return this.repo.findOneChild(sub, childId, parentId2, req);
|
|
4513
5238
|
}, "findOneFn");
|
|
4514
5239
|
const decorators = /* @__PURE__ */ __name(() => {
|
|
4515
|
-
(0,
|
|
4516
|
-
(0,
|
|
4517
|
-
(0,
|
|
5240
|
+
(0, import_common14.Param)("id")(cls.prototype, methodName, 0);
|
|
5241
|
+
(0, import_common14.Param)("childId")(cls.prototype, methodName, 1);
|
|
5242
|
+
(0, import_common14.Req)()(cls.prototype, methodName, 2);
|
|
4518
5243
|
}, "decorators");
|
|
4519
5244
|
return {
|
|
4520
5245
|
route: `:id/${sub.childRoute}/:childId`,
|
|
@@ -4532,7 +5257,7 @@ var registerFindOne = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4532
5257
|
const { cls } = ctx;
|
|
4533
5258
|
def(cls, methodName, properties.findOneFn);
|
|
4534
5259
|
const d = desc(cls, methodName);
|
|
4535
|
-
(0,
|
|
5260
|
+
(0, import_common14.Get)(route)(cls.prototype, methodName, d);
|
|
4536
5261
|
(0, import_swagger6.ApiOperation)({
|
|
4537
5262
|
summary: `Get one ${name} by id`
|
|
4538
5263
|
})(cls.prototype, methodName, d);
|
|
@@ -4551,7 +5276,7 @@ var registerFindOne = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4551
5276
|
}, "registerFindOne");
|
|
4552
5277
|
|
|
4553
5278
|
// src/lib/crud/operations/register-patch.ts
|
|
4554
|
-
var
|
|
5279
|
+
var import_common15 = require("@nestjs/common");
|
|
4555
5280
|
var import_swagger7 = require("@nestjs/swagger");
|
|
4556
5281
|
var defaultPatch = /* @__PURE__ */ __name((ctx) => {
|
|
4557
5282
|
if (!isOperationEnabled(ctx.definition, "patch")) return null;
|
|
@@ -4565,9 +5290,9 @@ var defaultPatch = /* @__PURE__ */ __name((ctx) => {
|
|
|
4565
5290
|
return this.repo.patch(id, body, req);
|
|
4566
5291
|
}, "patchFn"),
|
|
4567
5292
|
decorators: /* @__PURE__ */ __name(() => {
|
|
4568
|
-
(0,
|
|
5293
|
+
(0, import_common15.Param)("id")(cls.prototype, methodName, 0);
|
|
4569
5294
|
bodyDecorator(patchSchema)(cls.prototype, methodName, 1);
|
|
4570
|
-
(0,
|
|
5295
|
+
(0, import_common15.Req)()(cls.prototype, methodName, 2);
|
|
4571
5296
|
}, "decorators")
|
|
4572
5297
|
};
|
|
4573
5298
|
}, "defaultPatch");
|
|
@@ -4579,10 +5304,10 @@ var childPatch = /* @__PURE__ */ __name((sub) => (ctx) => {
|
|
|
4579
5304
|
return this.repo.updateChild(sub, childId, body, req);
|
|
4580
5305
|
}, "patchFn");
|
|
4581
5306
|
const decorators = /* @__PURE__ */ __name(() => {
|
|
4582
|
-
(0,
|
|
4583
|
-
(0,
|
|
4584
|
-
(0,
|
|
4585
|
-
(0,
|
|
5307
|
+
(0, import_common15.Param)("id")(cls.prototype, methodName, 0);
|
|
5308
|
+
(0, import_common15.Param)("childId")(cls.prototype, methodName, 1);
|
|
5309
|
+
(0, import_common15.Body)()(cls.prototype, methodName, 2);
|
|
5310
|
+
(0, import_common15.Req)()(cls.prototype, methodName, 3);
|
|
4586
5311
|
}, "decorators");
|
|
4587
5312
|
return {
|
|
4588
5313
|
route: `:id/${sub.childRoute}/:childId`,
|
|
@@ -4600,7 +5325,7 @@ var registerPatch = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4600
5325
|
const { cls } = ctx;
|
|
4601
5326
|
def(cls, methodName, properties.patchFn);
|
|
4602
5327
|
const d = desc(cls, methodName);
|
|
4603
|
-
(0,
|
|
5328
|
+
(0, import_common15.Patch)(route)(cls.prototype, methodName, d);
|
|
4604
5329
|
(0, import_swagger7.ApiOperation)({
|
|
4605
5330
|
summary: `Update a ${name}`
|
|
4606
5331
|
})(cls.prototype, methodName, d);
|
|
@@ -4615,37 +5340,37 @@ var registerPatch = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
4615
5340
|
}, "registerPatch");
|
|
4616
5341
|
|
|
4617
5342
|
// src/lib/crud/operations/register-schema-endpoints.ts
|
|
4618
|
-
var
|
|
5343
|
+
var import_common16 = require("@nestjs/common");
|
|
4619
5344
|
var import_swagger8 = require("@nestjs/swagger");
|
|
4620
5345
|
|
|
4621
5346
|
// src/lib/crud/resource/PatchResourceJson.schema.ts
|
|
4622
|
-
var
|
|
4623
|
-
var FieldVariantPatchSchema =
|
|
4624
|
-
type:
|
|
4625
|
-
format:
|
|
4626
|
-
resource:
|
|
4627
|
-
position:
|
|
4628
|
-
options:
|
|
5347
|
+
var import_zod29 = require("zod");
|
|
5348
|
+
var FieldVariantPatchSchema = import_zod29.z.object({
|
|
5349
|
+
type: import_zod29.z.string().nullable().optional(),
|
|
5350
|
+
format: import_zod29.z.string().nullable().optional(),
|
|
5351
|
+
resource: import_zod29.z.string().nullable().optional(),
|
|
5352
|
+
position: import_zod29.z.number().nullable().optional(),
|
|
5353
|
+
options: import_zod29.z.record(import_zod29.z.string(), import_zod29.z.unknown().nullable()).optional()
|
|
4629
5354
|
}).partial();
|
|
4630
|
-
var PatchColumnSchema =
|
|
4631
|
-
label:
|
|
4632
|
-
column:
|
|
4633
|
-
hiddenInTable:
|
|
4634
|
-
hiddenInForm:
|
|
4635
|
-
hiddenInView:
|
|
5355
|
+
var PatchColumnSchema = import_zod29.z.object({
|
|
5356
|
+
label: import_zod29.z.string().optional(),
|
|
5357
|
+
column: import_zod29.z.string().optional(),
|
|
5358
|
+
hiddenInTable: import_zod29.z.boolean().optional(),
|
|
5359
|
+
hiddenInForm: import_zod29.z.boolean().optional(),
|
|
5360
|
+
hiddenInView: import_zod29.z.boolean().optional(),
|
|
4636
5361
|
fieldInput: FieldVariantPatchSchema.optional(),
|
|
4637
5362
|
fieldView: FieldVariantPatchSchema.optional(),
|
|
4638
5363
|
fieldTable: FieldVariantPatchSchema.optional()
|
|
4639
5364
|
}).partial();
|
|
4640
|
-
var PatchResourceJsonSchema =
|
|
4641
|
-
columns:
|
|
5365
|
+
var PatchResourceJsonSchema = import_zod29.z.object({
|
|
5366
|
+
columns: import_zod29.z.record(import_zod29.z.string(), PatchColumnSchema)
|
|
4642
5367
|
});
|
|
4643
5368
|
|
|
4644
5369
|
// src/lib/crud/resource/WriteResourceJson.ts
|
|
4645
|
-
var
|
|
5370
|
+
var import_node_fs6 = require("fs");
|
|
4646
5371
|
var readRawResourceJson = /* @__PURE__ */ __name((jsonPath) => {
|
|
4647
|
-
if (!(0,
|
|
4648
|
-
return JSON.parse((0,
|
|
5372
|
+
if (!(0, import_node_fs6.existsSync)(jsonPath)) return void 0;
|
|
5373
|
+
return JSON.parse((0, import_node_fs6.readFileSync)(jsonPath, "utf-8"));
|
|
4649
5374
|
}, "readRawResourceJson");
|
|
4650
5375
|
var FIELD_VARIANT_KEYS = [
|
|
4651
5376
|
"fieldInput",
|
|
@@ -4701,7 +5426,7 @@ var serializeResourceJson = /* @__PURE__ */ __name((config) => `${JSON.stringify
|
|
|
4701
5426
|
`, "serializeResourceJson");
|
|
4702
5427
|
var validateResourceJson = /* @__PURE__ */ __name((raw) => ResourceJsonSchema.safeParse(raw), "validateResourceJson");
|
|
4703
5428
|
var writeRawResourceJson = /* @__PURE__ */ __name((jsonPath, raw) => {
|
|
4704
|
-
(0,
|
|
5429
|
+
(0, import_node_fs6.writeFileSync)(jsonPath, serializeResourceJson(raw), "utf-8");
|
|
4705
5430
|
}, "writeRawResourceJson");
|
|
4706
5431
|
|
|
4707
5432
|
// src/lib/crud/operations/payload-builders.ts
|
|
@@ -4960,20 +5685,21 @@ var buildEditableColumnsPayload = /* @__PURE__ */ __name((config) => {
|
|
|
4960
5685
|
}, "buildEditableColumnsPayload");
|
|
4961
5686
|
|
|
4962
5687
|
// src/lib/crud/operations/register-schema-endpoints.ts
|
|
4963
|
-
var
|
|
5688
|
+
var import_node_path9 = require("path");
|
|
4964
5689
|
var registerDefinitionEndpoint = /* @__PURE__ */ __name((ctx) => {
|
|
4965
5690
|
const { cls, config } = ctx;
|
|
4966
5691
|
const { route, name } = config;
|
|
4967
5692
|
const definitionPayload = buildDefinitionPayload(config);
|
|
4968
5693
|
def(cls, "getDefinition", async function() {
|
|
4969
|
-
|
|
4970
|
-
|
|
5694
|
+
const language = getRequestLanguage();
|
|
5695
|
+
if (IS_DEV || language) {
|
|
5696
|
+
const fresh = await this.configRegistry.getByRoute(route, language);
|
|
4971
5697
|
if (fresh) return buildDefinitionPayload(fresh);
|
|
4972
5698
|
}
|
|
4973
5699
|
return definitionPayload;
|
|
4974
5700
|
});
|
|
4975
5701
|
const d = desc(cls, "getDefinition");
|
|
4976
|
-
(0,
|
|
5702
|
+
(0, import_common16.Get)("definition")(cls.prototype, "getDefinition", d);
|
|
4977
5703
|
(0, import_swagger8.ApiOperation)({
|
|
4978
5704
|
summary: `Get the resource definition for ${name}`
|
|
4979
5705
|
})(cls.prototype, "getDefinition", d);
|
|
@@ -4987,14 +5713,15 @@ var registerResourceJsonEndpoint = /* @__PURE__ */ __name((ctx) => {
|
|
|
4987
5713
|
const { route, name } = config;
|
|
4988
5714
|
const resourceJsonPayload = buildResourceJsonPayload(config, baseUrl);
|
|
4989
5715
|
def(cls, "getResourceJson", async function() {
|
|
4990
|
-
|
|
4991
|
-
|
|
5716
|
+
const language = getRequestLanguage();
|
|
5717
|
+
if (IS_DEV || language) {
|
|
5718
|
+
const fresh = await this.configRegistry.getByRoute(route, language);
|
|
4992
5719
|
if (fresh) return buildResourceJsonPayload(fresh, baseUrl);
|
|
4993
5720
|
}
|
|
4994
5721
|
return resourceJsonPayload;
|
|
4995
5722
|
});
|
|
4996
5723
|
const d = desc(cls, "getResourceJson");
|
|
4997
|
-
(0,
|
|
5724
|
+
(0, import_common16.Get)("resource.json")(cls.prototype, "getResourceJson", d);
|
|
4998
5725
|
(0, import_swagger8.ApiOperation)({
|
|
4999
5726
|
summary: `Get resource descriptor for ${name}`
|
|
5000
5727
|
})(cls.prototype, "getResourceJson", d);
|
|
@@ -5008,13 +5735,13 @@ var registerResourceColumnsEndpoint = /* @__PURE__ */ __name((ctx) => {
|
|
|
5008
5735
|
const { route, name } = config;
|
|
5009
5736
|
def(cls, "getResourceColumns", async function() {
|
|
5010
5737
|
if (!IS_DEV) {
|
|
5011
|
-
throw new
|
|
5738
|
+
throw new import_common16.ForbiddenException("The resource schema editor is only available when the backend is running in local dev mode.");
|
|
5012
5739
|
}
|
|
5013
5740
|
const fresh = await this.configRegistry.getByRoute(route);
|
|
5014
5741
|
return buildEditableColumnsPayload(fresh ?? config);
|
|
5015
5742
|
});
|
|
5016
5743
|
const d = desc(cls, "getResourceColumns");
|
|
5017
|
-
(0,
|
|
5744
|
+
(0, import_common16.Get)("resource-columns")(cls.prototype, "getResourceColumns", d);
|
|
5018
5745
|
(0, import_swagger8.ApiOperation)({
|
|
5019
5746
|
summary: `Dev-only: get the editable column list for ${name}`
|
|
5020
5747
|
})(cls.prototype, "getResourceColumns", d);
|
|
@@ -5028,30 +5755,30 @@ var registerResourceJsonPatchEndpoint = /* @__PURE__ */ __name((ctx) => {
|
|
|
5028
5755
|
const { route, name } = config;
|
|
5029
5756
|
def(cls, "patchResourceJson", async function(body) {
|
|
5030
5757
|
if (!IS_DEV) {
|
|
5031
|
-
throw new
|
|
5758
|
+
throw new import_common16.ForbiddenException("Editing resource.json is only available when the backend is running in local dev mode.");
|
|
5032
5759
|
}
|
|
5033
5760
|
await this.configRegistry.getByRoute(route);
|
|
5034
5761
|
const dir = this.configRegistry.getResourceDir(route);
|
|
5035
5762
|
if (!dir) {
|
|
5036
|
-
throw new
|
|
5763
|
+
throw new import_common16.NotFoundException(`No resource.json on disk for "${name}" (route "${route}").`);
|
|
5037
5764
|
}
|
|
5038
|
-
const jsonPath = (0,
|
|
5765
|
+
const jsonPath = (0, import_node_path9.join)(dir, "resource.json");
|
|
5039
5766
|
const raw = readRawResourceJson(jsonPath);
|
|
5040
5767
|
if (!raw) {
|
|
5041
|
-
throw new
|
|
5768
|
+
throw new import_common16.NotFoundException(`resource.json not found at ${jsonPath}`);
|
|
5042
5769
|
}
|
|
5043
5770
|
const merged = applyColumnPatch(raw, body);
|
|
5044
5771
|
const validated = validateResourceJson(merged);
|
|
5045
5772
|
if (!validated.success) {
|
|
5046
|
-
throw new
|
|
5773
|
+
throw new import_common16.BadRequestException(validated.error.issues);
|
|
5047
5774
|
}
|
|
5048
5775
|
writeRawResourceJson(jsonPath, merged);
|
|
5049
5776
|
const fresh = await this.configRegistry.getByRoute(route);
|
|
5050
5777
|
return buildEditableColumnsPayload(fresh ?? config);
|
|
5051
5778
|
});
|
|
5052
5779
|
const d = desc(cls, "patchResourceJson");
|
|
5053
|
-
(0,
|
|
5054
|
-
(0,
|
|
5780
|
+
(0, import_common16.Patch)("resource.json")(cls.prototype, "patchResourceJson", d);
|
|
5781
|
+
(0, import_common16.Body)(new ZodValidationPipe(PatchResourceJsonSchema))(cls.prototype, "patchResourceJson", 0);
|
|
5055
5782
|
(0, import_swagger8.ApiOperation)({
|
|
5056
5783
|
summary: `Dev-only: patch column layout in resource.json for ${name}`
|
|
5057
5784
|
})(cls.prototype, "patchResourceJson", d);
|
|
@@ -5065,22 +5792,22 @@ var registerResourceJsonRawGetEndpoint = /* @__PURE__ */ __name((ctx) => {
|
|
|
5065
5792
|
const { route, name } = config;
|
|
5066
5793
|
def(cls, "getResourceJsonRaw", async function() {
|
|
5067
5794
|
if (!IS_DEV) {
|
|
5068
|
-
throw new
|
|
5795
|
+
throw new import_common16.ForbiddenException("The resource JSON editor is only available when the backend is running in local dev mode.");
|
|
5069
5796
|
}
|
|
5070
5797
|
await this.configRegistry.getByRoute(route);
|
|
5071
5798
|
const dir = this.configRegistry.getResourceDir(route);
|
|
5072
5799
|
if (!dir) {
|
|
5073
|
-
throw new
|
|
5800
|
+
throw new import_common16.NotFoundException(`No resource.json on disk for "${name}" (route "${route}").`);
|
|
5074
5801
|
}
|
|
5075
|
-
const jsonPath = (0,
|
|
5802
|
+
const jsonPath = (0, import_node_path9.join)(dir, "resource.json");
|
|
5076
5803
|
const raw = readRawResourceJson(jsonPath);
|
|
5077
5804
|
if (!raw) {
|
|
5078
|
-
throw new
|
|
5805
|
+
throw new import_common16.NotFoundException(`resource.json not found at ${jsonPath}`);
|
|
5079
5806
|
}
|
|
5080
5807
|
return raw;
|
|
5081
5808
|
});
|
|
5082
5809
|
const d = desc(cls, "getResourceJsonRaw");
|
|
5083
|
-
(0,
|
|
5810
|
+
(0, import_common16.Get)("resource-json-raw")(cls.prototype, "getResourceJsonRaw", d);
|
|
5084
5811
|
(0, import_swagger8.ApiOperation)({
|
|
5085
5812
|
summary: `Dev-only: get the raw resource.json for ${name}`
|
|
5086
5813
|
})(cls.prototype, "getResourceJsonRaw", d);
|
|
@@ -5094,24 +5821,24 @@ var registerResourceJsonRawPutEndpoint = /* @__PURE__ */ __name((ctx) => {
|
|
|
5094
5821
|
const { route, name } = config;
|
|
5095
5822
|
def(cls, "putResourceJsonRaw", async function(body) {
|
|
5096
5823
|
if (!IS_DEV) {
|
|
5097
|
-
throw new
|
|
5824
|
+
throw new import_common16.ForbiddenException("Editing resource.json is only available when the backend is running in local dev mode.");
|
|
5098
5825
|
}
|
|
5099
5826
|
await this.configRegistry.getByRoute(route);
|
|
5100
5827
|
const dir = this.configRegistry.getResourceDir(route);
|
|
5101
5828
|
if (!dir) {
|
|
5102
|
-
throw new
|
|
5829
|
+
throw new import_common16.NotFoundException(`No resource.json on disk for "${name}" (route "${route}").`);
|
|
5103
5830
|
}
|
|
5104
5831
|
const validated = validateResourceJson(body);
|
|
5105
5832
|
if (!validated.success) {
|
|
5106
|
-
throw new
|
|
5833
|
+
throw new import_common16.BadRequestException(validated.error.issues);
|
|
5107
5834
|
}
|
|
5108
|
-
const jsonPath = (0,
|
|
5835
|
+
const jsonPath = (0, import_node_path9.join)(dir, "resource.json");
|
|
5109
5836
|
writeRawResourceJson(jsonPath, body);
|
|
5110
5837
|
return body;
|
|
5111
5838
|
});
|
|
5112
5839
|
const d = desc(cls, "putResourceJsonRaw");
|
|
5113
|
-
(0,
|
|
5114
|
-
(0,
|
|
5840
|
+
(0, import_common16.Put)("resource-json-raw")(cls.prototype, "putResourceJsonRaw", d);
|
|
5841
|
+
(0, import_common16.Body)()(cls.prototype, "putResourceJsonRaw", 0);
|
|
5115
5842
|
(0, import_swagger8.ApiOperation)({
|
|
5116
5843
|
summary: `Dev-only: replace the full resource.json for ${name}`
|
|
5117
5844
|
})(cls.prototype, "putResourceJsonRaw", d);
|
|
@@ -5122,7 +5849,7 @@ var registerResourceJsonRawPutEndpoint = /* @__PURE__ */ __name((ctx) => {
|
|
|
5122
5849
|
}, "registerResourceJsonRawPutEndpoint");
|
|
5123
5850
|
|
|
5124
5851
|
// src/lib/crud/operations/register-schemas.ts
|
|
5125
|
-
var
|
|
5852
|
+
var import_common17 = require("@nestjs/common");
|
|
5126
5853
|
var import_swagger9 = require("@nestjs/swagger");
|
|
5127
5854
|
var defaultSchemas = /* @__PURE__ */ __name((ctx) => {
|
|
5128
5855
|
const { config, baseUrl } = ctx;
|
|
@@ -5133,8 +5860,9 @@ var defaultSchemas = /* @__PURE__ */ __name((ctx) => {
|
|
|
5133
5860
|
methodName: "getSchemas",
|
|
5134
5861
|
name,
|
|
5135
5862
|
schemasFn: /* @__PURE__ */ __name(async function() {
|
|
5136
|
-
|
|
5137
|
-
|
|
5863
|
+
const language = getRequestLanguage();
|
|
5864
|
+
if (IS_DEV || language) {
|
|
5865
|
+
const fresh = await this.configRegistry.getByRoute(route, language);
|
|
5138
5866
|
if (fresh) return buildViewsPayload(fresh, baseUrl) ?? viewsPayload;
|
|
5139
5867
|
}
|
|
5140
5868
|
return viewsPayload;
|
|
@@ -5166,7 +5894,7 @@ var registerSchemas = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
5166
5894
|
const { cls } = ctx;
|
|
5167
5895
|
def(cls, methodName, properties.schemasFn);
|
|
5168
5896
|
const d = desc(cls, methodName);
|
|
5169
|
-
(0,
|
|
5897
|
+
(0, import_common17.Get)(route)(cls.prototype, methodName, d);
|
|
5170
5898
|
(0, import_swagger9.ApiOperation)({
|
|
5171
5899
|
summary: `Get view schemas for ${name}`
|
|
5172
5900
|
})(cls.prototype, methodName, d);
|
|
@@ -5178,7 +5906,7 @@ var registerSchemas = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
5178
5906
|
}, "registerSchemas");
|
|
5179
5907
|
|
|
5180
5908
|
// src/lib/crud/operations/register-update.ts
|
|
5181
|
-
var
|
|
5909
|
+
var import_common18 = require("@nestjs/common");
|
|
5182
5910
|
var import_swagger10 = require("@nestjs/swagger");
|
|
5183
5911
|
var defaultUpdate = /* @__PURE__ */ __name((ctx) => {
|
|
5184
5912
|
if (!isOperationEnabled(ctx.definition, "update")) return null;
|
|
@@ -5192,9 +5920,9 @@ var defaultUpdate = /* @__PURE__ */ __name((ctx) => {
|
|
|
5192
5920
|
return this.repo.update(id, body, req);
|
|
5193
5921
|
}, "updateFn"),
|
|
5194
5922
|
decorators: /* @__PURE__ */ __name(() => {
|
|
5195
|
-
(0,
|
|
5923
|
+
(0, import_common18.Param)("id")(cls.prototype, methodName, 0);
|
|
5196
5924
|
bodyDecorator(updateSchema)(cls.prototype, methodName, 1);
|
|
5197
|
-
(0,
|
|
5925
|
+
(0, import_common18.Req)()(cls.prototype, methodName, 2);
|
|
5198
5926
|
}, "decorators")
|
|
5199
5927
|
};
|
|
5200
5928
|
}, "defaultUpdate");
|
|
@@ -5206,10 +5934,10 @@ var childUpdate = /* @__PURE__ */ __name((sub) => (ctx) => {
|
|
|
5206
5934
|
return this.repo.updateChild(sub, childId, body, req);
|
|
5207
5935
|
}, "updateFn");
|
|
5208
5936
|
const decorators = /* @__PURE__ */ __name(() => {
|
|
5209
|
-
(0,
|
|
5210
|
-
(0,
|
|
5211
|
-
(0,
|
|
5212
|
-
(0,
|
|
5937
|
+
(0, import_common18.Param)("id")(cls.prototype, methodName, 0);
|
|
5938
|
+
(0, import_common18.Param)("childId")(cls.prototype, methodName, 1);
|
|
5939
|
+
(0, import_common18.Body)()(cls.prototype, methodName, 2);
|
|
5940
|
+
(0, import_common18.Req)()(cls.prototype, methodName, 3);
|
|
5213
5941
|
}, "decorators");
|
|
5214
5942
|
return {
|
|
5215
5943
|
route: `:id/${sub.childRoute}/:childId`,
|
|
@@ -5227,7 +5955,7 @@ var registerUpdate = /* @__PURE__ */ __name((ctx, sub) => {
|
|
|
5227
5955
|
const { cls } = ctx;
|
|
5228
5956
|
def(cls, methodName, properties.updateFn);
|
|
5229
5957
|
const d = desc(cls, methodName);
|
|
5230
|
-
(0,
|
|
5958
|
+
(0, import_common18.Put)(route)(cls.prototype, methodName, d);
|
|
5231
5959
|
(0, import_swagger10.ApiOperation)({
|
|
5232
5960
|
summary: `Replace a ${name}`
|
|
5233
5961
|
})(cls.prototype, methodName, d);
|
|
@@ -5285,9 +6013,9 @@ function createCrudController(config, baseUrl) {
|
|
|
5285
6013
|
throw new Error(`Resource "${name}" declares 'upsert' but no upsertOn`);
|
|
5286
6014
|
}
|
|
5287
6015
|
const bodyDecorator = /* @__PURE__ */ __name((schema, options) => {
|
|
5288
|
-
if (!schema) return (0,
|
|
5289
|
-
if (isZodSchema(schema)) return (0,
|
|
5290
|
-
return (0,
|
|
6016
|
+
if (!schema) return (0, import_common19.Body)();
|
|
6017
|
+
if (isZodSchema(schema)) return (0, import_common19.Body)(new ZodValidationPipe(schema, options));
|
|
6018
|
+
return (0, import_common19.Body)();
|
|
5291
6019
|
}, "bodyDecorator");
|
|
5292
6020
|
const resolveClient = /* @__PURE__ */ __name((registry, resource) => {
|
|
5293
6021
|
try {
|
|
@@ -5305,7 +6033,7 @@ function createCrudController(config, baseUrl) {
|
|
|
5305
6033
|
configRegistry;
|
|
5306
6034
|
constructor(registry, configRegistry) {
|
|
5307
6035
|
const prisma = resolveClient(registry, config);
|
|
5308
|
-
this.repo = createCrudRepository(prisma, config, registry);
|
|
6036
|
+
this.repo = createCrudRepository(prisma, config, registry, configRegistry);
|
|
5309
6037
|
this.configRegistry = configRegistry;
|
|
5310
6038
|
}
|
|
5311
6039
|
};
|
|
@@ -5327,7 +6055,7 @@ function createCrudController(config, baseUrl) {
|
|
|
5327
6055
|
baseUrl
|
|
5328
6056
|
};
|
|
5329
6057
|
registerEndpoints(ctx);
|
|
5330
|
-
(0,
|
|
6058
|
+
(0, import_common19.Controller)(resourceControllerPath(route, config.parent))(CrudControllerBase);
|
|
5331
6059
|
(0, import_swagger11.ApiTags)(tag)(CrudControllerBase);
|
|
5332
6060
|
Object.defineProperty(CrudControllerBase, "name", {
|
|
5333
6061
|
value: `${name.charAt(0).toUpperCase() + name.slice(1)}Controller`
|
|
@@ -5341,7 +6069,7 @@ function createCrudController(config, baseUrl) {
|
|
|
5341
6069
|
__name(createCrudController, "createCrudController");
|
|
5342
6070
|
|
|
5343
6071
|
// src/lib/crud/dev-tools/dev-resources.controller.ts
|
|
5344
|
-
var
|
|
6072
|
+
var import_common20 = require("@nestjs/common");
|
|
5345
6073
|
var import_swagger12 = require("@nestjs/swagger");
|
|
5346
6074
|
|
|
5347
6075
|
// ../crouton-codegen/src/naming.ts
|
|
@@ -5673,7 +6401,7 @@ var fileExists2 = /* @__PURE__ */ __name(async (p) => {
|
|
|
5673
6401
|
return false;
|
|
5674
6402
|
}
|
|
5675
6403
|
}, "fileExists");
|
|
5676
|
-
var
|
|
6404
|
+
var clone2 = /* @__PURE__ */ __name((value) => JSON.parse(JSON.stringify(value)), "clone");
|
|
5677
6405
|
var deepEqual = /* @__PURE__ */ __name((a, b) => {
|
|
5678
6406
|
if (a === b) return true;
|
|
5679
6407
|
if (typeof a !== typeof b) return false;
|
|
@@ -5791,7 +6519,7 @@ var recommendedResolver = {
|
|
|
5791
6519
|
return out;
|
|
5792
6520
|
}
|
|
5793
6521
|
};
|
|
5794
|
-
var
|
|
6522
|
+
var resolve4 = /* @__PURE__ */ __name(async (diff2, resolver = recommendedResolver) => {
|
|
5795
6523
|
const raw = await resolver.resolve(diff2.decisions, diff2);
|
|
5796
6524
|
const resolutions = /* @__PURE__ */ new Map();
|
|
5797
6525
|
for (const d of diff2.decisions) {
|
|
@@ -5836,7 +6564,7 @@ var apply = /* @__PURE__ */ __name((resolved, ctx) => {
|
|
|
5836
6564
|
const notes = diff2.draft.unwiredRelations.map((r) => `Relation "${r.field}" \u2192 model "${r.targetModel}": target resource not found; left hidden.`);
|
|
5837
6565
|
const files = [];
|
|
5838
6566
|
if (diff2.isNew) {
|
|
5839
|
-
const config =
|
|
6567
|
+
const config = clone2(diff2.draft.config);
|
|
5840
6568
|
const addToSidebar = (resolutions.get("sidebar") ?? "yes") !== "no";
|
|
5841
6569
|
config.sidebar = {
|
|
5842
6570
|
hide: !addToSidebar
|
|
@@ -5850,7 +6578,7 @@ var apply = /* @__PURE__ */ __name((resolved, ctx) => {
|
|
|
5850
6578
|
action: "create"
|
|
5851
6579
|
});
|
|
5852
6580
|
} else {
|
|
5853
|
-
const existing =
|
|
6581
|
+
const existing = clone2(diff2.existing);
|
|
5854
6582
|
const draftMap = new Map(columnEntries(diff2.draft.config.columns));
|
|
5855
6583
|
const entries = columnEntries(existing.columns);
|
|
5856
6584
|
const indexOf = /* @__PURE__ */ __name((id) => entries.findIndex(([eid]) => eid === id), "indexOf");
|
|
@@ -5917,7 +6645,7 @@ var apply = /* @__PURE__ */ __name((resolved, ctx) => {
|
|
|
5917
6645
|
|
|
5918
6646
|
// ../crouton-codegen/src/commit.ts
|
|
5919
6647
|
var import_promises3 = require("fs/promises");
|
|
5920
|
-
var
|
|
6648
|
+
var import_node_path10 = require("path");
|
|
5921
6649
|
var commit = /* @__PURE__ */ __name(async (plan, opts = {}) => {
|
|
5922
6650
|
const written = [];
|
|
5923
6651
|
const skipped = [];
|
|
@@ -5927,7 +6655,7 @@ var commit = /* @__PURE__ */ __name(async (plan, opts = {}) => {
|
|
|
5927
6655
|
continue;
|
|
5928
6656
|
}
|
|
5929
6657
|
if (!opts.dryRun) {
|
|
5930
|
-
await (0, import_promises3.mkdir)((0,
|
|
6658
|
+
await (0, import_promises3.mkdir)((0, import_node_path10.dirname)(file.path), {
|
|
5931
6659
|
recursive: true
|
|
5932
6660
|
});
|
|
5933
6661
|
await (0, import_promises3.writeFile)(file.path, file.contents, "utf-8");
|
|
@@ -5942,15 +6670,15 @@ var commit = /* @__PURE__ */ __name(async (plan, opts = {}) => {
|
|
|
5942
6670
|
|
|
5943
6671
|
// ../crouton-codegen/src/config.ts
|
|
5944
6672
|
var import_promises4 = require("fs/promises");
|
|
5945
|
-
var
|
|
6673
|
+
var import_node_path11 = require("path");
|
|
5946
6674
|
var findConfigPath2 = /* @__PURE__ */ __name(async (cwd) => {
|
|
5947
|
-
let dir = (0,
|
|
6675
|
+
let dir = (0, import_node_path11.resolve)(cwd);
|
|
5948
6676
|
while (true) {
|
|
5949
6677
|
for (const name of CONFIG_FILES) {
|
|
5950
|
-
const candidate = (0,
|
|
6678
|
+
const candidate = (0, import_node_path11.join)(dir, name);
|
|
5951
6679
|
if (await fileExists2(candidate)) return candidate;
|
|
5952
6680
|
}
|
|
5953
|
-
const parent = (0,
|
|
6681
|
+
const parent = (0, import_node_path11.dirname)(dir);
|
|
5954
6682
|
if (parent === dir) return void 0;
|
|
5955
6683
|
dir = parent;
|
|
5956
6684
|
}
|
|
@@ -5971,7 +6699,7 @@ var loadConfig2 = /* @__PURE__ */ __name(async (cwd) => {
|
|
|
5971
6699
|
return {
|
|
5972
6700
|
config,
|
|
5973
6701
|
path,
|
|
5974
|
-
root: (0,
|
|
6702
|
+
root: (0, import_node_path11.dirname)(path)
|
|
5975
6703
|
};
|
|
5976
6704
|
}, "loadConfig");
|
|
5977
6705
|
var validateConfig = /* @__PURE__ */ __name((config, path = "<config>") => {
|
|
@@ -5988,7 +6716,7 @@ var loadDatasources = /* @__PURE__ */ __name(async (loaded) => {
|
|
|
5988
6716
|
const datasources = [];
|
|
5989
6717
|
for (const e of entries) {
|
|
5990
6718
|
if (!e.isDirectory()) continue;
|
|
5991
|
-
const jsonPath = (0,
|
|
6719
|
+
const jsonPath = (0, import_node_path11.join)(base, e.name, "data-source.json");
|
|
5992
6720
|
if (!await fileExists2(jsonPath)) continue;
|
|
5993
6721
|
const ds_json = JSON.parse(await (0, import_promises4.readFile)(jsonPath, "utf-8"));
|
|
5994
6722
|
const name = ds_json.name ?? e.name;
|
|
@@ -6034,29 +6762,29 @@ var makeSchemaExportName = /* @__PURE__ */ __name((config) => {
|
|
|
6034
6762
|
const template = config.schemaExportName ?? "{Model}WithRelationsSchema";
|
|
6035
6763
|
return (prismaName) => template.replace("{Model}", prismaName);
|
|
6036
6764
|
}, "makeSchemaExportName");
|
|
6037
|
-
var resolveFromRoot = /* @__PURE__ */ __name((root, p) => (0,
|
|
6765
|
+
var resolveFromRoot = /* @__PURE__ */ __name((root, p) => (0, import_node_path11.isAbsolute)(p) ? p : (0, import_node_path11.join)(root, p), "resolveFromRoot");
|
|
6038
6766
|
|
|
6039
6767
|
// ../crouton-codegen/src/scaffold.ts
|
|
6040
|
-
var
|
|
6768
|
+
var import_zod30 = require("zod");
|
|
6041
6769
|
var import_promises5 = require("fs/promises");
|
|
6042
|
-
var
|
|
6770
|
+
var import_node_path12 = require("path");
|
|
6043
6771
|
var ScallfoldDatasourceSchema = DataSourceShape.extend({
|
|
6044
6772
|
/** Folder name under `dataSourcesDir`. */
|
|
6045
|
-
folder:
|
|
6773
|
+
folder: import_zod30.z.string().default("default")
|
|
6046
6774
|
}).transform(transformDataSource);
|
|
6047
6775
|
|
|
6048
6776
|
// ../crouton-codegen/src/datasource-scaffold.ts
|
|
6049
|
-
var
|
|
6777
|
+
var import_node_path13 = require("path");
|
|
6050
6778
|
|
|
6051
6779
|
// ../crouton-codegen/src/project.ts
|
|
6052
6780
|
var import_promises6 = require("fs/promises");
|
|
6053
|
-
var
|
|
6054
|
-
var resourceDir = /* @__PURE__ */ __name((loaded, name) => (0,
|
|
6781
|
+
var import_node_path14 = require("path");
|
|
6782
|
+
var resourceDir = /* @__PURE__ */ __name((loaded, name) => (0, import_node_path14.join)(resolveFromRoot(loaded.root, loaded.config.resourcesDir), name), "resourceDir");
|
|
6055
6783
|
var readExistingResource = /* @__PURE__ */ __name(async (loaded, name) => {
|
|
6056
6784
|
const dir = resourceDir(loaded, name);
|
|
6057
|
-
const jsonPath = (0,
|
|
6785
|
+
const jsonPath = (0, import_node_path14.join)(dir, "resource.json");
|
|
6058
6786
|
const config = await fileExists2(jsonPath) ? JSON.parse(await (0, import_promises6.readFile)(jsonPath, "utf-8")) : null;
|
|
6059
|
-
const hasSchemaFile = await fileExists2((0,
|
|
6787
|
+
const hasSchemaFile = await fileExists2((0, import_node_path14.join)(dir, "schema.ts")) || await fileExists2((0, import_node_path14.join)(dir, "schema.js"));
|
|
6060
6788
|
return {
|
|
6061
6789
|
config,
|
|
6062
6790
|
hasSchemaFile
|
|
@@ -6079,7 +6807,7 @@ var listResourceNames = /* @__PURE__ */ __name(async (loaded) => {
|
|
|
6079
6807
|
const names = [];
|
|
6080
6808
|
for (const e of entries) {
|
|
6081
6809
|
if (!e.isDirectory()) continue;
|
|
6082
|
-
const jsonPath = (0,
|
|
6810
|
+
const jsonPath = (0, import_node_path14.join)(base, e.name, "resource.json");
|
|
6083
6811
|
if (!await fileExists2(jsonPath)) continue;
|
|
6084
6812
|
if (await isCustomResourceFile(jsonPath)) continue;
|
|
6085
6813
|
names.push(e.name);
|
|
@@ -6118,9 +6846,9 @@ var buildResourceDiffs = /* @__PURE__ */ __name(async (models, deps) => {
|
|
|
6118
6846
|
|
|
6119
6847
|
// ../crouton-codegen/src/prisma-shell.ts
|
|
6120
6848
|
var import_node_child_process = require("child_process");
|
|
6121
|
-
var
|
|
6849
|
+
var import_node_fs7 = require("fs");
|
|
6122
6850
|
var import_promises7 = require("fs/promises");
|
|
6123
|
-
var
|
|
6851
|
+
var import_node_path15 = require("path");
|
|
6124
6852
|
var run = /* @__PURE__ */ __name((cmd, args, cwd) => new Promise((resolve7) => {
|
|
6125
6853
|
const child = (0, import_node_child_process.spawn)(cmd, args, {
|
|
6126
6854
|
cwd,
|
|
@@ -6207,7 +6935,7 @@ var fixZodImports = /* @__PURE__ */ __name(async (zodOutputDir) => {
|
|
|
6207
6935
|
return;
|
|
6208
6936
|
}
|
|
6209
6937
|
for (const entry of entries) {
|
|
6210
|
-
const full = (0,
|
|
6938
|
+
const full = (0, import_node_path15.join)(dir, entry.name);
|
|
6211
6939
|
if (entry.isDirectory()) {
|
|
6212
6940
|
await walk(full);
|
|
6213
6941
|
} else if (entry.name.endsWith(".ts")) {
|
|
@@ -6256,9 +6984,9 @@ var pullAndGenerate = /* @__PURE__ */ __name(async (input) => {
|
|
|
6256
6984
|
};
|
|
6257
6985
|
}, "pullAndGenerate");
|
|
6258
6986
|
var normalizeSchema = /* @__PURE__ */ __name(async (schemaPath, configDir) => {
|
|
6259
|
-
const dir = configDir ?? (0,
|
|
6260
|
-
const configPath = (0,
|
|
6261
|
-
if (!(0,
|
|
6987
|
+
const dir = configDir ?? (0, import_node_path15.dirname)(schemaPath);
|
|
6988
|
+
const configPath = (0, import_node_path15.join)(dir, "normalize-schema.json");
|
|
6989
|
+
if (!(0, import_node_fs7.existsSync)(configPath)) return {
|
|
6262
6990
|
renamed: 0
|
|
6263
6991
|
};
|
|
6264
6992
|
const config = JSON.parse(await (0, import_promises7.readFile)(configPath, "utf-8"));
|
|
@@ -6287,7 +7015,7 @@ var normalizeSchema = /* @__PURE__ */ __name(async (schemaPath, configDir) => {
|
|
|
6287
7015
|
}, "normalizeSchema");
|
|
6288
7016
|
|
|
6289
7017
|
// src/lib/crud/resource/ResourceFlags.ts
|
|
6290
|
-
var
|
|
7018
|
+
var import_node_path16 = require("path");
|
|
6291
7019
|
var applyResourceFlagPatch = /* @__PURE__ */ __name((raw, patch) => {
|
|
6292
7020
|
const result = {
|
|
6293
7021
|
...raw
|
|
@@ -6328,8 +7056,8 @@ var applyResourceFlagPatch = /* @__PURE__ */ __name((raw, patch) => {
|
|
|
6328
7056
|
return result;
|
|
6329
7057
|
}, "applyResourceFlagPatch");
|
|
6330
7058
|
var resolveResourcePath = /* @__PURE__ */ __name((resourcesDir, name) => {
|
|
6331
|
-
const resolved = (0,
|
|
6332
|
-
if (!resolved.startsWith((0,
|
|
7059
|
+
const resolved = (0, import_node_path16.resolve)(resourcesDir, name, "resource.json");
|
|
7060
|
+
if (!resolved.startsWith((0, import_node_path16.resolve)(resourcesDir) + "/")) {
|
|
6333
7061
|
throw new Error(`Invalid resource name: "${name}"`);
|
|
6334
7062
|
}
|
|
6335
7063
|
return resolved;
|
|
@@ -6359,23 +7087,32 @@ var ResourceLoadReportRegistry = class ResourceLoadReportRegistry2 {
|
|
|
6359
7087
|
var resourceLoadReportRegistry = new ResourceLoadReportRegistry();
|
|
6360
7088
|
|
|
6361
7089
|
// src/lib/crud/dev-tools/dev-resources.controller.ts
|
|
6362
|
-
function
|
|
7090
|
+
function _ts_decorate6(decorators, target, key, desc2) {
|
|
6363
7091
|
var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
|
|
6364
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
6365
|
-
|
|
7092
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
7093
|
+
r = Reflect.decorate(decorators, target, key, desc2);
|
|
7094
|
+
} else {
|
|
7095
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
7096
|
+
if (d = decorators[i]) {
|
|
7097
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
7098
|
+
}
|
|
7099
|
+
}
|
|
7100
|
+
}
|
|
6366
7101
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6367
7102
|
}
|
|
6368
|
-
__name(
|
|
6369
|
-
function
|
|
6370
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
7103
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
7104
|
+
function _ts_metadata6(metadataKey, metadataValue) {
|
|
7105
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
7106
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
7107
|
+
}
|
|
6371
7108
|
}
|
|
6372
|
-
__name(
|
|
6373
|
-
function
|
|
7109
|
+
__name(_ts_metadata6, "_ts_metadata");
|
|
7110
|
+
function _ts_param2(paramIndex, decorator) {
|
|
6374
7111
|
return function(target, key) {
|
|
6375
7112
|
decorator(target, key, paramIndex);
|
|
6376
7113
|
};
|
|
6377
7114
|
}
|
|
6378
|
-
__name(
|
|
7115
|
+
__name(_ts_param2, "_ts_param");
|
|
6379
7116
|
var DevResourcesController = class {
|
|
6380
7117
|
static {
|
|
6381
7118
|
__name(this, "DevResourcesController");
|
|
@@ -6388,7 +7125,7 @@ var DevResourcesController = class {
|
|
|
6388
7125
|
}
|
|
6389
7126
|
assertDev() {
|
|
6390
7127
|
if (!IS_DEV) {
|
|
6391
|
-
throw new
|
|
7128
|
+
throw new import_common20.ForbiddenException("The database sync tools are only available when CROUTON_SCHEMA_EDITOR is enabled.");
|
|
6392
7129
|
}
|
|
6393
7130
|
}
|
|
6394
7131
|
/** Loads project config + resolves the datasource + Prisma schema path. Throws 404/400 with a clear message on misconfiguration. */
|
|
@@ -6397,14 +7134,14 @@ var DevResourcesController = class {
|
|
|
6397
7134
|
try {
|
|
6398
7135
|
loaded = await loadConfig2(process.cwd());
|
|
6399
7136
|
} catch (e) {
|
|
6400
|
-
throw new
|
|
7137
|
+
throw new import_common20.NotFoundException(e.message ?? "No crouton.json config found.");
|
|
6401
7138
|
}
|
|
6402
7139
|
const datasources = await loadDatasources(loaded);
|
|
6403
7140
|
let ds;
|
|
6404
7141
|
try {
|
|
6405
7142
|
ds = resolveDatasource(datasources, datasourceName);
|
|
6406
7143
|
} catch (e) {
|
|
6407
|
-
throw new
|
|
7144
|
+
throw new import_common20.BadRequestException(e.message);
|
|
6408
7145
|
}
|
|
6409
7146
|
const schemaPath = resolveFromRoot(loaded.root, ds.prismaSchema);
|
|
6410
7147
|
return {
|
|
@@ -6419,7 +7156,7 @@ var DevResourcesController = class {
|
|
|
6419
7156
|
schemaPath
|
|
6420
7157
|
});
|
|
6421
7158
|
} catch (e) {
|
|
6422
|
-
throw new
|
|
7159
|
+
throw new import_common20.BadRequestException(`Failed to read Prisma schema at ${schemaPath}: ${e.message}`);
|
|
6423
7160
|
}
|
|
6424
7161
|
}
|
|
6425
7162
|
buildApplyContext(loaded, ds) {
|
|
@@ -6489,7 +7226,7 @@ var DevResourcesController = class {
|
|
|
6489
7226
|
zodOutputDir: zodDir
|
|
6490
7227
|
});
|
|
6491
7228
|
if (!result.ok) {
|
|
6492
|
-
throw new
|
|
7229
|
+
throw new import_common20.BadRequestException(`prisma db pull failed:
|
|
6493
7230
|
${result.dbPull.output}`);
|
|
6494
7231
|
}
|
|
6495
7232
|
return {
|
|
@@ -6506,13 +7243,13 @@ ${result.dbPull.output}`);
|
|
|
6506
7243
|
async sync(body) {
|
|
6507
7244
|
this.assertDev();
|
|
6508
7245
|
if (!body?.model) {
|
|
6509
|
-
throw new
|
|
7246
|
+
throw new import_common20.BadRequestException('"model" is required.');
|
|
6510
7247
|
}
|
|
6511
7248
|
const { loaded, ds, schemaPath } = await this.loadProject(body.datasource);
|
|
6512
7249
|
const models = await this.introspectModels(schemaPath);
|
|
6513
7250
|
const model = models.find((m) => m.prismaName === body.model || m.clientAccessor === body.model);
|
|
6514
7251
|
if (!model) {
|
|
6515
|
-
throw new
|
|
7252
|
+
throw new import_common20.NotFoundException(`Model "${body.model}" not found in ${schemaPath}.`);
|
|
6516
7253
|
}
|
|
6517
7254
|
const resolveRelationResource = await makeRelationResolver(loaded);
|
|
6518
7255
|
const diff2 = await buildResourceDiff(model, {
|
|
@@ -6521,7 +7258,7 @@ ${result.dbPull.output}`);
|
|
|
6521
7258
|
resolveRelationResource,
|
|
6522
7259
|
readExisting: /* @__PURE__ */ __name((name) => readExistingResource(loaded, name), "readExisting")
|
|
6523
7260
|
});
|
|
6524
|
-
const resolved = await
|
|
7261
|
+
const resolved = await resolve4(diff2, recommendedResolver);
|
|
6525
7262
|
const plan = apply(resolved, this.buildApplyContext(loaded, ds));
|
|
6526
7263
|
const result = await commit(plan);
|
|
6527
7264
|
return {
|
|
@@ -6545,7 +7282,7 @@ ${result.dbPull.output}`);
|
|
|
6545
7282
|
const applyCtx = this.buildApplyContext(loaded, ds);
|
|
6546
7283
|
const resources = [];
|
|
6547
7284
|
for (const diff2 of diffs) {
|
|
6548
|
-
const resolved = await
|
|
7285
|
+
const resolved = await resolve4(diff2, recommendedResolver);
|
|
6549
7286
|
const writePlan = apply(resolved, applyCtx);
|
|
6550
7287
|
if (writePlan.files.length === 0 && writePlan.notes.length === 0) continue;
|
|
6551
7288
|
resources.push({
|
|
@@ -6579,7 +7316,7 @@ ${result.dbPull.output}`);
|
|
|
6579
7316
|
const applyCtx = this.buildApplyContext(loaded, ds);
|
|
6580
7317
|
const results = [];
|
|
6581
7318
|
for (const diff2 of diffs) {
|
|
6582
|
-
const resolved = await
|
|
7319
|
+
const resolved = await resolve4(diff2, recommendedResolver);
|
|
6583
7320
|
const writePlan = apply(resolved, applyCtx);
|
|
6584
7321
|
if (writePlan.files.length === 0) continue;
|
|
6585
7322
|
const result = await commit(writePlan);
|
|
@@ -6634,14 +7371,14 @@ ${result.dbPull.output}`);
|
|
|
6634
7371
|
const resourcesDir = resolveFromRoot(loaded.root, loaded.config.resourcesDir);
|
|
6635
7372
|
const jsonPath = resolveResourcePath(resourcesDir, name);
|
|
6636
7373
|
const raw = readRawResourceJson(jsonPath);
|
|
6637
|
-
if (!raw) throw new
|
|
6638
|
-
if (jsonPath.endsWith(".ts")) throw new
|
|
7374
|
+
if (!raw) throw new import_common20.NotFoundException(`Resource "${name}" not found.`);
|
|
7375
|
+
if (jsonPath.endsWith(".ts")) throw new import_common20.ForbiddenException("TypeScript resources cannot be edited.");
|
|
6639
7376
|
const patched = applyResourceFlagPatch(raw, {
|
|
6640
7377
|
draft: false
|
|
6641
7378
|
});
|
|
6642
7379
|
const result = validateResourceJson(patched);
|
|
6643
7380
|
if (!result.success) {
|
|
6644
|
-
throw new
|
|
7381
|
+
throw new import_common20.BadRequestException(`Validation failed: ${result.error.message}`);
|
|
6645
7382
|
}
|
|
6646
7383
|
writeRawResourceJson(jsonPath, patched);
|
|
6647
7384
|
return {
|
|
@@ -6654,8 +7391,8 @@ ${result.dbPull.output}`);
|
|
|
6654
7391
|
const resourcesDir = resolveFromRoot(loaded.root, loaded.config.resourcesDir);
|
|
6655
7392
|
const jsonPath = resolveResourcePath(resourcesDir, name);
|
|
6656
7393
|
const raw = readRawResourceJson(jsonPath);
|
|
6657
|
-
if (!raw) throw new
|
|
6658
|
-
if (jsonPath.endsWith(".ts")) throw new
|
|
7394
|
+
if (!raw) throw new import_common20.NotFoundException(`Resource "${name}" not found.`);
|
|
7395
|
+
if (jsonPath.endsWith(".ts")) throw new import_common20.ForbiddenException("TypeScript resources cannot be edited.");
|
|
6659
7396
|
const patched = applyResourceFlagPatch(raw, {
|
|
6660
7397
|
sidebar: {
|
|
6661
7398
|
hide: true
|
|
@@ -6663,7 +7400,7 @@ ${result.dbPull.output}`);
|
|
|
6663
7400
|
});
|
|
6664
7401
|
const result = validateResourceJson(patched);
|
|
6665
7402
|
if (!result.success) {
|
|
6666
|
-
throw new
|
|
7403
|
+
throw new import_common20.BadRequestException(`Validation failed: ${result.error.message}`);
|
|
6667
7404
|
}
|
|
6668
7405
|
writeRawResourceJson(jsonPath, patched);
|
|
6669
7406
|
return {
|
|
@@ -6676,8 +7413,8 @@ ${result.dbPull.output}`);
|
|
|
6676
7413
|
const resourcesDir = resolveFromRoot(loaded.root, loaded.config.resourcesDir);
|
|
6677
7414
|
const jsonPath = resolveResourcePath(resourcesDir, name);
|
|
6678
7415
|
const raw = readRawResourceJson(jsonPath);
|
|
6679
|
-
if (!raw) throw new
|
|
6680
|
-
if (jsonPath.endsWith(".ts")) throw new
|
|
7416
|
+
if (!raw) throw new import_common20.NotFoundException(`Resource "${name}" not found.`);
|
|
7417
|
+
if (jsonPath.endsWith(".ts")) throw new import_common20.ForbiddenException("TypeScript resources cannot be edited.");
|
|
6681
7418
|
const sidebarPatch = {
|
|
6682
7419
|
hide: false
|
|
6683
7420
|
};
|
|
@@ -6690,7 +7427,7 @@ ${result.dbPull.output}`);
|
|
|
6690
7427
|
});
|
|
6691
7428
|
const result = validateResourceJson(patched);
|
|
6692
7429
|
if (!result.success) {
|
|
6693
|
-
throw new
|
|
7430
|
+
throw new import_common20.BadRequestException(`Validation failed: ${result.error.message}`);
|
|
6694
7431
|
}
|
|
6695
7432
|
writeRawResourceJson(jsonPath, patched);
|
|
6696
7433
|
return {
|
|
@@ -6703,12 +7440,12 @@ ${result.dbPull.output}`);
|
|
|
6703
7440
|
const resourcesDir = resolveFromRoot(loaded.root, loaded.config.resourcesDir);
|
|
6704
7441
|
const jsonPath = resolveResourcePath(resourcesDir, name);
|
|
6705
7442
|
const raw = readRawResourceJson(jsonPath);
|
|
6706
|
-
if (!raw) throw new
|
|
6707
|
-
if (jsonPath.endsWith(".ts")) throw new
|
|
7443
|
+
if (!raw) throw new import_common20.NotFoundException(`Resource "${name}" not found.`);
|
|
7444
|
+
if (jsonPath.endsWith(".ts")) throw new import_common20.ForbiddenException("TypeScript resources cannot be edited.");
|
|
6708
7445
|
const patched = applyResourceFlagPatch(raw, body);
|
|
6709
7446
|
const result = validateResourceJson(patched);
|
|
6710
7447
|
if (!result.success) {
|
|
6711
|
-
throw new
|
|
7448
|
+
throw new import_common20.BadRequestException(`Validation failed: ${result.error.message}`);
|
|
6712
7449
|
}
|
|
6713
7450
|
writeRawResourceJson(jsonPath, patched);
|
|
6714
7451
|
return {
|
|
@@ -6716,8 +7453,8 @@ ${result.dbPull.output}`);
|
|
|
6716
7453
|
};
|
|
6717
7454
|
}
|
|
6718
7455
|
};
|
|
6719
|
-
|
|
6720
|
-
(0,
|
|
7456
|
+
_ts_decorate6([
|
|
7457
|
+
(0, import_common20.Get)("models"),
|
|
6721
7458
|
(0, import_swagger12.ApiOperation)({
|
|
6722
7459
|
summary: "Dev-only: list DB models from the Prisma schema, flagging which already have a resource.json and whether the running backend can actually use them yet"
|
|
6723
7460
|
}),
|
|
@@ -6725,12 +7462,12 @@ _ts_decorate5([
|
|
|
6725
7462
|
status: 200,
|
|
6726
7463
|
description: "DB models and their resource/client status"
|
|
6727
7464
|
}),
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
7465
|
+
_ts_metadata6("design:type", Function),
|
|
7466
|
+
_ts_metadata6("design:paramtypes", []),
|
|
7467
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6731
7468
|
], DevResourcesController.prototype, "listModels", null);
|
|
6732
|
-
|
|
6733
|
-
(0,
|
|
7469
|
+
_ts_decorate6([
|
|
7470
|
+
(0, import_common20.Post)("restart"),
|
|
6734
7471
|
(0, import_swagger12.ApiOperation)({
|
|
6735
7472
|
summary: "Dev-only: exit this process so a dev watcher/process manager (nodemon, `nest start --watch`, pm2, a Docker restart policy, ...) restarts it with a fresh Prisma client. Does nothing useful if this process isn't supervised by one of those."
|
|
6736
7473
|
}),
|
|
@@ -6738,12 +7475,12 @@ _ts_decorate5([
|
|
|
6738
7475
|
status: 200,
|
|
6739
7476
|
description: "Restart scheduled \u2014 the connection will drop shortly after"
|
|
6740
7477
|
}),
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
7478
|
+
_ts_metadata6("design:type", Function),
|
|
7479
|
+
_ts_metadata6("design:paramtypes", []),
|
|
7480
|
+
_ts_metadata6("design:returntype", Object)
|
|
6744
7481
|
], DevResourcesController.prototype, "restart", null);
|
|
6745
|
-
|
|
6746
|
-
(0,
|
|
7482
|
+
_ts_decorate6([
|
|
7483
|
+
(0, import_common20.Post)("pull"),
|
|
6747
7484
|
(0, import_swagger12.ApiOperation)({
|
|
6748
7485
|
summary: "Dev-only: run `prisma db pull` + case-format + `prisma generate` for a datasource, refreshing schema.prisma and the generated Prisma client/Zod types from the live database"
|
|
6749
7486
|
}),
|
|
@@ -6751,15 +7488,15 @@ _ts_decorate5([
|
|
|
6751
7488
|
status: 200,
|
|
6752
7489
|
description: "Result of each step, or requiresConfirmation if schema.prisma has uncommitted changes"
|
|
6753
7490
|
}),
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
7491
|
+
_ts_param2(0, (0, import_common20.Body)()),
|
|
7492
|
+
_ts_metadata6("design:type", Function),
|
|
7493
|
+
_ts_metadata6("design:paramtypes", [
|
|
6757
7494
|
Object
|
|
6758
7495
|
]),
|
|
6759
|
-
|
|
7496
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6760
7497
|
], DevResourcesController.prototype, "pull", null);
|
|
6761
|
-
|
|
6762
|
-
(0,
|
|
7498
|
+
_ts_decorate6([
|
|
7499
|
+
(0, import_common20.Post)("sync"),
|
|
6763
7500
|
(0, import_swagger12.ApiOperation)({
|
|
6764
7501
|
summary: "Dev-only: generate or update a single resource.json from its DB model, using recommended defaults (non-interactive)"
|
|
6765
7502
|
}),
|
|
@@ -6767,15 +7504,15 @@ _ts_decorate5([
|
|
|
6767
7504
|
status: 200,
|
|
6768
7505
|
description: "Files written for this resource"
|
|
6769
7506
|
}),
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
7507
|
+
_ts_param2(0, (0, import_common20.Body)()),
|
|
7508
|
+
_ts_metadata6("design:type", Function),
|
|
7509
|
+
_ts_metadata6("design:paramtypes", [
|
|
6773
7510
|
Object
|
|
6774
7511
|
]),
|
|
6775
|
-
|
|
7512
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6776
7513
|
], DevResourcesController.prototype, "sync", null);
|
|
6777
|
-
|
|
6778
|
-
(0,
|
|
7514
|
+
_ts_decorate6([
|
|
7515
|
+
(0, import_common20.Post)("plan"),
|
|
6779
7516
|
(0, import_swagger12.ApiOperation)({
|
|
6780
7517
|
summary: "Dev-only: dry-run introspect + diff across all (or selected) DB models using recommended defaults \u2014 computes what would change, writes nothing"
|
|
6781
7518
|
}),
|
|
@@ -6783,15 +7520,15 @@ _ts_decorate5([
|
|
|
6783
7520
|
status: 200,
|
|
6784
7521
|
description: "Proposed per-resource changes"
|
|
6785
7522
|
}),
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
7523
|
+
_ts_param2(0, (0, import_common20.Body)()),
|
|
7524
|
+
_ts_metadata6("design:type", Function),
|
|
7525
|
+
_ts_metadata6("design:paramtypes", [
|
|
6789
7526
|
Object
|
|
6790
7527
|
]),
|
|
6791
|
-
|
|
7528
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6792
7529
|
], DevResourcesController.prototype, "plan", null);
|
|
6793
|
-
|
|
6794
|
-
(0,
|
|
7530
|
+
_ts_decorate6([
|
|
7531
|
+
(0, import_common20.Post)("apply"),
|
|
6795
7532
|
(0, import_swagger12.ApiOperation)({
|
|
6796
7533
|
summary: "Dev-only: commit resource.json/schema.ts changes to disk for the given resources (or all, if omitted), using recommended defaults"
|
|
6797
7534
|
}),
|
|
@@ -6799,15 +7536,15 @@ _ts_decorate5([
|
|
|
6799
7536
|
status: 200,
|
|
6800
7537
|
description: "Per-resource commit results"
|
|
6801
7538
|
}),
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
7539
|
+
_ts_param2(0, (0, import_common20.Body)()),
|
|
7540
|
+
_ts_metadata6("design:type", Function),
|
|
7541
|
+
_ts_metadata6("design:paramtypes", [
|
|
6805
7542
|
Object
|
|
6806
7543
|
]),
|
|
6807
|
-
|
|
7544
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6808
7545
|
], DevResourcesController.prototype, "apply", null);
|
|
6809
|
-
|
|
6810
|
-
(0,
|
|
7546
|
+
_ts_decorate6([
|
|
7547
|
+
(0, import_common20.Get)("visibility"),
|
|
6811
7548
|
(0, import_swagger12.ApiOperation)({
|
|
6812
7549
|
summary: "Dev-only: list all resources with their menu visibility state (in-menu, hidden, draft, error)"
|
|
6813
7550
|
}),
|
|
@@ -6815,12 +7552,12 @@ _ts_decorate5([
|
|
|
6815
7552
|
status: 200,
|
|
6816
7553
|
description: "Resource visibility list"
|
|
6817
7554
|
}),
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
7555
|
+
_ts_metadata6("design:type", Function),
|
|
7556
|
+
_ts_metadata6("design:paramtypes", []),
|
|
7557
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6821
7558
|
], DevResourcesController.prototype, "visibility", null);
|
|
6822
|
-
|
|
6823
|
-
(0,
|
|
7559
|
+
_ts_decorate6([
|
|
7560
|
+
(0, import_common20.Post)(":name/publish"),
|
|
6824
7561
|
(0, import_swagger12.ApiOperation)({
|
|
6825
7562
|
summary: "Dev-only: publish a draft resource (removes `draft: true` from resource.json)"
|
|
6826
7563
|
}),
|
|
@@ -6828,15 +7565,15 @@ _ts_decorate5([
|
|
|
6828
7565
|
status: 200,
|
|
6829
7566
|
description: "Resource published"
|
|
6830
7567
|
}),
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
7568
|
+
_ts_param2(0, (0, import_common20.Param)("name")),
|
|
7569
|
+
_ts_metadata6("design:type", Function),
|
|
7570
|
+
_ts_metadata6("design:paramtypes", [
|
|
6834
7571
|
String
|
|
6835
7572
|
]),
|
|
6836
|
-
|
|
7573
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6837
7574
|
], DevResourcesController.prototype, "publish", null);
|
|
6838
|
-
|
|
6839
|
-
(0,
|
|
7575
|
+
_ts_decorate6([
|
|
7576
|
+
(0, import_common20.Post)(":name/remove-from-menu"),
|
|
6840
7577
|
(0, import_swagger12.ApiOperation)({
|
|
6841
7578
|
summary: "Dev-only: hide a resource from the sidebar menu (sets `sidebar.hide: true` in resource.json)"
|
|
6842
7579
|
}),
|
|
@@ -6844,15 +7581,15 @@ _ts_decorate5([
|
|
|
6844
7581
|
status: 200,
|
|
6845
7582
|
description: "Resource removed from menu"
|
|
6846
7583
|
}),
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
7584
|
+
_ts_param2(0, (0, import_common20.Param)("name")),
|
|
7585
|
+
_ts_metadata6("design:type", Function),
|
|
7586
|
+
_ts_metadata6("design:paramtypes", [
|
|
6850
7587
|
String
|
|
6851
7588
|
]),
|
|
6852
|
-
|
|
7589
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6853
7590
|
], DevResourcesController.prototype, "removeFromMenu", null);
|
|
6854
|
-
|
|
6855
|
-
(0,
|
|
7591
|
+
_ts_decorate6([
|
|
7592
|
+
(0, import_common20.Post)(":name/add-to-menu"),
|
|
6856
7593
|
(0, import_swagger12.ApiOperation)({
|
|
6857
7594
|
summary: "Dev-only: publish + un-hide a resource and optionally set sidebar group/position/label"
|
|
6858
7595
|
}),
|
|
@@ -6860,17 +7597,17 @@ _ts_decorate5([
|
|
|
6860
7597
|
status: 200,
|
|
6861
7598
|
description: "Resource added to menu"
|
|
6862
7599
|
}),
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
7600
|
+
_ts_param2(0, (0, import_common20.Param)("name")),
|
|
7601
|
+
_ts_param2(1, (0, import_common20.Body)()),
|
|
7602
|
+
_ts_metadata6("design:type", Function),
|
|
7603
|
+
_ts_metadata6("design:paramtypes", [
|
|
6867
7604
|
String,
|
|
6868
7605
|
Object
|
|
6869
7606
|
]),
|
|
6870
|
-
|
|
7607
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6871
7608
|
], DevResourcesController.prototype, "addToMenu", null);
|
|
6872
|
-
|
|
6873
|
-
(0,
|
|
7609
|
+
_ts_decorate6([
|
|
7610
|
+
(0, import_common20.Patch)(":name/flags"),
|
|
6874
7611
|
(0, import_swagger12.ApiOperation)({
|
|
6875
7612
|
summary: "Dev-only: set arbitrary resource flags (draft, sidebar.hide, group, position, label)"
|
|
6876
7613
|
}),
|
|
@@ -6878,55 +7615,55 @@ _ts_decorate5([
|
|
|
6878
7615
|
status: 200,
|
|
6879
7616
|
description: "Flags updated"
|
|
6880
7617
|
}),
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
7618
|
+
_ts_param2(0, (0, import_common20.Param)("name")),
|
|
7619
|
+
_ts_param2(1, (0, import_common20.Body)()),
|
|
7620
|
+
_ts_metadata6("design:type", Function),
|
|
7621
|
+
_ts_metadata6("design:paramtypes", [
|
|
6885
7622
|
String,
|
|
6886
7623
|
typeof ResourceFlagPatch === "undefined" ? Object : ResourceFlagPatch
|
|
6887
7624
|
]),
|
|
6888
|
-
|
|
7625
|
+
_ts_metadata6("design:returntype", Promise)
|
|
6889
7626
|
], DevResourcesController.prototype, "updateFlags", null);
|
|
6890
|
-
DevResourcesController =
|
|
6891
|
-
(0,
|
|
7627
|
+
DevResourcesController = _ts_decorate6([
|
|
7628
|
+
(0, import_common20.Controller)("_app/resources"),
|
|
6892
7629
|
(0, import_swagger12.ApiTags)("Dev tools"),
|
|
6893
|
-
|
|
6894
|
-
|
|
7630
|
+
_ts_metadata6("design:type", Function),
|
|
7631
|
+
_ts_metadata6("design:paramtypes", [
|
|
6895
7632
|
typeof DataSourceRegistry === "undefined" ? Object : DataSourceRegistry,
|
|
6896
7633
|
typeof ResourceConfigRegistry === "undefined" ? Object : ResourceConfigRegistry
|
|
6897
7634
|
])
|
|
6898
7635
|
], DevResourcesController);
|
|
6899
7636
|
|
|
6900
7637
|
// src/lib/crud/enum-registry/enum-registry.types.ts
|
|
6901
|
-
var
|
|
6902
|
-
var EnumEntrySchema =
|
|
6903
|
-
value:
|
|
6904
|
-
label:
|
|
7638
|
+
var import_zod31 = require("zod");
|
|
7639
|
+
var EnumEntrySchema = import_zod31.z.object({
|
|
7640
|
+
value: import_zod31.z.unknown(),
|
|
7641
|
+
label: import_zod31.z.string()
|
|
6905
7642
|
});
|
|
6906
|
-
var EnumRegistrySchema =
|
|
7643
|
+
var EnumRegistrySchema = import_zod31.z.record(import_zod31.z.string(), import_zod31.z.array(EnumEntrySchema)).default({});
|
|
6907
7644
|
|
|
6908
7645
|
// src/lib/crud/enum-registry/enum-registry.loader.ts
|
|
6909
|
-
var
|
|
6910
|
-
var
|
|
7646
|
+
var import_node_fs8 = require("fs");
|
|
7647
|
+
var import_node_path17 = require("path");
|
|
6911
7648
|
var ENUMS_FILE = "crouton.enums.json";
|
|
6912
7649
|
var loadEnumRegistry = /* @__PURE__ */ __name((startDir, enumsFile) => {
|
|
6913
7650
|
let file = enumsFile;
|
|
6914
7651
|
if (!file) {
|
|
6915
7652
|
let dir = startDir;
|
|
6916
7653
|
while (true) {
|
|
6917
|
-
const candidate = (0,
|
|
6918
|
-
if ((0,
|
|
7654
|
+
const candidate = (0, import_node_path17.join)(dir, ENUMS_FILE);
|
|
7655
|
+
if ((0, import_node_fs8.existsSync)(candidate)) {
|
|
6919
7656
|
file = candidate;
|
|
6920
7657
|
break;
|
|
6921
7658
|
}
|
|
6922
|
-
const parent = (0,
|
|
7659
|
+
const parent = (0, import_node_path17.dirname)(dir);
|
|
6923
7660
|
if (parent === dir) break;
|
|
6924
7661
|
dir = parent;
|
|
6925
7662
|
}
|
|
6926
7663
|
}
|
|
6927
|
-
if (!file || !(0,
|
|
7664
|
+
if (!file || !(0, import_node_fs8.existsSync)(file)) return EnumRegistrySchema.parse(void 0);
|
|
6928
7665
|
try {
|
|
6929
|
-
return EnumRegistrySchema.parse(JSON.parse((0,
|
|
7666
|
+
return EnumRegistrySchema.parse(JSON.parse((0, import_node_fs8.readFileSync)(file, "utf-8")));
|
|
6930
7667
|
} catch {
|
|
6931
7668
|
return EnumRegistrySchema.parse(void 0);
|
|
6932
7669
|
}
|
|
@@ -6985,9 +7722,9 @@ var upsertOp = /* @__PURE__ */ __name((entry, schema) => {
|
|
|
6985
7722
|
}, "upsertOp");
|
|
6986
7723
|
|
|
6987
7724
|
// src/lib/crud/adapter/relation-type.ts
|
|
6988
|
-
var
|
|
7725
|
+
var import_zod32 = require("zod");
|
|
6989
7726
|
var unwrapZodType = /* @__PURE__ */ __name((type) => {
|
|
6990
|
-
if (type instanceof
|
|
7727
|
+
if (type instanceof import_zod32.ZodOptional || type instanceof import_zod32.ZodNullable) {
|
|
6991
7728
|
return unwrapZodType(type.unwrap());
|
|
6992
7729
|
}
|
|
6993
7730
|
return type;
|
|
@@ -6997,7 +7734,7 @@ var deriveRelationType = /* @__PURE__ */ __name((schema, columnId) => {
|
|
|
6997
7734
|
const field = schema.shape[columnId];
|
|
6998
7735
|
if (!field) return void 0;
|
|
6999
7736
|
const inner = unwrapZodType(field);
|
|
7000
|
-
return inner instanceof
|
|
7737
|
+
return inner instanceof import_zod32.ZodArray ? "oneToMany" : "manyToOne";
|
|
7001
7738
|
}, "deriveRelationType");
|
|
7002
7739
|
var deriveRelationTypeFromColumns = /* @__PURE__ */ __name((col, cols) => {
|
|
7003
7740
|
const base = col.column ?? col.id;
|
|
@@ -7027,89 +7764,6 @@ var enrichRelationTypes = /* @__PURE__ */ __name((columns, schema) => {
|
|
|
7027
7764
|
});
|
|
7028
7765
|
}, "enrichRelationTypes");
|
|
7029
7766
|
|
|
7030
|
-
// src/lib/crud/resource/ReadResourceJson.ts
|
|
7031
|
-
var import_node_fs6 = require("fs");
|
|
7032
|
-
var import_node_path15 = require("path");
|
|
7033
|
-
var readResourceJson = /* @__PURE__ */ __name((jsonPath) => {
|
|
7034
|
-
if (!(0, import_node_fs6.existsSync)(jsonPath)) return void 0;
|
|
7035
|
-
let fileContent;
|
|
7036
|
-
try {
|
|
7037
|
-
fileContent = JSON.parse((0, import_node_fs6.readFileSync)(jsonPath, "utf-8"));
|
|
7038
|
-
} catch (err) {
|
|
7039
|
-
return {
|
|
7040
|
-
success: false,
|
|
7041
|
-
error: `Invalid JSON in ${jsonPath}: ${err.message}`
|
|
7042
|
-
};
|
|
7043
|
-
}
|
|
7044
|
-
const resource = ResourceJsonSchema.safeParse(fileContent);
|
|
7045
|
-
if (resource.error) {
|
|
7046
|
-
return {
|
|
7047
|
-
success: false,
|
|
7048
|
-
error: `Resource cannot be parsed ${jsonPath}: ${resource.error.message}`
|
|
7049
|
-
};
|
|
7050
|
-
}
|
|
7051
|
-
return {
|
|
7052
|
-
success: true,
|
|
7053
|
-
data: {
|
|
7054
|
-
json: resource.data,
|
|
7055
|
-
dir: (0, import_node_path15.dirname)(jsonPath)
|
|
7056
|
-
}
|
|
7057
|
-
};
|
|
7058
|
-
}, "readResourceJson");
|
|
7059
|
-
|
|
7060
|
-
// src/lib/crud/adapter/resource-resolver.ts
|
|
7061
|
-
var import_node_fs7 = require("fs");
|
|
7062
|
-
var import_node_path16 = require("path");
|
|
7063
|
-
var resolveChildResourceDetailed = /* @__PURE__ */ __name((resourcePath, parentDir) => {
|
|
7064
|
-
const attempted = [];
|
|
7065
|
-
try {
|
|
7066
|
-
if (resourcePath.endsWith(".json")) {
|
|
7067
|
-
const directPath = (0, import_node_path16.resolve)(parentDir, resourcePath);
|
|
7068
|
-
attempted.push(directPath);
|
|
7069
|
-
if ((0, import_node_fs7.existsSync)(directPath)) {
|
|
7070
|
-
const result2 = readResourceJson(directPath);
|
|
7071
|
-
if (result2?.success) return {
|
|
7072
|
-
ok: true,
|
|
7073
|
-
value: result2.data
|
|
7074
|
-
};
|
|
7075
|
-
return {
|
|
7076
|
-
ok: false,
|
|
7077
|
-
reason: "invalid",
|
|
7078
|
-
error: result2?.error ?? `Could not read ${directPath}`
|
|
7079
|
-
};
|
|
7080
|
-
}
|
|
7081
|
-
}
|
|
7082
|
-
const childName = resourcePath.replace(/^\.\//, "").replace(/\.resource$/, "");
|
|
7083
|
-
const childJsonPath = (0, import_node_path16.resolve)((0, import_node_path16.dirname)(parentDir), childName, "resource.json");
|
|
7084
|
-
attempted.push(childJsonPath);
|
|
7085
|
-
const result = readResourceJson(childJsonPath);
|
|
7086
|
-
if (result?.success) return {
|
|
7087
|
-
ok: true,
|
|
7088
|
-
value: result.data
|
|
7089
|
-
};
|
|
7090
|
-
if (result) return {
|
|
7091
|
-
ok: false,
|
|
7092
|
-
reason: "invalid",
|
|
7093
|
-
error: result.error
|
|
7094
|
-
};
|
|
7095
|
-
return {
|
|
7096
|
-
ok: false,
|
|
7097
|
-
reason: "missing",
|
|
7098
|
-
attempted
|
|
7099
|
-
};
|
|
7100
|
-
} catch (err) {
|
|
7101
|
-
return {
|
|
7102
|
-
ok: false,
|
|
7103
|
-
reason: "invalid",
|
|
7104
|
-
error: err.message
|
|
7105
|
-
};
|
|
7106
|
-
}
|
|
7107
|
-
}, "resolveChildResourceDetailed");
|
|
7108
|
-
var resolveChildResource = /* @__PURE__ */ __name((resourcePath, parentDir) => {
|
|
7109
|
-
const resolution = resolveChildResourceDetailed(resourcePath, parentDir);
|
|
7110
|
-
return resolution.ok ? resolution.value : void 0;
|
|
7111
|
-
}, "resolveChildResource");
|
|
7112
|
-
|
|
7113
7767
|
// src/lib/crud/adapter/column-enrichment.ts
|
|
7114
7768
|
var enrichActionColumns = /* @__PURE__ */ __name((columns, parentRoute, subResources, baseUrl) => {
|
|
7115
7769
|
if (!columns) return columns;
|
|
@@ -7196,96 +7850,6 @@ var enrichIncludeWithSort = /* @__PURE__ */ __name((include, columns) => {
|
|
|
7196
7850
|
});
|
|
7197
7851
|
}, "enrichIncludeWithSort");
|
|
7198
7852
|
|
|
7199
|
-
// src/lib/crud/adapter/column-transforms.ts
|
|
7200
|
-
var expandExtendColumns = /* @__PURE__ */ __name((columns, dirPath) => {
|
|
7201
|
-
if (!dirPath) return columns;
|
|
7202
|
-
const result = [];
|
|
7203
|
-
for (const col of columns) {
|
|
7204
|
-
if (!col.extend) {
|
|
7205
|
-
result.push(col);
|
|
7206
|
-
continue;
|
|
7207
|
-
}
|
|
7208
|
-
const resolved = resolveChildResource(col.extend, dirPath);
|
|
7209
|
-
if (!resolved) {
|
|
7210
|
-
console.warn(`[extend] Could not resolve "${col.extend}" for column "${col.id}" \u2014 keeping as-is`);
|
|
7211
|
-
result.push(col);
|
|
7212
|
-
continue;
|
|
7213
|
-
}
|
|
7214
|
-
const refColumns = resolved.json.columns;
|
|
7215
|
-
const parentColumnKey = col.column ?? col.id;
|
|
7216
|
-
for (const refCol of refColumns) {
|
|
7217
|
-
if (refCol.idField) continue;
|
|
7218
|
-
const virtualId = `${col.id}_${refCol.id}`;
|
|
7219
|
-
const displayKey = refCol.displayKey ? `${refCol.id}.${refCol.displayKey}` : refCol.id;
|
|
7220
|
-
const hiddenInTable = col.hiddenInTable === true || refCol.hiddenInTable === true ? true : col.hiddenInTable ?? refCol.hiddenInTable;
|
|
7221
|
-
const hiddenInForm = col.hiddenInForm === true || refCol.hiddenInForm === true ? true : col.hiddenInForm ?? refCol.hiddenInForm;
|
|
7222
|
-
const hiddenInView = col.hiddenInView === true || refCol.hiddenInView === true ? true : col.hiddenInView ?? refCol.hiddenInView;
|
|
7223
|
-
const override = col.columns?.[virtualId] ?? col.columns?.[refCol.id] ?? {};
|
|
7224
|
-
const virtualCol = {
|
|
7225
|
-
id: virtualId,
|
|
7226
|
-
column: parentColumnKey,
|
|
7227
|
-
displayKey,
|
|
7228
|
-
label: refCol.label ?? refCol.id,
|
|
7229
|
-
columnType: "object",
|
|
7230
|
-
...hiddenInTable !== void 0 && {
|
|
7231
|
-
hiddenInTable
|
|
7232
|
-
},
|
|
7233
|
-
...hiddenInForm !== void 0 && {
|
|
7234
|
-
hiddenInForm
|
|
7235
|
-
},
|
|
7236
|
-
...hiddenInView !== void 0 && {
|
|
7237
|
-
hiddenInView
|
|
7238
|
-
},
|
|
7239
|
-
...refCol.sortable != null && {
|
|
7240
|
-
sortable: refCol.sortable
|
|
7241
|
-
},
|
|
7242
|
-
...refCol.fieldInput && {
|
|
7243
|
-
fieldInput: refCol.fieldInput
|
|
7244
|
-
},
|
|
7245
|
-
...override
|
|
7246
|
-
};
|
|
7247
|
-
result.push(virtualCol);
|
|
7248
|
-
}
|
|
7249
|
-
}
|
|
7250
|
-
return result;
|
|
7251
|
-
}, "expandExtendColumns");
|
|
7252
|
-
var buildValueLabelColumns = /* @__PURE__ */ __name((columns) => (columns ?? []).flatMap((c) => {
|
|
7253
|
-
const opts = c.fieldInput?.options;
|
|
7254
|
-
if (!opts?.emitObject || !Array.isArray(opts.values)) return [];
|
|
7255
|
-
return [
|
|
7256
|
-
{
|
|
7257
|
-
field: c.column ?? c.id,
|
|
7258
|
-
values: opts.values
|
|
7259
|
-
}
|
|
7260
|
-
];
|
|
7261
|
-
}), "buildValueLabelColumns");
|
|
7262
|
-
var applyRelationFormatDefault = /* @__PURE__ */ __name((cols) => cols?.map((col) => {
|
|
7263
|
-
const fi = col.fieldInput;
|
|
7264
|
-
if (fi && fi.resource && !fi.format && !fi.type) {
|
|
7265
|
-
return {
|
|
7266
|
-
...col,
|
|
7267
|
-
fieldInput: {
|
|
7268
|
-
...fi,
|
|
7269
|
-
format: "relation"
|
|
7270
|
-
}
|
|
7271
|
-
};
|
|
7272
|
-
}
|
|
7273
|
-
return col;
|
|
7274
|
-
}), "applyRelationFormatDefault");
|
|
7275
|
-
var resolveColumnFieldVariants = /* @__PURE__ */ __name((cols) => cols?.map((col) => {
|
|
7276
|
-
const fieldView = resolveViewField(col);
|
|
7277
|
-
const fieldTable = resolveTableField(col);
|
|
7278
|
-
return {
|
|
7279
|
-
...col,
|
|
7280
|
-
...fieldView && {
|
|
7281
|
-
fieldView
|
|
7282
|
-
},
|
|
7283
|
-
...fieldTable && {
|
|
7284
|
-
fieldTable
|
|
7285
|
-
}
|
|
7286
|
-
};
|
|
7287
|
-
}), "resolveColumnFieldVariants");
|
|
7288
|
-
|
|
7289
7853
|
// src/lib/crud/adapter/sub-resource.builder.ts
|
|
7290
7854
|
var REMOTE_RESOURCE = /^https?:\/\//i;
|
|
7291
7855
|
var buildSubResources = /* @__PURE__ */ __name((columns, parentRoute, parentModel, parentDir, enums = {}, baseUrl) => {
|
|
@@ -7521,7 +8085,7 @@ var buildLookup = /* @__PURE__ */ __name((columns) => {
|
|
|
7521
8085
|
}, "buildLookup");
|
|
7522
8086
|
|
|
7523
8087
|
// src/lib/crud/resource/MigrateResourceJson.ts
|
|
7524
|
-
var
|
|
8088
|
+
var import_node_fs9 = require("fs");
|
|
7525
8089
|
var migrateResourceJsonFile = /* @__PURE__ */ __name((jsonPath, opts) => {
|
|
7526
8090
|
let raw;
|
|
7527
8091
|
try {
|
|
@@ -7562,7 +8126,7 @@ var migrateResourceJsonFile = /* @__PURE__ */ __name((jsonPath, opts) => {
|
|
|
7562
8126
|
error: `migrated resource.json (v${from}\u2192v${result.to}) is invalid: ${validation.error.message}`
|
|
7563
8127
|
};
|
|
7564
8128
|
}
|
|
7565
|
-
(0,
|
|
8129
|
+
(0, import_node_fs9.writeFileSync)(jsonPath, serializeResourceJson(result.raw), "utf-8");
|
|
7566
8130
|
return {
|
|
7567
8131
|
status: "migrated",
|
|
7568
8132
|
from: result.from,
|
|
@@ -7581,25 +8145,25 @@ var migrateResourceJsonFile = /* @__PURE__ */ __name((jsonPath, opts) => {
|
|
|
7581
8145
|
}, "migrateResourceJsonFile");
|
|
7582
8146
|
|
|
7583
8147
|
// src/lib/crud/loader/index.ts
|
|
7584
|
-
var
|
|
7585
|
-
var
|
|
8148
|
+
var import_node_fs10 = require("fs");
|
|
8149
|
+
var import_node_path18 = require("path");
|
|
7586
8150
|
var loadResourceConfigsFromDir = /* @__PURE__ */ __name(async (dirPath, baseUrl, enumsFile, onResourceDir) => {
|
|
7587
|
-
if (!(0,
|
|
8151
|
+
if (!(0, import_node_fs10.existsSync)(dirPath)) return [];
|
|
7588
8152
|
resourceLoadErrorsRegistry.clear();
|
|
7589
8153
|
resourceLoadReportRegistry.clear();
|
|
7590
8154
|
const enums = loadEnumRegistry(dirPath, enumsFile);
|
|
7591
|
-
const entries = (0,
|
|
8155
|
+
const entries = (0, import_node_fs10.readdirSync)(dirPath, {
|
|
7592
8156
|
withFileTypes: true
|
|
7593
8157
|
});
|
|
7594
8158
|
const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
7595
8159
|
const configs = [];
|
|
7596
8160
|
for (const dir of dirs) {
|
|
7597
|
-
const basePath = (0,
|
|
8161
|
+
const basePath = (0, import_node_path18.join)(dirPath, dir);
|
|
7598
8162
|
const schemaFile = findModule(basePath, "schema");
|
|
7599
8163
|
const schema = schemaFile ? await importDefault(schemaFile) : void 0;
|
|
7600
8164
|
const hooks = await loadResourceHooks(basePath);
|
|
7601
|
-
const jsonFile = (0,
|
|
7602
|
-
if ((0,
|
|
8165
|
+
const jsonFile = (0, import_node_path18.join)(basePath, "resource.json");
|
|
8166
|
+
if ((0, import_node_fs10.existsSync)(jsonFile)) {
|
|
7603
8167
|
const migration = migrateResourceJsonFile(jsonFile, {
|
|
7604
8168
|
isDev: IS_DEV
|
|
7605
8169
|
});
|
|
@@ -7718,23 +8282,23 @@ var FileSystemResourceConfigLoader = class extends ResourceConfigLoader2 {
|
|
|
7718
8282
|
};
|
|
7719
8283
|
|
|
7720
8284
|
// src/lib/crud/status/status.service.ts
|
|
7721
|
-
var
|
|
7722
|
-
var
|
|
8285
|
+
var import_node_fs11 = require("fs");
|
|
8286
|
+
var import_node_path19 = require("path");
|
|
7723
8287
|
var import_node_url = require("url");
|
|
7724
8288
|
var DB_CHECK_TIMEOUT_MS = 3e3;
|
|
7725
8289
|
var CONNECTION_STRING_PATTERN = /(?:postgresql|postgres|mysql|mongodb|sqlserver|sqlite):\/\/[^\s"')]+/gi;
|
|
7726
8290
|
var stripConnectionStrings = /* @__PURE__ */ __name((message) => message.replace(CONNECTION_STRING_PATTERN, "[REDACTED]"), "stripConnectionStrings");
|
|
7727
8291
|
var getCroutonVersion = /* @__PURE__ */ __name(() => {
|
|
7728
8292
|
try {
|
|
7729
|
-
const startDir = typeof __dirname !== "undefined" ? __dirname : (0,
|
|
8293
|
+
const startDir = typeof __dirname !== "undefined" ? __dirname : (0, import_node_path19.dirname)((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
7730
8294
|
let dir = startDir;
|
|
7731
|
-
while (dir !== (0,
|
|
7732
|
-
const pkgPath = (0,
|
|
7733
|
-
if ((0,
|
|
7734
|
-
const pkg = JSON.parse((0,
|
|
8295
|
+
while (dir !== (0, import_node_path19.dirname)(dir)) {
|
|
8296
|
+
const pkgPath = (0, import_node_path19.join)(dir, "package.json");
|
|
8297
|
+
if ((0, import_node_fs11.existsSync)(pkgPath)) {
|
|
8298
|
+
const pkg = JSON.parse((0, import_node_fs11.readFileSync)(pkgPath, "utf-8"));
|
|
7735
8299
|
if (pkg.name === "@ghentcdh/crouton-api") return pkg.version;
|
|
7736
8300
|
}
|
|
7737
|
-
dir = (0,
|
|
8301
|
+
dir = (0, import_node_path19.dirname)(dir);
|
|
7738
8302
|
}
|
|
7739
8303
|
} catch {
|
|
7740
8304
|
}
|
|
@@ -7919,7 +8483,46 @@ var getEnums = /* @__PURE__ */ __name((enumRegistry) => {
|
|
|
7919
8483
|
project: getProjectEnums(enumRegistry)
|
|
7920
8484
|
};
|
|
7921
8485
|
}, "getEnums");
|
|
7922
|
-
var
|
|
8486
|
+
var countKeys = /* @__PURE__ */ __name((obj, prefix = "") => {
|
|
8487
|
+
let total = 0;
|
|
8488
|
+
let empty = 0;
|
|
8489
|
+
for (const [, v] of Object.entries(obj)) {
|
|
8490
|
+
if (typeof v === "string") {
|
|
8491
|
+
total++;
|
|
8492
|
+
if (v === "") empty++;
|
|
8493
|
+
} else if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
8494
|
+
const sub = countKeys(v, prefix);
|
|
8495
|
+
total += sub.total;
|
|
8496
|
+
empty += sub.empty;
|
|
8497
|
+
}
|
|
8498
|
+
}
|
|
8499
|
+
return {
|
|
8500
|
+
total,
|
|
8501
|
+
empty
|
|
8502
|
+
};
|
|
8503
|
+
}, "countKeys");
|
|
8504
|
+
var getI18nStatus = /* @__PURE__ */ __name((translationRegistry) => {
|
|
8505
|
+
if (!translationRegistry?.active) return void 0;
|
|
8506
|
+
const languages = [
|
|
8507
|
+
...translationRegistry.languages
|
|
8508
|
+
];
|
|
8509
|
+
const bundles = languages.map((language) => {
|
|
8510
|
+
const bundle = translationRegistry.bundleFor(language);
|
|
8511
|
+
const { total, empty } = countKeys(bundle);
|
|
8512
|
+
return {
|
|
8513
|
+
language,
|
|
8514
|
+
keyCount: total,
|
|
8515
|
+
emptyKeys: empty
|
|
8516
|
+
};
|
|
8517
|
+
});
|
|
8518
|
+
return {
|
|
8519
|
+
active: true,
|
|
8520
|
+
defaultLanguage: translationRegistry.defaultLanguage,
|
|
8521
|
+
languages,
|
|
8522
|
+
bundles
|
|
8523
|
+
};
|
|
8524
|
+
}, "getI18nStatus");
|
|
8525
|
+
var buildStatus = /* @__PURE__ */ __name(async (registry, loadedConfigs, enumRegistry, translationRegistry) => {
|
|
7923
8526
|
const databases = await checkDatabases(registry);
|
|
7924
8527
|
const resources = getResourceStatus(loadedConfigs);
|
|
7925
8528
|
const summary = buildSummary(databases, resources);
|
|
@@ -7930,25 +8533,37 @@ var buildStatus = /* @__PURE__ */ __name(async (registry, loadedConfigs, enumReg
|
|
|
7930
8533
|
summary,
|
|
7931
8534
|
databases,
|
|
7932
8535
|
resources,
|
|
7933
|
-
enums: getEnums(enumRegistry)
|
|
8536
|
+
enums: getEnums(enumRegistry),
|
|
8537
|
+
...translationRegistry?.active && {
|
|
8538
|
+
i18n: getI18nStatus(translationRegistry)
|
|
8539
|
+
}
|
|
7934
8540
|
};
|
|
7935
8541
|
}, "buildStatus");
|
|
7936
8542
|
|
|
7937
8543
|
// src/lib/crud/status/status.controller.ts
|
|
7938
|
-
var
|
|
8544
|
+
var import_common21 = require("@nestjs/common");
|
|
7939
8545
|
var import_swagger13 = require("@nestjs/swagger");
|
|
7940
|
-
function
|
|
8546
|
+
function _ts_decorate7(decorators, target, key, desc2) {
|
|
7941
8547
|
var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
|
|
7942
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
7943
|
-
|
|
8548
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
8549
|
+
r = Reflect.decorate(decorators, target, key, desc2);
|
|
8550
|
+
} else {
|
|
8551
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8552
|
+
if (d = decorators[i]) {
|
|
8553
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
8554
|
+
}
|
|
8555
|
+
}
|
|
8556
|
+
}
|
|
7944
8557
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7945
8558
|
}
|
|
7946
|
-
__name(
|
|
7947
|
-
function
|
|
7948
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
8559
|
+
__name(_ts_decorate7, "_ts_decorate");
|
|
8560
|
+
function _ts_metadata7(metadataKey, metadataValue) {
|
|
8561
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
8562
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
8563
|
+
}
|
|
7949
8564
|
}
|
|
7950
|
-
__name(
|
|
7951
|
-
var createStatusController = /* @__PURE__ */ __name((enumRegistry) => {
|
|
8565
|
+
__name(_ts_metadata7, "_ts_metadata");
|
|
8566
|
+
var createStatusController = /* @__PURE__ */ __name((enumRegistry, translationRegistry) => {
|
|
7952
8567
|
let StatusController = class StatusController {
|
|
7953
8568
|
static {
|
|
7954
8569
|
__name(this, "StatusController");
|
|
@@ -7961,11 +8576,11 @@ var createStatusController = /* @__PURE__ */ __name((enumRegistry) => {
|
|
|
7961
8576
|
}
|
|
7962
8577
|
async getStatus() {
|
|
7963
8578
|
const configs = await this.configRegistry.getAll();
|
|
7964
|
-
return buildStatus(this.dataSourceRegistry, configs, enumRegistry);
|
|
8579
|
+
return buildStatus(this.dataSourceRegistry, configs, enumRegistry, translationRegistry);
|
|
7965
8580
|
}
|
|
7966
8581
|
};
|
|
7967
|
-
|
|
7968
|
-
(0,
|
|
8582
|
+
_ts_decorate7([
|
|
8583
|
+
(0, import_common21.Get)("status.json"),
|
|
7969
8584
|
(0, import_swagger13.ApiOperation)({
|
|
7970
8585
|
summary: "Crouton system status (db, resources, version)"
|
|
7971
8586
|
}),
|
|
@@ -7973,15 +8588,15 @@ var createStatusController = /* @__PURE__ */ __name((enumRegistry) => {
|
|
|
7973
8588
|
status: 200,
|
|
7974
8589
|
description: "System status"
|
|
7975
8590
|
}),
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
8591
|
+
_ts_metadata7("design:type", Function),
|
|
8592
|
+
_ts_metadata7("design:paramtypes", []),
|
|
8593
|
+
_ts_metadata7("design:returntype", Promise)
|
|
7979
8594
|
], StatusController.prototype, "getStatus", null);
|
|
7980
|
-
StatusController =
|
|
7981
|
-
(0,
|
|
8595
|
+
StatusController = _ts_decorate7([
|
|
8596
|
+
(0, import_common21.Controller)("crouton"),
|
|
7982
8597
|
(0, import_swagger13.ApiTags)("Status"),
|
|
7983
|
-
|
|
7984
|
-
|
|
8598
|
+
_ts_metadata7("design:type", Function),
|
|
8599
|
+
_ts_metadata7("design:paramtypes", [
|
|
7985
8600
|
typeof DataSourceRegistry === "undefined" ? Object : DataSourceRegistry,
|
|
7986
8601
|
typeof ResourceConfigRegistry === "undefined" ? Object : ResourceConfigRegistry
|
|
7987
8602
|
])
|
|
@@ -7994,15 +8609,22 @@ var createStatusController = /* @__PURE__ */ __name((enumRegistry) => {
|
|
|
7994
8609
|
}, "createStatusController");
|
|
7995
8610
|
|
|
7996
8611
|
// src/lib/crouton-api.module.ts
|
|
7997
|
-
var
|
|
8612
|
+
var import_node_path20 = require("path");
|
|
7998
8613
|
var import_node_url2 = require("url");
|
|
7999
|
-
function
|
|
8614
|
+
function _ts_decorate8(decorators, target, key, desc2) {
|
|
8000
8615
|
var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
|
|
8001
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
8002
|
-
|
|
8616
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
8617
|
+
r = Reflect.decorate(decorators, target, key, desc2);
|
|
8618
|
+
} else {
|
|
8619
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8620
|
+
if (d = decorators[i]) {
|
|
8621
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
8622
|
+
}
|
|
8623
|
+
}
|
|
8624
|
+
}
|
|
8003
8625
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
8004
8626
|
}
|
|
8005
|
-
__name(
|
|
8627
|
+
__name(_ts_decorate8, "_ts_decorate");
|
|
8006
8628
|
var CroutonApiModule = class _CroutonApiModule {
|
|
8007
8629
|
static {
|
|
8008
8630
|
__name(this, "CroutonApiModule");
|
|
@@ -8016,7 +8638,7 @@ var CroutonApiModule = class _CroutonApiModule {
|
|
|
8016
8638
|
}
|
|
8017
8639
|
static forResources(configs, dataSources, loader, { baseUrl }, config) {
|
|
8018
8640
|
const dataSourceRegistry = new DataSourceRegistry(dataSources);
|
|
8019
|
-
const startDir = typeof __dirname !== "undefined" ? __dirname : (0,
|
|
8641
|
+
const startDir = typeof __dirname !== "undefined" ? __dirname : (0, import_node_path20.dirname)((0, import_node_url2.fileURLToPath)(importMetaUrl));
|
|
8020
8642
|
const enumRegistry = loadEnumRegistry(startDir, config.enumsFile);
|
|
8021
8643
|
const validConfigs = [];
|
|
8022
8644
|
for (const c of configs) {
|
|
@@ -8066,15 +8688,21 @@ var CroutonApiModule = class _CroutonApiModule {
|
|
|
8066
8688
|
validConfigs.push(c);
|
|
8067
8689
|
}
|
|
8068
8690
|
const configRegistry = new ResourceConfigRegistry(loader, validConfigs);
|
|
8691
|
+
let translationRegistry;
|
|
8692
|
+
if (config.i18n) {
|
|
8693
|
+
const translationsDir = (0, import_node_path20.join)(process.cwd(), config.i18n.translationsDir);
|
|
8694
|
+
translationRegistry = new TranslationRegistry2(translationsDir, config.i18n);
|
|
8695
|
+
configRegistry.setTranslationRegistry(translationRegistry);
|
|
8696
|
+
}
|
|
8069
8697
|
const controllers = [
|
|
8070
8698
|
...validConfigs.map((c) => createCrudController(c, baseUrl)),
|
|
8071
|
-
createAppLayoutController(configs, config.sidebarGroups, config.title, config.autoSave ?? true),
|
|
8699
|
+
createAppLayoutController(configs, config.sidebarGroups, config.title, config.autoSave ?? true, translationRegistry, config.i18n),
|
|
8072
8700
|
// Only registered (and thus only visible in Swagger/routing) when the
|
|
8073
8701
|
// visual resource builder is enabled — see dev-resources.controller.ts.
|
|
8074
8702
|
...IS_DEV ? [
|
|
8075
8703
|
DevResourcesController
|
|
8076
8704
|
] : [],
|
|
8077
|
-
createStatusController(enumRegistry)
|
|
8705
|
+
createStatusController(enumRegistry, translationRegistry)
|
|
8078
8706
|
];
|
|
8079
8707
|
return {
|
|
8080
8708
|
module: _CroutonApiModule,
|
|
@@ -8091,7 +8719,17 @@ var CroutonApiModule = class _CroutonApiModule {
|
|
|
8091
8719
|
{
|
|
8092
8720
|
provide: ResourceConfigRegistry,
|
|
8093
8721
|
useValue: configRegistry
|
|
8094
|
-
}
|
|
8722
|
+
},
|
|
8723
|
+
...translationRegistry ? [
|
|
8724
|
+
{
|
|
8725
|
+
provide: TranslationRegistry2,
|
|
8726
|
+
useValue: translationRegistry
|
|
8727
|
+
},
|
|
8728
|
+
{
|
|
8729
|
+
provide: import_core.APP_INTERCEPTOR,
|
|
8730
|
+
useFactory: /* @__PURE__ */ __name(() => new LanguageInterceptor(translationRegistry), "useFactory")
|
|
8731
|
+
}
|
|
8732
|
+
] : []
|
|
8095
8733
|
]
|
|
8096
8734
|
};
|
|
8097
8735
|
}
|
|
@@ -8109,8 +8747,8 @@ var CroutonApiModule = class _CroutonApiModule {
|
|
|
8109
8747
|
return _CroutonApiModule.forResources(configs, dataSources, loader, appConfig, config);
|
|
8110
8748
|
}
|
|
8111
8749
|
};
|
|
8112
|
-
CroutonApiModule =
|
|
8113
|
-
(0,
|
|
8750
|
+
CroutonApiModule = _ts_decorate8([
|
|
8751
|
+
(0, import_common22.Module)({
|
|
8114
8752
|
controllers: [],
|
|
8115
8753
|
providers: [],
|
|
8116
8754
|
exports: []
|