@ronin/compiler 0.14.3 → 0.14.4

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 +59 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -23,8 +23,14 @@ var RAW_FIELD_TYPES = ["string", "number", "boolean"];
23
23
  var CURRENT_TIME_EXPRESSION = {
24
24
  [QUERY_SYMBOLS.EXPRESSION]: `strftime('%Y-%m-%dT%H:%M:%f', 'now') || 'Z'`
25
25
  };
26
- var composeIncludedTableAlias = (fieldSlug) => {
27
- return `including_${fieldSlug}`;
26
+ var MOUNTING_PATH_SUFFIX = /(.*?)(\{(\d+)\})?$/;
27
+ var composeMountingPath = (single, key, mountingPath) => {
28
+ const subMountingPath = key === "ronin_root" ? mountingPath ? mountingPath.replace(
29
+ MOUNTING_PATH_SUFFIX,
30
+ (_, p, __, n) => `${p}{${n ? +n + 1 : 1}}`
31
+ ) : void 0 : `${mountingPath ? `${mountingPath}.` : ""}${single ? key : `${key}[0]`}`;
32
+ const tableAlias = `including_${subMountingPath || key}`;
33
+ return { subMountingPath, tableAlias };
28
34
  };
29
35
  var MODEL_ENTITY_ERROR_CODES = {
30
36
  field: "FIELD_NOT_FOUND",
@@ -299,7 +305,7 @@ var handleFor = (model, instructions) => {
299
305
  };
300
306
 
301
307
  // src/instructions/including.ts
302
- var handleIncluding = (models, model, statementParams, single, instruction) => {
308
+ var handleIncluding = (models, model, statementParams, single, instruction, options = {}) => {
303
309
  let statement = "";
304
310
  let tableSubQuery;
305
311
  for (const ephemeralFieldSlug in instruction) {
@@ -311,8 +317,12 @@ var handleIncluding = (models, model, statementParams, single, instruction) => {
311
317
  const relatedModel = getModelBySlug(models, queryModel);
312
318
  let joinType = "LEFT";
313
319
  let relatedTableSelector = `"${relatedModel.table}"`;
314
- const tableAlias = composeIncludedTableAlias(ephemeralFieldSlug);
315
320
  const subSingle = queryModel !== relatedModel.pluralSlug;
321
+ const { tableAlias, subMountingPath } = composeMountingPath(
322
+ subSingle,
323
+ ephemeralFieldSlug,
324
+ options.mountingPath
325
+ );
316
326
  if (!modifiableQueryInstructions?.with) {
317
327
  joinType = "CROSS";
318
328
  if (subSingle) {
@@ -332,7 +342,7 @@ var handleIncluding = (models, model, statementParams, single, instruction) => {
332
342
  );
333
343
  relatedTableSelector = `(${subSelect.main.statement})`;
334
344
  }
335
- statement += `${joinType} JOIN ${relatedTableSelector} as ${tableAlias}`;
345
+ statement += `${joinType} JOIN ${relatedTableSelector} as "${tableAlias}"`;
336
346
  model.tableAlias = model.tableAlias || model.table;
337
347
  if (joinType === "LEFT") {
338
348
  const subStatement = composeConditions(
@@ -356,7 +366,8 @@ var handleIncluding = (models, model, statementParams, single, instruction) => {
356
366
  { ...relatedModel, tableAlias },
357
367
  statementParams,
358
368
  subSingle,
359
- modifiableQueryInstructions.including
369
+ modifiableQueryInstructions.including,
370
+ { mountingPath: subMountingPath }
360
371
  );
361
372
  statement += ` ${subIncluding.statement}`;
362
373
  }
@@ -409,7 +420,7 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
409
420
  ).filter((field) => !(field.type === "link" && field.kind === "many")).map((field) => {
410
421
  const newField = { ...field, mountingPath: field.slug };
411
422
  if (options.mountingPath) {
412
- newField.mountingPath = `${options.mountingPath}.${field.slug}`;
423
+ newField.mountingPath = `${options.mountingPath.replace(/\{\d+\}/g, "")}.${field.slug}`;
413
424
  }
414
425
  return newField;
415
426
  });
@@ -430,11 +441,14 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
430
441
  const subQueryModel = getModelBySlug(models, queryModel);
431
442
  isJoining = true;
432
443
  if (queryInstructions?.selecting) options.expandColumns = true;
433
- const tableAlias = composeIncludedTableAlias(key);
434
444
  const subSingle = queryModel !== subQueryModel.pluralSlug;
435
445
  if (!model.tableAlias)
436
446
  model.tableAlias = single && !subSingle ? `sub_${model.table}` : model.table;
437
- const subMountingPath = key === "ronin_root" ? options.mountingPath : `${options?.mountingPath ? `${options?.mountingPath}.` : ""}${subSingle ? key : `${key}[0]`}`;
447
+ const { tableAlias, subMountingPath } = composeMountingPath(
448
+ subSingle,
449
+ key,
450
+ options.mountingPath
451
+ );
438
452
  const { columns: nestedColumns, selectedFields: nestedSelectedFields } = handleSelecting(
439
453
  models,
440
454
  { ...subQueryModel, tableAlias },
@@ -1993,7 +2007,7 @@ var Transaction = class {
1993
2007
  const records = [];
1994
2008
  for (const row of rows) {
1995
2009
  const record = fields.reduce((acc, field, fieldIndex) => {
1996
- const newSlug = field.mountingPath;
2010
+ let newSlug = field.mountingPath;
1997
2011
  let newValue = row[fieldIndex];
1998
2012
  if (field.type === "json") {
1999
2013
  newValue = JSON.parse(newValue);
@@ -2005,6 +2019,29 @@ var Transaction = class {
2005
2019
  return { slug, ...attributes };
2006
2020
  }) : [];
2007
2021
  }
2022
+ const { parentField, parentIsArray } = (() => {
2023
+ const lastDotIndex = newSlug.lastIndexOf(".");
2024
+ if (lastDotIndex === -1) return { parentField: null };
2025
+ const parent = newSlug.slice(0, lastDotIndex);
2026
+ if (parent.endsWith("[0]")) {
2027
+ return { parentField: parent.slice(0, -3), parentIsArray: true };
2028
+ }
2029
+ return { parentField: parent };
2030
+ })();
2031
+ if (parentField) {
2032
+ if (field.slug === "id" && newValue === null) {
2033
+ newSlug = parentField;
2034
+ newValue = parentIsArray ? [] : null;
2035
+ }
2036
+ const parentFields = newSlug.split(".").map((_, index, array) => array.slice(0, index + 1).join(".")).reverse();
2037
+ if (parentFields.some((item) => {
2038
+ const isArray = item.endsWith("[0]");
2039
+ const value = getProperty(acc, item.replaceAll("[0]", ""));
2040
+ return isArray ? Array.isArray(value) && value.length === 0 : value === null;
2041
+ })) {
2042
+ return acc;
2043
+ }
2044
+ }
2008
2045
  setProperty(acc, newSlug, newValue);
2009
2046
  return acc;
2010
2047
  }, {});
@@ -2022,7 +2059,18 @@ var Transaction = class {
2022
2059
  for (const arrayField of joinFields.values()) {
2023
2060
  const currentValue = existingRecord[arrayField];
2024
2061
  const newValue = record[arrayField];
2025
- currentValue.push(...newValue);
2062
+ for (const newRecord of newValue) {
2063
+ if ("id" in newRecord) {
2064
+ const existingIndex = currentValue.findIndex((value) => {
2065
+ return value.id === newRecord.id;
2066
+ });
2067
+ if (existingIndex > -1) {
2068
+ Object.assign(currentValue[existingIndex], newRecord);
2069
+ continue;
2070
+ }
2071
+ }
2072
+ currentValue.push(newRecord);
2073
+ }
2026
2074
  }
2027
2075
  }
2028
2076
  return single ? records[0] : records;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronin/compiler",
3
- "version": "0.14.3",
3
+ "version": "0.14.4",
4
4
  "type": "module",
5
5
  "description": "Compiles RONIN queries to SQL statements.",
6
6
  "publishConfig": {