@ronin/compiler 0.14.1 → 0.14.2-leo-ron-1099-1-experimental-320

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 CHANGED
@@ -36,6 +36,22 @@ declare class RoninError extends Error {
36
36
  queries?: Details['queries'];
37
37
  constructor(details: Details);
38
38
  }
39
+ /**
40
+ * Checks if the provided value contains a RONIN model symbol (a represenation of a
41
+ * particular entity inside a query, such as an expression or a sub query) and returns
42
+ * its type and value.
43
+ *
44
+ * @param value - The value that should be checked.
45
+ *
46
+ * @returns The type and value of the symbol, if the provided value contains one.
47
+ */
48
+ declare const getQuerySymbol: (value: unknown) => {
49
+ type: "query";
50
+ value: Query;
51
+ } | {
52
+ type: "expression";
53
+ value: string;
54
+ } | null;
39
55
 
40
56
  type QueryTypeEnum = 'get' | 'set' | 'add' | 'remove' | 'count';
41
57
  type ModelQueryTypeEnum = 'create' | 'alter' | 'drop';
@@ -378,4 +394,4 @@ declare class Transaction {
378
394
 
379
395
  declare const CLEAN_ROOT_MODEL: PublicModel;
380
396
 
381
- export { type AddInstructions, type AddQuery, type AddInstructions as AddQueryInstructions, type CombinedInstructions, type CountInstructions, type CountQuery, type CountInstructions as CountQueryInstructions, type GetInstructions, type GetQuery, type GetInstructions as GetQueryInstructions, type PublicModel as Model, type ModelField, type ModelIndex, type ModelPreset, type ModelTrigger, QUERY_SYMBOLS, type Query, type QueryInstructionType as QueryInstruction, type QuerySchemaType, type QueryType, CLEAN_ROOT_MODEL as ROOT_MODEL, type RemoveInstructions, type RemoveQuery, type RemoveInstructions as RemoveQueryInstructions, type Result, RoninError, type SetInstructions, type SetQuery, type SetInstructions as SetQueryInstructions, type Statement, Transaction, type WithInstruction };
397
+ export { type AddInstructions, type AddQuery, type AddInstructions as AddQueryInstructions, type CombinedInstructions, type CountInstructions, type CountQuery, type CountInstructions as CountQueryInstructions, type GetInstructions, type GetQuery, type GetInstructions as GetQueryInstructions, type PublicModel as Model, type ModelField, type ModelIndex, type ModelPreset, type ModelTrigger, QUERY_SYMBOLS, type Query, type QueryInstructionType as QueryInstruction, type QuerySchemaType, type QueryType, CLEAN_ROOT_MODEL as ROOT_MODEL, type RemoveInstructions, type RemoveQuery, type RemoveInstructions as RemoveQueryInstructions, type Result, RoninError, type SetInstructions, type SetQuery, type SetInstructions as SetQueryInstructions, type Statement, Transaction, type WithInstruction, getQuerySymbol };
package/dist/index.js CHANGED
@@ -70,7 +70,7 @@ var convertToCamelCase = (str) => {
70
70
  return sanitize(str).split(SPLIT_REGEX).map((part, index) => index === 0 ? part.toLowerCase() : capitalize(part)).join("");
71
71
  };
72
72
  var isObject = (value) => value != null && typeof value === "object" && Array.isArray(value) === false;
73
- var getSymbol = (value) => {
73
+ var getQuerySymbol = (value) => {
74
74
  if (!isObject(value)) return null;
75
75
  const objectValue = value;
76
76
  if (QUERY_SYMBOLS.QUERY in objectValue) {
@@ -110,7 +110,7 @@ var flatten = (obj, prefix = "", res = {}) => {
110
110
  if (!Object.hasOwn(obj, key)) continue;
111
111
  const path = prefix ? `${prefix}.${key}` : key;
112
112
  const value = obj[key];
113
- if (typeof value === "object" && value !== null && !getSymbol(value)) {
113
+ if (typeof value === "object" && value !== null && !getQuerySymbol(value)) {
114
114
  flatten(value, path, res);
115
115
  } else {
116
116
  res[path] = value;
@@ -304,7 +304,7 @@ var handleIncluding = (models, model, statementParams, single, instruction) => {
304
304
  let tableSubQuery;
305
305
  for (const ephemeralFieldSlug in instruction) {
306
306
  if (!Object.hasOwn(instruction, ephemeralFieldSlug)) continue;
307
- const symbol = getSymbol(instruction[ephemeralFieldSlug]);
307
+ const symbol = getQuerySymbol(instruction[ephemeralFieldSlug]);
308
308
  if (symbol?.type !== "query") continue;
309
309
  const { queryType, queryModel, queryInstructions } = splitQuery(symbol.value);
310
310
  let modifiableQueryInstructions = queryInstructions;
@@ -383,7 +383,7 @@ var handleOrderedBy = (model, instruction) => {
383
383
  if (statement.length > 0) {
384
384
  statement += ", ";
385
385
  }
386
- const symbol = getSymbol(item.value);
386
+ const symbol = getQuerySymbol(item.value);
387
387
  const instructionName = item.order === "ASC" ? "orderedBy.ascending" : "orderedBy.descending";
388
388
  if (symbol?.type === "expression") {
389
389
  statement += `(${parseFieldExpression(model, instructionName, symbol.value)}) ${item.order}`;
@@ -403,12 +403,10 @@ var handleOrderedBy = (model, instruction) => {
403
403
  // src/instructions/selecting.ts
404
404
  var handleSelecting = (models, model, statementParams, single, instructions, options = {}) => {
405
405
  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) => {
406
+ const selectedFields = filterSelectedFields(
407
+ model,
408
+ instructions.selecting
409
+ ).filter((field) => !(field.type === "link" && field.kind === "many")).map((field) => {
412
410
  const newField = { ...field, mountingPath: field.slug };
413
411
  if (options.mountingPath) {
414
412
  newField.mountingPath = `${options.mountingPath}.${field.slug}`;
@@ -419,14 +417,14 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
419
417
  const joinedSelectedFields = [];
420
418
  const joinedColumns = [];
421
419
  if (instructions.including) {
422
- const symbol = getSymbol(instructions.including);
420
+ const symbol = getQuerySymbol(instructions.including);
423
421
  if (symbol?.type === "query") {
424
422
  instructions.including.ronin_root = { ...instructions.including };
425
423
  delete instructions.including[QUERY_SYMBOLS.QUERY];
426
424
  }
427
425
  const flatObject = flatten(instructions.including);
428
426
  for (const [key, value] of Object.entries(flatObject)) {
429
- const symbol2 = getSymbol(value);
427
+ const symbol2 = getQuerySymbol(value);
430
428
  if (symbol2?.type === "query") {
431
429
  const { queryModel, queryInstructions } = splitQuery(symbol2.value);
432
430
  const subQueryModel = getModelBySlug(models, queryModel);
@@ -504,15 +502,10 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
504
502
  ...toInstruction.ronin
505
503
  };
506
504
  }
507
- const symbol = getSymbol(toInstruction);
505
+ const symbol = getQuerySymbol(toInstruction);
508
506
  if (symbol?.type === "query") {
509
507
  const { queryModel: subQueryModelSlug, queryInstructions: subQueryInstructions } = splitQuery(symbol.value);
510
508
  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
509
  const subQuerySelectedFields = subQueryInstructions?.selecting;
517
510
  const subQueryIncludedFields = subQueryInstructions?.including;
518
511
  const subQueryFields = [
@@ -762,6 +755,32 @@ var replaceJSON = (key, value) => {
762
755
  if (key === QUERY_SYMBOLS.EXPRESSION) return value.replaceAll(`'`, `''`);
763
756
  return value;
764
757
  };
758
+ var matchSelectedFields = (fields, pattern) => {
759
+ let regexStr = pattern.replace(/\./g, "\\.");
760
+ regexStr = regexStr.replace(/\*\*/g, "<<DOUBLESTAR>>");
761
+ regexStr = regexStr.replace(/\*/g, "[^.]*");
762
+ regexStr = regexStr.replace(/<<DOUBLESTAR>>/g, ".*");
763
+ const regex2 = new RegExp(`^${regexStr}$`);
764
+ return fields.filter((field) => regex2.test(field.slug));
765
+ };
766
+ var filterSelectedFields = (model, instruction) => {
767
+ if (!instruction) return model.fields;
768
+ let selectedFields = [];
769
+ for (const pattern of instruction) {
770
+ const isNegative = pattern.startsWith("!");
771
+ const cleanPattern = isNegative ? pattern.slice(1) : pattern;
772
+ const matchedFields = matchSelectedFields(
773
+ isNegative ? selectedFields : model.fields,
774
+ cleanPattern
775
+ );
776
+ if (isNegative) {
777
+ selectedFields = selectedFields.filter((field) => !matchedFields.includes(field));
778
+ } else {
779
+ selectedFields.push(...matchedFields);
780
+ }
781
+ }
782
+ return selectedFields;
783
+ };
765
784
  var prepareStatementValue = (statementParams, value) => {
766
785
  if (value === null) return "NULL";
767
786
  if (!statementParams) {
@@ -802,7 +821,7 @@ var composeFieldValues = (models, model, statementParams, instructionName, value
802
821
  { instructionName }
803
822
  );
804
823
  const collectStatementValue = options.type !== "fields";
805
- const symbol = getSymbol(value);
824
+ const symbol = getQuerySymbol(value);
806
825
  let conditionMatcher = "=";
807
826
  let conditionValue = value;
808
827
  if (options.condition) {
@@ -848,7 +867,7 @@ var composeConditions = (models, model, statementParams, instructionName, value,
848
867
  });
849
868
  const { field: modelField } = fieldDetails || {};
850
869
  const consumeJSON = modelField?.type === "json" && instructionName === "to";
851
- if (modelField && !(isObject(value) || Array.isArray(value)) || getSymbol(value) || consumeJSON) {
870
+ if (modelField && !(isObject(value) || Array.isArray(value)) || getQuerySymbol(value) || consumeJSON) {
852
871
  return composeFieldValues(
853
872
  models,
854
873
  model,
@@ -1507,7 +1526,7 @@ var getFieldStatement = (models, model, field) => {
1507
1526
  if (field.unique === true) statement += " UNIQUE";
1508
1527
  if (field.required === true) statement += " NOT NULL";
1509
1528
  if (typeof field.defaultValue !== "undefined") {
1510
- const symbol = getSymbol(field.defaultValue);
1529
+ const symbol = getQuerySymbol(field.defaultValue);
1511
1530
  let value = typeof field.defaultValue === "string" ? `'${field.defaultValue}'` : field.defaultValue;
1512
1531
  if (symbol) value = `(${parseFieldExpression(model, "to", symbol.value)})`;
1513
1532
  statement += ` DEFAULT ${value}`;
@@ -1519,12 +1538,12 @@ var getFieldStatement = (models, model, field) => {
1519
1538
  statement += " AUTOINCREMENT";
1520
1539
  }
1521
1540
  if (typeof field.check !== "undefined") {
1522
- const symbol = getSymbol(field.check);
1541
+ const symbol = getQuerySymbol(field.check);
1523
1542
  statement += ` CHECK (${parseFieldExpression(model, "to", symbol?.value)})`;
1524
1543
  }
1525
1544
  if (typeof field.computedAs !== "undefined") {
1526
1545
  const { kind, value } = field.computedAs;
1527
- const symbol = getSymbol(value);
1546
+ const symbol = getQuerySymbol(value);
1528
1547
  statement += ` GENERATED ALWAYS AS (${parseFieldExpression(model, "to", symbol?.value)}) ${kind}`;
1529
1548
  }
1530
1549
  if (field.type === "link") {
@@ -2090,5 +2109,6 @@ export {
2090
2109
  QUERY_SYMBOLS,
2091
2110
  CLEAN_ROOT_MODEL as ROOT_MODEL,
2092
2111
  RoninError,
2093
- Transaction
2112
+ Transaction,
2113
+ getQuerySymbol
2094
2114
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronin/compiler",
3
- "version": "0.14.1",
3
+ "version": "0.14.2-leo-ron-1099-1-experimental-320",
4
4
  "type": "module",
5
5
  "description": "Compiles RONIN queries to SQL statements.",
6
6
  "publishConfig": {