@ronin/compiler 0.13.1 → 0.13.2-leo-ron-1071-experimental-293

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.
Files changed (2) hide show
  1. package/dist/index.js +45 -53
  2. 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 composeIncludedTableAlias = (fieldSlug) => `including_${fieldSlug}`;
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
  };
@@ -814,10 +808,14 @@ var splitQuery = (query) => {
814
808
  };
815
809
 
816
810
  // src/utils/statement.ts
811
+ var replaceJSON = (key, value) => {
812
+ if (key === QUERY_SYMBOLS.EXPRESSION) return value.replaceAll(`'`, `''`);
813
+ return value;
814
+ };
817
815
  var prepareStatementValue = (statementParams, value) => {
818
816
  if (value === null) return "NULL";
819
817
  if (!statementParams) {
820
- const valueString = typeof value === "object" ? `json('${JSON.stringify(value)}')` : `'${value.toString()}'`;
818
+ const valueString = typeof value === "object" ? `json('${JSON.stringify(value, replaceJSON)}')` : `'${value.toString()}'`;
821
819
  return valueString;
822
820
  }
823
821
  let formattedValue = value;
@@ -1329,7 +1327,8 @@ var SYSTEM_FIELDS = [
1329
1327
  {
1330
1328
  name: "RONIN - Created At",
1331
1329
  type: "date",
1332
- slug: "ronin.createdAt"
1330
+ slug: "ronin.createdAt",
1331
+ defaultValue: CURRENT_TIME_EXPRESSION
1333
1332
  },
1334
1333
  {
1335
1334
  name: "RONIN - Created By",
@@ -1339,7 +1338,8 @@ var SYSTEM_FIELDS = [
1339
1338
  {
1340
1339
  name: "RONIN - Updated At",
1341
1340
  type: "date",
1342
- slug: "ronin.updatedAt"
1341
+ slug: "ronin.updatedAt",
1342
+ defaultValue: CURRENT_TIME_EXPRESSION
1343
1343
  },
1344
1344
  {
1345
1345
  name: "RONIN - Updated By",
@@ -1489,8 +1489,12 @@ var getFieldStatement = (models, model, field) => {
1489
1489
  if (field.slug === "id") statement += " PRIMARY KEY";
1490
1490
  if (field.unique === true) statement += " UNIQUE";
1491
1491
  if (field.required === true) statement += " NOT NULL";
1492
- if (typeof field.defaultValue !== "undefined")
1493
- statement += ` DEFAULT ${typeof field.defaultValue === "string" ? `'${field.defaultValue}'` : field.defaultValue}`;
1492
+ if (typeof field.defaultValue !== "undefined") {
1493
+ const symbol = getSymbol(field.defaultValue);
1494
+ let value = typeof field.defaultValue === "string" ? `'${field.defaultValue}'` : field.defaultValue;
1495
+ if (symbol) value = `(${parseFieldExpression(model, "to", symbol.value)})`;
1496
+ statement += ` DEFAULT ${value}`;
1497
+ }
1494
1498
  if (field.collation) statement += ` COLLATE ${field.collation}`;
1495
1499
  if (field.increment === true) statement += " AUTOINCREMENT";
1496
1500
  if (typeof field.check !== "undefined") {
@@ -1509,6 +1513,7 @@ var getFieldStatement = (models, model, field) => {
1509
1513
  const targetTable = getModelBySlug(modelList, field.target).table;
1510
1514
  statement += ` REFERENCES ${targetTable}("id")`;
1511
1515
  for (const trigger in actions) {
1516
+ if (!Object.hasOwn(actions, trigger)) continue;
1512
1517
  const triggerName = trigger.toUpperCase().slice(2);
1513
1518
  const action = actions[trigger];
1514
1519
  statement += ` ON ${triggerName} ${action}`;
@@ -1601,7 +1606,8 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1601
1606
  models.push(modelWithPresets);
1602
1607
  const modelWithObjects = Object.assign({}, modelWithPresets);
1603
1608
  for (const entity2 in entities) {
1604
- if (entities[entity2]) modelWithObjects[entity2] = entities[entity2];
1609
+ if (!Object.hasOwn(entities, entity2)) continue;
1610
+ Object.defineProperty(modelWithObjects, entity2, { value: entities[entity2] });
1605
1611
  }
1606
1612
  queryTypeDetails = { to: modelWithObjects };
1607
1613
  getSystemModels(models, modelWithPresets).map((systemModel) => {
@@ -1695,7 +1701,6 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1695
1701
  if (entity === "index") {
1696
1702
  const index = jsonValue;
1697
1703
  const indexName = convertToSnakeCase(slug);
1698
- const params = [];
1699
1704
  let statement = `${statementAction}${index?.unique ? " UNIQUE" : ""} INDEX "${indexName}"`;
1700
1705
  if (action === "create") {
1701
1706
  const columns = index.fields.map((field2) => {
@@ -1711,15 +1716,14 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1711
1716
  });
1712
1717
  statement += ` ON "${existingModel.table}" (${columns.join(", ")})`;
1713
1718
  if (index.filter) {
1714
- const withStatement = handleWith(models, existingModel, params, index.filter);
1719
+ const withStatement = handleWith(models, existingModel, null, index.filter);
1715
1720
  statement += ` WHERE (${withStatement})`;
1716
1721
  }
1717
1722
  }
1718
- dependencyStatements.push({ statement, params });
1723
+ dependencyStatements.push({ statement, params: [] });
1719
1724
  }
1720
1725
  if (entity === "trigger") {
1721
1726
  const triggerName = convertToSnakeCase(slug);
1722
- const params = [];
1723
1727
  let statement = `${statementAction} TRIGGER "${triggerName}"`;
1724
1728
  if (action === "create") {
1725
1729
  const trigger = jsonValue;
@@ -1746,13 +1750,13 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1746
1750
  const withStatement = handleWith(
1747
1751
  models,
1748
1752
  { ...existingModel, tableAlias },
1749
- params,
1753
+ null,
1750
1754
  trigger.filter
1751
1755
  );
1752
1756
  statementParts.push("WHEN", `(${withStatement})`);
1753
1757
  }
1754
1758
  const effectStatements = trigger.effects.map((effectQuery) => {
1755
- return compileQueryInput(effectQuery, models, params, {
1759
+ return compileQueryInput(effectQuery, models, null, {
1756
1760
  returning: false,
1757
1761
  parentModel: existingModel
1758
1762
  }).main.statement;
@@ -1762,7 +1766,7 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1762
1766
  statementParts.push("END");
1763
1767
  statement += ` ${statementParts.join(" ")}`;
1764
1768
  }
1765
- dependencyStatements.push({ statement, params });
1769
+ dependencyStatements.push({ statement, params: [] });
1766
1770
  }
1767
1771
  const field = `${QUERY_SYMBOLS.FIELD}${pluralType}`;
1768
1772
  let json;
@@ -1935,6 +1939,7 @@ var handleBeforeOrAfter = (model, statementParams, instructions) => {
1935
1939
  var handleFor = (model, instructions) => {
1936
1940
  const normalizedFor = Array.isArray(instructions.for) ? Object.fromEntries(instructions.for.map((presetSlug) => [presetSlug, null])) : instructions.for;
1937
1941
  for (const presetSlug in normalizedFor) {
1942
+ if (!Object.hasOwn(normalizedFor, presetSlug)) continue;
1938
1943
  const arg = normalizedFor[presetSlug];
1939
1944
  const preset = model.presets?.find((preset2) => preset2.slug === presetSlug);
1940
1945
  if (!preset) {
@@ -1952,6 +1957,7 @@ var handleFor = (model, instructions) => {
1952
1957
  );
1953
1958
  }
1954
1959
  for (const subInstruction in replacedForFilter) {
1960
+ if (!Object.hasOwn(replacedForFilter, subInstruction)) continue;
1955
1961
  const instructionName = subInstruction;
1956
1962
  const currentValue = instructions[instructionName];
1957
1963
  if (currentValue) {
@@ -1983,6 +1989,7 @@ var handleIncluding = (models, model, statementParams, instruction) => {
1983
1989
  let statement = "";
1984
1990
  let tableSubQuery;
1985
1991
  for (const ephemeralFieldSlug in instruction) {
1992
+ if (!Object.hasOwn(instruction, ephemeralFieldSlug)) continue;
1986
1993
  const symbol = getSymbol(instruction[ephemeralFieldSlug]);
1987
1994
  if (symbol?.type !== "query") continue;
1988
1995
  const { queryType, queryModel, queryInstructions } = splitQuery(symbol.value);
@@ -2155,23 +2162,22 @@ var handleSelecting = (models, model, statementParams, instructions, options) =>
2155
2162
 
2156
2163
  // src/instructions/to.ts
2157
2164
  var handleTo = (models, model, statementParams, queryType, dependencyStatements, instructions, parentModel) => {
2158
- const currentTime = (/* @__PURE__ */ new Date()).toISOString();
2159
2165
  const { with: withInstruction, to: toInstruction } = instructions;
2160
2166
  const defaultFields = {};
2161
2167
  if (queryType === "add") {
2162
2168
  defaultFields.id = toInstruction.id || generateRecordId(model.idPrefix);
2163
2169
  }
2164
- defaultFields.ronin = {
2165
- // If records are being created, set their creation time.
2166
- ...queryType === "add" ? { createdAt: currentTime } : {},
2167
- // If records are being created or updated, set their update time.
2168
- updatedAt: currentTime,
2169
- // Allow for overwriting the default values provided above.
2170
- ...toInstruction.ronin
2171
- };
2170
+ if (queryType === "set" || toInstruction.ronin) {
2171
+ defaultFields.ronin = {
2172
+ // If records are being updated, bump their update time.
2173
+ ...queryType === "set" ? { updatedAt: CURRENT_TIME_EXPRESSION } : {},
2174
+ // Allow for overwriting the default values provided above.
2175
+ ...toInstruction.ronin
2176
+ };
2177
+ }
2172
2178
  const symbol = getSymbol(toInstruction);
2173
2179
  if (symbol?.type === "query") {
2174
- let { queryModel: subQueryModelSlug, queryInstructions: subQueryInstructions } = splitQuery(symbol.value);
2180
+ const { queryModel: subQueryModelSlug, queryInstructions: subQueryInstructions } = splitQuery(symbol.value);
2175
2181
  const subQueryModel = getModelBySlug(models, subQueryModelSlug);
2176
2182
  if (subQueryInstructions?.selecting) {
2177
2183
  const currentFields = new Set(subQueryInstructions.selecting);
@@ -2189,24 +2195,9 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
2189
2195
  for (const field of subQueryFields || []) {
2190
2196
  getFieldFromModel(model, field, "to");
2191
2197
  }
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
2198
  let statement2 = "";
2204
2199
  if (subQuerySelectedFields) {
2205
- const selectedFields = [
2206
- ...subQueryFields,
2207
- ...defaultFieldsToAdd.map(([key]) => key)
2208
- ];
2209
- const columns = selectedFields.map((field) => {
2200
+ const columns = subQueryFields.map((field) => {
2210
2201
  return getFieldFromModel(model, field, "to").fieldSelector;
2211
2202
  });
2212
2203
  statement2 = `(${columns.join(", ")}) `;
@@ -2216,6 +2207,7 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
2216
2207
  }
2217
2208
  Object.assign(toInstruction, defaultFields);
2218
2209
  for (const fieldSlug in toInstruction) {
2210
+ if (!Object.hasOwn(toInstruction, fieldSlug)) continue;
2219
2211
  const fieldValue = toInstruction[fieldSlug];
2220
2212
  const fieldDetails = getFieldFromModel(model, fieldSlug, "to", false);
2221
2213
  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.1",
3
+ "version": "0.13.2-leo-ron-1071-experimental-293",
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",