@ronin/compiler 0.17.0-leo-ron-1099-experimental-376 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +18 -19
- package/dist/index.js +140 -150
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
@@ -261,19 +261,19 @@ type ModelField = ModelFieldBasics & ({
|
|
261
261
|
/** Whether the field should be related to one record, or many records. */
|
262
262
|
kind: 'many';
|
263
263
|
});
|
264
|
-
type ModelIndexField<T extends
|
264
|
+
type ModelIndexField<T extends Array<ModelField> = Array<ModelField>> = {
|
265
265
|
/** The collating sequence used for text placed inside the field. */
|
266
266
|
collation?: ModelFieldCollation;
|
267
267
|
/** How the records in the index should be ordered. */
|
268
268
|
order?: 'ASC' | 'DESC';
|
269
269
|
} & ({
|
270
270
|
/** The field slug for which the index should be created. */
|
271
|
-
slug:
|
271
|
+
slug: T[number]['slug'];
|
272
272
|
} | {
|
273
273
|
/** The field expression for which the index should be created. */
|
274
274
|
expression: string;
|
275
275
|
});
|
276
|
-
type ModelIndex<T extends
|
276
|
+
type ModelIndex<T extends Array<ModelField> = Array<ModelField>> = {
|
277
277
|
/**
|
278
278
|
* The list of fields in the model for which the index should be created.
|
279
279
|
*/
|
@@ -281,7 +281,7 @@ type ModelIndex<T extends ModelEntityList<ModelField> = ModelEntityList<ModelFie
|
|
281
281
|
/**
|
282
282
|
* The identifier of the index.
|
283
283
|
*/
|
284
|
-
slug
|
284
|
+
slug?: string;
|
285
285
|
/**
|
286
286
|
* Whether only one record with a unique value for the provided fields will be allowed.
|
287
287
|
*/
|
@@ -292,16 +292,18 @@ type ModelIndex<T extends ModelEntityList<ModelField> = ModelEntityList<ModelFie
|
|
292
292
|
*/
|
293
293
|
filter?: WithInstruction;
|
294
294
|
};
|
295
|
-
type ModelTriggerField<T extends
|
295
|
+
type ModelTriggerField<T extends Array<ModelField> = Array<ModelField>> = {
|
296
296
|
/**
|
297
297
|
* The slug of the field that should cause the trigger to fire if the value of the
|
298
298
|
* field has changed.
|
299
299
|
*/
|
300
|
-
slug:
|
300
|
+
slug: T[number]['slug'];
|
301
301
|
};
|
302
|
-
type ModelTrigger<T extends
|
303
|
-
/**
|
304
|
-
|
302
|
+
type ModelTrigger<T extends Array<ModelField> = Array<ModelField>> = {
|
303
|
+
/**
|
304
|
+
* The identifier of the trigger.
|
305
|
+
*/
|
306
|
+
slug?: string;
|
305
307
|
/** The type of query for which the trigger should fire. */
|
306
308
|
action: 'INSERT' | 'UPDATE' | 'DELETE';
|
307
309
|
/** When the trigger should fire in the case that a matching query is executed. */
|
@@ -322,18 +324,15 @@ type ModelPreset = {
|
|
322
324
|
/** The query instructions that should be applied when the preset is used. */
|
323
325
|
instructions: GetInstructions;
|
324
326
|
};
|
325
|
-
|
326
|
-
slug: string;
|
327
|
-
}> = Record<NonNullable<T['slug']>, Partial<T>>;
|
328
|
-
interface Model<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> {
|
327
|
+
interface Model<T extends Array<ModelField> = Array<ModelField>> {
|
329
328
|
id: string;
|
330
329
|
name: string;
|
331
330
|
pluralName: string;
|
332
331
|
slug: string;
|
333
332
|
pluralSlug: string;
|
334
333
|
identifiers: {
|
335
|
-
name:
|
336
|
-
slug:
|
334
|
+
name: T[number]['slug'];
|
335
|
+
slug: T[number]['slug'];
|
337
336
|
};
|
338
337
|
idPrefix: string;
|
339
338
|
/** The name of the table in SQLite. */
|
@@ -358,11 +357,11 @@ interface Model<T extends ModelEntityList<ModelField> = ModelEntityList<ModelFie
|
|
358
357
|
associationSlug?: string;
|
359
358
|
};
|
360
359
|
fields: T;
|
361
|
-
indexes?:
|
362
|
-
triggers?:
|
363
|
-
presets?:
|
360
|
+
indexes?: Array<ModelIndex<T>>;
|
361
|
+
triggers?: Array<ModelTrigger<T>>;
|
362
|
+
presets?: Array<ModelPreset>;
|
364
363
|
}
|
365
|
-
type PublicModel<T extends
|
364
|
+
type PublicModel<T extends Array<ModelField> = Array<ModelField>> = Omit<Partial<Model<T>>, 'slug' | 'identifiers' | 'system' | 'tableAlias'> & {
|
366
365
|
slug: Required<Model['slug']>;
|
367
366
|
identifiers?: Partial<Model['identifiers']>;
|
368
367
|
};
|
package/dist/index.js
CHANGED
@@ -587,24 +587,22 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
|
|
587
587
|
var handleUsing = (model, instructions) => {
|
588
588
|
const normalizedUsing = Array.isArray(instructions.using) ? Object.fromEntries(instructions.using.map((presetSlug) => [presetSlug, null])) : instructions.using;
|
589
589
|
if ("links" in normalizedUsing) {
|
590
|
-
for (const
|
590
|
+
for (const field of model.fields) {
|
591
591
|
if (field.type !== "link" || field.kind === "many") continue;
|
592
|
-
normalizedUsing[
|
592
|
+
normalizedUsing[field.slug] = null;
|
593
593
|
}
|
594
594
|
}
|
595
595
|
for (const presetSlug in normalizedUsing) {
|
596
596
|
if (!Object.hasOwn(normalizedUsing, presetSlug) || presetSlug === "links") continue;
|
597
597
|
const arg = normalizedUsing[presetSlug];
|
598
|
-
const preset = model.presets?.
|
598
|
+
const preset = model.presets?.find((preset2) => preset2.slug === presetSlug);
|
599
599
|
if (!preset) {
|
600
600
|
throw new RoninError({
|
601
601
|
message: `Preset "${presetSlug}" does not exist in model "${model.name}".`,
|
602
602
|
code: "PRESET_NOT_FOUND"
|
603
603
|
});
|
604
604
|
}
|
605
|
-
const replacedUsingFilter = structuredClone(
|
606
|
-
preset.instructions
|
607
|
-
);
|
605
|
+
const replacedUsingFilter = structuredClone(preset.instructions);
|
608
606
|
if (arg !== null) {
|
609
607
|
findInObject(
|
610
608
|
replacedUsingFilter,
|
@@ -829,16 +827,13 @@ var matchSelectedFields = (fields, pattern) => {
|
|
829
827
|
return fields.filter((field) => regex2.test(field.slug));
|
830
828
|
};
|
831
829
|
var filterSelectedFields = (model, instruction) => {
|
832
|
-
|
833
|
-
([fieldSlug, field]) => ({ slug: fieldSlug, ...field })
|
834
|
-
);
|
835
|
-
if (!instruction) return mappedFields;
|
830
|
+
if (!instruction) return model.fields;
|
836
831
|
let selectedFields = [];
|
837
832
|
for (const pattern of instruction) {
|
838
833
|
const isNegative = pattern.startsWith("!");
|
839
834
|
const cleanPattern = isNegative ? pattern.slice(1) : pattern;
|
840
835
|
const matchedFields = matchSelectedFields(
|
841
|
-
isNegative ? selectedFields :
|
836
|
+
isNegative ? selectedFields : model.fields,
|
842
837
|
cleanPattern
|
843
838
|
);
|
844
839
|
if (isNegative) {
|
@@ -927,7 +922,7 @@ var composeConditions = (models, model, statementParams, instructionName, value,
|
|
927
922
|
return conditions.join(" AND ");
|
928
923
|
}
|
929
924
|
if (options.fieldSlug) {
|
930
|
-
const childField =
|
925
|
+
const childField = model.fields.some(({ slug }) => {
|
931
926
|
return slug.includes(".") && slug.split(".")[0] === options.fieldSlug;
|
932
927
|
});
|
933
928
|
if (!childField) {
|
@@ -1287,19 +1282,19 @@ var addDefaultModelAttributes = (model, isNew) => {
|
|
1287
1282
|
copiedModel[setting] = generator(copiedModel[base]);
|
1288
1283
|
}
|
1289
1284
|
const newFields = copiedModel.fields || [];
|
1290
|
-
if (isNew ||
|
1285
|
+
if (isNew || newFields.length > 0) {
|
1291
1286
|
if (!copiedModel.identifiers) copiedModel.identifiers = {};
|
1292
1287
|
if (!copiedModel.identifiers.name) {
|
1293
|
-
const suitableField =
|
1294
|
-
(
|
1288
|
+
const suitableField = newFields.find(
|
1289
|
+
(field) => field.type === "string" && field.required === true && ["name"].includes(field.slug)
|
1295
1290
|
);
|
1296
|
-
copiedModel.identifiers.name = suitableField?.
|
1291
|
+
copiedModel.identifiers.name = suitableField?.slug || "id";
|
1297
1292
|
}
|
1298
1293
|
if (!copiedModel.identifiers.slug) {
|
1299
|
-
const suitableField =
|
1300
|
-
(
|
1294
|
+
const suitableField = newFields.find(
|
1295
|
+
(field) => field.type === "string" && field.unique === true && field.required === true && ["slug", "handle"].includes(field.slug)
|
1301
1296
|
);
|
1302
|
-
copiedModel.identifiers.slug = suitableField?.
|
1297
|
+
copiedModel.identifiers.slug = suitableField?.slug || "id";
|
1303
1298
|
}
|
1304
1299
|
}
|
1305
1300
|
return copiedModel;
|
@@ -1307,32 +1302,29 @@ var addDefaultModelAttributes = (model, isNew) => {
|
|
1307
1302
|
var addDefaultModelFields = (model, isNew) => {
|
1308
1303
|
const copiedModel = { ...model };
|
1309
1304
|
const existingFields = copiedModel.fields || [];
|
1310
|
-
if (isNew ||
|
1311
|
-
const additionalFields =
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
);
|
1316
|
-
copiedModel.fields = { ...additionalFields, ...existingFields };
|
1305
|
+
if (isNew || existingFields.length > 0) {
|
1306
|
+
const additionalFields = getSystemFields(copiedModel.idPrefix).filter((newField) => {
|
1307
|
+
return !existingFields.some(({ slug }) => slug === newField.slug);
|
1308
|
+
});
|
1309
|
+
copiedModel.fields = [...additionalFields, ...existingFields];
|
1317
1310
|
}
|
1318
1311
|
return copiedModel;
|
1319
1312
|
};
|
1320
1313
|
var addDefaultModelPresets = (list, model) => {
|
1321
|
-
const defaultPresets =
|
1322
|
-
for (const
|
1323
|
-
|
1324
|
-
if (field.type === "link" && !fieldSlug.startsWith("ronin.")) {
|
1314
|
+
const defaultPresets = [];
|
1315
|
+
for (const field of model.fields || []) {
|
1316
|
+
if (field.type === "link" && !field.slug.startsWith("ronin.")) {
|
1325
1317
|
const targetModel = getModelBySlug(list, field.target);
|
1326
1318
|
if (field.kind === "many") {
|
1327
1319
|
const systemModel = list.find(({ system }) => {
|
1328
1320
|
return system?.model === model.id && system?.associationSlug === field.slug;
|
1329
1321
|
});
|
1330
1322
|
if (!systemModel) continue;
|
1331
|
-
const
|
1323
|
+
const preset = {
|
1332
1324
|
instructions: {
|
1333
1325
|
// Perform a LEFT JOIN that adds the associative table.
|
1334
1326
|
including: {
|
1335
|
-
[
|
1327
|
+
[field.slug]: {
|
1336
1328
|
[QUERY_SYMBOLS.QUERY]: {
|
1337
1329
|
get: {
|
1338
1330
|
[systemModel.pluralSlug]: {
|
@@ -1363,15 +1355,16 @@ var addDefaultModelPresets = (list, model) => {
|
|
1363
1355
|
}
|
1364
1356
|
}
|
1365
1357
|
}
|
1366
|
-
}
|
1358
|
+
},
|
1359
|
+
slug: field.slug
|
1367
1360
|
};
|
1368
|
-
defaultPresets
|
1361
|
+
defaultPresets.push(preset);
|
1369
1362
|
continue;
|
1370
1363
|
}
|
1371
|
-
|
1364
|
+
defaultPresets.push({
|
1372
1365
|
instructions: {
|
1373
1366
|
including: {
|
1374
|
-
[
|
1367
|
+
[field.slug]: {
|
1375
1368
|
[QUERY_SYMBOLS.QUERY]: {
|
1376
1369
|
get: {
|
1377
1370
|
[targetModel.slug]: {
|
@@ -1387,24 +1380,24 @@ var addDefaultModelPresets = (list, model) => {
|
|
1387
1380
|
}
|
1388
1381
|
}
|
1389
1382
|
}
|
1390
|
-
}
|
1391
|
-
|
1392
|
-
|
1383
|
+
},
|
1384
|
+
slug: field.slug
|
1385
|
+
});
|
1393
1386
|
}
|
1394
1387
|
}
|
1395
1388
|
const childModels = list.map((subModel) => {
|
1396
1389
|
if (subModel.system?.associationSlug) return null;
|
1397
|
-
const field =
|
1390
|
+
const field = subModel.fields?.find((field2) => {
|
1398
1391
|
return field2.type === "link" && field2.target === model.slug;
|
1399
1392
|
});
|
1400
1393
|
if (!field) return null;
|
1401
|
-
return { model: subModel, field
|
1394
|
+
return { model: subModel, field };
|
1402
1395
|
}).filter((match) => match !== null);
|
1403
1396
|
for (const childMatch of childModels) {
|
1404
1397
|
const { model: childModel, field: childField } = childMatch;
|
1405
1398
|
const pluralSlug = childModel.pluralSlug;
|
1406
1399
|
const presetSlug = childModel.system?.associationSlug || pluralSlug;
|
1407
|
-
|
1400
|
+
defaultPresets.push({
|
1408
1401
|
instructions: {
|
1409
1402
|
including: {
|
1410
1403
|
[presetSlug]: {
|
@@ -1421,18 +1414,16 @@ var addDefaultModelPresets = (list, model) => {
|
|
1421
1414
|
}
|
1422
1415
|
}
|
1423
1416
|
}
|
1424
|
-
}
|
1425
|
-
|
1426
|
-
|
1417
|
+
},
|
1418
|
+
slug: presetSlug
|
1419
|
+
});
|
1427
1420
|
}
|
1428
|
-
if (
|
1429
|
-
const existingPresets = model.presets;
|
1430
|
-
const additionalPresets =
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
);
|
1435
|
-
model.presets = { ...additionalPresets, ...existingPresets };
|
1421
|
+
if (defaultPresets.length > 0) {
|
1422
|
+
const existingPresets = model.presets || [];
|
1423
|
+
const additionalPresets = defaultPresets.filter((newPreset) => {
|
1424
|
+
return !existingPresets.some(({ slug }) => slug === newPreset.slug);
|
1425
|
+
});
|
1426
|
+
model.presets = [...additionalPresets, ...existingPresets];
|
1436
1427
|
}
|
1437
1428
|
return model;
|
1438
1429
|
};
|
@@ -1464,12 +1455,7 @@ function getFieldFromModel(model, fieldPath, source, shouldThrow = true) {
|
|
1464
1455
|
const writingField = "instructionName" in source ? source.instructionName === "to" : true;
|
1465
1456
|
const errorTarget = "instructionName" in source ? `\`${source.instructionName}\`` : `${source.modelEntityType} "${source.modelEntityName}"`;
|
1466
1457
|
const errorPrefix = `Field "${fieldPath}" defined for ${errorTarget}`;
|
1467
|
-
const modelFields =
|
1468
|
-
([fieldSlug, field]) => ({
|
1469
|
-
slug: fieldSlug,
|
1470
|
-
...field
|
1471
|
-
})
|
1472
|
-
);
|
1458
|
+
const modelFields = model.fields || [];
|
1473
1459
|
let modelField;
|
1474
1460
|
if (fieldPath.includes(".")) {
|
1475
1461
|
modelField = modelFields.find((field) => field.slug === fieldPath.split(".")[0]);
|
@@ -1493,36 +1479,36 @@ function getFieldFromModel(model, fieldPath, source, shouldThrow = true) {
|
|
1493
1479
|
const fieldSelector = getFieldSelector(model, modelField, fieldPath, writingField);
|
1494
1480
|
return { field: modelField, fieldSelector };
|
1495
1481
|
}
|
1496
|
-
var getSystemFields = (idPrefix) =>
|
1497
|
-
|
1482
|
+
var getSystemFields = (idPrefix) => [
|
1483
|
+
{
|
1498
1484
|
name: "ID",
|
1499
1485
|
type: "string",
|
1500
1486
|
slug: "id",
|
1501
1487
|
defaultValue: ID_EXPRESSION(idPrefix)
|
1502
1488
|
},
|
1503
|
-
|
1489
|
+
{
|
1504
1490
|
name: "RONIN - Created At",
|
1505
1491
|
type: "date",
|
1506
1492
|
slug: "ronin.createdAt",
|
1507
1493
|
defaultValue: CURRENT_TIME_EXPRESSION
|
1508
1494
|
},
|
1509
|
-
|
1495
|
+
{
|
1510
1496
|
name: "RONIN - Created By",
|
1511
1497
|
type: "string",
|
1512
1498
|
slug: "ronin.createdBy"
|
1513
1499
|
},
|
1514
|
-
|
1500
|
+
{
|
1515
1501
|
name: "RONIN - Updated At",
|
1516
1502
|
type: "date",
|
1517
1503
|
slug: "ronin.updatedAt",
|
1518
1504
|
defaultValue: CURRENT_TIME_EXPRESSION
|
1519
1505
|
},
|
1520
|
-
|
1506
|
+
{
|
1521
1507
|
name: "RONIN - Updated By",
|
1522
1508
|
type: "string",
|
1523
1509
|
slug: "ronin.updatedBy"
|
1524
1510
|
}
|
1525
|
-
|
1511
|
+
];
|
1526
1512
|
var ROOT_MODEL = {
|
1527
1513
|
slug: "model",
|
1528
1514
|
identifiers: {
|
@@ -1533,43 +1519,43 @@ var ROOT_MODEL = {
|
|
1533
1519
|
table: "ronin_schema",
|
1534
1520
|
// Indicates that the model was automatically generated by RONIN.
|
1535
1521
|
system: { model: "root" },
|
1536
|
-
fields:
|
1537
|
-
|
1538
|
-
|
1539
|
-
slug:
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
"identifiers.name"
|
1544
|
-
"identifiers.slug"
|
1522
|
+
fields: [
|
1523
|
+
{ slug: "name", type: "string" },
|
1524
|
+
{ slug: "pluralName", type: "string" },
|
1525
|
+
{ slug: "slug", type: "string" },
|
1526
|
+
{ slug: "pluralSlug", type: "string" },
|
1527
|
+
{ slug: "idPrefix", type: "string" },
|
1528
|
+
{ slug: "table", type: "string" },
|
1529
|
+
{ slug: "identifiers.name", type: "string" },
|
1530
|
+
{ slug: "identifiers.slug", type: "string" },
|
1545
1531
|
// Providing an empty object as a default value allows us to use `json_insert`
|
1546
1532
|
// without needing to fall back to an empty object in the insertion statement,
|
1547
1533
|
// which makes the statement shorter.
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1534
|
+
{ slug: "fields", type: "json", defaultValue: "{}" },
|
1535
|
+
{ slug: "indexes", type: "json", defaultValue: "{}" },
|
1536
|
+
{ slug: "triggers", type: "json", defaultValue: "{}" },
|
1537
|
+
{ slug: "presets", type: "json", defaultValue: "{}" }
|
1538
|
+
]
|
1553
1539
|
};
|
1554
1540
|
var ROOT_MODEL_WITH_ATTRIBUTES = addDefaultModelAttributes(ROOT_MODEL, true);
|
1555
1541
|
var getSystemModels = (models, model) => {
|
1556
1542
|
const addedModels = [];
|
1557
|
-
for (const
|
1558
|
-
|
1559
|
-
if (field.type === "link" && !fieldSlug.startsWith("ronin.")) {
|
1543
|
+
for (const field of model.fields || []) {
|
1544
|
+
if (field.type === "link" && !field.slug.startsWith("ronin.")) {
|
1560
1545
|
const relatedModel = getModelBySlug(models, field.target);
|
1561
|
-
let
|
1546
|
+
let fieldSlug = relatedModel.slug;
|
1562
1547
|
if (field.kind === "many") {
|
1563
|
-
|
1548
|
+
fieldSlug = composeAssociationModelSlug(model, field);
|
1564
1549
|
addedModels.push({
|
1565
|
-
pluralSlug:
|
1566
|
-
slug:
|
1550
|
+
pluralSlug: fieldSlug,
|
1551
|
+
slug: fieldSlug,
|
1567
1552
|
system: {
|
1568
1553
|
model: model.id,
|
1569
1554
|
associationSlug: field.slug
|
1570
1555
|
},
|
1571
|
-
fields:
|
1572
|
-
|
1556
|
+
fields: [
|
1557
|
+
{
|
1558
|
+
slug: "source",
|
1573
1559
|
type: "link",
|
1574
1560
|
target: model.slug,
|
1575
1561
|
actions: {
|
@@ -1577,7 +1563,8 @@ var getSystemModels = (models, model) => {
|
|
1577
1563
|
onUpdate: "CASCADE"
|
1578
1564
|
}
|
1579
1565
|
},
|
1580
|
-
|
1566
|
+
{
|
1567
|
+
slug: "target",
|
1581
1568
|
type: "link",
|
1582
1569
|
target: relatedModel.slug,
|
1583
1570
|
actions: {
|
@@ -1585,7 +1572,7 @@ var getSystemModels = (models, model) => {
|
|
1585
1572
|
onUpdate: "CASCADE"
|
1586
1573
|
}
|
1587
1574
|
}
|
1588
|
-
|
1575
|
+
]
|
1589
1576
|
});
|
1590
1577
|
}
|
1591
1578
|
}
|
@@ -1649,6 +1636,13 @@ var PLURAL_MODEL_ENTITIES = {
|
|
1649
1636
|
preset: "presets"
|
1650
1637
|
};
|
1651
1638
|
var PLURAL_MODEL_ENTITIES_VALUES = Object.values(PLURAL_MODEL_ENTITIES);
|
1639
|
+
var formatModelEntity = (type, entities) => {
|
1640
|
+
const entries = entities?.map((entity) => {
|
1641
|
+
const { slug, ...rest } = "slug" in entity ? entity : { slug: `${type}Slug`, ...entity };
|
1642
|
+
return [slug, rest];
|
1643
|
+
});
|
1644
|
+
return entries ? Object.fromEntries(entries) : void 0;
|
1645
|
+
};
|
1652
1646
|
var handleSystemModel = (models, dependencyStatements, action, inlineDefaults, systemModel, newModel) => {
|
1653
1647
|
const { system: _, ...systemModelClean } = systemModel;
|
1654
1648
|
const query = {
|
@@ -1671,11 +1665,11 @@ var handleSystemModels = (models, dependencyStatements, previousModel, newModel,
|
|
1671
1665
|
oldSystemModel.system?.model === newSystemModel.system?.model
|
1672
1666
|
];
|
1673
1667
|
if (oldSystemModel.system?.associationSlug) {
|
1674
|
-
const oldFieldIndex =
|
1675
|
-
return slug === newSystemModel.system?.associationSlug;
|
1668
|
+
const oldFieldIndex = previousModel.fields.findIndex((item) => {
|
1669
|
+
return item.slug === newSystemModel.system?.associationSlug;
|
1676
1670
|
});
|
1677
|
-
const newFieldIndex =
|
1678
|
-
return slug === oldSystemModel.system?.associationSlug;
|
1671
|
+
const newFieldIndex = newModel.fields.findIndex((item) => {
|
1672
|
+
return item.slug === oldSystemModel.system?.associationSlug;
|
1679
1673
|
});
|
1680
1674
|
conditions.push(oldFieldIndex === newFieldIndex);
|
1681
1675
|
}
|
@@ -1731,7 +1725,7 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
|
|
1731
1725
|
slug = query.alter[action][entity];
|
1732
1726
|
if ("create" in query.alter) {
|
1733
1727
|
const item = query.alter.create[entity];
|
1734
|
-
slug = item.slug
|
1728
|
+
slug = item.slug || `${entity}Slug`;
|
1735
1729
|
jsonValue = { slug, ...item };
|
1736
1730
|
}
|
1737
1731
|
if ("alter" in query.alter && query.alter.alter) jsonValue = query.alter.alter.to;
|
@@ -1749,24 +1743,20 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
|
|
1749
1743
|
[...models, modelWithFields],
|
1750
1744
|
modelWithFields
|
1751
1745
|
);
|
1752
|
-
modelWithPresets.fields =
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
const columns = Object.entries(modelWithPresets.fields).map(
|
1765
|
-
([fieldSlug, rest]) => getFieldStatement(models, modelWithPresets, {
|
1766
|
-
slug: fieldSlug,
|
1767
|
-
...rest
|
1746
|
+
modelWithPresets.fields = modelWithPresets.fields.map((field2) => ({
|
1747
|
+
...field2,
|
1748
|
+
// Default field type.
|
1749
|
+
type: field2.type || "string",
|
1750
|
+
// Default field name.
|
1751
|
+
name: field2.name || slugToName(field2.slug)
|
1752
|
+
}));
|
1753
|
+
const columns = modelWithPresets.fields.map((field2) => getFieldStatement(models, modelWithPresets, field2)).filter(Boolean);
|
1754
|
+
const entities = Object.fromEntries(
|
1755
|
+
Object.entries(PLURAL_MODEL_ENTITIES).map(([type, pluralType2]) => {
|
1756
|
+
const list = modelWithPresets[pluralType2];
|
1757
|
+
return [pluralType2, formatModelEntity(type, list)];
|
1768
1758
|
})
|
1769
|
-
)
|
1759
|
+
);
|
1770
1760
|
models.push(modelWithPresets);
|
1771
1761
|
dependencyStatements.push({
|
1772
1762
|
statement: `CREATE TABLE "${modelWithPresets.table}" (${columns.join(", ")})`,
|
@@ -1776,27 +1766,28 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
|
|
1776
1766
|
["index", "indexes"],
|
1777
1767
|
["trigger", "triggers"]
|
1778
1768
|
]) {
|
1779
|
-
const
|
1780
|
-
if (!
|
1781
|
-
for (const
|
1769
|
+
const entityValue = modelWithPresets[pluralModelEntity];
|
1770
|
+
if (!entityValue) continue;
|
1771
|
+
for (const item of entityValue) {
|
1782
1772
|
const query2 = {
|
1783
1773
|
alter: {
|
1784
1774
|
model: modelWithPresets.slug,
|
1785
1775
|
create: {
|
1786
|
-
[modelEntity]:
|
1776
|
+
[modelEntity]: item
|
1787
1777
|
}
|
1788
1778
|
}
|
1789
1779
|
};
|
1790
|
-
|
1791
|
-
...models.filter((model2) => model2.slug !== modelWithPresets.slug),
|
1792
|
-
{ ...modelWithPresets, indexes: {}, triggers: {} }
|
1793
|
-
];
|
1794
|
-
transformMetaQuery(tempModels, dependencyStatements, null, query2, {
|
1780
|
+
transformMetaQuery(models, dependencyStatements, null, query2, {
|
1795
1781
|
inlineDefaults: options.inlineDefaults
|
1796
1782
|
});
|
1797
1783
|
}
|
1798
1784
|
}
|
1799
|
-
|
1785
|
+
const modelWithObjects = Object.assign({}, modelWithPresets);
|
1786
|
+
for (const entity2 in entities) {
|
1787
|
+
if (!Object.hasOwn(entities, entity2)) continue;
|
1788
|
+
Object.defineProperty(modelWithObjects, entity2, { value: entities[entity2] });
|
1789
|
+
}
|
1790
|
+
queryTypeDetails = { with: modelWithObjects };
|
1800
1791
|
getSystemModels(models, modelWithPresets).map((systemModel) => {
|
1801
1792
|
return handleSystemModel(
|
1802
1793
|
models,
|
@@ -1861,13 +1852,16 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
|
|
1861
1852
|
const modelBeforeUpdate = structuredClone(model);
|
1862
1853
|
const existingModel = model;
|
1863
1854
|
const pluralType = PLURAL_MODEL_ENTITIES[entity];
|
1864
|
-
const
|
1865
|
-
|
1855
|
+
const targetEntityIndex = existingModel[pluralType]?.findIndex(
|
1856
|
+
(entity2) => entity2.slug === slug
|
1857
|
+
);
|
1858
|
+
if ((action === "alter" || action === "drop") && (typeof targetEntityIndex === "undefined" || targetEntityIndex === -1)) {
|
1866
1859
|
throw new RoninError({
|
1867
1860
|
message: `No ${entity} with slug "${slug}" defined in model "${existingModel.name}".`,
|
1868
1861
|
code: MODEL_ENTITY_ERROR_CODES[entity]
|
1869
1862
|
});
|
1870
1863
|
}
|
1864
|
+
const existingEntity = existingModel[pluralType]?.[targetEntityIndex];
|
1871
1865
|
if (action === "create" && existingEntity) {
|
1872
1866
|
throw new RoninError({
|
1873
1867
|
message: `A ${entity} with the slug "${slug}" already exists.`,
|
@@ -1904,7 +1898,7 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
|
|
1904
1898
|
}
|
1905
1899
|
} else if (action === "drop" && !existingLinkField) {
|
1906
1900
|
const systemFields = getSystemFields(existingModel.idPrefix);
|
1907
|
-
const isSystemField = slug
|
1901
|
+
const isSystemField = systemFields.some((field2) => field2.slug === slug);
|
1908
1902
|
if (isSystemField) {
|
1909
1903
|
throw new RoninError({
|
1910
1904
|
message: `The ${entity} "${slug}" is a system ${entity} and cannot be removed.`,
|
@@ -2008,33 +2002,23 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
|
|
2008
2002
|
case "create": {
|
2009
2003
|
const value = prepareStatementValue(statementParams, jsonValue);
|
2010
2004
|
json = `json_insert(${field}, '$.${slug}', ${value})`;
|
2011
|
-
|
2012
|
-
|
2005
|
+
existingModel[pluralType] = [
|
2006
|
+
...existingModel[pluralType] || [],
|
2007
|
+
jsonValue
|
2008
|
+
];
|
2013
2009
|
break;
|
2014
2010
|
}
|
2015
2011
|
case "alter": {
|
2016
|
-
const
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
targetEntities,
|
2021
|
-
newSlug,
|
2022
|
-
Object.getOwnPropertyDescriptor(targetEntities, slug)
|
2023
|
-
);
|
2024
|
-
delete targetEntities[slug];
|
2025
|
-
const value = prepareStatementValue(statementParams, entityValue);
|
2026
|
-
json = `json_insert(json_remove(${field}, '$.${slug}'), '$.${newSlug}', ${value})`;
|
2027
|
-
} else {
|
2028
|
-
Object.assign(targetEntities[slug], jsonValue);
|
2029
|
-
const value = prepareStatementValue(statementParams, jsonValue);
|
2030
|
-
json = `json_set(${field}, '$.${slug}', json_patch(json_extract(${field}, '$.${slug}'), ${value}))`;
|
2031
|
-
}
|
2012
|
+
const value = prepareStatementValue(statementParams, jsonValue);
|
2013
|
+
json = `json_set(${field}, '$.${slug}', json_patch(json_extract(${field}, '$.${slug}'), ${value}))`;
|
2014
|
+
const targetEntity = existingModel[pluralType];
|
2015
|
+
Object.assign(targetEntity[targetEntityIndex], jsonValue);
|
2032
2016
|
break;
|
2033
2017
|
}
|
2034
2018
|
case "drop": {
|
2035
2019
|
json = `json_remove(${field}, '$.${slug}')`;
|
2036
|
-
const
|
2037
|
-
|
2020
|
+
const targetEntity = existingModel[pluralType];
|
2021
|
+
targetEntity.splice(targetEntityIndex, 1);
|
2038
2022
|
}
|
2039
2023
|
}
|
2040
2024
|
handleSystemModels(
|
@@ -2126,7 +2110,7 @@ var Transaction = class {
|
|
2126
2110
|
this.models = modelsWithPresets;
|
2127
2111
|
return statements;
|
2128
2112
|
};
|
2129
|
-
#formatRows(fields, rows, single) {
|
2113
|
+
#formatRows(fields, rows, single, isMeta) {
|
2130
2114
|
const records = [];
|
2131
2115
|
for (const row of rows) {
|
2132
2116
|
const record = fields.reduce((acc, field, fieldIndex) => {
|
@@ -2139,6 +2123,11 @@ var Transaction = class {
|
|
2139
2123
|
newValue = Boolean(newValue);
|
2140
2124
|
}
|
2141
2125
|
}
|
2126
|
+
if (isMeta && PLURAL_MODEL_ENTITIES_VALUES.includes(newSlug)) {
|
2127
|
+
newValue = newValue ? Object.entries(newValue).map(([slug, attributes]) => {
|
2128
|
+
return { slug, ...attributes };
|
2129
|
+
}) : [];
|
2130
|
+
}
|
2142
2131
|
const { parentField, parentIsArray } = (() => {
|
2143
2132
|
const lastDotIndex = newSlug.lastIndexOf(".");
|
2144
2133
|
if (lastDotIndex === -1) return { parentField: null };
|
@@ -2232,8 +2221,9 @@ var Transaction = class {
|
|
2232
2221
|
};
|
2233
2222
|
const { queryType, queryModel, queryInstructions } = splitQuery(query);
|
2234
2223
|
const model = getModelBySlug(this.models, queryModel);
|
2224
|
+
const isMeta = queryModel === "model" || queryModel === "models";
|
2235
2225
|
const modelFields = Object.fromEntries(
|
2236
|
-
|
2226
|
+
model.fields.map((field) => [field.slug, field.type])
|
2237
2227
|
);
|
2238
2228
|
if (queryType === "count") {
|
2239
2229
|
return addResult({ amount: rows[0][0] });
|
@@ -2241,13 +2231,13 @@ var Transaction = class {
|
|
2241
2231
|
const single = queryModel !== model.pluralSlug;
|
2242
2232
|
if (single) {
|
2243
2233
|
return addResult({
|
2244
|
-
record: rows[0] ? this.#formatRows(selectedFields, rows, true) : null,
|
2234
|
+
record: rows[0] ? this.#formatRows(selectedFields, rows, true, isMeta) : null,
|
2245
2235
|
modelFields
|
2246
2236
|
});
|
2247
2237
|
}
|
2248
2238
|
const pageSize = queryInstructions?.limitedTo;
|
2249
2239
|
const result = {
|
2250
|
-
records: this.#formatRows(selectedFields, rows, false),
|
2240
|
+
records: this.#formatRows(selectedFields, rows, false, isMeta),
|
2251
2241
|
modelFields
|
2252
2242
|
};
|
2253
2243
|
if (pageSize && result.records.length > 0) {
|