@ronin/compiler 0.14.2 → 0.14.3-leo-ron-1099-1-experimental-323

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 +70 -23
  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
  }
@@ -403,15 +414,13 @@ var handleOrderedBy = (model, instruction) => {
403
414
  // src/instructions/selecting.ts
404
415
  var handleSelecting = (models, model, statementParams, single, instructions, options = {}) => {
405
416
  let isJoining = false;
406
- const selectedFields = (instructions.selecting ? instructions.selecting.map((slug) => {
407
- const { field } = getFieldFromModel(model, slug, {
408
- instructionName: "selecting"
409
- });
410
- return field;
411
- }) : model.fields).filter((field) => !(field.type === "link" && field.kind === "many")).map((field) => {
417
+ const selectedFields = filterSelectedFields(
418
+ model,
419
+ instructions.selecting
420
+ ).filter((field) => !(field.type === "link" && field.kind === "many")).map((field) => {
412
421
  const newField = { ...field, mountingPath: field.slug };
413
422
  if (options.mountingPath) {
414
- newField.mountingPath = `${options.mountingPath}.${field.slug}`;
423
+ newField.mountingPath = `${options.mountingPath.replace(/\{\d+\}/g, "")}.${field.slug}`;
415
424
  }
416
425
  return newField;
417
426
  });
@@ -432,11 +441,14 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
432
441
  const subQueryModel = getModelBySlug(models, queryModel);
433
442
  isJoining = true;
434
443
  if (queryInstructions?.selecting) options.expandColumns = true;
435
- const tableAlias = composeIncludedTableAlias(key);
436
444
  const subSingle = queryModel !== subQueryModel.pluralSlug;
437
445
  if (!model.tableAlias)
438
446
  model.tableAlias = single && !subSingle ? `sub_${model.table}` : model.table;
439
- 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
+ );
440
452
  const { columns: nestedColumns, selectedFields: nestedSelectedFields } = handleSelecting(
441
453
  models,
442
454
  { ...subQueryModel, tableAlias },
@@ -508,15 +520,12 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
508
520
  if (symbol?.type === "query") {
509
521
  const { queryModel: subQueryModelSlug, queryInstructions: subQueryInstructions } = splitQuery(symbol.value);
510
522
  const subQueryModel = getModelBySlug(models, subQueryModelSlug);
511
- if (subQueryInstructions?.selecting) {
512
- const currentFields = new Set(subQueryInstructions.selecting);
513
- currentFields.add("id");
514
- subQueryInstructions.selecting = Array.from(currentFields);
515
- }
516
523
  const subQuerySelectedFields = subQueryInstructions?.selecting;
517
524
  const subQueryIncludedFields = subQueryInstructions?.including;
518
525
  const subQueryFields = [
519
- ...subQuerySelectedFields || (subQueryModel.fields || []).map((field) => field.slug),
526
+ ...filterSelectedFields(subQueryModel, subQuerySelectedFields).map(
527
+ (field) => field.slug
528
+ ),
520
529
  ...subQueryIncludedFields ? Object.keys(
521
530
  flatten(subQueryIncludedFields || {})
522
531
  ) : []
@@ -762,6 +771,32 @@ var replaceJSON = (key, value) => {
762
771
  if (key === QUERY_SYMBOLS.EXPRESSION) return value.replaceAll(`'`, `''`);
763
772
  return value;
764
773
  };
774
+ var matchSelectedFields = (fields, pattern) => {
775
+ let regexStr = pattern.replace(/\./g, "\\.");
776
+ regexStr = regexStr.replace(/\*\*/g, "<<DOUBLESTAR>>");
777
+ regexStr = regexStr.replace(/\*/g, "[^.]*");
778
+ regexStr = regexStr.replace(/<<DOUBLESTAR>>/g, ".*");
779
+ const regex2 = new RegExp(`^${regexStr}$`);
780
+ return fields.filter((field) => regex2.test(field.slug));
781
+ };
782
+ var filterSelectedFields = (model, instruction) => {
783
+ if (!instruction) return model.fields;
784
+ let selectedFields = [];
785
+ for (const pattern of instruction) {
786
+ const isNegative = pattern.startsWith("!");
787
+ const cleanPattern = isNegative ? pattern.slice(1) : pattern;
788
+ const matchedFields = matchSelectedFields(
789
+ isNegative ? selectedFields : model.fields,
790
+ cleanPattern
791
+ );
792
+ if (isNegative) {
793
+ selectedFields = selectedFields.filter((field) => !matchedFields.includes(field));
794
+ } else {
795
+ selectedFields.push(...matchedFields);
796
+ }
797
+ }
798
+ return selectedFields;
799
+ };
765
800
  var prepareStatementValue = (statementParams, value) => {
766
801
  if (value === null) return "NULL";
767
802
  if (!statementParams) {
@@ -1261,7 +1296,8 @@ var addDefaultModelPresets = (list, model) => {
1261
1296
  }
1262
1297
  }
1263
1298
  }
1264
- }
1299
+ },
1300
+ selecting: ["**", "!source", "!target"]
1265
1301
  }
1266
1302
  }
1267
1303
  }
@@ -2000,7 +2036,18 @@ var Transaction = class {
2000
2036
  for (const arrayField of joinFields.values()) {
2001
2037
  const currentValue = existingRecord[arrayField];
2002
2038
  const newValue = record[arrayField];
2003
- currentValue.push(...newValue);
2039
+ for (const newRecord of newValue) {
2040
+ if ("id" in newRecord) {
2041
+ const existingIndex = currentValue.findIndex((value) => {
2042
+ return value.id === newRecord.id;
2043
+ });
2044
+ if (existingIndex > -1) {
2045
+ Object.assign(currentValue[existingIndex], newRecord);
2046
+ continue;
2047
+ }
2048
+ }
2049
+ currentValue.push(newRecord);
2050
+ }
2004
2051
  }
2005
2052
  }
2006
2053
  return single ? records[0] : records;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronin/compiler",
3
- "version": "0.14.2",
3
+ "version": "0.14.3-leo-ron-1099-1-experimental-323",
4
4
  "type": "module",
5
5
  "description": "Compiles RONIN queries to SQL statements.",
6
6
  "publishConfig": {