sql-linter 0.1.0 → 0.1.1

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 ADDED
@@ -0,0 +1,28 @@
1
+ # sql-linter
2
+
3
+ A CLI that type-checks SQL queries in TypeScript source files by connecting to a live PostgreSQL database. It finds `sql\`...\`` tagged template expressions and validates query parameters and return types against your TypeScript types.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install
9
+ npm run build
10
+ npm link
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```sh
16
+ sql-linter <dir> [--db <connection-url>]
17
+ ```
18
+
19
+ - `<dir>` — directory to scan for TypeScript files
20
+ - `--db` — PostgreSQL connection URL (default: `postgres://postgres:postgres@localhost:5432/postgres`)
21
+
22
+ ### Example
23
+
24
+ ```sh
25
+ sql-linter ./src --db postgres://user:pass@localhost:5432/mydb
26
+ ```
27
+
28
+ The linter exits with code `1` if any errors are found, `0` otherwise.
package/dist/index.js CHANGED
@@ -41,26 +41,35 @@ async function walk(dir) {
41
41
  await walkInner(dir, results);
42
42
  return results;
43
43
  }
44
- async function lintNode(node, callback, program) {
44
+ async function lintNode(node, program) {
45
45
  if (ts.isTaggedTemplateExpression(node)) {
46
- await callback(node, program);
46
+ const reports = [];
47
+ await lintTaggedTemplate(node, program, (n, message) => {
48
+ reports.push({ node: n, message });
49
+ });
50
+ flushReports(node, reports);
47
51
  }
48
52
  const promises = [];
49
53
  ts.forEachChild(node, (n) => {
50
- promises.push(lintNode(n, callback, program));
54
+ promises.push(lintNode(n, program));
51
55
  });
52
56
  await Promise.all(promises);
53
57
  }
54
- async function lint(dir, callback) {
58
+ async function lint(dir) {
55
59
  const fileNames = await walk(dir);
56
- const program = ts.createProgram(fileNames, {
57
- target: ts.ScriptTarget.ES2015,
58
- });
60
+ const tsconfigPath = ts.findConfigFile(dir, ts.sys.fileExists, "tsconfig.json");
61
+ let compilerOptions = { target: ts.ScriptTarget.ES2015 };
62
+ if (tsconfigPath) {
63
+ const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
64
+ const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(tsconfigPath));
65
+ compilerOptions = parsed.options;
66
+ }
67
+ const program = ts.createProgram(fileNames, compilerOptions);
59
68
  await Promise.all(fileNames.map(async (fileName) => {
60
69
  const sourceFile = program.getSourceFile(fileName);
61
70
  if (!sourceFile)
62
71
  return;
63
- await lintNode(sourceFile, callback, program);
72
+ await lintNode(sourceFile, program);
64
73
  }));
65
74
  }
66
75
  function pgTypeToTsInnerForParams(pg_type, typeChecker) {
@@ -217,6 +226,9 @@ function checkQueryParams(givenParams, expectedParams, argNames, typeChecker) {
217
226
  const givenParameters = {};
218
227
  if (argNames != null) {
219
228
  const t = typeChecker.getTypeAtLocation(givenParams);
229
+ if (t.flags & ts.TypeFlags.Any) {
230
+ return null;
231
+ }
220
232
  for (const property of t.getProperties()) {
221
233
  const t = typeChecker.getTypeOfSymbol(property);
222
234
  givenParameters[property.escapedName.toString()] = t;
@@ -243,6 +255,11 @@ function checkQueryParams(givenParams, expectedParams, argNames, typeChecker) {
243
255
  const name = argNames?.[i] || i;
244
256
  const eName = argNames?.[i] || i + 1;
245
257
  const paramType = givenParameters[name];
258
+ if (paramType == null) {
259
+ return {
260
+ message: `Missing argument for $${eName}`,
261
+ };
262
+ }
246
263
  try {
247
264
  const expected = pgTypeToTsMappingForParams(expectedParam, false, typeChecker);
248
265
  if (!typeChecker.isTypeAssignableTo(paramType, typeChecker.getNullableType(expected, ts.TypeFlags.Undefined))) {
@@ -261,129 +278,138 @@ function checkQueryParams(givenParams, expectedParams, argNames, typeChecker) {
261
278
  return null;
262
279
  }
263
280
  let count = 0;
264
- function report(node, message) {
265
- count++;
266
- const sourceFile = node.getSourceFile();
267
- const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
268
- console.log(`${sourceFile.fileName}:${line}:${character}:
269
- ${chalk.red(message)}
270
- `);
281
+ function flushReports(queryNode, reports) {
282
+ if (reports.length === 0)
283
+ return;
284
+ const sourceFile = queryNode.getSourceFile();
285
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(queryNode.getStart());
286
+ console.log(`${sourceFile.fileName}:${line}:${character}:`);
287
+ for (const { message } of reports) {
288
+ count++;
289
+ console.log(` ${chalk.red(message)}`);
290
+ }
291
+ console.log();
271
292
  }
272
- async function main() {
273
- await lint(targetDir, async (node, program) => {
274
- let typeChecker = program.getTypeChecker();
275
- if (!ts.isIdentifier(node.tag) || node.tag.escapedText !== "sql")
276
- return;
277
- let sqlStatement = node.template.rawText;
278
- if (sqlStatement == null || sqlStatement.length === 0) {
279
- report(node, "Empty sql query");
280
- return;
281
- }
282
- const parent = node.parent;
283
- if (!ts.isCallExpression(parent)) {
284
- report(parent, "The parent of a sql`...` call should be a Call expression.");
293
+ async function lintTaggedTemplate(node, program, report) {
294
+ const typeChecker = program.getTypeChecker();
295
+ if (!ts.isIdentifier(node.tag) || node.tag.escapedText !== "sql")
296
+ return;
297
+ let sqlStatement = node.template.rawText;
298
+ if (sqlStatement == null || sqlStatement.length === 0) {
299
+ report(node, "Empty sql query");
300
+ return;
301
+ }
302
+ const parent = node.parent;
303
+ if (!ts.isCallExpression(parent)) {
304
+ report(parent, "The parent of a sql`...` call should be a Call expression.");
305
+ return;
306
+ }
307
+ if (parent.arguments.length > 2) {
308
+ report(parent, "Expected at most 2 arguments to this call");
309
+ return;
310
+ }
311
+ const params = parent.arguments[1];
312
+ const usesRemappings = sqlStatement.includes("$/") || sqlStatement.includes("$(");
313
+ let description;
314
+ let argNames = null;
315
+ sqlStatement = sqlStatement
316
+ .replaceAll(":csv", "")
317
+ .replaceAll(/[^:]:json/g, "");
318
+ if (!usesRemappings) {
319
+ const descriptions = await asyncDescribeQueries(dbUrl, [sqlStatement]);
320
+ const first = descriptions[0];
321
+ if ("error" in first) {
322
+ report(node, `DBError: ${first.error}`);
285
323
  return;
286
324
  }
287
- if (parent.arguments.length > 2) {
288
- report(parent, "Expected at most 2 arguments to this call");
289
- return;
325
+ else {
326
+ description = first.description;
290
327
  }
291
- const params = parent.arguments[1];
292
- const usesRemappings = sqlStatement.includes("$/") || sqlStatement.includes("$(");
293
- let description;
294
- let argNames = null;
295
- sqlStatement = sqlStatement
296
- .replaceAll(":csv", "")
297
- .replaceAll(/[^:]:json/g, "");
298
- if (!usesRemappings) {
299
- const descriptions = await asyncDescribeQueries(dbUrl, [sqlStatement]);
300
- const first = descriptions[0];
301
- if ("error" in first) {
302
- report(node, `DBError: ${first.error}`);
303
- return;
328
+ }
329
+ else {
330
+ argNames = [];
331
+ let prefix = "/";
332
+ let suffix = "/";
333
+ let counter = 1;
334
+ const normalizedStatement = sqlStatement.replaceAll(/\$[\/\(]\s*([a-zA-Z0-9_]*)\s*[\/\)]/g, (substring, name) => {
335
+ if (substring.endsWith(")")) {
336
+ prefix = "(";
337
+ suffix = ")";
338
+ }
339
+ let index = argNames.indexOf(name);
340
+ if (index < 0) {
341
+ argNames.push(name);
342
+ index = counter;
343
+ counter += 1;
304
344
  }
305
345
  else {
306
- description = first.description;
346
+ index += 1;
307
347
  }
348
+ return `$${index}`;
349
+ });
350
+ const descriptions = await asyncDescribeQueries(dbUrl, [
351
+ normalizedStatement,
352
+ ]);
353
+ const first = descriptions[0];
354
+ if ("error" in first) {
355
+ report(node, "DBError: " +
356
+ first.error.replace(/\$(\d+)/, (_, d) => `$${prefix}${argNames[parseInt(d, 10) - 1]}${suffix}`));
357
+ return;
308
358
  }
309
359
  else {
310
- argNames = [];
311
- let prefix = "/";
312
- let suffix = "/";
313
- let counter = 1;
314
- const normalizedStatement = sqlStatement.replaceAll(/\$[\/\(]\s*([a-zA-Z0-9_]*)\s*[\/\)]/g, (substring, name) => {
315
- if (substring.endsWith(")")) {
316
- prefix = "(";
317
- suffix = ")";
318
- }
319
- let index = argNames.indexOf(name);
320
- if (index < 0) {
321
- argNames.push(name);
322
- index = counter;
323
- counter += 1;
324
- }
325
- else {
326
- index += 1;
327
- }
328
- return `$${index}`;
329
- });
330
- const descriptions = await asyncDescribeQueries(dbUrl, [
331
- normalizedStatement,
332
- ]);
333
- const first = descriptions[0];
334
- if ("error" in first) {
335
- report(node, "DBError: " +
336
- first.error.replace(/\$(\d+)/, (_, d) => `$${prefix}${argNames[parseInt(d, 10) - 1]}${suffix}`));
337
- return;
338
- }
339
- else {
340
- description = first.description;
341
- }
360
+ description = first.description;
342
361
  }
343
- if (description == null) {
344
- throw new Error("Failed to get description of query");
362
+ }
363
+ if (description == null) {
364
+ throw new Error("Failed to get description of query");
365
+ }
366
+ const err = checkQueryParams(params, description.parameters, argNames, typeChecker);
367
+ if (err != null) {
368
+ report(err.node || node, err.message);
369
+ }
370
+ const isResultCall = ts.isPropertyAccessExpression(parent.expression) &&
371
+ parent.expression.name.text === "result";
372
+ if (isResultCall) {
373
+ return;
374
+ }
375
+ const ppp = parent.parent.parent;
376
+ if (ts.isVariableDeclaration(ppp)) {
377
+ const parentType = typeChecker.getTypeAtLocation(ppp);
378
+ let rowType = parentType;
379
+ if (rowType.isUnion()) {
380
+ const nonNull = rowType.types.filter((t) => !(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)));
381
+ if (nonNull.length === 1)
382
+ rowType = nonNull[0];
345
383
  }
346
- const err = checkQueryParams(params, description.parameters, argNames, typeChecker);
347
- if (err != null) {
348
- report(err.node || node, err.message);
384
+ if (typeChecker.isArrayType(rowType)) {
385
+ rowType = typeChecker.getTypeArguments(rowType)[0];
349
386
  }
350
- const isResultCall = ts.isPropertyAccessExpression(parent.expression) &&
351
- parent.expression.name.text === "result";
352
- if (isResultCall) {
387
+ if (rowType.flags & ts.TypeFlags.Any) {
388
+ report(node, "Return type is typed as `any`. Use a concrete type that matches the query's returned columns.");
353
389
  return;
354
390
  }
355
- const ppp = parent.parent.parent;
356
- if (ts.isVariableDeclaration(ppp)) {
357
- const parentType = typeChecker.getTypeAtLocation(ppp);
358
- let rowType = parentType;
359
- if (rowType.isUnion()) {
360
- const nonNull = rowType.types.filter((t) => !(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)));
361
- if (nonNull.length === 1)
362
- rowType = nonNull[0];
391
+ for (const col of description.columns) {
392
+ const returnedType = pgTypeToTsForColumns(col.type_info, typeChecker);
393
+ const prop = typeChecker.getPropertyOfType(rowType, col.name);
394
+ if (!prop) {
395
+ report(node, `Return type is missing column "${col.name}" which is returned by the query.`);
396
+ continue;
363
397
  }
364
- if (typeChecker.isArrayType(rowType)) {
365
- rowType = typeChecker.getTypeArguments(rowType)[0];
398
+ const userDefinedType = typeChecker.getTypeOfSymbol(prop);
399
+ if (!returnedType.some((t) => typeChecker.isTypeAssignableTo(t, userDefinedType))) {
400
+ report(node, `Column "${col.name}" typed as ${typeChecker.typeToString(userDefinedType)} but query returns${returnedType.length > 1 ? " one of" : ""} ${returnedType.map((t) => typeChecker.typeToString(t)).join(", ")}`);
366
401
  }
367
- for (const col of description.columns) {
368
- const returnedType = pgTypeToTsForColumns(col.type_info, typeChecker);
369
- const prop = typeChecker.getPropertyOfType(rowType, col.name);
370
- if (!prop) {
371
- report(node, `Return type is missing column "${col.name}" which is returned by the query.`);
372
- continue;
373
- }
374
- const userDefinedType = typeChecker.getTypeOfSymbol(prop);
375
- if (!returnedType.some((t) => typeChecker.isTypeAssignableTo(t, userDefinedType))) {
376
- report(node, `Column "${col.name}" typed as ${typeChecker.typeToString(userDefinedType)} but query returns${returnedType.length > 1 ? " one of" : ""} ${returnedType.map((t) => typeChecker.typeToString(t)).join(", ")}`);
377
- }
378
- }
379
- const expectedNames = new Set(description.columns.map((c) => c.name));
380
- for (const prop of typeChecker.getPropertiesOfType(rowType)) {
381
- if (!expectedNames.has(prop.name)) {
382
- report(node, `Return type has extra property "${prop.name}" not returned by the query`);
383
- }
402
+ }
403
+ const expectedNames = new Set(description.columns.map((c) => c.name));
404
+ for (const prop of typeChecker.getPropertiesOfType(rowType)) {
405
+ if (!expectedNames.has(prop.name)) {
406
+ report(node, `Return type has extra property "${prop.name}" not returned by the query`);
384
407
  }
385
408
  }
386
- });
409
+ }
410
+ }
411
+ async function main() {
412
+ await lint(targetDir);
387
413
  console.log(`${count} errors found`);
388
414
  process.exit(count > 0 ? 1 : 0);
389
415
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sql-linter",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "SQL type-checker",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.ts CHANGED
@@ -55,42 +55,48 @@ async function walk(dir: string): Promise<string[]> {
55
55
  return results;
56
56
  }
57
57
 
58
- async function lintNode(
59
- node: ts.Node,
60
- callback: (
61
- taggedTemplateExpression: ts.TaggedTemplateExpression,
62
- program: ts.Program,
63
- ) => Promise<void>,
64
- program: ts.Program,
65
- ) {
58
+ async function lintNode(node: ts.Node, program: ts.Program) {
66
59
  if (ts.isTaggedTemplateExpression(node)) {
67
- await callback(node, program);
60
+ const reports: ReportEntry[] = [];
61
+ await lintTaggedTemplate(node, program, (n, message) => {
62
+ reports.push({ node: n, message });
63
+ });
64
+ flushReports(node, reports);
68
65
  }
69
66
 
70
67
  const promises: Promise<void>[] = [];
71
68
  ts.forEachChild(node, (n) => {
72
- promises.push(lintNode(n, callback, program));
69
+ promises.push(lintNode(n, program));
73
70
  });
74
71
  await Promise.all(promises);
75
72
  }
76
73
 
77
- async function lint(
78
- dir: string,
79
- callback: (
80
- taggedTemplateExpression: ts.TaggedTemplateExpression,
81
- program: ts.Program,
82
- ) => Promise<void>,
83
- ) {
74
+ async function lint(dir: string) {
84
75
  const fileNames = await walk(dir);
85
- const program = ts.createProgram(fileNames, {
86
- target: ts.ScriptTarget.ES2015,
87
- });
76
+
77
+ const tsconfigPath = ts.findConfigFile(
78
+ dir,
79
+ ts.sys.fileExists,
80
+ "tsconfig.json",
81
+ );
82
+ let compilerOptions: ts.CompilerOptions = { target: ts.ScriptTarget.ES2015 };
83
+ if (tsconfigPath) {
84
+ const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
85
+ const parsed = ts.parseJsonConfigFileContent(
86
+ configFile.config,
87
+ ts.sys,
88
+ path.dirname(tsconfigPath),
89
+ );
90
+ compilerOptions = parsed.options;
91
+ }
92
+
93
+ const program = ts.createProgram(fileNames, compilerOptions);
88
94
 
89
95
  await Promise.all(
90
96
  fileNames.map(async (fileName) => {
91
97
  const sourceFile = program.getSourceFile(fileName);
92
98
  if (!sourceFile) return;
93
- await lintNode(sourceFile, callback, program);
99
+ await lintNode(sourceFile, program);
94
100
  }),
95
101
  );
96
102
  }
@@ -300,6 +306,9 @@ function checkQueryParams(
300
306
 
301
307
  if (argNames != null) {
302
308
  const t = typeChecker.getTypeAtLocation(givenParams);
309
+ if (t.flags & ts.TypeFlags.Any) {
310
+ return null;
311
+ }
303
312
  for (const property of t.getProperties()) {
304
313
  const t = typeChecker.getTypeOfSymbol(property);
305
314
  givenParameters[property.escapedName.toString()] = t;
@@ -324,7 +333,12 @@ function checkQueryParams(
324
333
  for (const expectedParam of expectedParameters) {
325
334
  const name = argNames?.[i] || i;
326
335
  const eName = argNames?.[i] || i + 1;
327
- const paramType = givenParameters[name]!;
336
+ const paramType = givenParameters[name];
337
+ if (paramType == null) {
338
+ return {
339
+ message: `Missing argument for $${eName}`,
340
+ };
341
+ }
328
342
  try {
329
343
  const expected = pgTypeToTsMappingForParams(
330
344
  expectedParam,
@@ -354,171 +368,191 @@ function checkQueryParams(
354
368
 
355
369
  let count = 0;
356
370
 
357
- function report(node: ts.Node, message: string) {
358
- count++;
359
- const sourceFile = node.getSourceFile();
371
+ type ReportEntry = { node: ts.Node; message: string };
372
+ type ReportCallback = (node: ts.Node, message: string) => void;
373
+
374
+ function flushReports(queryNode: ts.Node, reports: ReportEntry[]) {
375
+ if (reports.length === 0) return;
376
+ const sourceFile = queryNode.getSourceFile();
360
377
  const { line, character } = sourceFile.getLineAndCharacterOfPosition(
361
- node.getStart(),
378
+ queryNode.getStart(),
362
379
  );
363
- console.log(`${sourceFile.fileName}:${line}:${character}:
364
- ${chalk.red(message)}
365
- `);
380
+ console.log(`${sourceFile.fileName}:${line}:${character}:`);
381
+ for (const { message } of reports) {
382
+ count++;
383
+ console.log(` ${chalk.red(message)}`);
384
+ }
385
+ console.log();
366
386
  }
367
387
 
368
- async function main() {
369
- await lint(targetDir, async (node, program) => {
370
- let typeChecker = program.getTypeChecker();
388
+ async function lintTaggedTemplate(
389
+ node: ts.TaggedTemplateExpression,
390
+ program: ts.Program,
391
+ report: ReportCallback,
392
+ ) {
393
+ const typeChecker = program.getTypeChecker();
394
+
395
+ if (!ts.isIdentifier(node.tag) || node.tag.escapedText !== "sql") return;
396
+ let sqlStatement: string = (node.template as any).rawText;
397
+ if (sqlStatement == null || sqlStatement.length === 0) {
398
+ report(node, "Empty sql query");
399
+ return;
400
+ }
401
+ const parent = node.parent;
402
+ if (!ts.isCallExpression(parent)) {
403
+ report(
404
+ parent,
405
+ "The parent of a sql`...` call should be a Call expression.",
406
+ );
407
+ return;
408
+ }
409
+ if (parent.arguments.length > 2) {
410
+ report(parent, "Expected at most 2 arguments to this call");
411
+ return;
412
+ }
371
413
 
372
- if (!ts.isIdentifier(node.tag) || node.tag.escapedText !== "sql") return;
373
- let sqlStatement: string = (node.template as any).rawText;
374
- if (sqlStatement == null || sqlStatement.length === 0) {
375
- report(node, "Empty sql query");
414
+ const params = parent.arguments[1];
415
+
416
+ const usesRemappings =
417
+ sqlStatement.includes("$/") || sqlStatement.includes("$(");
418
+ let description: PgDescribe;
419
+ let argNames: string[] | null = null;
420
+ sqlStatement = sqlStatement
421
+ .replaceAll(":csv", "")
422
+ .replaceAll(/[^:]:json/g, "");
423
+
424
+ if (!usesRemappings) {
425
+ const descriptions = await asyncDescribeQueries(dbUrl, [sqlStatement]);
426
+ const first = descriptions[0]!;
427
+ if ("error" in first) {
428
+ report(node, `DBError: ${first.error}`);
376
429
  return;
430
+ } else {
431
+ description = first.description;
377
432
  }
378
- const parent = node.parent;
379
- if (!ts.isCallExpression(parent)) {
433
+ } else {
434
+ argNames = [];
435
+ let prefix = "/";
436
+ let suffix = "/";
437
+ let counter = 1;
438
+ const normalizedStatement = sqlStatement.replaceAll(
439
+ /\$[\/\(]\s*([a-zA-Z0-9_]*)\s*[\/\)]/g,
440
+ (substring, name) => {
441
+ if (substring.endsWith(")")) {
442
+ prefix = "(";
443
+ suffix = ")";
444
+ }
445
+ let index = argNames!.indexOf(name);
446
+ if (index < 0) {
447
+ argNames!.push(name);
448
+ index = counter;
449
+ counter += 1;
450
+ } else {
451
+ index += 1;
452
+ }
453
+ return `$${index}`;
454
+ },
455
+ );
456
+ const descriptions = await asyncDescribeQueries(dbUrl, [
457
+ normalizedStatement,
458
+ ]);
459
+ const first = descriptions[0]!;
460
+ if ("error" in first) {
380
461
  report(
381
- parent,
382
- "The parent of a sql`...` call should be a Call expression.",
462
+ node,
463
+ "DBError: " +
464
+ first.error.replace(
465
+ /\$(\d+)/,
466
+ (_, d) => `$${prefix}${argNames![parseInt(d, 10) - 1]}${suffix}`,
467
+ ),
383
468
  );
384
469
  return;
385
- }
386
- if (parent.arguments.length > 2) {
387
- report(parent, "Expected at most 2 arguments to this call");
388
- return;
389
- }
390
-
391
- const params = parent.arguments[1];
392
-
393
- const usesRemappings =
394
- sqlStatement.includes("$/") || sqlStatement.includes("$(");
395
- let description: PgDescribe;
396
- let argNames: string[] | null = null;
397
- sqlStatement = sqlStatement
398
- .replaceAll(":csv", "")
399
- .replaceAll(/[^:]:json/g, "");
400
-
401
- if (!usesRemappings) {
402
- const descriptions = await asyncDescribeQueries(dbUrl, [sqlStatement]);
403
- const first = descriptions[0]!;
404
- if ("error" in first) {
405
- report(node, `DBError: ${first.error}`);
406
- return;
407
- } else {
408
- description = first.description;
409
- }
410
470
  } else {
411
- argNames = [];
412
- let prefix = "/";
413
- let suffix = "/";
414
- let counter = 1;
415
- const normalizedStatement = sqlStatement.replaceAll(
416
- /\$[\/\(]\s*([a-zA-Z0-9_]*)\s*[\/\)]/g,
417
- (substring, name) => {
418
- if (substring.endsWith(")")) {
419
- prefix = "(";
420
- suffix = ")";
421
- }
422
- let index = argNames!.indexOf(name);
423
- if (index < 0) {
424
- argNames!.push(name);
425
- index = counter;
426
- counter += 1;
427
- } else {
428
- index += 1;
429
- }
430
- return `$${index}`;
431
- },
432
- );
433
- const descriptions = await asyncDescribeQueries(dbUrl, [
434
- normalizedStatement,
435
- ]);
436
- const first = descriptions[0]!;
437
- if ("error" in first) {
438
- report(
439
- node,
440
- "DBError: " +
441
- first.error.replace(
442
- /\$(\d+)/,
443
- (_, d) => `$${prefix}${argNames![parseInt(d, 10) - 1]}${suffix}`,
444
- ),
445
- );
446
- return;
447
- } else {
448
- description = first.description;
449
- }
471
+ description = first.description;
450
472
  }
473
+ }
451
474
 
452
- if (description == null) {
453
- throw new Error("Failed to get description of query");
454
- }
475
+ if (description == null) {
476
+ throw new Error("Failed to get description of query");
477
+ }
455
478
 
456
- const err = checkQueryParams(
457
- params,
458
- description.parameters,
459
- argNames,
460
- typeChecker,
461
- );
462
- if (err != null) {
463
- report(err.node || node, err.message);
479
+ const err = checkQueryParams(
480
+ params,
481
+ description.parameters,
482
+ argNames,
483
+ typeChecker,
484
+ );
485
+ if (err != null) {
486
+ report(err.node || node, err.message);
487
+ }
488
+
489
+ const isResultCall =
490
+ ts.isPropertyAccessExpression(parent.expression) &&
491
+ parent.expression.name.text === "result";
492
+ if (isResultCall) {
493
+ return;
494
+ }
495
+
496
+ const ppp = parent.parent.parent;
497
+ if (ts.isVariableDeclaration(ppp)) {
498
+ const parentType = typeChecker.getTypeAtLocation(ppp);
499
+
500
+ let rowType = parentType;
501
+ if (rowType.isUnion()) {
502
+ const nonNull = rowType.types.filter(
503
+ (t) => !(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)),
504
+ );
505
+ if (nonNull.length === 1) rowType = nonNull[0]!;
506
+ }
507
+ if ((typeChecker as any).isArrayType(rowType)) {
508
+ rowType = typeChecker.getTypeArguments(rowType as ts.TypeReference)[0]!;
464
509
  }
465
510
 
466
- const isResultCall =
467
- ts.isPropertyAccessExpression(parent.expression) &&
468
- parent.expression.name.text === "result";
469
- if (isResultCall) {
511
+ if (rowType.flags & ts.TypeFlags.Any) {
512
+ report(
513
+ node,
514
+ "Return type is typed as `any`. Use a concrete type that matches the query's returned columns.",
515
+ );
470
516
  return;
471
517
  }
472
518
 
473
- const ppp = parent.parent.parent;
474
- if (ts.isVariableDeclaration(ppp)) {
475
- const parentType = typeChecker.getTypeAtLocation(ppp);
476
-
477
- let rowType = parentType;
478
- if (rowType.isUnion()) {
479
- const nonNull = rowType.types.filter(
480
- (t) => !(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)),
519
+ for (const col of description.columns) {
520
+ const returnedType = pgTypeToTsForColumns(col.type_info, typeChecker);
521
+ const prop = typeChecker.getPropertyOfType(rowType, col.name);
522
+ if (!prop) {
523
+ report(
524
+ node,
525
+ `Return type is missing column "${col.name}" which is returned by the query.`,
481
526
  );
482
- if (nonNull.length === 1) rowType = nonNull[0]!;
527
+ continue;
483
528
  }
484
- if ((typeChecker as any).isArrayType(rowType)) {
485
- rowType = typeChecker.getTypeArguments(rowType as ts.TypeReference)[0]!;
486
- }
487
-
488
- for (const col of description.columns) {
489
- const returnedType = pgTypeToTsForColumns(col.type_info, typeChecker);
490
- const prop = typeChecker.getPropertyOfType(rowType, col.name);
491
- if (!prop) {
492
- report(
493
- node,
494
- `Return type is missing column "${col.name}" which is returned by the query.`,
495
- );
496
- continue;
497
- }
498
- const userDefinedType = typeChecker.getTypeOfSymbol(prop);
499
- if (
500
- !returnedType.some((t) =>
501
- typeChecker.isTypeAssignableTo(t, userDefinedType),
502
- )
503
- ) {
504
- report(
505
- node,
506
- `Column "${col.name}" typed as ${typeChecker.typeToString(userDefinedType)} but query returns${returnedType.length > 1 ? " one of" : ""} ${returnedType.map((t) => typeChecker.typeToString(t)).join(", ")}`,
507
- );
508
- }
529
+ const userDefinedType = typeChecker.getTypeOfSymbol(prop);
530
+ if (
531
+ !returnedType.some((t) =>
532
+ typeChecker.isTypeAssignableTo(t, userDefinedType),
533
+ )
534
+ ) {
535
+ report(
536
+ node,
537
+ `Column "${col.name}" typed as ${typeChecker.typeToString(userDefinedType)} but query returns${returnedType.length > 1 ? " one of" : ""} ${returnedType.map((t) => typeChecker.typeToString(t)).join(", ")}`,
538
+ );
509
539
  }
540
+ }
510
541
 
511
- const expectedNames = new Set(description.columns.map((c) => c.name));
512
- for (const prop of typeChecker.getPropertiesOfType(rowType)) {
513
- if (!expectedNames.has(prop.name)) {
514
- report(
515
- node,
516
- `Return type has extra property "${prop.name}" not returned by the query`,
517
- );
518
- }
542
+ const expectedNames = new Set(description.columns.map((c) => c.name));
543
+ for (const prop of typeChecker.getPropertiesOfType(rowType)) {
544
+ if (!expectedNames.has(prop.name)) {
545
+ report(
546
+ node,
547
+ `Return type has extra property "${prop.name}" not returned by the query`,
548
+ );
519
549
  }
520
550
  }
521
- });
551
+ }
552
+ }
553
+
554
+ async function main() {
555
+ await lint(targetDir);
522
556
 
523
557
  console.log(`${count} errors found`);
524
558
  process.exit(count > 0 ? 1 : 0);