@syncular/typegen 0.2.1 → 0.3.0

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.
Files changed (51) hide show
  1. package/README.md +25 -10
  2. package/dist/cli.js +155 -4
  3. package/dist/emit-dart.js +3 -2
  4. package/dist/emit-kotlin.js +3 -2
  5. package/dist/emit-queries-dart.js +87 -15
  6. package/dist/emit-queries-kotlin.js +89 -15
  7. package/dist/emit-queries-swift.js +92 -14
  8. package/dist/emit-queries.js +131 -22
  9. package/dist/emit-swift.js +3 -2
  10. package/dist/emit.d.ts +2 -1
  11. package/dist/emit.js +13 -27
  12. package/dist/fmt.d.ts +3 -0
  13. package/dist/fmt.js +356 -0
  14. package/dist/generate.d.ts +16 -6
  15. package/dist/generate.js +34 -9
  16. package/dist/index.d.ts +6 -0
  17. package/dist/index.js +6 -0
  18. package/dist/lower.d.ts +54 -0
  19. package/dist/lower.js +283 -0
  20. package/dist/lsp.d.ts +20 -0
  21. package/dist/lsp.js +376 -0
  22. package/dist/manifest.d.ts +11 -0
  23. package/dist/manifest.js +20 -0
  24. package/dist/naming.d.ts +22 -0
  25. package/dist/naming.js +240 -0
  26. package/dist/query-ir.d.ts +14 -0
  27. package/dist/query-ir.js +69 -0
  28. package/dist/query.d.ts +102 -6
  29. package/dist/query.js +126 -34
  30. package/dist/syql.d.ts +83 -0
  31. package/dist/syql.js +945 -0
  32. package/package.json +2 -2
  33. package/src/cli.ts +155 -4
  34. package/src/emit-dart.ts +3 -2
  35. package/src/emit-kotlin.ts +3 -2
  36. package/src/emit-queries-dart.ts +109 -16
  37. package/src/emit-queries-kotlin.ts +111 -18
  38. package/src/emit-queries-swift.ts +106 -17
  39. package/src/emit-queries.ts +179 -28
  40. package/src/emit-swift.ts +3 -2
  41. package/src/emit.ts +18 -28
  42. package/src/fmt.ts +351 -0
  43. package/src/generate.ts +54 -11
  44. package/src/index.ts +6 -0
  45. package/src/lower.ts +331 -0
  46. package/src/lsp.ts +445 -0
  47. package/src/manifest.ts +38 -0
  48. package/src/naming.ts +271 -0
  49. package/src/query-ir.ts +82 -0
  50. package/src/query.ts +241 -34
  51. package/src/syql.ts +1171 -0
package/src/query.ts CHANGED
@@ -48,7 +48,7 @@
48
48
  * error listing the fix. bun:sqlite can't name params, so we parse `:name`
49
49
  * tokens from the SQL ourselves (first-occurrence order = positional order).
50
50
  *
51
- * ## The tables set (for useSyncQuery `{tables}` — exact invalidation)
51
+ * ## The tables set (for useRawSql `{tables}` — exact invalidation)
52
52
  *
53
53
  * bun:sqlite exposes no authorizer and no statement table-list; EXPLAIN
54
54
  * opcodes are fragile. The honest mechanism: the FROM/JOIN table set we
@@ -62,6 +62,8 @@
62
62
  */
63
63
  import { TypegenError } from './errors';
64
64
  import type { IrColumnType, IrDocument, IrTable } from './ir';
65
+ import { lowerProjection, mainVerbAfterWith } from './lower';
66
+ import { buildNamingMap, type NamingMode, type NamingTarget } from './naming';
65
67
 
66
68
  /** The SQL decltype keyword → §2.4 type map (mirrors sql.ts TYPE_MAP so a
67
69
  * plain column ref's decltype resolves to the exact IR type). */
@@ -89,14 +91,45 @@ const DECLTYPE_MAP: Readonly<Record<string, IrColumnType>> = {
89
91
  export type QueryParamType = IrColumnType;
90
92
 
91
93
  export interface QueryParam {
94
+ /** SQL-truth `:name` (as authored). */
92
95
  readonly name: string;
96
+ /** Language-facing name (§5 naming map; equals `name` under "preserve"). */
97
+ readonly langName: string;
93
98
  readonly type: QueryParamType;
94
99
  /** How the type was resolved — for the docs/tests, not emitted. */
95
100
  readonly source: 'inferred' | 'comment';
101
+ /** §4 (DESIGN-queries.md): an optional param — its auto-guarded conjunct
102
+ * applies only when it is provided. Always false for the `.sql` tier. */
103
+ readonly optional?: boolean;
104
+ /** §4: the `from+to` pairing — params sharing a group apply together. */
105
+ readonly group?: string;
106
+ /** §3: a `: flag` boolean guard param (never in a predicate as written;
107
+ * the lowering binds it). Implies optional. */
108
+ readonly flag?: boolean;
109
+ }
110
+
111
+ /** §6 orderBy knob: a generate-time allowlist (identifiers cannot bind). */
112
+ export interface QueryOrderBy {
113
+ /** Allowed columns: authored SQL name + the language-facing key the
114
+ * generated signature accepts. Each is SQLite-checked at generate time. */
115
+ readonly allowed: readonly { name: string; langName: string }[];
116
+ /** Default column (authored SQL name). */
117
+ readonly defaultColumn: string;
118
+ readonly defaultDir: 'asc' | 'desc';
119
+ }
120
+
121
+ /** §6 limit knob: a bound value with a codegen clamp + default. */
122
+ export interface QueryLimit {
123
+ readonly max?: number;
124
+ readonly default?: number;
96
125
  }
97
126
 
98
127
  export interface QueryColumn {
128
+ /** SQL-truth result name (pre-lowering, as authored). */
99
129
  readonly name: string;
130
+ /** Language-facing name — the RUNTIME result key after §5 projection
131
+ * lowering (equals `name` under "preserve"). */
132
+ readonly langName: string;
100
133
  readonly type: IrColumnType;
101
134
  readonly nullable: boolean;
102
135
  /** `exact` = resolved to an IR column (plain ref); `fallback` = a computed
@@ -104,22 +137,78 @@ export interface QueryColumn {
104
137
  readonly fidelity: 'exact' | 'fallback';
105
138
  }
106
139
 
140
+ /** §7/§8 backend selection: neutralization (default), always-variants, or
141
+ * the small-N heuristic (`auto`: enumerate at ≤ 2 optional groups). */
142
+ export type QueryBackend = 'neutralize' | 'variants' | 'auto';
143
+
144
+ /** Naming/backend options threaded from the manifest into query analysis. */
145
+ export interface QueryNamingOptions {
146
+ readonly naming: NamingMode;
147
+ /** Emitter targets this run generates — keyword hazards are only real on
148
+ * targets that exist. */
149
+ readonly targets: readonly NamingTarget[];
150
+ /** `.syql` conditional-lowering backend (default `neutralize`); the
151
+ * per-query `variants` knob always forces enumeration. */
152
+ readonly backend?: QueryBackend;
153
+ }
154
+
155
+ const DEFAULT_NAMING: QueryNamingOptions = { naming: 'camel', targets: ['ts'] };
156
+
107
157
  export interface AnalyzedQuery {
108
158
  /** camelCase function name (path-derived, or a `-- name:` override). */
109
159
  readonly name: string;
110
160
  /** Source location for errors, e.g. `billing/list.sql` (or `list.sql#2`
111
161
  * for the 2nd statement of a multi-statement file). */
112
162
  readonly file: string;
113
- /** The SQL as written (named `:params`), trimmed. */
163
+ /** The SQL as authored (named `:params`), trimmed — pre-lowering. */
164
+ readonly sourceSql: string;
165
+ /** The LOWERED SQL (named `:params`): §5 projection aliasing applied, so
166
+ * runtime result keys are the language-facing names. Equals `sourceSql`
167
+ * when nothing needed rewriting. */
114
168
  readonly sql: string;
115
- /** The SQL with `:name` rewritten to positional `?` (wrapper surface). */
169
+ /** The lowered SQL with `:name` rewritten to positional `?`. */
116
170
  readonly positionalSql: string;
117
171
  /** Params in first-occurrence (positional) order. */
118
172
  readonly params: readonly QueryParam[];
119
173
  /** Result columns in SELECT order. */
120
174
  readonly columns: readonly QueryColumn[];
121
- /** IR tables this query reads (the useSyncQuery `{tables}` set), sorted. */
175
+ /** IR tables this query reads (the useRawSql `{tables}` set), sorted. */
122
176
  readonly tables: readonly string[];
177
+ /** §6 orderBy knob (`.syql` tier). When present, `sql`/`positionalSql`
178
+ * carry the DEFAULT order-by tail and `positionalSqlBase` is the static
179
+ * prefix emitters compose the selected column onto. */
180
+ readonly orderBy?: QueryOrderBy;
181
+ /** §6 limit knob (`.syql` tier): the trailing `LIMIT ?` bind's clamp. */
182
+ readonly limit?: QueryLimit;
183
+ /** positional SQL WITHOUT the dynamic ORDER BY/LIMIT tail; present only
184
+ * when `orderBy` is (emitters build `base + ORDER BY <baked> + limit
185
+ * tail`). */
186
+ readonly positionalSqlBase?: string;
187
+ /** The positional limit tail (e.g. ` limit min(coalesce(?, 50), 100)` —
188
+ * the default+clamp live IN the SQL, so runtimes bind `limit ?? null`).
189
+ * Present only when BOTH knobs are declared (composers need it verbatim). */
190
+ readonly positionalLimitTail?: string;
191
+ /** §7 variant-enumeration backend (opt-in `variants` knob): one checked
192
+ * statement per combination of provided optional groups. Semantically
193
+ * identical to the neutralization `sql` by construction; the TS emitter
194
+ * dispatches on provided-ness for perfect index use. `when` lists the
195
+ * provided group keys; `params` are the DISTINCT param names this variant
196
+ * binds, positional order. */
197
+ readonly variants?: readonly {
198
+ readonly when: readonly string[];
199
+ readonly sql: string;
200
+ readonly positionalSql: string;
201
+ readonly params: readonly string[];
202
+ }[];
203
+ /** The optional-group keys, in dispatch-bit order (bit i of the variant
204
+ * index = group i provided). Present iff `variants` is. */
205
+ readonly variantGroups?: readonly {
206
+ readonly key: string;
207
+ /** Params whose provision defines the group (all must be non-null; a
208
+ * flag group is "on" when its single param is TRUE). */
209
+ readonly params: readonly string[];
210
+ readonly flag: boolean;
211
+ }[];
123
212
  }
124
213
 
125
214
  // -- path → name --------------------------------------------------------------
@@ -422,12 +511,21 @@ function scanParamNames(sql: string): string[] {
422
511
  return seen;
423
512
  }
424
513
 
425
- /** Rewrite `:name` → positional `?` (repeats included) AND strip comments +
426
- * collapse whitespace, producing a clean single-line SQL string suitable for
514
+ /** Rewrite `:name` → positional placeholders AND strip comments + collapse
515
+ * whitespace, producing a clean single-line SQL string suitable for
427
516
  * embedding in a generated string literal. String literals are preserved
428
- * verbatim (their inner whitespace is not collapsed). */
429
- function toPositionalSql(sql: string): string {
430
- const tokens: string[] = [];
517
+ * verbatim (their inner whitespace is not collapsed).
518
+ *
519
+ * When every param occurs exactly once, plain `?` is emitted. When ANY
520
+ * param repeats (the §7 neutralization guards mention a param in the guard
521
+ * AND the predicate), the WHOLE statement uses SQLite's numbered `?N`
522
+ * form — one bound value per DISTINCT param, reuse resolved by SQLite —
523
+ * so the generated bind array stays one-entry-per-param. */
524
+ export function toPositionalSql(sql: string): string {
525
+ interface ParamToken {
526
+ readonly param: string;
527
+ }
528
+ const tokens: (string | ParamToken)[] = [];
431
529
  let i = 0;
432
530
  while (i < sql.length) {
433
531
  const ch = sql[i] as string;
@@ -467,7 +565,7 @@ function toPositionalSql(sql: string): string {
467
565
  while (end < sql.length && /[A-Za-z0-9_]/.test(sql[end] as string)) {
468
566
  end += 1;
469
567
  }
470
- tokens.push('?');
568
+ tokens.push({ param: sql.slice(i + 1, end) });
471
569
  i = end;
472
570
  } else if (/\s/.test(ch)) {
473
571
  tokens.push(' ');
@@ -477,8 +575,21 @@ function toPositionalSql(sql: string): string {
477
575
  i += 1;
478
576
  }
479
577
  }
578
+ const order: string[] = [];
579
+ let repeats = false;
580
+ for (const token of tokens) {
581
+ if (typeof token === 'string') continue;
582
+ if (order.includes(token.param)) repeats = true;
583
+ else order.push(token.param);
584
+ }
585
+ const rendered = tokens
586
+ .map((token) => {
587
+ if (typeof token === 'string') return token;
588
+ return repeats ? `?${order.indexOf(token.param) + 1}` : '?';
589
+ })
590
+ .join('');
480
591
  // Collapse runs of the whitespace placeholders; trim.
481
- return tokens.join('').replace(/\s+/g, ' ').trim();
592
+ return rendered.replace(/\s+/g, ' ').trim();
482
593
  }
483
594
 
484
595
  // -- FROM/JOIN table resolution ----------------------------------------------
@@ -671,6 +782,31 @@ function inferParamType(
671
782
  const t = lookup(inM[1], inM[2] as string);
672
783
  if (t !== null) return t;
673
784
  }
785
+ // `col BETWEEN :name AND …` / `col BETWEEN … AND :name` — both endpoints
786
+ // take the column's type (the §4 from+to group shape).
787
+ const btwLeft = new RegExp(
788
+ `(?:(${IDENT})\\.)?(${IDENT})\\s+BETWEEN\\s+:${paramName}\\b`,
789
+ 'i',
790
+ );
791
+ const btwLeftM = btwLeft.exec(cleaned);
792
+ if (btwLeftM !== null) {
793
+ const t = lookup(btwLeftM[1], btwLeftM[2] as string);
794
+ if (t !== null) return t;
795
+ }
796
+ const btwRight = new RegExp(
797
+ `(?:(${IDENT})\\.)?(${IDENT})\\s+BETWEEN\\s+\\S+\\s+AND\\s+:${paramName}\\b`,
798
+ 'i',
799
+ );
800
+ const btwRightM = btwRight.exec(cleaned);
801
+ if (btwRightM !== null) {
802
+ const t = lookup(btwRightM[1], btwRightM[2] as string);
803
+ if (t !== null) return t;
804
+ }
805
+ // `… LIKE <expr mentioning :name>` — a LIKE operand is TEXT, even inside
806
+ // a concatenation (`title like '%' || :q || '%'`, the search-fragment
807
+ // shape).
808
+ const like = new RegExp(`\\bLIKE\\b[^()]*:${paramName}\\b`, 'i');
809
+ if (like.test(cleaned)) return 'string';
674
810
  return null;
675
811
  }
676
812
 
@@ -747,36 +883,49 @@ export function analyzeStatement(
747
883
  statementText: string,
748
884
  ir: IrDocument,
749
885
  db: QueryDb,
886
+ naming: QueryNamingOptions = DEFAULT_NAMING,
750
887
  ): AnalyzedQuery {
751
888
  const file = location;
752
889
  const commentParams = parseCommentParams(file, statementText);
753
- const sql = statementText.trim();
754
- if (sql.length === 0) {
890
+ const sourceSql = statementText.trim();
891
+ if (sourceSql.length === 0) {
755
892
  throw new TypegenError(file, 'query file is empty');
756
893
  }
757
894
 
758
- // SELECT-only (the read tier). Reject the first keyword loudly otherwise.
895
+ // SELECT-only (the read tier). A `WITH` is allowed when its main statement
896
+ // is a SELECT (SQLite also allows WITH … INSERT/UPDATE/DELETE — writes).
759
897
  const firstKeyword = /^\s*([A-Za-z]+)/.exec(
760
898
  stripCommentsAndStrings(statementText).trimStart(),
761
899
  )?.[1];
762
- if (firstKeyword === undefined || firstKeyword.toUpperCase() !== 'SELECT') {
900
+ const upperKeyword = firstKeyword?.toUpperCase();
901
+ if (upperKeyword === 'WITH') {
902
+ const main = mainVerbAfterWith(stripCommentsAndStrings(statementText));
903
+ if (main !== 'SELECT') {
904
+ throw new TypegenError(
905
+ file,
906
+ `named queries are SELECT-only (the read tier); this WITH statement's main verb is ${JSON.stringify(main ?? '')}. Writes go through mutate() (SPEC §7.1).`,
907
+ );
908
+ }
909
+ } else if (upperKeyword !== 'SELECT') {
763
910
  throw new TypegenError(
764
911
  file,
765
912
  `named queries are SELECT-only (the read tier); found ${JSON.stringify(firstKeyword ?? '')}. Writes go through mutate() (SPEC §7.1).`,
766
913
  );
767
914
  }
768
915
 
769
- // Let SQLite validate + describe the query. Any bad reference throws here
770
- // with SQLite's own message (which names the offending table/column).
771
- let described: ReturnType<QueryDb['analyze']>;
772
- try {
773
- described = db.analyze(sql);
774
- } catch (error) {
775
- const message = error instanceof Error ? error.message : String(error);
776
- throw new TypegenError(file, `SQL rejected by SQLite: ${message}`);
777
- }
916
+ // Let SQLite validate + describe the AUTHORED query first. Any bad
917
+ // reference throws here with SQLite's own message.
918
+ const analyze = (candidate: string): ReturnType<QueryDb['analyze']> => {
919
+ try {
920
+ return db.analyze(candidate);
921
+ } catch (error) {
922
+ const message = error instanceof Error ? error.message : String(error);
923
+ throw new TypegenError(file, `SQL rejected by SQLite: ${message}`);
924
+ }
925
+ };
926
+ let described = analyze(sourceSql);
778
927
 
779
- const refs = scanTableRefs(sql, ir);
928
+ const refs = scanTableRefs(sourceSql, ir);
780
929
  const tableSet = new Set(refs.map((r) => r.table));
781
930
  const tables = [...tableSet].sort();
782
931
  if (tables.length === 0) {
@@ -786,17 +935,57 @@ export function analyzeStatement(
786
935
  );
787
936
  }
788
937
 
789
- // Columns: pair bun's column names + decltypes with our source resolution.
938
+ // §5 lowering: rewrite the projection so runtime result keys are the
939
+ // language-facing names ("camel"); a no-op pass-through under "preserve".
940
+ let sql = sourceSql;
941
+ let sqlNames: readonly string[] = described.columnNames;
942
+ let langNames: readonly string[] = described.columnNames;
943
+ if (naming.naming === 'camel') {
944
+ const lowered = lowerProjection(
945
+ sourceSql,
946
+ refs,
947
+ ir,
948
+ file,
949
+ (candidate) => analyze(candidate).columnNames,
950
+ (names) =>
951
+ buildNamingMap(names, 'camel', file, 'projection', naming.targets).map(
952
+ (m) => m.langName,
953
+ ),
954
+ );
955
+ sqlNames = lowered.sqlNames;
956
+ langNames = lowered.langNames;
957
+ if (lowered.changed) {
958
+ sql = lowered.sql;
959
+ described = analyze(sql);
960
+ // Defensive: the rewritten projection's runtime keys must BE the
961
+ // language names — this is the whole point of the lowering.
962
+ if (
963
+ described.columnNames.length !== langNames.length ||
964
+ described.columnNames.some((n, i) => n !== langNames[i])
965
+ ) {
966
+ throw new TypegenError(
967
+ file,
968
+ `internal: lowered projection keys [${described.columnNames.join(', ')}] do not match the naming map [${langNames.join(', ')}]`,
969
+ );
970
+ }
971
+ }
972
+ }
973
+
974
+ // Columns: pair bun's column names + decltypes with our source resolution
975
+ // (against the LOWERED sql — aliased plain refs still resolve exactly).
790
976
  const items = splitSelectList(sql);
791
977
  const columns: QueryColumn[] = described.columnNames.map((colName, index) => {
792
978
  const decl = described.declaredTypes[index];
793
979
  const item = items?.[index];
794
980
  const source = item !== undefined ? resolveSource(item, refs, ir) : null;
981
+ const sqlName = sqlNames[index] ?? colName;
982
+ const langName = langNames[index] ?? colName;
795
983
  if (source !== null) {
796
984
  // Exact: IR column type + IR nullability. (decltype agrees; we prefer
797
985
  // the IR type so blob_ref/crdt/json semantic types survive.)
798
986
  return {
799
- name: colName,
987
+ name: sqlName,
988
+ langName,
800
989
  type: source.column.type,
801
990
  nullable: source.column.nullable,
802
991
  fidelity: 'exact',
@@ -809,11 +998,18 @@ export function analyzeStatement(
809
998
  : undefined;
810
999
  const type =
811
1000
  mapped ?? (item !== undefined ? fallbackColumnType(item.expr) : 'string');
812
- return { name: colName, type, nullable: true, fidelity: 'fallback' };
1001
+ return {
1002
+ name: sqlName,
1003
+ langName,
1004
+ type,
1005
+ nullable: true,
1006
+ fidelity: 'fallback',
1007
+ };
813
1008
  });
814
1009
 
815
1010
  // Params: names from the text (positional order), types from inference or
816
- // the `-- param` comment; every param must resolve.
1011
+ // the `-- param` comment; every param must resolve. Param langNames go
1012
+ // through the same §12 map (authored camelCase params are identity).
817
1013
  const paramNames = scanParamNames(sql);
818
1014
  if (paramNames.length !== described.paramsCount) {
819
1015
  // Defensive: our scan and SQLite disagree (shouldn't happen for the subset).
@@ -822,15 +1018,23 @@ export function analyzeStatement(
822
1018
  `internal: scanned ${paramNames.length} params (${paramNames.join(', ')}) but SQLite reports ${described.paramsCount}`,
823
1019
  );
824
1020
  }
1021
+ const paramLangNames = buildNamingMap(
1022
+ paramNames,
1023
+ naming.naming,
1024
+ file,
1025
+ 'params',
1026
+ naming.targets,
1027
+ );
825
1028
  const commentByName = new Map(commentParams.map((p) => [p.name, p.type]));
826
- const params: QueryParam[] = paramNames.map((paramName) => {
1029
+ const params: QueryParam[] = paramNames.map((paramName, index) => {
1030
+ const langName = paramLangNames[index]?.langName ?? paramName;
827
1031
  const commented = commentByName.get(paramName);
828
1032
  if (commented !== undefined) {
829
- return { name: paramName, type: commented, source: 'comment' };
1033
+ return { name: paramName, langName, type: commented, source: 'comment' };
830
1034
  }
831
1035
  const inferred = inferParamType(paramName, sql, refs, ir);
832
1036
  if (inferred !== null) {
833
- return { name: paramName, type: inferred, source: 'inferred' };
1037
+ return { name: paramName, langName, type: inferred, source: 'inferred' };
834
1038
  }
835
1039
  throw new TypegenError(
836
1040
  file,
@@ -850,6 +1054,7 @@ export function analyzeStatement(
850
1054
  return {
851
1055
  name,
852
1056
  file,
1057
+ sourceSql,
853
1058
  sql,
854
1059
  positionalSql: toPositionalSql(sql),
855
1060
  params,
@@ -874,6 +1079,7 @@ export function analyzeQueryFile(
874
1079
  content: string,
875
1080
  ir: IrDocument,
876
1081
  db: QueryDb,
1082
+ naming: QueryNamingOptions = DEFAULT_NAMING,
877
1083
  ): AnalyzedQuery[] {
878
1084
  const statements = splitStatements(content);
879
1085
  if (statements.length === 0) {
@@ -893,7 +1099,7 @@ export function analyzeQueryFile(
893
1099
  );
894
1100
  }
895
1101
  const name = override ?? defaultName;
896
- return analyzeStatement(name, location, stmt.text, ir, db);
1102
+ return analyzeStatement(name, location, stmt.text, ir, db, naming);
897
1103
  });
898
1104
  }
899
1105
 
@@ -905,6 +1111,7 @@ export function analyzeQuery(
905
1111
  raw: string,
906
1112
  ir: IrDocument,
907
1113
  db: QueryDb,
1114
+ naming: QueryNamingOptions = DEFAULT_NAMING,
908
1115
  ): AnalyzedQuery {
909
1116
  const statements = splitStatements(raw);
910
1117
  if (statements.length > 1) {
@@ -913,6 +1120,6 @@ export function analyzeQuery(
913
1120
  'a query file holds exactly one SELECT statement here (found a `;` separating statements) — use analyzeQueryFile for multi-statement files',
914
1121
  );
915
1122
  }
916
- const results = analyzeQueryFile(file, raw, ir, db);
1123
+ const results = analyzeQueryFile(file, raw, ir, db, naming);
917
1124
  return results[0] as AnalyzedQuery;
918
1125
  }