allez-orm 1.0.12 → 1.0.13
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/package.json +1 -1
- package/tools/allez-orm.mjs +54 -25
package/package.json
CHANGED
package/tools/allez-orm.mjs
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* - --print-json-schema: output the JSON Schema used for validation
|
|
16
16
|
*
|
|
17
17
|
* Usage:
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* allez-orm create table <name> [fields...] [--dir=schemas_cli] [--stamps] [-f|--force] [--onDelete=cascade|restrict|setnull|noaction]
|
|
19
|
+
* allez-orm from-json <config.json> [--dir=schemas_cli] [-f|--force]
|
|
20
|
+
* allez-orm --print-json-schema
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import fs from "node:fs";
|
|
@@ -130,7 +130,7 @@ const CONFIG_JSON_SCHEMA = JSON.stringify({
|
|
|
130
130
|
required: ["name"],
|
|
131
131
|
properties: {
|
|
132
132
|
name: { type: "string" },
|
|
133
|
-
type: { type: "string" },
|
|
133
|
+
type: { type: "string" },
|
|
134
134
|
unique: { type: "boolean" },
|
|
135
135
|
notnull: { type: "boolean" },
|
|
136
136
|
fk: {
|
|
@@ -351,7 +351,12 @@ function parseFieldToken(tok) {
|
|
|
351
351
|
|
|
352
352
|
function camel(s){return s.replace(/[-_](.)/g,(_,c)=>c.toUpperCase());}
|
|
353
353
|
|
|
354
|
-
// ---------------- from-json implementation ----------------
|
|
354
|
+
// ---------------- from-json implementation (resilient) ----------------
|
|
355
|
+
|
|
356
|
+
function pick(obj, ...keys) {
|
|
357
|
+
for (const k of keys) { if (obj && obj[k] !== undefined) return obj[k]; }
|
|
358
|
+
return undefined;
|
|
359
|
+
}
|
|
355
360
|
|
|
356
361
|
async function runFromJson(cliOpts) {
|
|
357
362
|
const file = path.resolve(cliOpts.jsonFile);
|
|
@@ -361,38 +366,62 @@ async function runFromJson(cliOpts) {
|
|
|
361
366
|
let cfg;
|
|
362
367
|
try { cfg = JSON.parse(raw); } catch (e) { die(`Invalid JSON: ${e.message}`); }
|
|
363
368
|
|
|
364
|
-
//
|
|
365
|
-
|
|
366
|
-
|
|
369
|
+
// allow OutDir/DefaultOnDelete/Tables
|
|
370
|
+
const outDir = cliOpts.dir || pick(cfg, "outDir", "OutDir") || "schemas_cli";
|
|
371
|
+
const defaultOnDelete = pick(cfg, "defaultOnDelete", "DefaultOnDelete") ?? null;
|
|
367
372
|
|
|
368
|
-
const
|
|
369
|
-
|
|
373
|
+
const tables = pick(cfg, "tables", "Tables");
|
|
374
|
+
if (!Array.isArray(tables)) {
|
|
375
|
+
die(`Config must have an array at "tables" (or "Tables").`);
|
|
376
|
+
}
|
|
370
377
|
|
|
371
378
|
fs.mkdirSync(outDir, { recursive: true });
|
|
372
379
|
|
|
373
|
-
for (
|
|
374
|
-
|
|
375
|
-
|
|
380
|
+
for (let ti = 0; ti < tables.length; ti++) {
|
|
381
|
+
const tRaw = tables[ti] || {};
|
|
382
|
+
const tName = pick(tRaw, "name", "Name");
|
|
383
|
+
if (!tName || typeof tName !== "string") {
|
|
384
|
+
die(`Table at index ${ti} is missing "name".`);
|
|
385
|
+
}
|
|
386
|
+
const tStamps = !!pick(tRaw, "stamps", "Stamps");
|
|
387
|
+
|
|
388
|
+
// accept fields/Fields OR columns/Columns
|
|
389
|
+
let fieldsList = pick(tRaw, "fields", "Fields", "columns", "Columns");
|
|
390
|
+
if (!Array.isArray(fieldsList)) {
|
|
391
|
+
die(`Table "${tName}" must have "fields" (or "Fields"/"columns"/"Columns") array.`);
|
|
376
392
|
}
|
|
377
|
-
|
|
393
|
+
|
|
378
394
|
const tokens = [];
|
|
379
|
-
for (
|
|
380
|
-
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (f.notnull) token += `!`;
|
|
385
|
-
if (f.unique) token += `+`;
|
|
386
|
-
if (f.fk && f.fk.table) {
|
|
387
|
-
token += `->${f.fk.table}`;
|
|
395
|
+
for (let fi = 0; fi < fieldsList.length; fi++) {
|
|
396
|
+
const f = fieldsList[fi] || {};
|
|
397
|
+
const name = pick(f, "name", "Name");
|
|
398
|
+
if (!name || typeof name !== "string") {
|
|
399
|
+
die(`Table "${tName}" field #${fi} is missing "name".`);
|
|
388
400
|
}
|
|
401
|
+
const typeRaw = pick(f, "type", "Type");
|
|
402
|
+
const type = (typeRaw ? String(typeRaw) : "TEXT").toLowerCase();
|
|
403
|
+
|
|
404
|
+
const unique = !!pick(f, "unique", "Unique");
|
|
405
|
+
// support notnull, notNull, NotNull
|
|
406
|
+
const notnull = !!pick(f, "notnull", "notNull", "NotNull");
|
|
407
|
+
|
|
408
|
+
// FK variations: fk/FK with table/Table, column/Column
|
|
409
|
+
const fkRaw = pick(f, "fk", "FK");
|
|
410
|
+
const fkTable = fkRaw ? pick(fkRaw, "table", "Table") : undefined;
|
|
411
|
+
const fkCol = fkRaw ? (pick(fkRaw, "column", "Column") || "id") : undefined;
|
|
412
|
+
|
|
413
|
+
let token = name + `:${type}`;
|
|
414
|
+
if (notnull) token += `!`;
|
|
415
|
+
if (unique) token += `+`;
|
|
416
|
+
if (fkTable) token += `->` + fkTable;
|
|
417
|
+
|
|
389
418
|
tokens.push(token);
|
|
390
419
|
}
|
|
391
420
|
|
|
392
421
|
await generateOne({
|
|
393
422
|
outDir,
|
|
394
|
-
name:
|
|
395
|
-
stamps:
|
|
423
|
+
name: tName,
|
|
424
|
+
stamps: tStamps,
|
|
396
425
|
onDelete: defaultOnDelete || null,
|
|
397
426
|
force: cliOpts.force,
|
|
398
427
|
fieldTokens: tokens
|