sql-typechecker 0.0.18 → 0.0.21
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/out/cli.js +92 -37
- package/out/cli.js.map +2 -2
- package/package.json +1 -1
package/out/cli.js
CHANGED
|
@@ -4110,7 +4110,7 @@ var require_lodash = __commonJS((exports2, module2) => {
|
|
|
4110
4110
|
function isNull(value2) {
|
|
4111
4111
|
return value2 === null;
|
|
4112
4112
|
}
|
|
4113
|
-
function
|
|
4113
|
+
function isNil2(value2) {
|
|
4114
4114
|
return value2 == null;
|
|
4115
4115
|
}
|
|
4116
4116
|
function isNumber(value2) {
|
|
@@ -5174,7 +5174,7 @@ var require_lodash = __commonJS((exports2, module2) => {
|
|
|
5174
5174
|
lodash.isMatchWith = isMatchWith;
|
|
5175
5175
|
lodash.isNaN = isNaN2;
|
|
5176
5176
|
lodash.isNative = isNative;
|
|
5177
|
-
lodash.isNil =
|
|
5177
|
+
lodash.isNil = isNil2;
|
|
5178
5178
|
lodash.isNull = isNull;
|
|
5179
5179
|
lodash.isNumber = isNumber;
|
|
5180
5180
|
lodash.isObject = isObject;
|
|
@@ -226429,8 +226429,8 @@ ${fromBody}`;
|
|
|
226429
226429
|
jsxMode = true;
|
|
226430
226430
|
forceNoIndent = true;
|
|
226431
226431
|
const wrap = (doc2) => [ifBreak("("), indent([softline, doc2]), softline, ifBreak(")")];
|
|
226432
|
-
const
|
|
226433
|
-
parts.push(" ? ",
|
|
226432
|
+
const isNil2 = (node2) => node2.type === "NullLiteral" || node2.type === "Literal" && node2.value === null || node2.type === "Identifier" && node2.name === "undefined";
|
|
226433
|
+
parts.push(" ? ", isNil2(consequentNode) ? print(consequentNodePropertyName) : wrap(print(consequentNodePropertyName)), " : ", alternateNode.type === node.type || isNil2(alternateNode) ? print(alternateNodePropertyName) : wrap(print(alternateNodePropertyName)));
|
|
226434
226434
|
} else {
|
|
226435
226435
|
const part = [line, "? ", consequentNode.type === node.type ? ifBreak("", "(") : "", align(2, print(consequentNodePropertyName)), consequentNode.type === node.type ? ifBreak("", ")") : "", line, ": ", alternateNode.type === node.type ? print(alternateNodePropertyName) : align(2, print(alternateNodePropertyName))];
|
|
226436
226436
|
parts.push(parent.type !== node.type || parent[alternateNodePropertyName] === node || isParentTest ? part : options.useTabs ? dedent(indent(part)) : align(Math.max(0, options.tabWidth - 2), part));
|
|
@@ -235895,13 +235895,14 @@ ${text}`;
|
|
|
235895
235895
|
|
|
235896
235896
|
// src/cli.ts
|
|
235897
235897
|
var fs = __toModule(require("fs/promises"));
|
|
235898
|
-
var
|
|
235898
|
+
var import_lodash2 = __toModule(require_lodash());
|
|
235899
235899
|
var path = __toModule(require("path"));
|
|
235900
235900
|
var import_pgsql_ast_parser2 = __toModule(require_lib());
|
|
235901
235901
|
var prettier = __toModule(require_prettier());
|
|
235902
235902
|
|
|
235903
235903
|
// src/typecheck.ts
|
|
235904
235904
|
var import_assert = __toModule(require("assert"));
|
|
235905
|
+
var import_lodash = __toModule(require_lodash());
|
|
235905
235906
|
var import_pgsql_ast_parser = __toModule(require_lib());
|
|
235906
235907
|
|
|
235907
235908
|
// src/normalize.ts
|
|
@@ -241688,6 +241689,10 @@ var BuiltinTypes = {
|
|
|
241688
241689
|
Jsonb: {
|
|
241689
241690
|
kind: "scalar",
|
|
241690
241691
|
name: {name: "jsonb"}
|
|
241692
|
+
},
|
|
241693
|
+
Null: {
|
|
241694
|
+
kind: "scalar",
|
|
241695
|
+
name: {name: "null"}
|
|
241691
241696
|
}
|
|
241692
241697
|
};
|
|
241693
241698
|
var allNumericBuiltinTypes = [
|
|
@@ -241907,15 +241912,30 @@ function unifyCallGeneral(call, argTypes, expectedArgs, returnT) {
|
|
|
241907
241912
|
return returnT;
|
|
241908
241913
|
}
|
|
241909
241914
|
function castScalars(e, source, target, type) {
|
|
241915
|
+
const matchingCast = findMatchingCast([source.name], source, target, type);
|
|
241916
|
+
if (matchingCast === null) {
|
|
241917
|
+
throw new TypeMismatch(e, {expected: target, actual: source});
|
|
241918
|
+
}
|
|
241919
|
+
}
|
|
241920
|
+
function findMatchingCast(visited, from, to, type) {
|
|
241910
241921
|
const casts = builtincasts;
|
|
241911
|
-
if (eqQNames(
|
|
241912
|
-
return;
|
|
241922
|
+
if (eqQNames(from.name, to.name)) {
|
|
241923
|
+
return {source: from, target: to, type: "implicit"};
|
|
241913
241924
|
} else {
|
|
241914
|
-
const
|
|
241915
|
-
|
|
241916
|
-
|
|
241925
|
+
const halfMatching = casts.filter((c) => eqQNames(c.source.name, from.name) && (c.type === type || c.type === "implicit" && type === "assignment" || c.type === "implicit" && type === "explicit") && !visited.some((v) => eqQNames(v, c.target.name)));
|
|
241926
|
+
const matchingCast = halfMatching.find((c) => eqQNames(c.target.name, to.name));
|
|
241927
|
+
if (!import_lodash.isNil(matchingCast)) {
|
|
241928
|
+
return matchingCast;
|
|
241929
|
+
} else if (type === "explicit") {
|
|
241930
|
+
for (let halfM of halfMatching) {
|
|
241931
|
+
const found = findMatchingCast(visited.concat(from.name), halfM.target, to, type);
|
|
241932
|
+
if (!import_lodash.isNil(found)) {
|
|
241933
|
+
return found;
|
|
241934
|
+
}
|
|
241935
|
+
}
|
|
241936
|
+
return null;
|
|
241917
241937
|
} else {
|
|
241918
|
-
|
|
241938
|
+
return null;
|
|
241919
241939
|
}
|
|
241920
241940
|
}
|
|
241921
241941
|
}
|
|
@@ -242029,8 +242049,12 @@ function elabSelect(g, c, s) {
|
|
|
242029
242049
|
kind: "record",
|
|
242030
242050
|
fields: fr.type.fields.map((fi) => {
|
|
242031
242051
|
const foundNullabilityInference = inferredNullability.find((inf) => eqQNames(inf.fromName, fr.name) && inf.fieldName === fi.name?.name);
|
|
242032
|
-
|
|
242033
|
-
|
|
242052
|
+
if (foundNullabilityInference && isNullable(fi.type)) {
|
|
242053
|
+
const t = foundNullabilityInference.isNull === true ? BuiltinTypes.Null : unnullify(fi.type);
|
|
242054
|
+
return {name: fi.name, type: t};
|
|
242055
|
+
} else {
|
|
242056
|
+
return fi;
|
|
242057
|
+
}
|
|
242034
242058
|
})
|
|
242035
242059
|
}
|
|
242036
242060
|
}))
|
|
@@ -242043,13 +242067,12 @@ function elabSelect(g, c, s) {
|
|
|
242043
242067
|
const names = [];
|
|
242044
242068
|
const fields = (s.columns || []).flatMap((c2) => {
|
|
242045
242069
|
const n = c2.alias ? c2.alias : deriveNameFromExpr(c2.expr);
|
|
242046
|
-
if (n
|
|
242047
|
-
|
|
242048
|
-
|
|
242049
|
-
|
|
242050
|
-
|
|
242070
|
+
if (!import_lodash.isNil(n)) {
|
|
242071
|
+
if (names.includes(n.name)) {
|
|
242072
|
+
throw new DuplicateFieldNames(c2.expr, n.name);
|
|
242073
|
+
}
|
|
242074
|
+
names.push(n.name);
|
|
242051
242075
|
}
|
|
242052
|
-
names.push(n.name);
|
|
242053
242076
|
const t = elabExpr(g, newC, c2.expr);
|
|
242054
242077
|
if (t.kind === "record") {
|
|
242055
242078
|
if (t.fields.length === 0) {
|
|
@@ -242468,12 +242491,15 @@ var ColumnsMismatch = class extends ErrorWithLocation {
|
|
|
242468
242491
|
};
|
|
242469
242492
|
var KindMismatch = class extends ErrorWithLocation {
|
|
242470
242493
|
constructor(e, type, errormsg) {
|
|
242471
|
-
super(e._location, `
|
|
242472
|
-
|
|
242473
|
-
}
|
|
242474
|
-
|
|
242475
|
-
|
|
242476
|
-
|
|
242494
|
+
super(e._location, `
|
|
242495
|
+
KindMismatch:
|
|
242496
|
+
${import_pgsql_ast_parser.toSql.expr(e)}
|
|
242497
|
+
|
|
242498
|
+
${errormsg}}
|
|
242499
|
+
|
|
242500
|
+
Type:
|
|
242501
|
+
${JSON.stringify(type)}
|
|
242502
|
+
`);
|
|
242477
242503
|
}
|
|
242478
242504
|
};
|
|
242479
242505
|
var DuplicateFieldNames = class extends ErrorWithLocation {
|
|
@@ -242510,6 +242536,22 @@ ${JSON.stringify(ts.actual)}}
|
|
|
242510
242536
|
this.mess = mess;
|
|
242511
242537
|
}
|
|
242512
242538
|
};
|
|
242539
|
+
var CannotCast = class extends ErrorWithLocation {
|
|
242540
|
+
constructor(e, ts) {
|
|
242541
|
+
super(e._location, `
|
|
242542
|
+
Cannot cast:
|
|
242543
|
+
${JSON.stringify(ts.from)}
|
|
242544
|
+
|
|
242545
|
+
to
|
|
242546
|
+
${JSON.stringify(ts.to)}}
|
|
242547
|
+
|
|
242548
|
+
in expr:
|
|
242549
|
+
${import_pgsql_ast_parser.toSql.expr(e)}
|
|
242550
|
+
`);
|
|
242551
|
+
this.from = ts.from;
|
|
242552
|
+
this.to = ts.to;
|
|
242553
|
+
}
|
|
242554
|
+
};
|
|
242513
242555
|
var warnings = [];
|
|
242514
242556
|
function registerWarning(e, message) {
|
|
242515
242557
|
warnings.push([e, message]);
|
|
@@ -242814,6 +242856,9 @@ function elabCall(g, c, e) {
|
|
|
242814
242856
|
if (eqQNames(e.function, {name: "nextval"})) {
|
|
242815
242857
|
return unifyCallGeneral(e, argTypes, [BuiltinTypes.Text], BuiltinTypes.Bigint);
|
|
242816
242858
|
}
|
|
242859
|
+
if (eqQNames(e.function, {name: "now"})) {
|
|
242860
|
+
return unifyCallGeneral(e, argTypes, [], BuiltinTypes.Timestamp);
|
|
242861
|
+
}
|
|
242817
242862
|
if (eqQNames(e.function, {name: "any"}) || eqQNames(e.function, {name: "some"}) || eqQNames(e.function, {name: "all"})) {
|
|
242818
242863
|
if (e.args.length !== 1) {
|
|
242819
242864
|
throw new InvalidArguments(e, e.function, argTypes);
|
|
@@ -242863,7 +242908,6 @@ function elabCall(g, c, e) {
|
|
|
242863
242908
|
return unifyCallGeneral(e, argTypes, [BuiltinTypes.AnyScalar], BuiltinTypes.Boolean);
|
|
242864
242909
|
}
|
|
242865
242910
|
if (eqQNames(e.function, {name: "coalesce"}) || eqQNames(e.function, {name: "nullif"})) {
|
|
242866
|
-
debugger;
|
|
242867
242911
|
if (e.args.length === 0) {
|
|
242868
242912
|
throw new InvalidArguments(e, e.function, []);
|
|
242869
242913
|
}
|
|
@@ -243051,7 +243095,11 @@ function elabExpr(g, c, e) {
|
|
|
243051
243095
|
} else if (e.type === "cast") {
|
|
243052
243096
|
const operandT = elabExpr(g, c, e.operand);
|
|
243053
243097
|
const toT = mkType(e.to, []);
|
|
243054
|
-
|
|
243098
|
+
try {
|
|
243099
|
+
cast(e, operandT, toT, "explicit");
|
|
243100
|
+
} catch (err) {
|
|
243101
|
+
throw new CannotCast(e, {from: operandT, to: toT});
|
|
243102
|
+
}
|
|
243055
243103
|
if (isNullable(operandT)) {
|
|
243056
243104
|
return toT;
|
|
243057
243105
|
} else {
|
|
@@ -243276,7 +243324,7 @@ function functionToTypescript(f) {
|
|
|
243276
243324
|
return "";
|
|
243277
243325
|
}
|
|
243278
243326
|
}
|
|
243279
|
-
const asExpression = f.returns.kind === "record" ? ` AS ${f.name.name}(${f.returns.fields.map((f2) => (f2.name?.name || "") + " " + showTypeDroppingNullable(f2.type)).join(", ")})` : "";
|
|
243327
|
+
const asExpression = f.returns.kind === "record" ? ` AS ${f.name.name}(${f.returns.fields.map((f2, i) => (f2.name?.name || "field" + i) + " " + showTypeDroppingNullable(f2.type)).join(", ")})` : "";
|
|
243280
243328
|
const recreatedSqlFunctionStatement = `
|
|
243281
243329
|
CREATE FUNCTION ${f.name.name}(${argsForCreateFunction}) RETURNS ${f.multipleRows ? "SETOF " : ""}${f.returns.kind === "record" ? "RECORD" : f.returns.kind === "void" ? "void" : showTypeDroppingNullable(f.returns)} AS
|
|
243282
243330
|
$$${f.code}$$ LANGUAGE ${f.language};
|
|
@@ -243342,15 +243390,15 @@ ${f.name?.name}?: ${showTypeAsTypescriptType(f.type)}`).join(",");
|
|
|
243342
243390
|
const insert = `
|
|
243343
243391
|
export async function insert(pool: Pool, row: {${inputRow}}): Promise<{${primaryKeySingleCol.name.name}: ${showTypeAsTypescriptType(primaryKeySingleCol.type)}} | null>{
|
|
243344
243392
|
|
|
243345
|
-
const providedFields = Object.keys(row);
|
|
243393
|
+
const providedFields = Object.keys(row) as (keyof typeof row)[];
|
|
243346
243394
|
|
|
243347
243395
|
const res = await pool.query({
|
|
243348
243396
|
text: "INSERT INTO ${showQName(table.name)} (" + (providedFields.join(", ")) + ") VALUES (" + providedFields.map((_, i) => "$" + (i + 1)).join(", ") +") RETURNING ${primaryKeySingleCol.name.name}",
|
|
243349
243397
|
values: providedFields.map(f => row[f]),
|
|
243350
243398
|
rowMode: "array",
|
|
243351
243399
|
});
|
|
243352
|
-
if (res && res[0]){
|
|
243353
|
-
return {${primaryKeySingleCol.name.name}: res[0][0]};
|
|
243400
|
+
if (res && res.rows[0]){
|
|
243401
|
+
return {${primaryKeySingleCol.name.name}: res.rows[0][0]};
|
|
243354
243402
|
} else {
|
|
243355
243403
|
return null;
|
|
243356
243404
|
}
|
|
@@ -243360,12 +243408,12 @@ ${f.name?.name}?: ${showTypeAsTypescriptType(f.type)}`).join(",");
|
|
|
243360
243408
|
const update = `
|
|
243361
243409
|
export async function update(pool: Pool, pk: {${primaryKeySingleCol.name.name}: ${showTypeAsTypescriptType(primaryKeySingleCol.type)}}, row: {${inputRowForUpdate}}): Promise<null>{
|
|
243362
243410
|
|
|
243363
|
-
const providedFields = Object.keys(row);
|
|
243411
|
+
const providedFields = Object.keys(row) as (keyof typeof row)[] ;
|
|
243364
243412
|
if (providedFields.length === 0){ return null; }
|
|
243365
243413
|
|
|
243366
243414
|
await pool.query({
|
|
243367
243415
|
text: "UPDATE ${showQName(table.name)} SET " + providedFields.map((f, i) => f + " = $" + (i + 2)).join(", ") + " WHERE ${primaryKeySingleCol.name.name} = $1",
|
|
243368
|
-
values: [pk.${primaryKeySingleCol.name.name}].concat(providedFields.map(f => row[f])),
|
|
243416
|
+
values: ([pk.${primaryKeySingleCol.name.name}] as any[]).concat(providedFields.map(f => row[f])),
|
|
243369
243417
|
rowMode: "array",
|
|
243370
243418
|
});
|
|
243371
243419
|
return null;
|
|
@@ -243448,6 +243496,12 @@ async function go() {
|
|
|
243448
243496
|
}
|
|
243449
243497
|
await fs.appendFile(domainFile, `
|
|
243450
243498
|
`, "utf-8");
|
|
243499
|
+
const tablesIndexFile = path.format({
|
|
243500
|
+
dir: outDir,
|
|
243501
|
+
name: "tables",
|
|
243502
|
+
ext: ".ts"
|
|
243503
|
+
});
|
|
243504
|
+
await prepOutFile(tablesIndexFile);
|
|
243451
243505
|
await fs.mkdir(path.join(outDir, "tables"), {recursive: true});
|
|
243452
243506
|
for (let table of g.tables) {
|
|
243453
243507
|
const tableOutFile = path.format({
|
|
@@ -243459,6 +243513,8 @@ async function go() {
|
|
|
243459
243513
|
const text = genCrudOperations(table);
|
|
243460
243514
|
await fs.appendFile(tableOutFile, mkImportDomainsStatement(g.domains, tableOutFile, domainFile), "utf8");
|
|
243461
243515
|
await fs.appendFile(tableOutFile, prettier.format(text, {parser: "typescript"}), "utf-8");
|
|
243516
|
+
await fs.appendFile(tablesIndexFile, `export * as ${table.name.name} from "./tables/${table.name.name}";
|
|
243517
|
+
`);
|
|
243462
243518
|
}
|
|
243463
243519
|
for (let f of allStatements) {
|
|
243464
243520
|
const createFunctionStatements = f.statements.filter(isCreateFunctionStatement);
|
|
@@ -243480,14 +243536,13 @@ async function go() {
|
|
|
243480
243536
|
await fs.appendFile(functionsOutFile, writing, "utf-8");
|
|
243481
243537
|
} catch (err) {
|
|
243482
243538
|
if (err instanceof ErrorWithLocation && err.l !== void 0) {
|
|
243483
|
-
debugger;
|
|
243484
243539
|
const found = findCode(st.code || "", err.l);
|
|
243485
243540
|
if (found) {
|
|
243486
243541
|
console.error("");
|
|
243487
|
-
console.error(`
|
|
243542
|
+
console.error(`Typechecking error`);
|
|
243488
243543
|
console.error("");
|
|
243489
243544
|
console.error(found.line);
|
|
243490
|
-
console.error(
|
|
243545
|
+
console.error(import_lodash2.repeat(" ", found.range[0]) + import_lodash2.repeat("^", found.range[1] - found.range[0]));
|
|
243491
243546
|
}
|
|
243492
243547
|
}
|
|
243493
243548
|
console.error(err instanceof Error ? err.message : JSON.stringify(err));
|
|
@@ -243510,7 +243565,7 @@ function findCode(s, l) {
|
|
|
243510
243565
|
lineNumber,
|
|
243511
243566
|
range: [
|
|
243512
243567
|
l.start - counted,
|
|
243513
|
-
|
|
243568
|
+
import_lodash2.min([lineLength, l.end - counted]) || lineLength
|
|
243514
243569
|
]
|
|
243515
243570
|
};
|
|
243516
243571
|
}
|