@ronin/compiler 0.16.5 → 0.17.0-leo-ron-1099-experimental-373

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/README.md CHANGED
@@ -127,7 +127,12 @@ new Transaction(queries, {
127
127
  // Instead of returning an array of parameters for every statement (which allows for
128
128
  // preventing SQL injections), all parameters are inlined directly into the SQL strings.
129
129
  // This option should only be used if the generated SQL will be manually verified.
130
- inlineParams: true
130
+ inlineParams: true,
131
+
132
+ // By default, the compiler relies on dynamic column default values for computing the
133
+ // values of all meta fields (such as `id`, `ronin.createdAt`, etc). In order to compute
134
+ // those values at the time of insertion instead, use this option.
135
+ inlineDefaults: true
131
136
  });
132
137
  ```
133
138
 
package/dist/index.d.ts CHANGED
@@ -261,19 +261,19 @@ type ModelField = ModelFieldBasics & ({
261
261
  /** Whether the field should be related to one record, or many records. */
262
262
  kind: 'many';
263
263
  });
264
- type ModelIndexField<T extends Array<ModelField> = Array<ModelField>> = {
264
+ type ModelIndexField<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> = {
265
265
  /** The collating sequence used for text placed inside the field. */
266
266
  collation?: ModelFieldCollation;
267
267
  /** How the records in the index should be ordered. */
268
268
  order?: 'ASC' | 'DESC';
269
269
  } & ({
270
270
  /** The field slug for which the index should be created. */
271
- slug: T[number]['slug'];
271
+ slug: keyof T;
272
272
  } | {
273
273
  /** The field expression for which the index should be created. */
274
274
  expression: string;
275
275
  });
276
- type ModelIndex<T extends Array<ModelField> = Array<ModelField>> = {
276
+ type ModelIndex<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> = {
277
277
  /**
278
278
  * The list of fields in the model for which the index should be created.
279
279
  */
@@ -281,7 +281,7 @@ type ModelIndex<T extends Array<ModelField> = Array<ModelField>> = {
281
281
  /**
282
282
  * The identifier of the index.
283
283
  */
284
- slug?: string;
284
+ slug: string;
285
285
  /**
286
286
  * Whether only one record with a unique value for the provided fields will be allowed.
287
287
  */
@@ -292,18 +292,16 @@ type ModelIndex<T extends Array<ModelField> = Array<ModelField>> = {
292
292
  */
293
293
  filter?: WithInstruction;
294
294
  };
295
- type ModelTriggerField<T extends Array<ModelField> = Array<ModelField>> = {
295
+ type ModelTriggerField<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> = {
296
296
  /**
297
297
  * The slug of the field that should cause the trigger to fire if the value of the
298
298
  * field has changed.
299
299
  */
300
- slug: T[number]['slug'];
300
+ slug: keyof T;
301
301
  };
302
- type ModelTrigger<T extends Array<ModelField> = Array<ModelField>> = {
303
- /**
304
- * The identifier of the trigger.
305
- */
306
- slug?: string;
302
+ type ModelTrigger<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> = {
303
+ /** The identifier of the trigger. */
304
+ slug: string;
307
305
  /** The type of query for which the trigger should fire. */
308
306
  action: 'INSERT' | 'UPDATE' | 'DELETE';
309
307
  /** When the trigger should fire in the case that a matching query is executed. */
@@ -324,15 +322,18 @@ type ModelPreset = {
324
322
  /** The query instructions that should be applied when the preset is used. */
325
323
  instructions: GetInstructions;
326
324
  };
327
- interface Model<T extends Array<ModelField> = Array<ModelField>> {
325
+ type ModelEntityList<T extends {
326
+ slug: string;
327
+ }> = Record<NonNullable<T['slug']>, Partial<T>>;
328
+ interface Model<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> {
328
329
  id: string;
329
330
  name: string;
330
331
  pluralName: string;
331
332
  slug: string;
332
333
  pluralSlug: string;
333
334
  identifiers: {
334
- name: T[number]['slug'];
335
- slug: T[number]['slug'];
335
+ name: keyof T;
336
+ slug: keyof T;
336
337
  };
337
338
  idPrefix: string;
338
339
  /** The name of the table in SQLite. */
@@ -357,11 +358,11 @@ interface Model<T extends Array<ModelField> = Array<ModelField>> {
357
358
  associationSlug?: string;
358
359
  };
359
360
  fields: T;
360
- indexes?: Array<ModelIndex<T>>;
361
- triggers?: Array<ModelTrigger<T>>;
362
- presets?: Array<ModelPreset>;
361
+ indexes?: ModelEntityList<ModelIndex<T>>;
362
+ triggers?: ModelEntityList<ModelTrigger<T>>;
363
+ presets?: ModelEntityList<ModelPreset>;
363
364
  }
364
- type PublicModel<T extends Array<ModelField> = Array<ModelField>> = Omit<Partial<Model<T>>, 'slug' | 'identifiers' | 'system' | 'tableAlias'> & {
365
+ type PublicModel<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> = Omit<Partial<Model<T>>, 'slug' | 'identifiers' | 'system' | 'tableAlias'> & {
365
366
  slug: Required<Model['slug']>;
366
367
  identifiers?: Partial<Model['identifiers']>;
367
368
  };
@@ -404,6 +405,10 @@ interface TransactionOptions {
404
405
  * separating them out into a dedicated `params` array.
405
406
  */
406
407
  inlineParams?: boolean;
408
+ /**
409
+ * Whether to compute default field values as part of the generated statement.
410
+ */
411
+ inlineDefaults?: boolean;
407
412
  }
408
413
  declare class Transaction {
409
414
  #private;
package/dist/index.js CHANGED
@@ -23,6 +23,12 @@ 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 ID_EXPRESSION = (idPrefix) => ({
27
+ // Since default values in SQLite cannot rely on other columns, we unfortunately
28
+ // cannot rely on the `idPrefix` column here. Instead, we need to inject it directly
29
+ // into the expression as a static string.
30
+ [QUERY_SYMBOLS.EXPRESSION]: `'${idPrefix}_' || lower(substr(hex(randomblob(12)), 1, 16))`
31
+ });
26
32
  var MOUNTING_PATH_SUFFIX = /(.*?)(\{(\d+)\})?$/;
27
33
  var composeMountingPath = (single, key, mountingPath) => {
28
34
  if (key === "ronin_root") {
@@ -257,7 +263,9 @@ var handleBeforeOrAfter = (model, statementParams, queryType, instructions) => {
257
263
  };
258
264
 
259
265
  // src/instructions/including.ts
260
- var handleIncluding = (models, model, statementParams, single, instruction, options = {}) => {
266
+ var handleIncluding = (models, model, statementParams, single, instruction, options = {
267
+ inlineDefaults: false
268
+ }) => {
261
269
  let statement = "";
262
270
  let tableSubQuery;
263
271
  for (const ephemeralFieldSlug in instruction) {
@@ -293,7 +301,7 @@ var handleIncluding = (models, model, statementParams, single, instruction, opti
293
301
  },
294
302
  models,
295
303
  statementParams,
296
- { parentModel: model }
304
+ { parentModel: model, inlineDefaults: options.inlineDefaults }
297
305
  );
298
306
  relatedTableSelector = `(${subSelect.main.statement})`;
299
307
  }
@@ -322,7 +330,7 @@ var handleIncluding = (models, model, statementParams, single, instruction, opti
322
330
  statementParams,
323
331
  subSingle,
324
332
  modifiableQueryInstructions.including,
325
- { mountingPath: subMountingPath }
333
+ { mountingPath: subMountingPath, inlineDefaults: options.inlineDefaults }
326
334
  );
327
335
  statement += ` ${subIncluding.statement}`;
328
336
  }
@@ -367,7 +375,7 @@ var handleOrderedBy = (model, instruction) => {
367
375
  };
368
376
 
369
377
  // src/instructions/selecting.ts
370
- var handleSelecting = (models, model, statementParams, single, instructions, options = {}) => {
378
+ var handleSelecting = (models, model, statementParams, single, instructions, options = { inlineDefaults: false }) => {
371
379
  let isJoining = false;
372
380
  const selectedFields = filterSelectedFields(
373
381
  model,
@@ -395,7 +403,8 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
395
403
  const subQueryModel = getModelBySlug(models, queryModel);
396
404
  if (queryType === "count") {
397
405
  const subSelect = compileQueryInput(symbol2.value, models, statementParams, {
398
- parentModel: { ...model, tableAlias: model.table }
406
+ parentModel: { ...model, tableAlias: model.table },
407
+ inlineDefaults: options.inlineDefaults
399
408
  });
400
409
  selectedFields.push({
401
410
  slug: key,
@@ -457,16 +466,23 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
457
466
  };
458
467
 
459
468
  // src/instructions/to.ts
460
- var handleTo = (models, model, statementParams, queryType, dependencyStatements, instructions, parentModel) => {
469
+ var handleTo = (models, model, statementParams, queryType, dependencyStatements, instructions, options) => {
461
470
  const { with: withInstruction, to: toInstruction } = instructions;
462
471
  const defaultFields = {};
463
- if (queryType === "set" || toInstruction.ronin) {
464
- defaultFields.ronin = {
472
+ const inlineDefaultInsertionFields = queryType === "add" && options?.inlineDefaults;
473
+ if (inlineDefaultInsertionFields) {
474
+ defaultFields.id = toInstruction.id || ID_EXPRESSION(model.idPrefix);
475
+ }
476
+ if (queryType === "add" || queryType === "set" || toInstruction.ronin) {
477
+ const defaults = {
478
+ // If records are being created, set their creation time.
479
+ ...inlineDefaultInsertionFields ? { createdAt: CURRENT_TIME_EXPRESSION } : {},
465
480
  // If records are being updated, bump their update time.
466
- ...queryType === "set" ? { updatedAt: CURRENT_TIME_EXPRESSION } : {},
481
+ ...queryType === "set" || inlineDefaultInsertionFields ? { updatedAt: CURRENT_TIME_EXPRESSION } : {},
467
482
  // Allow for overwriting the default values provided above.
468
483
  ...toInstruction.ronin
469
484
  };
485
+ if (Object.keys(defaults).length > 0) defaultFields.ronin = defaults;
470
486
  }
471
487
  const symbol = getQuerySymbol(toInstruction);
472
488
  if (symbol?.type === "query") {
@@ -492,7 +508,10 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
492
508
  });
493
509
  statement2 = `(${columns.join(", ")}) `;
494
510
  }
495
- statement2 += compileQueryInput(symbol.value, models, statementParams).main.statement;
511
+ statement2 += compileQueryInput(symbol.value, models, statementParams, {
512
+ // biome-ignore lint/complexity/useSimplifiedLogicExpression: This is needed.
513
+ inlineDefaults: options?.inlineDefaults || false
514
+ }).main.statement;
496
515
  return statement2;
497
516
  }
498
517
  Object.assign(toInstruction, defaultFields);
@@ -520,7 +539,8 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
520
539
  },
521
540
  models,
522
541
  [],
523
- { returning: false }
542
+ // biome-ignore lint/complexity/useSimplifiedLogicExpression: This is needed.
543
+ { returning: false, inlineDefaults: options?.inlineDefaults || false }
524
544
  ).main;
525
545
  dependencyStatements.push({ ...query, after: true });
526
546
  };
@@ -541,7 +561,7 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
541
561
  }
542
562
  }
543
563
  let statement = composeConditions(models, model, statementParams, "to", toInstruction, {
544
- parentModel,
564
+ parentModel: options?.parentModel,
545
565
  type: queryType === "add" ? "fields" : void 0
546
566
  });
547
567
  if (queryType === "add") {
@@ -552,7 +572,7 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
552
572
  "to",
553
573
  toInstruction,
554
574
  {
555
- parentModel,
575
+ parentModel: options?.parentModel,
556
576
  type: "values"
557
577
  }
558
578
  );
@@ -567,22 +587,24 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
567
587
  var handleUsing = (model, instructions) => {
568
588
  const normalizedUsing = Array.isArray(instructions.using) ? Object.fromEntries(instructions.using.map((presetSlug) => [presetSlug, null])) : instructions.using;
569
589
  if ("links" in normalizedUsing) {
570
- for (const field of model.fields) {
590
+ for (const [fieldSlug, field] of Object.entries(model.fields)) {
571
591
  if (field.type !== "link" || field.kind === "many") continue;
572
- normalizedUsing[field.slug] = null;
592
+ normalizedUsing[fieldSlug] = null;
573
593
  }
574
594
  }
575
595
  for (const presetSlug in normalizedUsing) {
576
596
  if (!Object.hasOwn(normalizedUsing, presetSlug) || presetSlug === "links") continue;
577
597
  const arg = normalizedUsing[presetSlug];
578
- const preset = model.presets?.find((preset2) => preset2.slug === presetSlug);
598
+ const preset = model.presets?.[presetSlug];
579
599
  if (!preset) {
580
600
  throw new RoninError({
581
601
  message: `Preset "${presetSlug}" does not exist in model "${model.name}".`,
582
602
  code: "PRESET_NOT_FOUND"
583
603
  });
584
604
  }
585
- const replacedUsingFilter = structuredClone(preset.instructions);
605
+ const replacedUsingFilter = structuredClone(
606
+ preset.instructions
607
+ );
586
608
  if (arg !== null) {
587
609
  findInObject(
588
610
  replacedUsingFilter,
@@ -625,7 +647,11 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
625
647
  models,
626
648
  dependencyStatements,
627
649
  statementParams,
628
- defaultQuery
650
+ defaultQuery,
651
+ {
652
+ // biome-ignore lint/complexity/useSimplifiedLogicExpression: This is needed.
653
+ inlineDefaults: options?.inlineDefaults || false
654
+ }
629
655
  );
630
656
  if (query === null)
631
657
  return { dependencies: [], main: dependencyStatements[0], selectedFields: [] };
@@ -655,7 +681,9 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
655
681
  {
656
682
  selecting: instructions?.selecting,
657
683
  including: instructions?.including
658
- }
684
+ },
685
+ // biome-ignore lint/complexity/useSimplifiedLogicExpression: This is needed.
686
+ { inlineDefaults: options?.inlineDefaults || false }
659
687
  );
660
688
  let statement = "";
661
689
  switch (queryType) {
@@ -709,7 +737,7 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
709
737
  queryType,
710
738
  dependencyStatements,
711
739
  { with: instructions.with, to: instructionValue },
712
- options?.parentModel
740
+ options
713
741
  );
714
742
  statement += `${toStatement} `;
715
743
  }
@@ -801,13 +829,16 @@ var matchSelectedFields = (fields, pattern) => {
801
829
  return fields.filter((field) => regex2.test(field.slug));
802
830
  };
803
831
  var filterSelectedFields = (model, instruction) => {
804
- if (!instruction) return model.fields;
832
+ const mappedFields = Object.entries(model.fields).map(
833
+ ([fieldSlug, field]) => ({ slug: fieldSlug, ...field })
834
+ );
835
+ if (!instruction) return mappedFields;
805
836
  let selectedFields = [];
806
837
  for (const pattern of instruction) {
807
838
  const isNegative = pattern.startsWith("!");
808
839
  const cleanPattern = isNegative ? pattern.slice(1) : pattern;
809
840
  const matchedFields = matchSelectedFields(
810
- isNegative ? selectedFields : model.fields,
841
+ isNegative ? selectedFields : mappedFields,
811
842
  cleanPattern
812
843
  );
813
844
  if (isNegative) {
@@ -896,7 +927,7 @@ var composeConditions = (models, model, statementParams, instructionName, value,
896
927
  return conditions.join(" AND ");
897
928
  }
898
929
  if (options.fieldSlug) {
899
- const childField = model.fields.some(({ slug }) => {
930
+ const childField = Object.keys(model.fields).some((slug) => {
900
931
  return slug.includes(".") && slug.split(".")[0] === options.fieldSlug;
901
932
  });
902
933
  if (!childField) {
@@ -1256,19 +1287,19 @@ var addDefaultModelAttributes = (model, isNew) => {
1256
1287
  copiedModel[setting] = generator(copiedModel[base]);
1257
1288
  }
1258
1289
  const newFields = copiedModel.fields || [];
1259
- if (isNew || newFields.length > 0) {
1290
+ if (isNew || Object.keys(newFields).length > 0) {
1260
1291
  if (!copiedModel.identifiers) copiedModel.identifiers = {};
1261
1292
  if (!copiedModel.identifiers.name) {
1262
- const suitableField = newFields.find(
1263
- (field) => field.type === "string" && field.required === true && ["name"].includes(field.slug)
1293
+ const suitableField = Object.entries(newFields).find(
1294
+ ([fieldSlug, field]) => field.type === "string" && field.required === true && ["name"].includes(fieldSlug)
1264
1295
  );
1265
- copiedModel.identifiers.name = suitableField?.slug || "id";
1296
+ copiedModel.identifiers.name = suitableField?.[0] || "id";
1266
1297
  }
1267
1298
  if (!copiedModel.identifiers.slug) {
1268
- const suitableField = newFields.find(
1269
- (field) => field.type === "string" && field.unique === true && field.required === true && ["slug", "handle"].includes(field.slug)
1299
+ const suitableField = Object.entries(newFields).find(
1300
+ ([fieldSlug, field]) => field.type === "string" && field.unique === true && field.required === true && ["slug", "handle"].includes(fieldSlug)
1270
1301
  );
1271
- copiedModel.identifiers.slug = suitableField?.slug || "id";
1302
+ copiedModel.identifiers.slug = suitableField?.[0] || "id";
1272
1303
  }
1273
1304
  }
1274
1305
  return copiedModel;
@@ -1276,29 +1307,32 @@ var addDefaultModelAttributes = (model, isNew) => {
1276
1307
  var addDefaultModelFields = (model, isNew) => {
1277
1308
  const copiedModel = { ...model };
1278
1309
  const existingFields = copiedModel.fields || [];
1279
- if (isNew || existingFields.length > 0) {
1280
- const additionalFields = getSystemFields(copiedModel.idPrefix).filter((newField) => {
1281
- return !existingFields.some(({ slug }) => slug === newField.slug);
1282
- });
1283
- copiedModel.fields = [...additionalFields, ...existingFields];
1310
+ if (isNew || Object.keys(existingFields).length > 0) {
1311
+ const additionalFields = Object.fromEntries(
1312
+ Object.entries(getSystemFields(copiedModel.idPrefix)).filter(([newFieldSlug]) => {
1313
+ return !Object.hasOwn(existingFields, newFieldSlug);
1314
+ })
1315
+ );
1316
+ copiedModel.fields = { ...additionalFields, ...existingFields };
1284
1317
  }
1285
1318
  return copiedModel;
1286
1319
  };
1287
1320
  var addDefaultModelPresets = (list, model) => {
1288
- const defaultPresets = [];
1289
- for (const field of model.fields || []) {
1290
- if (field.type === "link" && !field.slug.startsWith("ronin.")) {
1321
+ const defaultPresets = {};
1322
+ for (const [fieldSlug, rest] of Object.entries(model.fields || {})) {
1323
+ const field = { slug: fieldSlug, ...rest };
1324
+ if (field.type === "link" && !fieldSlug.startsWith("ronin.")) {
1291
1325
  const targetModel = getModelBySlug(list, field.target);
1292
1326
  if (field.kind === "many") {
1293
1327
  const systemModel = list.find(({ system }) => {
1294
1328
  return system?.model === model.id && system?.associationSlug === field.slug;
1295
1329
  });
1296
1330
  if (!systemModel) continue;
1297
- const preset = {
1331
+ const preset2 = {
1298
1332
  instructions: {
1299
1333
  // Perform a LEFT JOIN that adds the associative table.
1300
1334
  including: {
1301
- [field.slug]: {
1335
+ [fieldSlug]: {
1302
1336
  [QUERY_SYMBOLS.QUERY]: {
1303
1337
  get: {
1304
1338
  [systemModel.pluralSlug]: {
@@ -1329,16 +1363,15 @@ var addDefaultModelPresets = (list, model) => {
1329
1363
  }
1330
1364
  }
1331
1365
  }
1332
- },
1333
- slug: field.slug
1366
+ }
1334
1367
  };
1335
- defaultPresets.push(preset);
1368
+ defaultPresets[fieldSlug] = preset2;
1336
1369
  continue;
1337
1370
  }
1338
- defaultPresets.push({
1371
+ const preset = {
1339
1372
  instructions: {
1340
1373
  including: {
1341
- [field.slug]: {
1374
+ [fieldSlug]: {
1342
1375
  [QUERY_SYMBOLS.QUERY]: {
1343
1376
  get: {
1344
1377
  [targetModel.slug]: {
@@ -1354,24 +1387,24 @@ var addDefaultModelPresets = (list, model) => {
1354
1387
  }
1355
1388
  }
1356
1389
  }
1357
- },
1358
- slug: field.slug
1359
- });
1390
+ }
1391
+ };
1392
+ defaultPresets[fieldSlug] = preset;
1360
1393
  }
1361
1394
  }
1362
1395
  const childModels = list.map((subModel) => {
1363
1396
  if (subModel.system?.associationSlug) return null;
1364
- const field = subModel.fields?.find((field2) => {
1397
+ const field = Object.entries(subModel.fields).find(([_, field2]) => {
1365
1398
  return field2.type === "link" && field2.target === model.slug;
1366
1399
  });
1367
1400
  if (!field) return null;
1368
- return { model: subModel, field };
1401
+ return { model: subModel, field: { slug: field[0], ...field[1] } };
1369
1402
  }).filter((match) => match !== null);
1370
1403
  for (const childMatch of childModels) {
1371
1404
  const { model: childModel, field: childField } = childMatch;
1372
1405
  const pluralSlug = childModel.pluralSlug;
1373
1406
  const presetSlug = childModel.system?.associationSlug || pluralSlug;
1374
- defaultPresets.push({
1407
+ const preset = {
1375
1408
  instructions: {
1376
1409
  including: {
1377
1410
  [presetSlug]: {
@@ -1388,16 +1421,18 @@ var addDefaultModelPresets = (list, model) => {
1388
1421
  }
1389
1422
  }
1390
1423
  }
1391
- },
1392
- slug: presetSlug
1393
- });
1424
+ }
1425
+ };
1426
+ defaultPresets[presetSlug] = preset;
1394
1427
  }
1395
- if (defaultPresets.length > 0) {
1396
- const existingPresets = model.presets || [];
1397
- const additionalPresets = defaultPresets.filter((newPreset) => {
1398
- return !existingPresets.some(({ slug }) => slug === newPreset.slug);
1399
- });
1400
- model.presets = [...additionalPresets, ...existingPresets];
1428
+ if (Object.keys(defaultPresets).length > 0) {
1429
+ const existingPresets = model.presets;
1430
+ const additionalPresets = Object.fromEntries(
1431
+ Object.entries(defaultPresets).filter(([newPresetSlug]) => {
1432
+ return !existingPresets?.[newPresetSlug];
1433
+ })
1434
+ );
1435
+ model.presets = { ...additionalPresets, ...existingPresets };
1401
1436
  }
1402
1437
  return model;
1403
1438
  };
@@ -1429,7 +1464,12 @@ function getFieldFromModel(model, fieldPath, source, shouldThrow = true) {
1429
1464
  const writingField = "instructionName" in source ? source.instructionName === "to" : true;
1430
1465
  const errorTarget = "instructionName" in source ? `\`${source.instructionName}\`` : `${source.modelEntityType} "${source.modelEntityName}"`;
1431
1466
  const errorPrefix = `Field "${fieldPath}" defined for ${errorTarget}`;
1432
- const modelFields = model.fields || [];
1467
+ const modelFields = Object.entries(model.fields).map(
1468
+ ([fieldSlug, field]) => ({
1469
+ slug: fieldSlug,
1470
+ ...field
1471
+ })
1472
+ );
1433
1473
  let modelField;
1434
1474
  if (fieldPath.includes(".")) {
1435
1475
  modelField = modelFields.find((field) => field.slug === fieldPath.split(".")[0]);
@@ -1453,41 +1493,36 @@ function getFieldFromModel(model, fieldPath, source, shouldThrow = true) {
1453
1493
  const fieldSelector = getFieldSelector(model, modelField, fieldPath, writingField);
1454
1494
  return { field: modelField, fieldSelector };
1455
1495
  }
1456
- var getSystemFields = (idPrefix) => [
1457
- {
1496
+ var getSystemFields = (idPrefix) => ({
1497
+ id: {
1458
1498
  name: "ID",
1459
1499
  type: "string",
1460
1500
  slug: "id",
1461
- defaultValue: {
1462
- // Since default values in SQLite cannot rely on other columns, we unfortunately
1463
- // cannot rely on the `idPrefix` column here. Instead, we need to inject it directly
1464
- // into the expression as a static string.
1465
- [QUERY_SYMBOLS.EXPRESSION]: `'${idPrefix}_' || lower(substr(hex(randomblob(12)), 1, 16))`
1466
- }
1501
+ defaultValue: ID_EXPRESSION(idPrefix)
1467
1502
  },
1468
- {
1503
+ "ronin.createdAt": {
1469
1504
  name: "RONIN - Created At",
1470
1505
  type: "date",
1471
1506
  slug: "ronin.createdAt",
1472
1507
  defaultValue: CURRENT_TIME_EXPRESSION
1473
1508
  },
1474
- {
1509
+ "ronin.createdBy": {
1475
1510
  name: "RONIN - Created By",
1476
1511
  type: "string",
1477
1512
  slug: "ronin.createdBy"
1478
1513
  },
1479
- {
1514
+ "ronin.updatedAt": {
1480
1515
  name: "RONIN - Updated At",
1481
1516
  type: "date",
1482
1517
  slug: "ronin.updatedAt",
1483
1518
  defaultValue: CURRENT_TIME_EXPRESSION
1484
1519
  },
1485
- {
1520
+ "ronin.updatedBy": {
1486
1521
  name: "RONIN - Updated By",
1487
1522
  type: "string",
1488
1523
  slug: "ronin.updatedBy"
1489
1524
  }
1490
- ];
1525
+ });
1491
1526
  var ROOT_MODEL = {
1492
1527
  slug: "model",
1493
1528
  identifiers: {
@@ -1498,43 +1533,43 @@ var ROOT_MODEL = {
1498
1533
  table: "ronin_schema",
1499
1534
  // Indicates that the model was automatically generated by RONIN.
1500
1535
  system: { model: "root" },
1501
- fields: [
1502
- { slug: "name", type: "string" },
1503
- { slug: "pluralName", type: "string" },
1504
- { slug: "slug", type: "string" },
1505
- { slug: "pluralSlug", type: "string" },
1506
- { slug: "idPrefix", type: "string" },
1507
- { slug: "table", type: "string" },
1508
- { slug: "identifiers.name", type: "string" },
1509
- { slug: "identifiers.slug", type: "string" },
1536
+ fields: {
1537
+ name: { type: "string" },
1538
+ pluralName: { type: "string" },
1539
+ slug: { type: "string" },
1540
+ pluralSlug: { type: "string" },
1541
+ idPrefix: { type: "string" },
1542
+ table: { type: "string" },
1543
+ "identifiers.name": { type: "string" },
1544
+ "identifiers.slug": { type: "string" },
1510
1545
  // Providing an empty object as a default value allows us to use `json_insert`
1511
1546
  // without needing to fall back to an empty object in the insertion statement,
1512
1547
  // which makes the statement shorter.
1513
- { slug: "fields", type: "json", defaultValue: "{}" },
1514
- { slug: "indexes", type: "json", defaultValue: "{}" },
1515
- { slug: "triggers", type: "json", defaultValue: "{}" },
1516
- { slug: "presets", type: "json", defaultValue: "{}" }
1517
- ]
1548
+ fields: { type: "json", defaultValue: "{}" },
1549
+ indexes: { type: "json", defaultValue: "{}" },
1550
+ triggers: { type: "json", defaultValue: "{}" },
1551
+ presets: { type: "json", defaultValue: "{}" }
1552
+ }
1518
1553
  };
1519
1554
  var ROOT_MODEL_WITH_ATTRIBUTES = addDefaultModelAttributes(ROOT_MODEL, true);
1520
1555
  var getSystemModels = (models, model) => {
1521
1556
  const addedModels = [];
1522
- for (const field of model.fields || []) {
1523
- if (field.type === "link" && !field.slug.startsWith("ronin.")) {
1557
+ for (const [fieldSlug, rest] of Object.entries(model.fields || {})) {
1558
+ const field = { slug: fieldSlug, ...rest };
1559
+ if (field.type === "link" && !fieldSlug.startsWith("ronin.")) {
1524
1560
  const relatedModel = getModelBySlug(models, field.target);
1525
- let fieldSlug = relatedModel.slug;
1561
+ let fieldSlug2 = relatedModel.slug;
1526
1562
  if (field.kind === "many") {
1527
- fieldSlug = composeAssociationModelSlug(model, field);
1563
+ fieldSlug2 = composeAssociationModelSlug(model, field);
1528
1564
  addedModels.push({
1529
- pluralSlug: fieldSlug,
1530
- slug: fieldSlug,
1565
+ pluralSlug: fieldSlug2,
1566
+ slug: fieldSlug2,
1531
1567
  system: {
1532
1568
  model: model.id,
1533
1569
  associationSlug: field.slug
1534
1570
  },
1535
- fields: [
1536
- {
1537
- slug: "source",
1571
+ fields: {
1572
+ source: {
1538
1573
  type: "link",
1539
1574
  target: model.slug,
1540
1575
  actions: {
@@ -1542,8 +1577,7 @@ var getSystemModels = (models, model) => {
1542
1577
  onUpdate: "CASCADE"
1543
1578
  }
1544
1579
  },
1545
- {
1546
- slug: "target",
1580
+ target: {
1547
1581
  type: "link",
1548
1582
  target: relatedModel.slug,
1549
1583
  actions: {
@@ -1551,7 +1585,7 @@ var getSystemModels = (models, model) => {
1551
1585
  onUpdate: "CASCADE"
1552
1586
  }
1553
1587
  }
1554
- ]
1588
+ }
1555
1589
  });
1556
1590
  }
1557
1591
  }
@@ -1615,14 +1649,7 @@ var PLURAL_MODEL_ENTITIES = {
1615
1649
  preset: "presets"
1616
1650
  };
1617
1651
  var PLURAL_MODEL_ENTITIES_VALUES = Object.values(PLURAL_MODEL_ENTITIES);
1618
- var formatModelEntity = (type, entities) => {
1619
- const entries = entities?.map((entity) => {
1620
- const { slug, ...rest } = "slug" in entity ? entity : { slug: `${type}Slug`, ...entity };
1621
- return [slug, rest];
1622
- });
1623
- return entries ? Object.fromEntries(entries) : void 0;
1624
- };
1625
- var handleSystemModel = (models, dependencyStatements, action, systemModel, newModel) => {
1652
+ var handleSystemModel = (models, dependencyStatements, action, inlineDefaults, systemModel, newModel) => {
1626
1653
  const { system: _, ...systemModelClean } = systemModel;
1627
1654
  const query = {
1628
1655
  [action]: { model: action === "create" ? systemModelClean : systemModelClean.slug }
@@ -1631,10 +1658,10 @@ var handleSystemModel = (models, dependencyStatements, action, systemModel, newM
1631
1658
  const { system: _2, ...newModelClean } = newModel;
1632
1659
  query.alter.to = newModelClean;
1633
1660
  }
1634
- const statement = compileQueryInput(query, models, []);
1661
+ const statement = compileQueryInput(query, models, [], { inlineDefaults });
1635
1662
  dependencyStatements.push(...statement.dependencies);
1636
1663
  };
1637
- var handleSystemModels = (models, dependencyStatements, previousModel, newModel) => {
1664
+ var handleSystemModels = (models, dependencyStatements, previousModel, newModel, inlineDefaults) => {
1638
1665
  const currentSystemModels = models.filter(({ system }) => {
1639
1666
  return system?.model === newModel.id;
1640
1667
  });
@@ -1644,11 +1671,11 @@ var handleSystemModels = (models, dependencyStatements, previousModel, newModel)
1644
1671
  oldSystemModel.system?.model === newSystemModel.system?.model
1645
1672
  ];
1646
1673
  if (oldSystemModel.system?.associationSlug) {
1647
- const oldFieldIndex = previousModel.fields.findIndex((item) => {
1648
- return item.slug === newSystemModel.system?.associationSlug;
1674
+ const oldFieldIndex = Object.keys(previousModel.fields).findIndex((slug) => {
1675
+ return slug === newSystemModel.system?.associationSlug;
1649
1676
  });
1650
- const newFieldIndex = newModel.fields.findIndex((item) => {
1651
- return item.slug === oldSystemModel.system?.associationSlug;
1677
+ const newFieldIndex = Object.keys(newModel.fields).findIndex((slug) => {
1678
+ return slug === oldSystemModel.system?.associationSlug;
1652
1679
  });
1653
1680
  conditions.push(oldFieldIndex === newFieldIndex);
1654
1681
  }
@@ -1658,19 +1685,32 @@ var handleSystemModels = (models, dependencyStatements, previousModel, newModel)
1658
1685
  const exists = newSystemModels.find(matchSystemModels.bind(null, systemModel));
1659
1686
  if (exists) {
1660
1687
  if (exists.slug !== systemModel.slug) {
1661
- handleSystemModel(models, dependencyStatements, "alter", systemModel, exists);
1688
+ handleSystemModel(
1689
+ models,
1690
+ dependencyStatements,
1691
+ "alter",
1692
+ inlineDefaults,
1693
+ systemModel,
1694
+ exists
1695
+ );
1662
1696
  }
1663
1697
  continue;
1664
1698
  }
1665
- handleSystemModel(models, dependencyStatements, "drop", systemModel);
1699
+ handleSystemModel(models, dependencyStatements, "drop", inlineDefaults, systemModel);
1666
1700
  }
1667
1701
  for (const systemModel of newSystemModels) {
1668
1702
  const exists = currentSystemModels.find(matchSystemModels.bind(null, systemModel));
1669
1703
  if (exists) continue;
1670
- handleSystemModel(models, dependencyStatements, "create", systemModel);
1704
+ handleSystemModel(
1705
+ models,
1706
+ dependencyStatements,
1707
+ "create",
1708
+ inlineDefaults,
1709
+ systemModel
1710
+ );
1671
1711
  }
1672
1712
  };
1673
- var transformMetaQuery = (models, dependencyStatements, statementParams, query) => {
1713
+ var transformMetaQuery = (models, dependencyStatements, statementParams, query, options) => {
1674
1714
  const { queryType } = splitQuery(query);
1675
1715
  const subAltering = "alter" in query && query.alter && !("to" in query.alter);
1676
1716
  const action = subAltering && query.alter ? Object.keys(query.alter).filter((key) => key !== "model")[0] : queryType;
@@ -1691,7 +1731,7 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1691
1731
  slug = query.alter[action][entity];
1692
1732
  if ("create" in query.alter) {
1693
1733
  const item = query.alter.create[entity];
1694
- slug = item.slug || `${entity}Slug`;
1734
+ slug = item.slug;
1695
1735
  jsonValue = { slug, ...item };
1696
1736
  }
1697
1737
  if ("alter" in query.alter && query.alter.alter) jsonValue = query.alter.alter.to;
@@ -1709,20 +1749,24 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1709
1749
  [...models, modelWithFields],
1710
1750
  modelWithFields
1711
1751
  );
1712
- modelWithPresets.fields = modelWithPresets.fields.map((field2) => ({
1713
- ...field2,
1714
- // Default field type.
1715
- type: field2.type || "string",
1716
- // Default field name.
1717
- name: field2.name || slugToName(field2.slug)
1718
- }));
1719
- const columns = modelWithPresets.fields.map((field2) => getFieldStatement(models, modelWithPresets, field2)).filter(Boolean);
1720
- const entities = Object.fromEntries(
1721
- Object.entries(PLURAL_MODEL_ENTITIES).map(([type, pluralType2]) => {
1722
- const list = modelWithPresets[pluralType2];
1723
- return [pluralType2, formatModelEntity(type, list)];
1724
- })
1752
+ modelWithPresets.fields = Object.fromEntries(
1753
+ Object.entries(modelWithPresets.fields).map(([fieldSlug, rest]) => [
1754
+ fieldSlug,
1755
+ {
1756
+ ...rest,
1757
+ // Default field type.
1758
+ type: rest.type || "string",
1759
+ // Default field name.
1760
+ name: rest.name || slugToName(fieldSlug)
1761
+ }
1762
+ ])
1725
1763
  );
1764
+ const columns = Object.entries(modelWithPresets.fields).map(
1765
+ ([fieldSlug, rest]) => getFieldStatement(models, modelWithPresets, {
1766
+ slug: fieldSlug,
1767
+ ...rest
1768
+ })
1769
+ ).filter(Boolean);
1726
1770
  models.push(modelWithPresets);
1727
1771
  dependencyStatements.push({
1728
1772
  statement: `CREATE TABLE "${modelWithPresets.table}" (${columns.join(", ")})`,
@@ -1732,28 +1776,35 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1732
1776
  ["index", "indexes"],
1733
1777
  ["trigger", "triggers"]
1734
1778
  ]) {
1735
- const entityValue = modelWithPresets[pluralModelEntity];
1736
- if (!entityValue) continue;
1737
- for (const item of entityValue) {
1779
+ const entityList = modelWithPresets[pluralModelEntity];
1780
+ if (!entityList) continue;
1781
+ for (const [itemSlug, item] of Object.entries(entityList)) {
1738
1782
  const query2 = {
1739
1783
  alter: {
1740
1784
  model: modelWithPresets.slug,
1741
1785
  create: {
1742
- [modelEntity]: item
1786
+ [modelEntity]: { slug: itemSlug, ...item }
1743
1787
  }
1744
1788
  }
1745
1789
  };
1746
- transformMetaQuery(models, dependencyStatements, null, query2);
1790
+ const tempModels = [
1791
+ ...models.filter((model2) => model2.slug !== modelWithPresets.slug),
1792
+ { slug: modelWithPresets.slug, fields: modelWithPresets.fields }
1793
+ ];
1794
+ transformMetaQuery(tempModels, dependencyStatements, null, query2, {
1795
+ inlineDefaults: options.inlineDefaults
1796
+ });
1747
1797
  }
1748
1798
  }
1749
- const modelWithObjects = Object.assign({}, modelWithPresets);
1750
- for (const entity2 in entities) {
1751
- if (!Object.hasOwn(entities, entity2)) continue;
1752
- Object.defineProperty(modelWithObjects, entity2, { value: entities[entity2] });
1753
- }
1754
- queryTypeDetails = { with: modelWithObjects };
1799
+ queryTypeDetails = { with: modelWithPresets };
1755
1800
  getSystemModels(models, modelWithPresets).map((systemModel) => {
1756
- return handleSystemModel(models, dependencyStatements, "create", systemModel);
1801
+ return handleSystemModel(
1802
+ models,
1803
+ dependencyStatements,
1804
+ "create",
1805
+ options.inlineDefaults,
1806
+ systemModel
1807
+ );
1757
1808
  });
1758
1809
  }
1759
1810
  if (action === "alter" && model) {
@@ -1776,14 +1827,26 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1776
1827
  },
1777
1828
  to: modelWithPresets
1778
1829
  };
1779
- handleSystemModels(models, dependencyStatements, modelBeforeUpdate2, model);
1830
+ handleSystemModels(
1831
+ models,
1832
+ dependencyStatements,
1833
+ modelBeforeUpdate2,
1834
+ model,
1835
+ options.inlineDefaults
1836
+ );
1780
1837
  }
1781
1838
  if (action === "drop" && model) {
1782
1839
  models.splice(models.indexOf(model), 1);
1783
1840
  dependencyStatements.push({ statement: `DROP TABLE "${model.table}"`, params: [] });
1784
1841
  queryTypeDetails = { with: { slug } };
1785
1842
  models.filter(({ system }) => system?.model === model.id).map((systemModel) => {
1786
- return handleSystemModel(models, dependencyStatements, "drop", systemModel);
1843
+ return handleSystemModel(
1844
+ models,
1845
+ dependencyStatements,
1846
+ "drop",
1847
+ options.inlineDefaults,
1848
+ systemModel
1849
+ );
1787
1850
  });
1788
1851
  }
1789
1852
  const modelSlug2 = "to" in queryTypeDetails ? queryTypeDetails?.to?.slug : "with" in queryTypeDetails ? queryTypeDetails?.with?.slug : void 0;
@@ -1798,16 +1861,13 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1798
1861
  const modelBeforeUpdate = structuredClone(model);
1799
1862
  const existingModel = model;
1800
1863
  const pluralType = PLURAL_MODEL_ENTITIES[entity];
1801
- const targetEntityIndex = existingModel[pluralType]?.findIndex(
1802
- (entity2) => entity2.slug === slug
1803
- );
1804
- if ((action === "alter" || action === "drop") && (typeof targetEntityIndex === "undefined" || targetEntityIndex === -1)) {
1864
+ const existingEntity = existingModel[pluralType]?.[slug];
1865
+ if ((action === "alter" || action === "drop") && !existingEntity) {
1805
1866
  throw new RoninError({
1806
1867
  message: `No ${entity} with slug "${slug}" defined in model "${existingModel.name}".`,
1807
1868
  code: MODEL_ENTITY_ERROR_CODES[entity]
1808
1869
  });
1809
1870
  }
1810
- const existingEntity = existingModel[pluralType]?.[targetEntityIndex];
1811
1871
  if (action === "create" && existingEntity) {
1812
1872
  throw new RoninError({
1813
1873
  message: `A ${entity} with the slug "${slug}" already exists.`,
@@ -1844,7 +1904,7 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1844
1904
  }
1845
1905
  } else if (action === "drop" && !existingLinkField) {
1846
1906
  const systemFields = getSystemFields(existingModel.idPrefix);
1847
- const isSystemField = systemFields.some((field2) => field2.slug === slug);
1907
+ const isSystemField = slug in systemFields;
1848
1908
  if (isSystemField) {
1849
1909
  throw new RoninError({
1850
1910
  message: `The ${entity} "${slug}" is a system ${entity} and cannot be removed.`,
@@ -1931,7 +1991,8 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1931
1991
  const effectStatements = trigger.effects.map((effectQuery) => {
1932
1992
  return compileQueryInput(effectQuery, models, null, {
1933
1993
  returning: false,
1934
- parentModel: existingModel
1994
+ parentModel: existingModel,
1995
+ inlineDefaults: options.inlineDefaults
1935
1996
  }).main.statement;
1936
1997
  });
1937
1998
  statementParts.push("BEGIN");
@@ -1947,26 +2008,42 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
1947
2008
  case "create": {
1948
2009
  const value = prepareStatementValue(statementParams, jsonValue);
1949
2010
  json = `json_insert(${field}, '$.${slug}', ${value})`;
1950
- existingModel[pluralType] = [
1951
- ...existingModel[pluralType] || [],
1952
- jsonValue
1953
- ];
2011
+ if (!existingModel[pluralType]) existingModel[pluralType] = {};
2012
+ existingModel[pluralType][slug] = jsonValue;
1954
2013
  break;
1955
2014
  }
1956
2015
  case "alter": {
1957
- const value = prepareStatementValue(statementParams, jsonValue);
1958
- json = `json_set(${field}, '$.${slug}', json_patch(json_extract(${field}, '$.${slug}'), ${value}))`;
1959
- const targetEntity = existingModel[pluralType];
1960
- Object.assign(targetEntity[targetEntityIndex], jsonValue);
2016
+ const targetEntities = existingModel[pluralType];
2017
+ if (jsonValue?.slug && jsonValue.slug !== slug) {
2018
+ const { slug: newSlug, ...entityValue } = jsonValue;
2019
+ Object.defineProperty(
2020
+ targetEntities,
2021
+ newSlug,
2022
+ Object.getOwnPropertyDescriptor(targetEntities, slug)
2023
+ );
2024
+ delete targetEntities[slug];
2025
+ const value = prepareStatementValue(statementParams, entityValue);
2026
+ json = `json_insert(json_remove(${field}, '$.${slug}'), '$.${newSlug}', ${value})`;
2027
+ } else {
2028
+ Object.assign(targetEntities[slug], jsonValue);
2029
+ const value = prepareStatementValue(statementParams, jsonValue);
2030
+ json = `json_set(${field}, '$.${slug}', json_patch(json_extract(${field}, '$.${slug}'), ${value}))`;
2031
+ }
1961
2032
  break;
1962
2033
  }
1963
2034
  case "drop": {
1964
2035
  json = `json_remove(${field}, '$.${slug}')`;
1965
- const targetEntity = existingModel[pluralType];
1966
- targetEntity.splice(targetEntityIndex, 1);
2036
+ const targetEntities = existingModel[pluralType];
2037
+ delete targetEntities[slug];
1967
2038
  }
1968
2039
  }
1969
- handleSystemModels(models, dependencyStatements, modelBeforeUpdate, existingModel);
2040
+ handleSystemModels(
2041
+ models,
2042
+ dependencyStatements,
2043
+ modelBeforeUpdate,
2044
+ existingModel,
2045
+ options.inlineDefaults
2046
+ );
1970
2047
  return {
1971
2048
  set: {
1972
2049
  model: {
@@ -2029,7 +2106,9 @@ var Transaction = class {
2029
2106
  const { dependencies, main, selectedFields } = compileQueryInput(
2030
2107
  query,
2031
2108
  modelsWithPresets,
2032
- options?.inlineParams ? null : []
2109
+ options?.inlineParams ? null : [],
2110
+ // biome-ignore lint/complexity/useSimplifiedLogicExpression: This is needed.
2111
+ { inlineDefaults: options?.inlineDefaults || false }
2033
2112
  );
2034
2113
  const preDependencies = dependencies.filter(({ after }) => !after);
2035
2114
  const postDependencies = dependencies.map(({ after, ...rest }) => after ? rest : null).filter((item) => item != null);
@@ -2047,7 +2126,7 @@ var Transaction = class {
2047
2126
  this.models = modelsWithPresets;
2048
2127
  return statements;
2049
2128
  };
2050
- #formatRows(fields, rows, single, isMeta) {
2129
+ #formatRows(fields, rows, single) {
2051
2130
  const records = [];
2052
2131
  for (const row of rows) {
2053
2132
  const record = fields.reduce((acc, field, fieldIndex) => {
@@ -2060,11 +2139,6 @@ var Transaction = class {
2060
2139
  newValue = Boolean(newValue);
2061
2140
  }
2062
2141
  }
2063
- if (isMeta && PLURAL_MODEL_ENTITIES_VALUES.includes(newSlug)) {
2064
- newValue = newValue ? Object.entries(newValue).map(([slug, attributes]) => {
2065
- return { slug, ...attributes };
2066
- }) : [];
2067
- }
2068
2142
  const { parentField, parentIsArray } = (() => {
2069
2143
  const lastDotIndex = newSlug.lastIndexOf(".");
2070
2144
  if (lastDotIndex === -1) return { parentField: null };
@@ -2158,9 +2232,8 @@ var Transaction = class {
2158
2232
  };
2159
2233
  const { queryType, queryModel, queryInstructions } = splitQuery(query);
2160
2234
  const model = getModelBySlug(this.models, queryModel);
2161
- const isMeta = queryModel === "model" || queryModel === "models";
2162
2235
  const modelFields = Object.fromEntries(
2163
- model.fields.map((field) => [field.slug, field.type])
2236
+ Object.entries(model.fields).map(([slug, rest]) => [slug, rest.type])
2164
2237
  );
2165
2238
  if (queryType === "count") {
2166
2239
  return addResult({ amount: rows[0][0] });
@@ -2168,13 +2241,13 @@ var Transaction = class {
2168
2241
  const single = queryModel !== model.pluralSlug;
2169
2242
  if (single) {
2170
2243
  return addResult({
2171
- record: rows[0] ? this.#formatRows(selectedFields, rows, true, isMeta) : null,
2244
+ record: rows[0] ? this.#formatRows(selectedFields, rows, true) : null,
2172
2245
  modelFields
2173
2246
  });
2174
2247
  }
2175
2248
  const pageSize = queryInstructions?.limitedTo;
2176
2249
  const result = {
2177
- records: this.#formatRows(selectedFields, rows, false, isMeta),
2250
+ records: this.#formatRows(selectedFields, rows, false),
2178
2251
  modelFields
2179
2252
  };
2180
2253
  if (pageSize && result.records.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronin/compiler",
3
- "version": "0.16.5",
3
+ "version": "0.17.0-leo-ron-1099-experimental-373",
4
4
  "type": "module",
5
5
  "description": "Compiles RONIN queries to SQL statements.",
6
6
  "publishConfig": {