@ronin/compiler 0.14.14 → 0.15.0-leo-ron-1099-1-experimental-362

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
@@ -132,7 +132,7 @@ type CreateQuery = {
132
132
  };
133
133
  type AlterQuery = {
134
134
  model: string;
135
- to?: Partial<PublicModel>;
135
+ to?: Partial<Omit<PublicModel, 'fields' | 'indexes' | 'triggers' | 'presets' | 'idPrefix'>>;
136
136
  create?: {
137
137
  field?: ModelField;
138
138
  index?: ModelIndex;
@@ -245,7 +245,7 @@ type ModelField = ModelFieldBasics & ({
245
245
  /** The target model of the relationship that is being established. */
246
246
  target: string;
247
247
  /** Whether the field should be related to one record, or many records. */
248
- kind?: 'one' | 'many';
248
+ kind?: 'one';
249
249
  /**
250
250
  * If the target record is updated or deleted, the defined actions maybe executed.
251
251
  */
@@ -253,6 +253,13 @@ type ModelField = ModelFieldBasics & ({
253
253
  onDelete?: ModelFieldLinkAction;
254
254
  onUpdate?: ModelFieldLinkAction;
255
255
  };
256
+ } | {
257
+ /** The kind of value that should be stored inside the field. */
258
+ type: 'link';
259
+ /** The target model of the relationship that is being established. */
260
+ target: string;
261
+ /** Whether the field should be related to one record, or many records. */
262
+ kind: 'many';
256
263
  });
257
264
  type ModelIndexField<T extends Array<ModelField> = Array<ModelField>> = {
258
265
  /** The collating sequence used for text placed inside the field. */
package/dist/index.js CHANGED
@@ -256,55 +256,6 @@ var handleBeforeOrAfter = (model, statementParams, instructions) => {
256
256
  return `${clause}(${conditions.join(" OR ")})`;
257
257
  };
258
258
 
259
- // src/instructions/for.ts
260
- var handleUsing = (model, instructions) => {
261
- const normalizedFor = Array.isArray(instructions.using) ? Object.fromEntries(instructions.using.map((presetSlug) => [presetSlug, null])) : instructions.using;
262
- for (const presetSlug in normalizedFor) {
263
- if (!Object.hasOwn(normalizedFor, presetSlug)) continue;
264
- const arg = normalizedFor[presetSlug];
265
- const preset = model.presets?.find((preset2) => preset2.slug === presetSlug);
266
- if (!preset) {
267
- throw new RoninError({
268
- message: `Preset "${presetSlug}" does not exist in model "${model.name}".`,
269
- code: "PRESET_NOT_FOUND"
270
- });
271
- }
272
- const replacedUsingFilter = structuredClone(preset.instructions);
273
- if (arg !== null) {
274
- findInObject(
275
- replacedUsingFilter,
276
- QUERY_SYMBOLS.VALUE,
277
- (match) => match.replace(QUERY_SYMBOLS.VALUE, arg)
278
- );
279
- }
280
- for (const subInstruction in replacedUsingFilter) {
281
- if (!Object.hasOwn(replacedUsingFilter, subInstruction)) continue;
282
- const instructionName = subInstruction;
283
- const currentValue = instructions[instructionName];
284
- if (currentValue) {
285
- let newValue;
286
- if (Array.isArray(currentValue)) {
287
- newValue = [
288
- ...replacedUsingFilter[instructionName],
289
- ...currentValue
290
- ];
291
- } else if (isObject(currentValue)) {
292
- newValue = {
293
- ...replacedUsingFilter[instructionName],
294
- ...currentValue
295
- };
296
- }
297
- Object.assign(instructions, { [instructionName]: newValue });
298
- continue;
299
- }
300
- Object.assign(instructions, {
301
- [instructionName]: replacedUsingFilter[instructionName]
302
- });
303
- }
304
- }
305
- return instructions;
306
- };
307
-
308
259
  // src/instructions/including.ts
309
260
  var handleIncluding = (models, model, statementParams, single, instruction, options = {}) => {
310
261
  let statement = "";
@@ -315,6 +266,7 @@ var handleIncluding = (models, model, statementParams, single, instruction, opti
315
266
  if (symbol?.type !== "query") continue;
316
267
  const { queryType, queryModel, queryInstructions } = splitQuery(symbol.value);
317
268
  let modifiableQueryInstructions = queryInstructions;
269
+ if (queryType === "count") continue;
318
270
  const relatedModel = getModelBySlug(models, queryModel);
319
271
  let joinType = "LEFT";
320
272
  let relatedTableSelector = `"${relatedModel.table}"`;
@@ -340,7 +292,8 @@ var handleIncluding = (models, model, statementParams, single, instruction, opti
340
292
  }
341
293
  },
342
294
  models,
343
- statementParams
295
+ statementParams,
296
+ { parentModel: model }
344
297
  );
345
298
  relatedTableSelector = `(${subSelect.main.statement})`;
346
299
  }
@@ -438,8 +391,20 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
438
391
  for (const [key, value] of Object.entries(flatObject)) {
439
392
  const symbol2 = getQuerySymbol(value);
440
393
  if (symbol2?.type === "query") {
441
- const { queryModel, queryInstructions } = splitQuery(symbol2.value);
394
+ const { queryType, queryModel, queryInstructions } = splitQuery(symbol2.value);
442
395
  const subQueryModel = getModelBySlug(models, queryModel);
396
+ if (queryType === "count") {
397
+ const subSelect = compileQueryInput(symbol2.value, models, statementParams, {
398
+ parentModel: { ...model, tableAlias: model.table }
399
+ });
400
+ selectedFields.push({
401
+ slug: key,
402
+ mountingPath: key,
403
+ type: "number",
404
+ mountedValue: `(${subSelect.main.statement})`
405
+ });
406
+ continue;
407
+ }
443
408
  isJoining = true;
444
409
  const subSingle = queryModel !== subQueryModel.pluralSlug;
445
410
  if (!model.tableAlias)
@@ -598,6 +563,61 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
598
563
  return statement;
599
564
  };
600
565
 
566
+ // src/instructions/using.ts
567
+ var handleUsing = (model, instructions) => {
568
+ const normalizedUsing = Array.isArray(instructions.using) ? Object.fromEntries(instructions.using.map((presetSlug) => [presetSlug, null])) : instructions.using;
569
+ if ("links" in normalizedUsing) {
570
+ for (const field of model.fields) {
571
+ if (field.type !== "link" || field.kind === "many") continue;
572
+ normalizedUsing[field.slug] = null;
573
+ }
574
+ }
575
+ for (const presetSlug in normalizedUsing) {
576
+ if (!Object.hasOwn(normalizedUsing, presetSlug) || presetSlug === "links") continue;
577
+ const arg = normalizedUsing[presetSlug];
578
+ const preset = model.presets?.find((preset2) => preset2.slug === presetSlug);
579
+ if (!preset) {
580
+ throw new RoninError({
581
+ message: `Preset "${presetSlug}" does not exist in model "${model.name}".`,
582
+ code: "PRESET_NOT_FOUND"
583
+ });
584
+ }
585
+ const replacedUsingFilter = structuredClone(preset.instructions);
586
+ if (arg !== null) {
587
+ findInObject(
588
+ replacedUsingFilter,
589
+ QUERY_SYMBOLS.VALUE,
590
+ (match) => match.replace(QUERY_SYMBOLS.VALUE, arg)
591
+ );
592
+ }
593
+ for (const subInstruction in replacedUsingFilter) {
594
+ if (!Object.hasOwn(replacedUsingFilter, subInstruction)) continue;
595
+ const instructionName = subInstruction;
596
+ const currentValue = instructions[instructionName];
597
+ if (currentValue) {
598
+ let newValue;
599
+ if (Array.isArray(currentValue)) {
600
+ newValue = [
601
+ ...replacedUsingFilter[instructionName],
602
+ ...currentValue
603
+ ];
604
+ } else if (isObject(currentValue)) {
605
+ newValue = {
606
+ ...replacedUsingFilter[instructionName],
607
+ ...currentValue
608
+ };
609
+ }
610
+ Object.assign(instructions, { [instructionName]: newValue });
611
+ continue;
612
+ }
613
+ Object.assign(instructions, {
614
+ [instructionName]: replacedUsingFilter[instructionName]
615
+ });
616
+ }
617
+ }
618
+ return instructions;
619
+ };
620
+
601
621
  // src/utils/index.ts
602
622
  var compileQueryInput = (defaultQuery, models, statementParams, options) => {
603
623
  const dependencyStatements = [];
@@ -1514,12 +1534,20 @@ var getSystemModels = (models, model) => {
1514
1534
  {
1515
1535
  slug: "source",
1516
1536
  type: "link",
1517
- target: model.slug
1537
+ target: model.slug,
1538
+ actions: {
1539
+ onDelete: "CASCADE",
1540
+ onUpdate: "CASCADE"
1541
+ }
1518
1542
  },
1519
1543
  {
1520
1544
  slug: "target",
1521
1545
  type: "link",
1522
- target: relatedModel.slug
1546
+ target: relatedModel.slug,
1547
+ actions: {
1548
+ onDelete: "CASCADE",
1549
+ onUpdate: "CASCADE"
1550
+ }
1523
1551
  }
1524
1552
  ]
1525
1553
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronin/compiler",
3
- "version": "0.14.14",
3
+ "version": "0.15.0-leo-ron-1099-1-experimental-362",
4
4
  "type": "module",
5
5
  "description": "Compiles RONIN queries to SQL statements.",
6
6
  "publishConfig": {