@ronin/compiler 0.10.3-leo-ron-1083-experimental-219 → 0.10.3-leo-ron-1083-experimental-221
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 +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +161 -107
- package/package.json +1 -1
package/README.md
CHANGED
@@ -65,9 +65,11 @@ Once the RONIN queries have been compiled down to SQL statements, the statements
|
|
65
65
|
executed and their results can be formatted by the compiler as well:
|
66
66
|
|
67
67
|
```typescript
|
68
|
-
// `
|
68
|
+
// Passing `rawResults` (rows being of arrays of values) provided by the database (ideal)
|
69
|
+
const results: Array<Result> = transaction.formatResults(rawResults);
|
69
70
|
|
70
|
-
|
71
|
+
// Passing `objectResults` (rows being of objects) provided by a driver
|
72
|
+
const results: Array<Result> = transaction.formatResults(objectResults, false);
|
71
73
|
```
|
72
74
|
|
73
75
|
#### Root Model
|
@@ -133,12 +135,13 @@ new Transaction(queries, {
|
|
133
135
|
//
|
134
136
|
// If the driver being used instead returns an object for every row, the driver must
|
135
137
|
// ensure the uniqueness of every key in that object, which means prefixing duplicated
|
136
|
-
// column names with the name of the respective table, if multiple tables are joined
|
138
|
+
// column names with the name of the respective table, if multiple tables are joined
|
139
|
+
// (example for an object key: "table_name.column_name").
|
137
140
|
//
|
138
141
|
// Drivers that return objects for rows offer this behavior as an option that is
|
139
142
|
// usually called "expand columns". If the driver being used does not offer such an
|
140
143
|
// option, you can instead activate the option in the compiler, which results in longer
|
141
|
-
// SQL statements because
|
144
|
+
// SQL statements because all column names are aliased.
|
142
145
|
expandColumns: true
|
143
146
|
});
|
144
147
|
```
|
package/dist/index.d.ts
CHANGED
@@ -5867,7 +5867,7 @@ type ModelFieldBasics = {
|
|
5867
5867
|
increment?: boolean;
|
5868
5868
|
};
|
5869
5869
|
type ModelFieldNormal = ModelFieldBasics & {
|
5870
|
-
type: 'string' | 'number' | 'boolean' | 'date' | 'json'
|
5870
|
+
type: 'string' | 'number' | 'boolean' | 'date' | 'json';
|
5871
5871
|
};
|
5872
5872
|
type ModelFieldReferenceAction = 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'SET DEFAULT' | 'NO ACTION';
|
5873
5873
|
type ModelFieldReference = ModelFieldBasics & {
|
@@ -5984,7 +5984,8 @@ type PublicModel<T extends Array<ModelField> = Array<ModelField>> = Omit<Partial
|
|
5984
5984
|
identifiers?: Partial<Model['identifiers']>;
|
5985
5985
|
};
|
5986
5986
|
|
5987
|
-
type
|
5987
|
+
type RawRow = Array<unknown>;
|
5988
|
+
type ObjectRow = Record<string, unknown>;
|
5988
5989
|
type NativeRecord = Record<string, unknown> & {
|
5989
5990
|
id: string;
|
5990
5991
|
ronin: {
|
@@ -6059,6 +6060,7 @@ declare class Transaction {
|
|
6059
6060
|
statements: Array<Statement>;
|
6060
6061
|
models: Array<Model>;
|
6061
6062
|
private queries;
|
6063
|
+
private fields;
|
6062
6064
|
constructor(queries: Array<Query>, options?: TransactionOptions);
|
6063
6065
|
/**
|
6064
6066
|
* Composes SQL statements for the provided RONIN queries.
|
@@ -6070,8 +6072,9 @@ declare class Transaction {
|
|
6070
6072
|
* @returns The composed SQL statements.
|
6071
6073
|
*/
|
6072
6074
|
private compileQueries;
|
6073
|
-
private
|
6074
|
-
|
6075
|
+
private formatRow;
|
6076
|
+
formatResults(results: Array<Array<RawRow>>, raw?: true): Array<Result>;
|
6077
|
+
formatResults(results: Array<Array<ObjectRow>>, raw?: false): Array<Result>;
|
6075
6078
|
}
|
6076
6079
|
|
6077
6080
|
declare const CLEAN_ROOT_MODEL: PublicModel;
|
package/dist/index.js
CHANGED
@@ -20,6 +20,7 @@ var RONIN_MODEL_FIELD_REGEX = new RegExp(
|
|
20
20
|
`${QUERY_SYMBOLS.FIELD}[_a-zA-Z0-9.]+`,
|
21
21
|
"g"
|
22
22
|
);
|
23
|
+
var composeIncludedTableAlias = (fieldSlug) => `including_${fieldSlug}`;
|
23
24
|
var MODEL_ENTITY_ERROR_CODES = {
|
24
25
|
field: "FIELD_NOT_FOUND",
|
25
26
|
index: "INDEX_NOT_FOUND",
|
@@ -117,7 +118,11 @@ var omit = (obj, properties) => Object.fromEntries(
|
|
117
118
|
var expand = (obj) => {
|
118
119
|
return Object.entries(obj).reduce((res, [key, val]) => {
|
119
120
|
key.split(".").reduce((acc, part, i, arr) => {
|
120
|
-
|
121
|
+
if (i === arr.length - 1) {
|
122
|
+
acc[part] = val;
|
123
|
+
} else {
|
124
|
+
acc[part] = typeof acc[part] === "object" && acc[part] !== null ? acc[part] : {};
|
125
|
+
}
|
121
126
|
return acc[part];
|
122
127
|
}, res);
|
123
128
|
return res;
|
@@ -208,47 +213,52 @@ var composeConditions = (models, model, statementParams, instructionName, value,
|
|
208
213
|
return conditions.join(" AND ");
|
209
214
|
}
|
210
215
|
if (options.fieldSlug) {
|
211
|
-
const
|
212
|
-
|
213
|
-
|
214
|
-
if (!
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
if (
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
216
|
+
const childField = model.fields.some(({ slug }) => {
|
217
|
+
return slug.includes(".") && slug.split(".")[0] === options.fieldSlug;
|
218
|
+
});
|
219
|
+
if (!childField) {
|
220
|
+
const fieldDetails = getFieldFromModel(model, options.fieldSlug, instructionName);
|
221
|
+
const { field: modelField } = fieldDetails || {};
|
222
|
+
const consumeJSON = modelField?.type === "json" && instructionName === "to";
|
223
|
+
if (modelField && !(isObject(value) || Array.isArray(value)) || getSymbol(value) || consumeJSON) {
|
224
|
+
return composeFieldValues(
|
225
|
+
models,
|
226
|
+
model,
|
227
|
+
statementParams,
|
228
|
+
instructionName,
|
229
|
+
value,
|
230
|
+
{ ...options, fieldSlug: options.fieldSlug }
|
231
|
+
);
|
232
|
+
}
|
233
|
+
if (modelField?.type === "link" && isNested) {
|
234
|
+
const keys = Object.keys(value);
|
235
|
+
const values = Object.values(value);
|
236
|
+
let recordTarget;
|
237
|
+
if (keys.length === 1 && keys[0] === "id") {
|
238
|
+
recordTarget = values[0];
|
239
|
+
} else {
|
240
|
+
const relatedModel = getModelBySlug(models, modelField.target);
|
241
|
+
const subQuery = {
|
242
|
+
get: {
|
243
|
+
[relatedModel.slug]: {
|
244
|
+
with: value,
|
245
|
+
selecting: ["id"]
|
246
|
+
}
|
237
247
|
}
|
238
|
-
}
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
}
|
248
|
+
};
|
249
|
+
recordTarget = {
|
250
|
+
[QUERY_SYMBOLS.QUERY]: subQuery
|
251
|
+
};
|
252
|
+
}
|
253
|
+
return composeConditions(
|
254
|
+
models,
|
255
|
+
model,
|
256
|
+
statementParams,
|
257
|
+
instructionName,
|
258
|
+
recordTarget,
|
259
|
+
options
|
260
|
+
);
|
243
261
|
}
|
244
|
-
return composeConditions(
|
245
|
-
models,
|
246
|
-
model,
|
247
|
-
statementParams,
|
248
|
-
instructionName,
|
249
|
-
recordTarget,
|
250
|
-
options
|
251
|
-
);
|
252
262
|
}
|
253
263
|
}
|
254
264
|
if (isNested) {
|
@@ -358,7 +368,7 @@ var getFieldSelector = (model, field, fieldPath, instructionName) => {
|
|
358
368
|
}
|
359
369
|
return `${tablePrefix}"${fieldPath}"`;
|
360
370
|
};
|
361
|
-
|
371
|
+
function getFieldFromModel(model, fieldPath, instructionName, shouldThrow = true) {
|
362
372
|
const errorPrefix = `Field "${fieldPath}" defined for \`${instructionName}\``;
|
363
373
|
const modelFields = model.fields || [];
|
364
374
|
let modelField;
|
@@ -376,16 +386,19 @@ var getFieldFromModel = (model, fieldPath, instructionName) => {
|
|
376
386
|
}
|
377
387
|
modelField = modelFields.find((field) => field.slug === fieldPath);
|
378
388
|
if (!modelField) {
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
389
|
+
if (shouldThrow) {
|
390
|
+
throw new RoninError({
|
391
|
+
message: `${errorPrefix} does not exist in model "${model.name}".`,
|
392
|
+
code: "FIELD_NOT_FOUND",
|
393
|
+
field: fieldPath,
|
394
|
+
queries: null
|
395
|
+
});
|
396
|
+
}
|
397
|
+
return null;
|
385
398
|
}
|
386
399
|
const fieldSelector = getFieldSelector(model, modelField, fieldPath, instructionName);
|
387
400
|
return { field: modelField, fieldSelector };
|
388
|
-
}
|
401
|
+
}
|
389
402
|
var slugToName = (slug) => {
|
390
403
|
const name = slug.replace(/([a-z])([A-Z])/g, "$1 $2");
|
391
404
|
return title(name);
|
@@ -441,11 +454,6 @@ var SYSTEM_FIELDS = [
|
|
441
454
|
slug: "id",
|
442
455
|
displayAs: "single-line"
|
443
456
|
},
|
444
|
-
{
|
445
|
-
name: "RONIN",
|
446
|
-
type: "group",
|
447
|
-
slug: "ronin"
|
448
|
-
},
|
449
457
|
{
|
450
458
|
name: "RONIN - Locked",
|
451
459
|
type: "boolean",
|
@@ -489,7 +497,6 @@ var ROOT_MODEL = {
|
|
489
497
|
{ slug: "pluralSlug", type: "string" },
|
490
498
|
{ slug: "idPrefix", type: "string" },
|
491
499
|
{ slug: "table", type: "string" },
|
492
|
-
{ slug: "identifiers", type: "group" },
|
493
500
|
{ slug: "identifiers.name", type: "string" },
|
494
501
|
{ slug: "identifiers.slug", type: "string" },
|
495
502
|
// Providing an empty object as a default value allows us to use `json_insert`
|
@@ -611,7 +618,6 @@ var typesInSQLite = {
|
|
611
618
|
json: "TEXT"
|
612
619
|
};
|
613
620
|
var getFieldStatement = (models, model, field) => {
|
614
|
-
if (field.type === "group") return null;
|
615
621
|
let statement = `"${field.slug}" ${typesInSQLite[field.type]}`;
|
616
622
|
if (field.slug === "id") statement += " PRIMARY KEY";
|
617
623
|
if (field.unique === true) statement += " UNIQUE";
|
@@ -1103,7 +1109,7 @@ var handleIncluding = (models, model, statementParams, instruction) => {
|
|
1103
1109
|
const relatedModel = getModelBySlug(models, queryModel);
|
1104
1110
|
let joinType = "LEFT";
|
1105
1111
|
let relatedTableSelector = `"${relatedModel.table}"`;
|
1106
|
-
const tableAlias =
|
1112
|
+
const tableAlias = composeIncludedTableAlias(ephemeralFieldSlug);
|
1107
1113
|
const single = queryModel !== relatedModel.pluralSlug;
|
1108
1114
|
if (!modifiableQueryInstructions?.with) {
|
1109
1115
|
joinType = "CROSS";
|
@@ -1185,49 +1191,69 @@ var handleOrderedBy = (model, instruction) => {
|
|
1185
1191
|
|
1186
1192
|
// src/instructions/selecting.ts
|
1187
1193
|
var handleSelecting = (models, model, statementParams, instructions, options) => {
|
1194
|
+
let loadedFields = [];
|
1195
|
+
let statement = "*";
|
1188
1196
|
let isJoining = false;
|
1189
|
-
let statement = instructions.selecting ? instructions.selecting.map((slug) => {
|
1190
|
-
return getFieldFromModel(model, slug, "selecting").fieldSelector;
|
1191
|
-
}).join(", ") : "*";
|
1192
1197
|
if (instructions.including) {
|
1193
1198
|
const flatObject = flatten(instructions.including);
|
1194
|
-
|
1199
|
+
instructions.including = {};
|
1200
|
+
for (const [key, value] of Object.entries(flatObject)) {
|
1195
1201
|
const symbol = getSymbol(value);
|
1196
1202
|
if (symbol?.type === "query") {
|
1197
1203
|
isJoining = true;
|
1198
|
-
|
1199
|
-
const
|
1200
|
-
const
|
1201
|
-
const
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
});
|
1204
|
+
const { queryModel, queryInstructions } = splitQuery(symbol.value);
|
1205
|
+
const subQueryModel = getModelBySlug(models, queryModel);
|
1206
|
+
const tableName = composeIncludedTableAlias(key);
|
1207
|
+
const queryModelFields = queryInstructions?.selecting ? subQueryModel.fields.filter((field) => {
|
1208
|
+
return queryInstructions.selecting?.includes(field.slug);
|
1209
|
+
}) : subQueryModel.fields;
|
1210
|
+
for (const field of queryModelFields) {
|
1211
|
+
loadedFields.push({ ...field, parentField: key });
|
1212
|
+
if (options?.expandColumns) {
|
1213
|
+
const newValue2 = parseFieldExpression(
|
1214
|
+
{ ...subQueryModel, tableAlias: tableName },
|
1215
|
+
"including",
|
1216
|
+
`${QUERY_SYMBOLS.FIELD}${field.slug}`
|
1217
|
+
);
|
1218
|
+
instructions.including[`${tableName}.${field.slug}`] = newValue2;
|
1219
|
+
}
|
1220
|
+
}
|
1221
|
+
continue;
|
1217
1222
|
}
|
1223
|
+
let newValue = value;
|
1218
1224
|
if (symbol?.type === "expression") {
|
1219
|
-
|
1225
|
+
newValue = `(${parseFieldExpression(model, "including", symbol.value)})`;
|
1220
1226
|
} else {
|
1221
|
-
|
1227
|
+
newValue = prepareStatementValue(statementParams, value);
|
1222
1228
|
}
|
1223
|
-
|
1224
|
-
}).filter((entry) => entry !== null).map((entry) => [entry.key, entry.value]);
|
1225
|
-
if (filteredObject.length > 0) {
|
1226
|
-
statement += ", ";
|
1227
|
-
statement += filteredObject.map(([key, value]) => `${value} as "${key}"`).join(", ");
|
1229
|
+
instructions.including[key] = newValue;
|
1228
1230
|
}
|
1229
1231
|
}
|
1230
|
-
|
1232
|
+
const expandColumns = isJoining && options?.expandColumns;
|
1233
|
+
if (expandColumns) {
|
1234
|
+
instructions.selecting = model.fields.map((field) => field.slug);
|
1235
|
+
}
|
1236
|
+
if (instructions.selecting) {
|
1237
|
+
const usableModel = expandColumns ? { ...model, tableAlias: model.tableAlias || model.table } : model;
|
1238
|
+
const selectedFields = [];
|
1239
|
+
statement = instructions.selecting.map((slug) => {
|
1240
|
+
const { field, fieldSelector } = getFieldFromModel(
|
1241
|
+
usableModel,
|
1242
|
+
slug,
|
1243
|
+
"selecting"
|
1244
|
+
);
|
1245
|
+
selectedFields.push(field);
|
1246
|
+
return fieldSelector;
|
1247
|
+
}).join(", ");
|
1248
|
+
loadedFields = [...selectedFields, ...loadedFields];
|
1249
|
+
} else {
|
1250
|
+
loadedFields = [...model.fields, ...loadedFields];
|
1251
|
+
}
|
1252
|
+
if (instructions.including && Object.keys(instructions.including).length > 0) {
|
1253
|
+
statement += ", ";
|
1254
|
+
statement += Object.entries(instructions.including).map(([key, value]) => `${value} as "${key}"`).join(", ");
|
1255
|
+
}
|
1256
|
+
return { columns: statement, isJoining, loadedFields };
|
1231
1257
|
};
|
1232
1258
|
|
1233
1259
|
// src/instructions/to.ts
|
@@ -1294,8 +1320,8 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
|
|
1294
1320
|
Object.assign(toInstruction, defaultFields);
|
1295
1321
|
for (const fieldSlug in toInstruction) {
|
1296
1322
|
const fieldValue = toInstruction[fieldSlug];
|
1297
|
-
const fieldDetails = getFieldFromModel(model, fieldSlug, "to");
|
1298
|
-
if (fieldDetails
|
1323
|
+
const fieldDetails = getFieldFromModel(model, fieldSlug, "to", false);
|
1324
|
+
if (fieldDetails?.field.type === "link" && fieldDetails.field.kind === "many") {
|
1299
1325
|
delete toInstruction[fieldSlug];
|
1300
1326
|
const associativeModelSlug = composeAssociationModelSlug(model, fieldDetails.field);
|
1301
1327
|
const composeStatement = (subQueryType, value) => {
|
@@ -1360,7 +1386,8 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
|
|
1360
1386
|
statementParams,
|
1361
1387
|
defaultQuery
|
1362
1388
|
);
|
1363
|
-
if (query === null)
|
1389
|
+
if (query === null)
|
1390
|
+
return { dependencies: [], main: dependencyStatements[0], loadedFields: [] };
|
1364
1391
|
const parsedQuery = splitQuery(query);
|
1365
1392
|
const { queryType, queryModel, queryInstructions } = parsedQuery;
|
1366
1393
|
const model = getModelBySlug(models, queryModel);
|
@@ -1370,7 +1397,7 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
|
|
1370
1397
|
if (instructions && Object.hasOwn(instructions, "for")) {
|
1371
1398
|
instructions = handleFor(model, instructions);
|
1372
1399
|
}
|
1373
|
-
const { columns, isJoining } = handleSelecting(
|
1400
|
+
const { columns, isJoining, loadedFields } = handleSelecting(
|
1374
1401
|
models,
|
1375
1402
|
model,
|
1376
1403
|
statementParams,
|
@@ -1499,7 +1526,8 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
|
|
1499
1526
|
if (returning) mainStatement.returning = true;
|
1500
1527
|
return {
|
1501
1528
|
dependencies: dependencyStatements,
|
1502
|
-
main: mainStatement
|
1529
|
+
main: mainStatement,
|
1530
|
+
loadedFields
|
1503
1531
|
};
|
1504
1532
|
};
|
1505
1533
|
|
@@ -1508,6 +1536,7 @@ var Transaction = class {
|
|
1508
1536
|
statements;
|
1509
1537
|
models = [];
|
1510
1538
|
queries;
|
1539
|
+
fields = [];
|
1511
1540
|
constructor(queries, options) {
|
1512
1541
|
const models = options?.models || [];
|
1513
1542
|
this.statements = this.compileQueries(queries, models, options);
|
@@ -1544,42 +1573,67 @@ var Transaction = class {
|
|
1544
1573
|
);
|
1545
1574
|
dependencyStatements.push(...result.dependencies);
|
1546
1575
|
mainStatements.push(result.main);
|
1576
|
+
this.fields.push(result.loadedFields);
|
1547
1577
|
}
|
1548
1578
|
this.models = modelListWithPresets;
|
1549
1579
|
return [...dependencyStatements, ...mainStatements];
|
1550
1580
|
};
|
1551
|
-
|
1552
|
-
const
|
1553
|
-
for (
|
1554
|
-
const
|
1581
|
+
formatRow(fields, row) {
|
1582
|
+
const record = {};
|
1583
|
+
for (let index = 0; index < row.length; index++) {
|
1584
|
+
const value = row[index];
|
1585
|
+
const field = fields[index];
|
1586
|
+
let newSlug = field.slug;
|
1587
|
+
let newValue = value;
|
1588
|
+
const parentFieldSlug = field.parentField;
|
1589
|
+
if (parentFieldSlug) {
|
1590
|
+
newSlug = `${parentFieldSlug}.${field.slug}`;
|
1591
|
+
}
|
1555
1592
|
if (field.type === "json") {
|
1556
|
-
|
1557
|
-
continue;
|
1593
|
+
newValue = JSON.parse(value);
|
1558
1594
|
}
|
1559
|
-
|
1595
|
+
record[newSlug] = newValue;
|
1560
1596
|
}
|
1561
|
-
return expand(
|
1597
|
+
return expand(record);
|
1562
1598
|
}
|
1563
|
-
|
1599
|
+
/**
|
1600
|
+
* Format the results returned from the database into RONIN records.
|
1601
|
+
*
|
1602
|
+
* @param results - A list of results from the database, where each result is an array
|
1603
|
+
* of rows.
|
1604
|
+
* @param raw - By default, rows are expected to be arrays of values, which is how SQL
|
1605
|
+
* databases return rows by default. If the driver being used returns rows as objects
|
1606
|
+
* instead, this option should be set to `false`.
|
1607
|
+
*
|
1608
|
+
* @returns A list of formatted RONIN results, where each result is either a single
|
1609
|
+
* RONIN record, an array of RONIN records, or a RONIN count result.
|
1610
|
+
*/
|
1611
|
+
formatResults(results, raw = true) {
|
1564
1612
|
const relevantResults = results.filter((_, index) => {
|
1565
1613
|
return this.statements[index].returning;
|
1566
1614
|
});
|
1567
|
-
|
1615
|
+
const normalizedResults = raw ? relevantResults : relevantResults.map((rows) => {
|
1616
|
+
return rows.map((row) => {
|
1617
|
+
if (Array.isArray(row)) return row;
|
1618
|
+
if (row["COUNT(*)"]) return [row["COUNT(*)"]];
|
1619
|
+
return Object.values(row);
|
1620
|
+
});
|
1621
|
+
});
|
1622
|
+
return normalizedResults.map((rows, index) => {
|
1568
1623
|
const query = this.queries.at(-index);
|
1624
|
+
const fields = this.fields.at(-index);
|
1569
1625
|
const { queryType, queryModel, queryInstructions } = splitQuery(query);
|
1570
1626
|
const model = getModelBySlug(this.models, queryModel);
|
1571
1627
|
if (queryType === "count") {
|
1572
|
-
return { amount:
|
1628
|
+
return { amount: rows[0][0] };
|
1573
1629
|
}
|
1574
1630
|
const single = queryModel !== model.pluralSlug;
|
1575
1631
|
if (single) {
|
1576
|
-
return { record: this.
|
1632
|
+
return { record: this.formatRow(fields, rows[0]) };
|
1577
1633
|
}
|
1578
1634
|
const pageSize = queryInstructions?.limitedTo;
|
1579
1635
|
const output = {
|
1580
|
-
records:
|
1581
|
-
return this.formatRecord(model, resultItem);
|
1582
|
-
})
|
1636
|
+
records: rows.map((row) => this.formatRow(fields, row))
|
1583
1637
|
};
|
1584
1638
|
if (pageSize && output.records.length > 0) {
|
1585
1639
|
if (queryInstructions?.before || queryInstructions?.after) {
|
package/package.json
CHANGED