@ronin/compiler 0.17.8 → 0.17.9

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
@@ -269,6 +269,13 @@ type ModelField = ModelFieldBasics & ({
269
269
  /** Whether the field should be related to one record, or many records. */
270
270
  kind: 'many';
271
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
+ };
272
279
  type ModelIndexField<T extends ModelEntityList<ModelField> = ModelEntityList<ModelField>> = {
273
280
  /** The collating sequence used for text placed inside the field. */
274
281
  collation?: ModelFieldCollation;
@@ -423,6 +430,20 @@ declare class Transaction {
423
430
  statements: Array<Statement>;
424
431
  models: Array<Model>;
425
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 of 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>;
426
447
  formatResults<RecordType>(results: Array<Array<ObjectRow>>, raw?: false): Array<Result<RecordType>>;
427
448
  formatResults<RecordType>(results: Array<Array<RawRow>>, raw?: true): Array<Result<RecordType>>;
428
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 { dependencies: [], main: dependencyStatements[0], selectedFields: [] };
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);
@@ -2065,21 +2069,21 @@ var transformMetaQuery = (models, dependencyStatements, statementParams, query,
2065
2069
  var Transaction = class {
2066
2070
  statements = [];
2067
2071
  models = [];
2068
- #internalStatements = [];
2072
+ #internalQueries = [];
2069
2073
  constructor(queries, options) {
2070
2074
  const models = options?.models || [];
2071
- this.#compileQueries(queries, models, options);
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 = (queries, models, options) => {
2086
+ #compileQueries = (models, options) => {
2083
2087
  const modelsWithAttributes = models.map((model) => {
2084
2088
  return addDefaultModelAttributes(model, true);
2085
2089
  });
@@ -2095,7 +2099,7 @@ var Transaction = class {
2095
2099
  return addDefaultModelPresets(modelsWithFields, model);
2096
2100
  });
2097
2101
  const statements = [];
2098
- const expandedQueries = queries.flatMap((query, expansionIndex) => {
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 || {};
@@ -2108,6 +2112,9 @@ var Transaction = class {
2108
2112
  );
2109
2113
  });
2110
2114
  }
2115
+ this.#internalQueries[expansionIndex].affectedModels = modelList.map(
2116
+ (model) => model.slug
2117
+ );
2111
2118
  return modelList.map((model) => {
2112
2119
  const query2 = {
2113
2120
  [queryType]: { [model.pluralSlug]: restInstructions }
@@ -2117,7 +2124,8 @@ var Transaction = class {
2117
2124
  }
2118
2125
  return { query };
2119
2126
  });
2120
- for (const { query, expansionIndex } of expandedQueries) {
2127
+ for (let index = 0; index < expandedQueries.length; index++) {
2128
+ const { query, expansionIndex } = expandedQueries[index];
2121
2129
  const { dependencies, main, selectedFields } = compileQueryInput(
2122
2130
  query,
2123
2131
  modelsWithPresets,
@@ -2129,14 +2137,8 @@ var Transaction = class {
2129
2137
  const postDependencies = dependencies.map(({ after, ...rest }) => after ? rest : null).filter((item) => item != null);
2130
2138
  const subStatements = [...preDependencies, main, ...postDependencies];
2131
2139
  this.statements.push(...subStatements);
2132
- this.#internalStatements.push(
2133
- ...subStatements.map((statement) => ({
2134
- ...statement,
2135
- query,
2136
- selectedFields,
2137
- expansionIndex
2138
- }))
2139
- );
2140
+ const queryIndex = typeof expansionIndex === "undefined" ? index : expansionIndex;
2141
+ this.#internalQueries[queryIndex].selectedFields = selectedFields;
2140
2142
  }
2141
2143
  this.models = modelsWithPresets;
2142
2144
  return statements;
@@ -2210,6 +2212,68 @@ var Transaction = class {
2210
2212
  }
2211
2213
  return single ? records[0] : records;
2212
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 of 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
+ }
2213
2277
  /**
2214
2278
  * Format the results returned from the database into RONIN records.
2215
2279
  *
@@ -2223,78 +2287,49 @@ var Transaction = class {
2223
2287
  * RONIN record, an array of RONIN records, or a RONIN count result.
2224
2288
  */
2225
2289
  formatResults(results, raw = false) {
2226
- const normalizedResults = raw ? results : results.map((rows, index) => {
2227
- const { query } = this.#internalStatements[index];
2228
- return rows.map((row) => {
2229
- if (Array.isArray(row)) return row;
2230
- if (query.count) return [row.amount];
2231
- return Object.values(row);
2232
- });
2233
- });
2234
- return normalizedResults.reduce(
2235
- (finalResults, rows, index) => {
2236
- const { returning, query, selectedFields, expansionIndex } = this.#internalStatements[index];
2237
- if (!returning) return finalResults;
2238
- const addResult = (result2) => {
2239
- if (typeof expansionIndex !== "undefined") {
2240
- let match = finalResults[expansionIndex];
2241
- if (!match) match = finalResults[expansionIndex] = { models: {} };
2242
- match.models[queryModel] = result2;
2243
- } else {
2244
- finalResults.push(result2);
2245
- }
2246
- return finalResults;
2247
- };
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;
2248
2295
  const { queryType, queryModel, queryInstructions } = splitQuery(query);
2249
- const model = getModelBySlug(this.models, queryModel);
2250
- const modelFields = Object.fromEntries(
2251
- Object.entries(model.fields).map(([slug, rest]) => [slug, rest.type])
2252
- );
2253
- if (queryType === "count") {
2254
- return addResult({ amount: rows[0][0] });
2255
- }
2256
- const single = queryModel !== model.pluralSlug;
2257
- if (single) {
2258
- return addResult({
2259
- record: rows[0] ? this.#formatRows(selectedFields, rows, true) : null,
2260
- 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);
2261
2301
  });
2262
- }
2263
- const pageSize = queryInstructions?.limitedTo;
2264
- const result = {
2265
- records: this.#formatRows(selectedFields, rows, false),
2266
- modelFields
2267
- };
2268
- if (pageSize && result.records.length > 0) {
2269
- if (result.records.length > pageSize) {
2270
- if (queryInstructions?.before) {
2271
- result.records.shift();
2272
- } else {
2273
- result.records.pop();
2274
- }
2275
- const direction = queryInstructions?.before ? "moreBefore" : "moreAfter";
2276
- const lastRecord = result.records.at(
2277
- direction === "moreAfter" ? -1 : 0
2278
- );
2279
- result[direction] = generatePaginationCursor(
2280
- model,
2281
- queryInstructions.orderedBy,
2282
- lastRecord
2283
- );
2284
- }
2285
- if (queryInstructions?.before || queryInstructions?.after) {
2286
- const direction = queryInstructions?.before ? "moreAfter" : "moreBefore";
2287
- const firstRecord = result.records.at(
2288
- direction === "moreAfter" ? -1 : 0
2289
- );
2290
- 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,
2291
2312
  model,
2292
- queryInstructions.orderedBy,
2293
- firstRecord
2313
+ absoluteResults[resultIndex++],
2314
+ selectedFields,
2315
+ false
2294
2316
  );
2317
+ models[model.pluralSlug] = result;
2295
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);
2296
2331
  }
2297
- return addResult(result);
2332
+ return finalResults;
2298
2333
  },
2299
2334
  []
2300
2335
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronin/compiler",
3
- "version": "0.17.8",
3
+ "version": "0.17.9",
4
4
  "type": "module",
5
5
  "description": "Compiles RONIN queries to SQL statements.",
6
6
  "publishConfig": {