@ronin/compiler 0.17.7 → 0.17.8-leo-ron-1099-experimental-396
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 +31 -2
- package/dist/index.js +129 -84
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
@@ -117,6 +117,14 @@ type AddQuery = Record<string, Omit<CombinedInstructions, 'with' | 'using'> & {
|
|
117
117
|
}>;
|
118
118
|
type RemoveQuery = Record<string, Omit<CombinedInstructions, 'to'>>;
|
119
119
|
type CountQuery = Record<string, Omit<CombinedInstructions, 'to'> | null>;
|
120
|
+
type AllQueryInstructions = {
|
121
|
+
for?: string;
|
122
|
+
};
|
123
|
+
type AllQuery = {
|
124
|
+
all: AllQueryInstructions | null;
|
125
|
+
};
|
126
|
+
type GetAllQuery = AllQuery;
|
127
|
+
type CountAllQuery = AllQuery;
|
120
128
|
type GetInstructions = Omit<CombinedInstructions, 'to'>;
|
121
129
|
type SetInstructions = Omit<CombinedInstructions, 'to'> & {
|
122
130
|
to: FieldSelector;
|
@@ -158,11 +166,11 @@ type DropQuery = {
|
|
158
166
|
model: string;
|
159
167
|
};
|
160
168
|
type Query = {
|
161
|
-
get?: GetQuery;
|
169
|
+
get?: GetQuery | GetAllQuery;
|
162
170
|
set?: SetQuery;
|
163
171
|
add?: AddQuery;
|
164
172
|
remove?: RemoveQuery;
|
165
|
-
count?: CountQuery;
|
173
|
+
count?: CountQuery | CountAllQuery;
|
166
174
|
create?: CreateQuery;
|
167
175
|
alter?: AlterQuery;
|
168
176
|
drop?: DropQuery;
|
@@ -261,6 +269,13 @@ type ModelField = ModelFieldBasics & ({
|
|
261
269
|
/** Whether the field should be related to one record, or many records. */
|
262
270
|
kind: 'many';
|
263
271
|
});
|
272
|
+
/** An extended version of `ModelField`, for internal use within the compiler. */
|
273
|
+
type InternalModelField = ModelField & {
|
274
|
+
/** The path on the final record where the value of the field should be mounted. */
|
275
|
+
mountingPath: string;
|
276
|
+
/** A custom value that was provided in the query, which is not stored in the DB. */
|
277
|
+
mountedValue?: unknown;
|
278
|
+
};
|
264
279
|
type ModelIndexField<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> = {
|
265
280
|
/** The collating sequence used for text placed inside the field. */
|
266
281
|
collation?: ModelFieldCollation;
|
@@ -415,6 +430,20 @@ declare class Transaction {
|
|
415
430
|
statements: Array<Statement>;
|
416
431
|
models: Array<Model>;
|
417
432
|
constructor(queries: Array<Query>, options?: TransactionOptions);
|
433
|
+
/**
|
434
|
+
* Formats an individual result of a query (each query has one individual result).
|
435
|
+
*
|
436
|
+
* @param queryType - The type of query that is being executed.
|
437
|
+
* @param queryInstructions - The instructions if the query that is being executed.
|
438
|
+
* @param model - The model for which the query is being executed.
|
439
|
+
* @param rows - The rows that were returned from the database for the query (in the
|
440
|
+
* form of an array containing arrays that contain strings).
|
441
|
+
* @param selectedFields - The model fields that were selected by the query.
|
442
|
+
* @param single - Whether a single or multiple records are being affected by the query.
|
443
|
+
*
|
444
|
+
* @returns A formatted RONIN result for a particular query.
|
445
|
+
*/
|
446
|
+
formatIndividualResult<RecordType>(queryType: QueryType, queryInstructions: CombinedInstructions, model: Model, rows: Array<Array<RawRow>>, selectedFields: Array<InternalModelField>, single: boolean): RegularResult<RecordType>;
|
418
447
|
formatResults<RecordType>(results: Array<Array<ObjectRow>>, raw?: false): Array<Result<RecordType>>;
|
419
448
|
formatResults<RecordType>(results: Array<Array<RawRow>>, raw?: true): Array<Result<RecordType>>;
|
420
449
|
}
|
package/dist/index.js
CHANGED
@@ -1035,7 +1035,11 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
|
|
1035
1035
|
}
|
1036
1036
|
);
|
1037
1037
|
if (query === null)
|
1038
|
-
return {
|
1038
|
+
return {
|
1039
|
+
dependencies: [],
|
1040
|
+
main: dependencyStatements[0],
|
1041
|
+
selectedFields: []
|
1042
|
+
};
|
1039
1043
|
const parsedQuery = splitQuery(query);
|
1040
1044
|
const { queryType, queryModel, queryInstructions } = parsedQuery;
|
1041
1045
|
const model = getModelBySlug(models, queryModel);
|
@@ -1719,7 +1723,7 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
|
|
1719
1723
|
const action = subAltering && query.alter ? Object.keys(query.alter).filter((key) => key !== "model")[0] : queryType;
|
1720
1724
|
const actionReadable = action === "create" ? "creating" : action === "alter" ? "altering" : "dropping";
|
1721
1725
|
const entity = subAltering && query.alter ? Object.keys(query.alter[action])[0] : "model";
|
1722
|
-
let slug = entity === "model" && action === "create" ? null : query[queryType].model;
|
1726
|
+
let slug = entity === "model" && action === "create" ? null : query[queryType] && "model" in query[queryType] ? query[queryType].model : null;
|
1723
1727
|
let modelSlug = slug;
|
1724
1728
|
let jsonValue;
|
1725
1729
|
if ("create" in query && query.create) {
|
@@ -2065,21 +2069,21 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
|
|
2065
2069
|
var Transaction = class {
|
2066
2070
|
statements = [];
|
2067
2071
|
models = [];
|
2068
|
-
#
|
2072
|
+
#internalQueries = [];
|
2069
2073
|
constructor(queries, options) {
|
2070
2074
|
const models = options?.models || [];
|
2071
|
-
this.#
|
2075
|
+
this.#internalQueries = queries.map((query) => ({ query, selectedFields: [] }));
|
2076
|
+
this.#compileQueries(models, options);
|
2072
2077
|
}
|
2073
2078
|
/**
|
2074
2079
|
* Composes SQL statements for the provided RONIN queries.
|
2075
2080
|
*
|
2076
|
-
* @param queries - The RONIN queries for which SQL statements should be composed.
|
2077
2081
|
* @param models - A list of models.
|
2078
2082
|
* @param options - Additional options to adjust the behavior of the statement generation.
|
2079
2083
|
*
|
2080
2084
|
* @returns The composed SQL statements.
|
2081
2085
|
*/
|
2082
|
-
#compileQueries = (
|
2086
|
+
#compileQueries = (models, options) => {
|
2083
2087
|
const modelsWithAttributes = models.map((model) => {
|
2084
2088
|
return addDefaultModelAttributes(model, true);
|
2085
2089
|
});
|
@@ -2095,19 +2099,33 @@ var Transaction = class {
|
|
2095
2099
|
return addDefaultModelPresets(modelsWithFields, model);
|
2096
2100
|
});
|
2097
2101
|
const statements = [];
|
2098
|
-
const expandedQueries =
|
2102
|
+
const expandedQueries = this.#internalQueries.flatMap(({ query }, expansionIndex) => {
|
2099
2103
|
const { queryType, queryModel, queryInstructions } = splitQuery(query);
|
2100
2104
|
if (queryModel === "all") {
|
2101
|
-
|
2105
|
+
const { for: forInstruction, ...restInstructions } = queryInstructions || {};
|
2106
|
+
let modelList = modelsWithAttributes;
|
2107
|
+
if (forInstruction) {
|
2108
|
+
const mainModel = getModelBySlug(modelsWithAttributes, forInstruction);
|
2109
|
+
modelList = Object.values(mainModel.fields || {}).filter((field) => field.type === "link").map((field) => {
|
2110
|
+
return modelsWithAttributes.find(
|
2111
|
+
(model) => model.slug === field.target
|
2112
|
+
);
|
2113
|
+
});
|
2114
|
+
}
|
2115
|
+
this.#internalQueries[expansionIndex].affectedModels = modelList.map(
|
2116
|
+
(model) => model.slug
|
2117
|
+
);
|
2118
|
+
return modelList.map((model) => {
|
2102
2119
|
const query2 = {
|
2103
|
-
[queryType]: { [model.pluralSlug]:
|
2120
|
+
[queryType]: { [model.pluralSlug]: restInstructions }
|
2104
2121
|
};
|
2105
2122
|
return { query: query2, expansionIndex };
|
2106
2123
|
});
|
2107
2124
|
}
|
2108
2125
|
return { query };
|
2109
2126
|
});
|
2110
|
-
for (
|
2127
|
+
for (let index = 0; index < expandedQueries.length; index++) {
|
2128
|
+
const { query, expansionIndex } = expandedQueries[index];
|
2111
2129
|
const { dependencies, main, selectedFields } = compileQueryInput(
|
2112
2130
|
query,
|
2113
2131
|
modelsWithPresets,
|
@@ -2119,14 +2137,8 @@ var Transaction = class {
|
|
2119
2137
|
const postDependencies = dependencies.map(({ after, ...rest }) => after ? rest : null).filter((item) => item != null);
|
2120
2138
|
const subStatements = [...preDependencies, main, ...postDependencies];
|
2121
2139
|
this.statements.push(...subStatements);
|
2122
|
-
|
2123
|
-
|
2124
|
-
...statement,
|
2125
|
-
query,
|
2126
|
-
selectedFields,
|
2127
|
-
expansionIndex
|
2128
|
-
}))
|
2129
|
-
);
|
2140
|
+
const queryIndex = typeof expansionIndex === "undefined" ? index : expansionIndex;
|
2141
|
+
this.#internalQueries[queryIndex].selectedFields = selectedFields;
|
2130
2142
|
}
|
2131
2143
|
this.models = modelsWithPresets;
|
2132
2144
|
return statements;
|
@@ -2200,6 +2212,68 @@ var Transaction = class {
|
|
2200
2212
|
}
|
2201
2213
|
return single ? records[0] : records;
|
2202
2214
|
}
|
2215
|
+
/**
|
2216
|
+
* Formats an individual result of a query (each query has one individual result).
|
2217
|
+
*
|
2218
|
+
* @param queryType - The type of query that is being executed.
|
2219
|
+
* @param queryInstructions - The instructions if the query that is being executed.
|
2220
|
+
* @param model - The model for which the query is being executed.
|
2221
|
+
* @param rows - The rows that were returned from the database for the query (in the
|
2222
|
+
* form of an array containing arrays that contain strings).
|
2223
|
+
* @param selectedFields - The model fields that were selected by the query.
|
2224
|
+
* @param single - Whether a single or multiple records are being affected by the query.
|
2225
|
+
*
|
2226
|
+
* @returns A formatted RONIN result for a particular query.
|
2227
|
+
*/
|
2228
|
+
formatIndividualResult(queryType, queryInstructions, model, rows, selectedFields, single) {
|
2229
|
+
const modelFields = Object.fromEntries(
|
2230
|
+
Object.entries(model.fields).map(([slug, rest]) => [slug, rest.type])
|
2231
|
+
);
|
2232
|
+
if (queryType === "count") {
|
2233
|
+
return { amount: rows[0][0] };
|
2234
|
+
}
|
2235
|
+
if (single) {
|
2236
|
+
return {
|
2237
|
+
record: rows[0] ? this.#formatRows(selectedFields, rows, true) : null,
|
2238
|
+
modelFields
|
2239
|
+
};
|
2240
|
+
}
|
2241
|
+
const pageSize = queryInstructions?.limitedTo;
|
2242
|
+
const result = {
|
2243
|
+
records: this.#formatRows(selectedFields, rows, false),
|
2244
|
+
modelFields
|
2245
|
+
};
|
2246
|
+
if (pageSize && result.records.length > 0) {
|
2247
|
+
if (result.records.length > pageSize) {
|
2248
|
+
if (queryInstructions?.before) {
|
2249
|
+
result.records.shift();
|
2250
|
+
} else {
|
2251
|
+
result.records.pop();
|
2252
|
+
}
|
2253
|
+
const direction = queryInstructions?.before ? "moreBefore" : "moreAfter";
|
2254
|
+
const lastRecord = result.records.at(
|
2255
|
+
direction === "moreAfter" ? -1 : 0
|
2256
|
+
);
|
2257
|
+
result[direction] = generatePaginationCursor(
|
2258
|
+
model,
|
2259
|
+
queryInstructions.orderedBy,
|
2260
|
+
lastRecord
|
2261
|
+
);
|
2262
|
+
}
|
2263
|
+
if (queryInstructions?.before || queryInstructions?.after) {
|
2264
|
+
const direction = queryInstructions?.before ? "moreAfter" : "moreBefore";
|
2265
|
+
const firstRecord = result.records.at(
|
2266
|
+
direction === "moreAfter" ? -1 : 0
|
2267
|
+
);
|
2268
|
+
result[direction] = generatePaginationCursor(
|
2269
|
+
model,
|
2270
|
+
queryInstructions.orderedBy,
|
2271
|
+
firstRecord
|
2272
|
+
);
|
2273
|
+
}
|
2274
|
+
}
|
2275
|
+
return result;
|
2276
|
+
}
|
2203
2277
|
/**
|
2204
2278
|
* Format the results returned from the database into RONIN records.
|
2205
2279
|
*
|
@@ -2213,78 +2287,49 @@ var Transaction = class {
|
|
2213
2287
|
* RONIN record, an array of RONIN records, or a RONIN count result.
|
2214
2288
|
*/
|
2215
2289
|
formatResults(results, raw = false) {
|
2216
|
-
const
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
return Object.values(row);
|
2222
|
-
});
|
2223
|
-
});
|
2224
|
-
return normalizedResults.reduce(
|
2225
|
-
(finalResults, rows, index) => {
|
2226
|
-
const { returning, query, selectedFields, expansionIndex } = this.#internalStatements[index];
|
2227
|
-
if (!returning) return finalResults;
|
2228
|
-
const addResult = (result2) => {
|
2229
|
-
if (typeof expansionIndex !== "undefined") {
|
2230
|
-
let match = finalResults[expansionIndex];
|
2231
|
-
if (!match) match = finalResults[expansionIndex] = { models: {} };
|
2232
|
-
match.models[queryModel] = result2;
|
2233
|
-
} else {
|
2234
|
-
finalResults.push(result2);
|
2235
|
-
}
|
2236
|
-
return finalResults;
|
2237
|
-
};
|
2290
|
+
const cleanResults = results.filter((_, index) => this.statements[index].returning);
|
2291
|
+
let resultIndex = 0;
|
2292
|
+
return this.#internalQueries.reduce(
|
2293
|
+
(finalResults, internalQuery) => {
|
2294
|
+
const { query, selectedFields, affectedModels } = internalQuery;
|
2238
2295
|
const { queryType, queryModel, queryInstructions } = splitQuery(query);
|
2239
|
-
const
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2244
|
-
return addResult({ amount: rows[0][0] });
|
2245
|
-
}
|
2246
|
-
const single = queryModel !== model.pluralSlug;
|
2247
|
-
if (single) {
|
2248
|
-
return addResult({
|
2249
|
-
record: rows[0] ? this.#formatRows(selectedFields, rows, true) : null,
|
2250
|
-
modelFields
|
2296
|
+
const absoluteResults = raw ? cleanResults : cleanResults.map((rows) => {
|
2297
|
+
return rows.map((row) => {
|
2298
|
+
if (Array.isArray(row)) return row;
|
2299
|
+
if (queryType === "count") return [row.amount];
|
2300
|
+
return Object.values(row);
|
2251
2301
|
});
|
2252
|
-
}
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
} else {
|
2263
|
-
result.records.pop();
|
2264
|
-
}
|
2265
|
-
const direction = queryInstructions?.before ? "moreBefore" : "moreAfter";
|
2266
|
-
const lastRecord = result.records.at(
|
2267
|
-
direction === "moreAfter" ? -1 : 0
|
2268
|
-
);
|
2269
|
-
result[direction] = generatePaginationCursor(
|
2270
|
-
model,
|
2271
|
-
queryInstructions.orderedBy,
|
2272
|
-
lastRecord
|
2273
|
-
);
|
2274
|
-
}
|
2275
|
-
if (queryInstructions?.before || queryInstructions?.after) {
|
2276
|
-
const direction = queryInstructions?.before ? "moreAfter" : "moreBefore";
|
2277
|
-
const firstRecord = result.records.at(
|
2278
|
-
direction === "moreAfter" ? -1 : 0
|
2279
|
-
);
|
2280
|
-
result[direction] = generatePaginationCursor(
|
2302
|
+
});
|
2303
|
+
if (queryModel === "all" && affectedModels) {
|
2304
|
+
const modelList = affectedModels.map((slug) => {
|
2305
|
+
return getModelBySlug(this.models, slug);
|
2306
|
+
});
|
2307
|
+
const models = {};
|
2308
|
+
for (const model of modelList) {
|
2309
|
+
const result = this.formatIndividualResult(
|
2310
|
+
queryType,
|
2311
|
+
queryInstructions,
|
2281
2312
|
model,
|
2282
|
-
|
2283
|
-
|
2313
|
+
absoluteResults[resultIndex++],
|
2314
|
+
selectedFields,
|
2315
|
+
false
|
2284
2316
|
);
|
2317
|
+
models[model.pluralSlug] = result;
|
2285
2318
|
}
|
2319
|
+
finalResults.push({ models });
|
2320
|
+
} else {
|
2321
|
+
const model = getModelBySlug(this.models, queryModel);
|
2322
|
+
const result = this.formatIndividualResult(
|
2323
|
+
queryType,
|
2324
|
+
queryInstructions,
|
2325
|
+
model,
|
2326
|
+
absoluteResults[resultIndex++],
|
2327
|
+
selectedFields,
|
2328
|
+
queryModel !== model.pluralSlug
|
2329
|
+
);
|
2330
|
+
finalResults.push(result);
|
2286
2331
|
}
|
2287
|
-
return
|
2332
|
+
return finalResults;
|
2288
2333
|
},
|
2289
2334
|
[]
|
2290
2335
|
);
|