sql-linter 0.1.0 → 0.1.2

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,134 @@ 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
+ const params = parent.arguments[1];
308
+ const usesRemappings = sqlStatement.includes("$/") || sqlStatement.includes("$(");
309
+ let description;
310
+ let argNames = null;
311
+ sqlStatement = sqlStatement
312
+ .replaceAll(":csv", "")
313
+ .replaceAll(/[^:]:json/g, "");
314
+ if (!usesRemappings) {
315
+ const descriptions = await asyncDescribeQueries(dbUrl, [sqlStatement]);
316
+ const first = descriptions[0];
317
+ if ("error" in first) {
318
+ report(node, `DBError: ${first.error}`);
285
319
  return;
286
320
  }
287
- if (parent.arguments.length > 2) {
288
- report(parent, "Expected at most 2 arguments to this call");
289
- return;
321
+ else {
322
+ description = first.description;
290
323
  }
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;
324
+ }
325
+ else {
326
+ argNames = [];
327
+ let prefix = "/";
328
+ let suffix = "/";
329
+ let counter = 1;
330
+ const normalizedStatement = sqlStatement.replaceAll(/\$[\/\(]\s*([a-zA-Z0-9_]*)\s*[\/\)]/g, (substring, name) => {
331
+ if (substring.endsWith(")")) {
332
+ prefix = "(";
333
+ suffix = ")";
334
+ }
335
+ let index = argNames.indexOf(name);
336
+ if (index < 0) {
337
+ argNames.push(name);
338
+ index = counter;
339
+ counter += 1;
304
340
  }
305
341
  else {
306
- description = first.description;
342
+ index += 1;
307
343
  }
344
+ return `$${index}`;
345
+ });
346
+ const descriptions = await asyncDescribeQueries(dbUrl, [
347
+ normalizedStatement,
348
+ ]);
349
+ const first = descriptions[0];
350
+ if ("error" in first) {
351
+ report(node, "DBError: " +
352
+ first.error.replace(/\$(\d+)/, (_, d) => `$${prefix}${argNames[parseInt(d, 10) - 1]}${suffix}`));
353
+ return;
308
354
  }
309
355
  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
- }
356
+ description = first.description;
342
357
  }
343
- if (description == null) {
344
- throw new Error("Failed to get description of query");
358
+ }
359
+ if (description == null) {
360
+ throw new Error("Failed to get description of query");
361
+ }
362
+ const err = checkQueryParams(params, description.parameters, argNames, typeChecker);
363
+ if (err != null) {
364
+ report(err.node || node, err.message);
365
+ }
366
+ const isResultCall = ts.isPropertyAccessExpression(parent.expression) &&
367
+ parent.expression.name.text === "result";
368
+ if (isResultCall) {
369
+ return;
370
+ }
371
+ const ppp = parent.parent.parent;
372
+ if (ts.isVariableDeclaration(ppp)) {
373
+ const parentType = typeChecker.getTypeAtLocation(ppp);
374
+ let rowType = parentType;
375
+ if (rowType.isUnion()) {
376
+ const nonNull = rowType.types.filter((t) => !(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)));
377
+ if (nonNull.length === 1)
378
+ rowType = nonNull[0];
345
379
  }
346
- const err = checkQueryParams(params, description.parameters, argNames, typeChecker);
347
- if (err != null) {
348
- report(err.node || node, err.message);
380
+ if (typeChecker.isArrayType(rowType)) {
381
+ rowType = typeChecker.getTypeArguments(rowType)[0];
349
382
  }
350
- const isResultCall = ts.isPropertyAccessExpression(parent.expression) &&
351
- parent.expression.name.text === "result";
352
- if (isResultCall) {
383
+ if (rowType.flags & ts.TypeFlags.Any) {
384
+ report(node, "Return type is typed as `any`. Use a concrete type that matches the query's returned columns.");
353
385
  return;
354
386
  }
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];
387
+ for (const col of description.columns) {
388
+ const returnedType = pgTypeToTsForColumns(col.type_info, typeChecker);
389
+ const prop = typeChecker.getPropertyOfType(rowType, col.name);
390
+ if (!prop) {
391
+ report(node, `Return type is missing column "${col.name}" which is returned by the query.`);
392
+ continue;
363
393
  }
364
- if (typeChecker.isArrayType(rowType)) {
365
- rowType = typeChecker.getTypeArguments(rowType)[0];
394
+ const userDefinedType = typeChecker.getTypeOfSymbol(prop);
395
+ if (!returnedType.some((t) => typeChecker.isTypeAssignableTo(t, userDefinedType))) {
396
+ 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
397
  }
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
- }
398
+ }
399
+ const expectedNames = new Set(description.columns.map((c) => c.name));
400
+ for (const prop of typeChecker.getPropertiesOfType(rowType)) {
401
+ if (!expectedNames.has(prop.name)) {
402
+ report(node, `Return type has extra property "${prop.name}" not returned by the query`);
384
403
  }
385
404
  }
386
- });
405
+ }
406
+ }
407
+ async function main() {
408
+ await lint(targetDir);
387
409
  console.log(`${count} errors found`);
388
410
  process.exit(count > 0 ? 1 : 0);
389
411
  }
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.2",
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,187 @@ 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
+ }
371
409
 
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");
410
+ const params = parent.arguments[1];
411
+
412
+ const usesRemappings =
413
+ sqlStatement.includes("$/") || sqlStatement.includes("$(");
414
+ let description: PgDescribe;
415
+ let argNames: string[] | null = null;
416
+ sqlStatement = sqlStatement
417
+ .replaceAll(":csv", "")
418
+ .replaceAll(/[^:]:json/g, "");
419
+
420
+ if (!usesRemappings) {
421
+ const descriptions = await asyncDescribeQueries(dbUrl, [sqlStatement]);
422
+ const first = descriptions[0]!;
423
+ if ("error" in first) {
424
+ report(node, `DBError: ${first.error}`);
376
425
  return;
426
+ } else {
427
+ description = first.description;
377
428
  }
378
- const parent = node.parent;
379
- if (!ts.isCallExpression(parent)) {
429
+ } else {
430
+ argNames = [];
431
+ let prefix = "/";
432
+ let suffix = "/";
433
+ let counter = 1;
434
+ const normalizedStatement = sqlStatement.replaceAll(
435
+ /\$[\/\(]\s*([a-zA-Z0-9_]*)\s*[\/\)]/g,
436
+ (substring, name) => {
437
+ if (substring.endsWith(")")) {
438
+ prefix = "(";
439
+ suffix = ")";
440
+ }
441
+ let index = argNames!.indexOf(name);
442
+ if (index < 0) {
443
+ argNames!.push(name);
444
+ index = counter;
445
+ counter += 1;
446
+ } else {
447
+ index += 1;
448
+ }
449
+ return `$${index}`;
450
+ },
451
+ );
452
+ const descriptions = await asyncDescribeQueries(dbUrl, [
453
+ normalizedStatement,
454
+ ]);
455
+ const first = descriptions[0]!;
456
+ if ("error" in first) {
380
457
  report(
381
- parent,
382
- "The parent of a sql`...` call should be a Call expression.",
458
+ node,
459
+ "DBError: " +
460
+ first.error.replace(
461
+ /\$(\d+)/,
462
+ (_, d) => `$${prefix}${argNames![parseInt(d, 10) - 1]}${suffix}`,
463
+ ),
383
464
  );
384
465
  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
466
  } 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
- }
467
+ description = first.description;
450
468
  }
469
+ }
451
470
 
452
- if (description == null) {
453
- throw new Error("Failed to get description of query");
454
- }
471
+ if (description == null) {
472
+ throw new Error("Failed to get description of query");
473
+ }
455
474
 
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);
475
+ const err = checkQueryParams(
476
+ params,
477
+ description.parameters,
478
+ argNames,
479
+ typeChecker,
480
+ );
481
+ if (err != null) {
482
+ report(err.node || node, err.message);
483
+ }
484
+
485
+ const isResultCall =
486
+ ts.isPropertyAccessExpression(parent.expression) &&
487
+ parent.expression.name.text === "result";
488
+ if (isResultCall) {
489
+ return;
490
+ }
491
+
492
+ const ppp = parent.parent.parent;
493
+ if (ts.isVariableDeclaration(ppp)) {
494
+ const parentType = typeChecker.getTypeAtLocation(ppp);
495
+
496
+ let rowType = parentType;
497
+ if (rowType.isUnion()) {
498
+ const nonNull = rowType.types.filter(
499
+ (t) => !(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)),
500
+ );
501
+ if (nonNull.length === 1) rowType = nonNull[0]!;
502
+ }
503
+ if ((typeChecker as any).isArrayType(rowType)) {
504
+ rowType = typeChecker.getTypeArguments(rowType as ts.TypeReference)[0]!;
464
505
  }
465
506
 
466
- const isResultCall =
467
- ts.isPropertyAccessExpression(parent.expression) &&
468
- parent.expression.name.text === "result";
469
- if (isResultCall) {
507
+ if (rowType.flags & ts.TypeFlags.Any) {
508
+ report(
509
+ node,
510
+ "Return type is typed as `any`. Use a concrete type that matches the query's returned columns.",
511
+ );
470
512
  return;
471
513
  }
472
514
 
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)),
515
+ for (const col of description.columns) {
516
+ const returnedType = pgTypeToTsForColumns(col.type_info, typeChecker);
517
+ const prop = typeChecker.getPropertyOfType(rowType, col.name);
518
+ if (!prop) {
519
+ report(
520
+ node,
521
+ `Return type is missing column "${col.name}" which is returned by the query.`,
481
522
  );
482
- if (nonNull.length === 1) rowType = nonNull[0]!;
483
- }
484
- if ((typeChecker as any).isArrayType(rowType)) {
485
- rowType = typeChecker.getTypeArguments(rowType as ts.TypeReference)[0]!;
523
+ continue;
486
524
  }
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
- }
525
+ const userDefinedType = typeChecker.getTypeOfSymbol(prop);
526
+ if (
527
+ !returnedType.some((t) =>
528
+ typeChecker.isTypeAssignableTo(t, userDefinedType),
529
+ )
530
+ ) {
531
+ report(
532
+ node,
533
+ `Column "${col.name}" typed as ${typeChecker.typeToString(userDefinedType)} but query returns${returnedType.length > 1 ? " one of" : ""} ${returnedType.map((t) => typeChecker.typeToString(t)).join(", ")}`,
534
+ );
509
535
  }
536
+ }
510
537
 
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
- }
538
+ const expectedNames = new Set(description.columns.map((c) => c.name));
539
+ for (const prop of typeChecker.getPropertiesOfType(rowType)) {
540
+ if (!expectedNames.has(prop.name)) {
541
+ report(
542
+ node,
543
+ `Return type has extra property "${prop.name}" not returned by the query`,
544
+ );
519
545
  }
520
546
  }
521
- });
547
+ }
548
+ }
549
+
550
+ async function main() {
551
+ await lint(targetDir);
522
552
 
523
553
  console.log(`${count} errors found`);
524
554
  process.exit(count > 0 ? 1 : 0);