@ronin/compiler 0.10.1 → 0.10.2-leo-ron-1083-experimental-212
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 +19 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +76 -5
- package/package.json +1 -1
package/README.md
CHANGED
@@ -103,7 +103,25 @@ new Transaction(queries, {
|
|
103
103
|
// Instead of returning an array of parameters for every statement (which allows for
|
104
104
|
// preventing SQL injections), all parameters are inlined directly into the SQL strings.
|
105
105
|
// This option should only be used if the generated SQL will be manually verified.
|
106
|
-
inlineParams: true
|
106
|
+
inlineParams: true,
|
107
|
+
|
108
|
+
// By default, in the generated SQL statements, the compiler does not alias columns if
|
109
|
+
// multiple different tables with the same column names are being joined. Only the table
|
110
|
+
// names themselves are aliased.
|
111
|
+
//
|
112
|
+
// This ensures the cleanest possible SQL statements in conjunction with the default
|
113
|
+
// behavior of SQL databases, where the result of a statement is a list (array) of
|
114
|
+
// values, which are inherently not prone to conflicts.
|
115
|
+
//
|
116
|
+
// If the driver being used instead returns an object for every row, the driver must
|
117
|
+
// ensure the uniqueness of every key in that object, which means prefixing duplicated
|
118
|
+
// column names with the name of the respective table, if multiple tables are joined.
|
119
|
+
//
|
120
|
+
// Drivers that return objects for rows offer this behavior as an option that is
|
121
|
+
// usually called "expand columns". If the driver being used does not offer such an
|
122
|
+
// option, you can instead activate the option in the compiler, which results in longer
|
123
|
+
// SQL statements because any duplicated column name is aliased.
|
124
|
+
expandColumns: true
|
107
125
|
});
|
108
126
|
```
|
109
127
|
|
package/dist/index.d.ts
CHANGED
@@ -6005,13 +6005,22 @@ type AmountResult = {
|
|
6005
6005
|
};
|
6006
6006
|
type Result = SingleRecordResult | MultipleRecordResult | AmountResult;
|
6007
6007
|
|
6008
|
+
interface TransactionOptions {
|
6009
|
+
/** A list of models that already exist in the database. */
|
6010
|
+
models?: Array<PublicModel>;
|
6011
|
+
/**
|
6012
|
+
* Place statement parameters directly inside the statement strings instead of
|
6013
|
+
* separating them out into a dedicated `params` array.
|
6014
|
+
*/
|
6015
|
+
inlineParams?: boolean;
|
6016
|
+
/** Alias column names that are duplicated when joining multiple tables. */
|
6017
|
+
expandColumns?: boolean;
|
6018
|
+
}
|
6008
6019
|
declare class Transaction {
|
6009
6020
|
statements: Array<Statement>;
|
6010
6021
|
models: Array<Model>;
|
6011
6022
|
private queries;
|
6012
|
-
constructor(queries: Array<Query>, options?:
|
6013
|
-
models?: Array<PublicModel>;
|
6014
|
-
});
|
6023
|
+
constructor(queries: Array<Query>, options?: TransactionOptions);
|
6015
6024
|
/**
|
6016
6025
|
* Composes SQL statements for the provided RONIN queries.
|
6017
6026
|
*
|
package/dist/index.js
CHANGED
@@ -102,6 +102,9 @@ var expand = (obj) => {
|
|
102
102
|
return res;
|
103
103
|
}, {});
|
104
104
|
};
|
105
|
+
var getProperty = (obj, path) => {
|
106
|
+
return path.split(".").reduce((acc, key) => acc?.[key], obj);
|
107
|
+
};
|
105
108
|
var splitQuery = (query) => {
|
106
109
|
const queryType = Object.keys(query)[0];
|
107
110
|
const queryModel = Object.keys(query[queryType])[0];
|
@@ -939,9 +942,24 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query)
|
|
939
942
|
};
|
940
943
|
};
|
941
944
|
|
942
|
-
// src/
|
945
|
+
// src/utils/pagination.ts
|
943
946
|
var CURSOR_SEPARATOR = ",";
|
944
947
|
var CURSOR_NULL_PLACEHOLDER = "RONIN_NULL";
|
948
|
+
var generatePaginationCursor = (model, orderedBy, record) => {
|
949
|
+
const { ascending = [], descending = [] } = orderedBy || {};
|
950
|
+
const keys = [...ascending, ...descending];
|
951
|
+
if (keys.length === 0) keys.push("ronin.createdAt");
|
952
|
+
const cursors = keys.map((fieldSlug) => {
|
953
|
+
const property = getProperty(record, fieldSlug);
|
954
|
+
if (property === null || property === void 0) return CURSOR_NULL_PLACEHOLDER;
|
955
|
+
const { field } = getFieldFromModel(model, fieldSlug, "orderedBy");
|
956
|
+
if (field.type === "date") return new Date(property).getTime();
|
957
|
+
return property;
|
958
|
+
});
|
959
|
+
return cursors.map((cursor) => encodeURIComponent(String(cursor))).join(CURSOR_SEPARATOR);
|
960
|
+
};
|
961
|
+
|
962
|
+
// src/instructions/before-after.ts
|
945
963
|
var handleBeforeOrAfter = (model, statementParams, instructions) => {
|
946
964
|
if (!(instructions.before || instructions.after)) {
|
947
965
|
throw new RoninError({
|
@@ -1212,6 +1230,11 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
|
|
1212
1230
|
if (symbol?.type === "query") {
|
1213
1231
|
let { queryModel: subQueryModelSlug, queryInstructions: subQueryInstructions } = splitQuery(symbol.value);
|
1214
1232
|
const subQueryModel = getModelBySlug(models, subQueryModelSlug);
|
1233
|
+
if (subQueryInstructions?.selecting) {
|
1234
|
+
const currentFields = new Set(subQueryInstructions.selecting);
|
1235
|
+
currentFields.add("id");
|
1236
|
+
subQueryInstructions.selecting = Array.from(currentFields);
|
1237
|
+
}
|
1215
1238
|
const subQuerySelectedFields = subQueryInstructions?.selecting;
|
1216
1239
|
const subQueryIncludedFields = subQueryInstructions?.including;
|
1217
1240
|
const subQueryFields = [
|
@@ -1234,7 +1257,19 @@ var handleTo = (models, model, statementParams, queryType, dependencyStatements,
|
|
1234
1257
|
...subQueryInstructions.including
|
1235
1258
|
};
|
1236
1259
|
}
|
1237
|
-
|
1260
|
+
let statement2 = "";
|
1261
|
+
if (subQuerySelectedFields) {
|
1262
|
+
const selectedFields = [
|
1263
|
+
...subQueryFields,
|
1264
|
+
...defaultFieldsToAdd.map(([key]) => key)
|
1265
|
+
];
|
1266
|
+
const columns = selectedFields.map((field) => {
|
1267
|
+
return getFieldFromModel(model, field, "to").fieldSelector;
|
1268
|
+
});
|
1269
|
+
statement2 = `(${columns.join(", ")}) `;
|
1270
|
+
}
|
1271
|
+
statement2 += compileQueryInput(symbol.value, models, statementParams).main.statement;
|
1272
|
+
return statement2;
|
1238
1273
|
}
|
1239
1274
|
Object.assign(toInstruction, defaultFields);
|
1240
1275
|
for (const fieldSlug in toInstruction) {
|
@@ -1498,11 +1533,47 @@ var Transaction = class {
|
|
1498
1533
|
return expand(formattedRecord);
|
1499
1534
|
}
|
1500
1535
|
prepareResults(results) {
|
1501
|
-
|
1536
|
+
const relevantResults = results.filter((_, index) => {
|
1537
|
+
return this.statements[index].returning;
|
1538
|
+
});
|
1539
|
+
return relevantResults.map((result, index) => {
|
1502
1540
|
const query = this.queries.at(-index);
|
1503
|
-
const { queryModel } = splitQuery(query);
|
1541
|
+
const { queryType, queryModel, queryInstructions } = splitQuery(query);
|
1504
1542
|
const model = getModelBySlug(this.models, queryModel);
|
1505
|
-
|
1543
|
+
if (queryType === "count") {
|
1544
|
+
return { amount: result[0]["COUNT(*)"] };
|
1545
|
+
}
|
1546
|
+
const single = queryModel !== model.pluralSlug;
|
1547
|
+
if (single) {
|
1548
|
+
return { record: this.formatRecord(model, result[0]) };
|
1549
|
+
}
|
1550
|
+
const pageSize = queryInstructions?.limitedTo;
|
1551
|
+
const output = {
|
1552
|
+
records: result.map((resultItem) => {
|
1553
|
+
return this.formatRecord(model, resultItem);
|
1554
|
+
})
|
1555
|
+
};
|
1556
|
+
if (pageSize && output.records.length > 0) {
|
1557
|
+
if (queryInstructions?.before || queryInstructions?.after) {
|
1558
|
+
const direction = queryInstructions?.before ? "moreAfter" : "moreBefore";
|
1559
|
+
const firstRecord = output.records[0];
|
1560
|
+
output[direction] = generatePaginationCursor(
|
1561
|
+
model,
|
1562
|
+
queryInstructions.orderedBy,
|
1563
|
+
firstRecord
|
1564
|
+
);
|
1565
|
+
}
|
1566
|
+
if (output.records.length > pageSize) {
|
1567
|
+
const direction = queryInstructions?.before ? "moreBefore" : "moreAfter";
|
1568
|
+
const lastRecord = output.records.pop();
|
1569
|
+
output[direction] = generatePaginationCursor(
|
1570
|
+
model,
|
1571
|
+
queryInstructions.orderedBy,
|
1572
|
+
lastRecord
|
1573
|
+
);
|
1574
|
+
}
|
1575
|
+
}
|
1576
|
+
return output;
|
1506
1577
|
});
|
1507
1578
|
}
|
1508
1579
|
};
|