@ronin/compiler 0.13.1 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +40 -52
- package/package.json +2 -2
package/dist/index.js
CHANGED
@@ -676,7 +676,12 @@ var RONIN_MODEL_FIELD_REGEX = new RegExp(
|
|
676
676
|
"g"
|
677
677
|
);
|
678
678
|
var RAW_FIELD_TYPES = ["string", "number", "boolean"];
|
679
|
-
var
|
679
|
+
var CURRENT_TIME_EXPRESSION = {
|
680
|
+
[QUERY_SYMBOLS.EXPRESSION]: `strftime('%Y-%m-%dT%H:%M:%f', 'now') || 'Z'`
|
681
|
+
};
|
682
|
+
var composeIncludedTableAlias = (fieldSlug) => {
|
683
|
+
return `including_${fieldSlug}`;
|
684
|
+
};
|
680
685
|
var MODEL_ENTITY_ERROR_CODES = {
|
681
686
|
field: "FIELD_NOT_FOUND",
|
682
687
|
index: "INDEX_NOT_FOUND",
|
@@ -742,6 +747,7 @@ var getSymbol = (value) => {
|
|
742
747
|
var findInObject = (obj, pattern, replacer) => {
|
743
748
|
let found = false;
|
744
749
|
for (const key in obj) {
|
750
|
+
if (!Object.hasOwn(obj, key)) continue;
|
745
751
|
const value = obj[key];
|
746
752
|
if (isObject(value)) {
|
747
753
|
found = findInObject(value, pattern, replacer);
|
@@ -758,6 +764,7 @@ var findInObject = (obj, pattern, replacer) => {
|
|
758
764
|
};
|
759
765
|
var flatten = (obj, prefix = "", res = {}) => {
|
760
766
|
for (const key in obj) {
|
767
|
+
if (!Object.hasOwn(obj, key)) continue;
|
761
768
|
const path = prefix ? `${prefix}.${key}` : key;
|
762
769
|
const value = obj[key];
|
763
770
|
if (typeof value === "object" && value !== null && !getSymbol(value)) {
|
@@ -771,19 +778,6 @@ var flatten = (obj, prefix = "", res = {}) => {
|
|
771
778
|
var omit = (obj, properties) => Object.fromEntries(
|
772
779
|
Object.entries(obj).filter(([key]) => !properties.includes(key))
|
773
780
|
);
|
774
|
-
var expand = (obj) => {
|
775
|
-
return Object.entries(obj).reduce((res, [key, val]) => {
|
776
|
-
key.split(".").reduce((acc, part, i, arr) => {
|
777
|
-
if (i === arr.length - 1) {
|
778
|
-
acc[part] = val;
|
779
|
-
} else {
|
780
|
-
acc[part] = typeof acc[part] === "object" && acc[part] !== null ? acc[part] : {};
|
781
|
-
}
|
782
|
-
return acc[part];
|
783
|
-
}, res);
|
784
|
-
return res;
|
785
|
-
}, {});
|
786
|
-
};
|
787
781
|
var getProperty = (obj, path) => {
|
788
782
|
return path.split(".").reduce((acc, key) => acc?.[key], obj);
|
789
783
|
};
|
@@ -1329,7 +1323,8 @@ var SYSTEM_FIELDS = [
|
|
1329
1323
|
{
|
1330
1324
|
name: "RONIN - Created At",
|
1331
1325
|
type: "date",
|
1332
|
-
slug: "ronin.createdAt"
|
1326
|
+
slug: "ronin.createdAt",
|
1327
|
+
defaultValue: CURRENT_TIME_EXPRESSION
|
1333
1328
|
},
|
1334
1329
|
{
|
1335
1330
|
name: "RONIN - Created By",
|
@@ -1339,7 +1334,8 @@ var SYSTEM_FIELDS = [
|
|
1339
1334
|
{
|
1340
1335
|
name: "RONIN - Updated At",
|
1341
1336
|
type: "date",
|
1342
|
-
slug: "ronin.updatedAt"
|
1337
|
+
slug: "ronin.updatedAt",
|
1338
|
+
defaultValue: CURRENT_TIME_EXPRESSION
|
1343
1339
|
},
|
1344
1340
|
{
|
1345
1341
|
name: "RONIN - Updated By",
|
@@ -1489,8 +1485,12 @@ var getFieldStatement = (models, model, field) => {
|
|
1489
1485
|
if (field.slug === "id") statement += " PRIMARY KEY";
|
1490
1486
|
if (field.unique === true) statement += " UNIQUE";
|
1491
1487
|
if (field.required === true) statement += " NOT NULL";
|
1492
|
-
if (typeof field.defaultValue !== "undefined")
|
1493
|
-
|
1488
|
+
if (typeof field.defaultValue !== "undefined") {
|
1489
|
+
const symbol = getSymbol(field.defaultValue);
|
1490
|
+
let value = typeof field.defaultValue === "string" ? `'${field.defaultValue}'` : field.defaultValue;
|
1491
|
+
if (symbol) value = `(${parseFieldExpression(model, "to", symbol.value)})`;
|
1492
|
+
statement += ` DEFAULT ${value}`;
|
1493
|
+
}
|
1494
1494
|
if (field.collation) statement += ` COLLATE ${field.collation}`;
|
1495
1495
|
if (field.increment === true) statement += " AUTOINCREMENT";
|
1496
1496
|
if (typeof field.check !== "undefined") {
|
@@ -1509,6 +1509,7 @@ var getFieldStatement = (models, model, field) => {
|
|
1509
1509
|
const targetTable = getModelBySlug(modelList, field.target).table;
|
1510
1510
|
statement += ` REFERENCES ${targetTable}("id")`;
|
1511
1511
|
for (const trigger in actions) {
|
1512
|
+
if (!Object.hasOwn(actions, trigger)) continue;
|
1512
1513
|
const triggerName = trigger.toUpperCase().slice(2);
|
1513
1514
|
const action = actions[trigger];
|
1514
1515
|
statement += ` ON ${triggerName} ${action}`;
|
@@ -1601,7 +1602,8 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
|
|
1601
1602
|
models.push(modelWithPresets);
|
1602
1603
|
const modelWithObjects = Object.assign({}, modelWithPresets);
|
1603
1604
|
for (const entity2 in entities) {
|
1604
|
-
if (entities
|
1605
|
+
if (!Object.hasOwn(entities, entity2)) continue;
|
1606
|
+
Object.defineProperty(modelWithObjects, entity2, { value: entities[entity2] });
|
1605
1607
|
}
|
1606
1608
|
queryTypeDetails = { to: modelWithObjects };
|
1607
1609
|
getSystemModels(models, modelWithPresets).map((systemModel) => {
|
@@ -1695,7 +1697,6 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
|
|
1695
1697
|
if (entity === "index") {
|
1696
1698
|
const index = jsonValue;
|
1697
1699
|
const indexName = convertToSnakeCase(slug);
|
1698
|
-
const params = [];
|
1699
1700
|
let statement = `${statementAction}${index?.unique ? " UNIQUE" : ""} INDEX "${indexName}"`;
|
1700
1701
|
if (action === "create") {
|
1701
1702
|
const columns = index.fields.map((field2) => {
|
@@ -1711,15 +1712,14 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
|
|
1711
1712
|
});
|
1712
1713
|
statement += ` ON "${existingModel.table}" (${columns.join(", ")})`;
|
1713
1714
|
if (index.filter) {
|
1714
|
-
const withStatement = handleWith(models, existingModel,
|
1715
|
+
const withStatement = handleWith(models, existingModel, null, index.filter);
|
1715
1716
|
statement += ` WHERE (${withStatement})`;
|
1716
1717
|
}
|
1717
1718
|
}
|
1718
|
-
dependencyStatements.push({ statement, params });
|
1719
|
+
dependencyStatements.push({ statement, params: [] });
|
1719
1720
|
}
|
1720
1721
|
if (entity === "trigger") {
|
1721
1722
|
const triggerName = convertToSnakeCase(slug);
|
1722
|
-
const params = [];
|
1723
1723
|
let statement = `${statementAction} TRIGGER "${triggerName}"`;
|
1724
1724
|
if (action === "create") {
|
1725
1725
|
const trigger = jsonValue;
|
@@ -1746,13 +1746,13 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
|
|
1746
1746
|
const withStatement = handleWith(
|
1747
1747
|
models,
|
1748
1748
|
{ ...existingModel, tableAlias },
|
1749
|
-
|
1749
|
+
null,
|
1750
1750
|
trigger.filter
|
1751
1751
|
);
|
1752
1752
|
statementParts.push("WHEN", `(${withStatement})`);
|
1753
1753
|
}
|
1754
1754
|
const effectStatements = trigger.effects.map((effectQuery) => {
|
1755
|
-
return compileQueryInput(effectQuery, models,
|
1755
|
+
return compileQueryInput(effectQuery, models, null, {
|
1756
1756
|
returning: false,
|
1757
1757
|
parentModel: existingModel
|
1758
1758
|
}).main.statement;
|
@@ -1762,7 +1762,7 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
|
|
1762
1762
|
statementParts.push("END");
|
1763
1763
|
statement += ` ${statementParts.join(" ")}`;
|
1764
1764
|
}
|
1765
|
-
dependencyStatements.push({ statement, params });
|
1765
|
+
dependencyStatements.push({ statement, params: [] });
|
1766
1766
|
}
|
1767
1767
|
const field = `${QUERY_SYMBOLS.FIELD}${pluralType}`;
|
1768
1768
|
let json;
|
@@ -1935,6 +1935,7 @@ var handleBeforeOrAfter = (model, statementParams, instructions) => {
|
|
1935
1935
|
var handleFor = (model, instructions) => {
|
1936
1936
|
const normalizedFor = Array.isArray(instructions.for) ? Object.fromEntries(instructions.for.map((presetSlug) => [presetSlug, null])) : instructions.for;
|
1937
1937
|
for (const presetSlug in normalizedFor) {
|
1938
|
+
if (!Object.hasOwn(normalizedFor, presetSlug)) continue;
|
1938
1939
|
const arg = normalizedFor[presetSlug];
|
1939
1940
|
const preset = model.presets?.find((preset2) => preset2.slug === presetSlug);
|
1940
1941
|
if (!preset) {
|
@@ -1952,6 +1953,7 @@ var handleFor = (model, instructions) => {
|
|
1952
1953
|
);
|
1953
1954
|
}
|
1954
1955
|
for (const subInstruction in replacedForFilter) {
|
1956
|
+
if (!Object.hasOwn(replacedForFilter, subInstruction)) continue;
|
1955
1957
|
const instructionName = subInstruction;
|
1956
1958
|
const currentValue = instructions[instructionName];
|
1957
1959
|
if (currentValue) {
|
@@ -1983,6 +1985,7 @@ var handleIncluding = (models, model, statementParams, instruction) => {
|
|
1983
1985
|
let statement = "";
|
1984
1986
|
let tableSubQuery;
|
1985
1987
|
for (const ephemeralFieldSlug in instruction) {
|
1988
|
+
if (!Object.hasOwn(instruction, ephemeralFieldSlug)) continue;
|
1986
1989
|
const symbol = getSymbol(instruction[ephemeralFieldSlug]);
|
1987
1990
|
if (symbol?.type !== "query") continue;
|
1988
1991
|
const { queryType, queryModel, queryInstructions } = splitQuery(symbol.value);
|
@@ -2155,23 +2158,22 @@ var handleSelecting = (models, model, statementParams, instructions, options) =>
|
|
2155
2158
|
|
2156
2159
|
// src/instructions/to.ts
|
2157
2160
|
var handleTo = (models, model, statementParams, queryType, dependencyStatements, instructions, parentModel) => {
|
2158
|
-
const currentTime = (/* @__PURE__ */ new Date()).toISOString();
|
2159
2161
|
const { with: withInstruction, to: toInstruction } = instructions;
|
2160
2162
|
const defaultFields = {};
|
2161
2163
|
if (queryType === "add") {
|
2162
2164
|
defaultFields.id = toInstruction.id || generateRecordId(model.idPrefix);
|
2163
2165
|
}
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2169
|
-
|
2170
|
-
|
2171
|
-
}
|
2166
|
+
if (queryType === "set" || toInstruction.ronin) {
|
2167
|
+
defaultFields.ronin = {
|
2168
|
+
// If records are being updated, bump their update time.
|
2169
|
+
...queryType === "set" ? { updatedAt: CURRENT_TIME_EXPRESSION } : {},
|
2170
|
+
// Allow for overwriting the default values provided above.
|
2171
|
+
...toInstruction.ronin
|
2172
|
+
};
|
2173
|
+
}
|
2172
2174
|
const symbol = getSymbol(toInstruction);
|
2173
2175
|
if (symbol?.type === "query") {
|
2174
|
-
|
2176
|
+
const { queryModel: subQueryModelSlug, queryInstructions: subQueryInstructions } = splitQuery(symbol.value);
|
2175
2177
|
const subQueryModel = getModelBySlug(models, subQueryModelSlug);
|
2176
2178
|
if (subQueryInstructions?.selecting) {
|
2177
2179
|
const currentFields = new Set(subQueryInstructions.selecting);
|
@@ -2189,24 +2191,9 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
|
|
2189
2191
|
for (const field of subQueryFields || []) {
|
2190
2192
|
getFieldFromModel(model, field, "to");
|
2191
2193
|
}
|
2192
|
-
const defaultFieldsToAdd = subQuerySelectedFields ? Object.entries(flatten(defaultFields)).filter(([key]) => {
|
2193
|
-
return !subQuerySelectedFields.includes(key);
|
2194
|
-
}) : [];
|
2195
|
-
if (defaultFieldsToAdd.length > 0) {
|
2196
|
-
const defaultFieldsObject = expand(Object.fromEntries(defaultFieldsToAdd));
|
2197
|
-
if (!subQueryInstructions) subQueryInstructions = {};
|
2198
|
-
subQueryInstructions.including = {
|
2199
|
-
...defaultFieldsObject,
|
2200
|
-
...subQueryInstructions.including
|
2201
|
-
};
|
2202
|
-
}
|
2203
2194
|
let statement2 = "";
|
2204
2195
|
if (subQuerySelectedFields) {
|
2205
|
-
const
|
2206
|
-
...subQueryFields,
|
2207
|
-
...defaultFieldsToAdd.map(([key]) => key)
|
2208
|
-
];
|
2209
|
-
const columns = selectedFields.map((field) => {
|
2196
|
+
const columns = subQueryFields.map((field) => {
|
2210
2197
|
return getFieldFromModel(model, field, "to").fieldSelector;
|
2211
2198
|
});
|
2212
2199
|
statement2 = `(${columns.join(", ")}) `;
|
@@ -2216,6 +2203,7 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
|
|
2216
2203
|
}
|
2217
2204
|
Object.assign(toInstruction, defaultFields);
|
2218
2205
|
for (const fieldSlug in toInstruction) {
|
2206
|
+
if (!Object.hasOwn(toInstruction, fieldSlug)) continue;
|
2219
2207
|
const fieldValue = toInstruction[fieldSlug];
|
2220
2208
|
const fieldDetails = getFieldFromModel(model, fieldSlug, "to", false);
|
2221
2209
|
if (fieldDetails?.field.type === "link" && fieldDetails.field.kind === "many") {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ronin/compiler",
|
3
|
-
"version": "0.13.
|
3
|
+
"version": "0.13.2",
|
4
4
|
"type": "module",
|
5
5
|
"description": "Compiles RONIN queries to SQL statements.",
|
6
6
|
"publishConfig": {
|
@@ -13,7 +13,7 @@
|
|
13
13
|
],
|
14
14
|
"scripts": {
|
15
15
|
"lint": "bun run --bun lint:tsc && bun run --bun lint:biome",
|
16
|
-
"lint:biome": "biome check",
|
16
|
+
"lint:biome": "biome check --error-on-warnings",
|
17
17
|
"lint:tsc": "tsc --pretty",
|
18
18
|
"format": "biome check --write && biome format --write",
|
19
19
|
"test": "bun test",
|