joist-core 2.3.0-next.89 → 2.3.0-next.90
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.
|
@@ -4,7 +4,7 @@ const require_Expr = require("../Expr.cjs");
|
|
|
4
4
|
let node_util = require("node:util");
|
|
5
5
|
//#region src/expressions/codecs.ts
|
|
6
6
|
/**
|
|
7
|
-
* Chooses one decoder for all possible result values. Columns must agree on SQL type and domain;
|
|
7
|
+
* Chooses one decoder for all possible result values. Columns must agree on a compatible SQL type and domain;
|
|
8
8
|
* literals use that column's encoder. This is conservative: PostgreSQL may accept other combinations,
|
|
9
9
|
* but Joist cannot safely choose their decoder. I.e. Author.id and Book.id both store integers but use different tags.
|
|
10
10
|
*/
|
|
@@ -17,9 +17,9 @@ function chooseExpressionCodec(parsed) {
|
|
|
17
17
|
if (other === first) continue;
|
|
18
18
|
const a = first.outputType;
|
|
19
19
|
const b = other.outputType;
|
|
20
|
-
if (!a || !b || a.dbType
|
|
20
|
+
if (!a || !b || !compatibleDbTypes(a.dbType, b.dbType) || a.domain !== b.domain || a.idMeta !== b.idMeta) {
|
|
21
21
|
const mismatches = !a || !b ? ["unknown codec"] : [
|
|
22
|
-
|
|
22
|
+
...!compatibleDbTypes(a.dbType, b.dbType) ? ["SQL type"] : [],
|
|
23
23
|
...a.domain !== b.domain ? ["domain"] : [],
|
|
24
24
|
...a.idMeta !== b.idMeta ? ["ID target"] : []
|
|
25
25
|
];
|
|
@@ -106,6 +106,11 @@ function describeType(type) {
|
|
|
106
106
|
const domain = typeof type.domain === "function" ? type.domain.name : (0, node_util.inspect)(type.domain, { depth: 0 });
|
|
107
107
|
return `${type.dbType} (domain ${domain}${type.idMeta ? `, ID target ${type.idMeta.type}` : ""})`;
|
|
108
108
|
}
|
|
109
|
+
const compatibleStringDbTypes = /* @__PURE__ */ new Set(["text", "varchar"]);
|
|
110
|
+
/** Allows PostgreSQL scalar string types that resolve to a common string result. */
|
|
111
|
+
function compatibleDbTypes(a, b) {
|
|
112
|
+
return a === b || compatibleStringDbTypes.has(a) && compatibleStringDbTypes.has(b);
|
|
113
|
+
}
|
|
109
114
|
//#endregion
|
|
110
115
|
exports.chooseExpressionCodec = chooseExpressionCodec;
|
|
111
116
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codecs.cjs","names":["BaseExpr","assertNever","inspect"],"sources":["../../src/expressions/codecs.ts"],"sourcesContent":["import { inspect } from \"node:util\";\n\nimport { BaseExpr } from \"../Expr.ts\";\nimport type { TypeInfo } from \"../TypeInfo.ts\";\nimport { assertNever } from \"../utils.ts\";\nimport type { ParsedExpression, ParsedLiteralExpression, ResultCodec } from \"./types.ts\";\n\n/**\n * Chooses one decoder for all possible result values. Columns must agree on SQL type and domain;\n * literals use that column's encoder. This is conservative: PostgreSQL may accept other combinations,\n * but Joist cannot safely choose their decoder. I.e. Author.id and Book.id both store integers but use different tags.\n */\nexport function chooseExpressionCodec(parsed: ParsedExpression): ResultCodec {\n const leaves = expressionLeaves(parsed);\n const expressions = leaves.filter((v): v is BaseExpr => v instanceof BaseExpr);\n const first = expressions[0];\n if (first) {\n for (const other of expressions.slice(1)) {\n if (other === first) continue;\n const a = first.outputType;\n const b = other.outputType;\n if (!a || !b || a.dbType
|
|
1
|
+
{"version":3,"file":"codecs.cjs","names":["BaseExpr","assertNever","inspect"],"sources":["../../src/expressions/codecs.ts"],"sourcesContent":["import { inspect } from \"node:util\";\n\nimport { BaseExpr } from \"../Expr.ts\";\nimport type { TypeInfo } from \"../TypeInfo.ts\";\nimport { assertNever } from \"../utils.ts\";\nimport type { ParsedExpression, ParsedLiteralExpression, ResultCodec } from \"./types.ts\";\n\n/**\n * Chooses one decoder for all possible result values. Columns must agree on a compatible SQL type and domain;\n * literals use that column's encoder. This is conservative: PostgreSQL may accept other combinations,\n * but Joist cannot safely choose their decoder. I.e. Author.id and Book.id both store integers but use different tags.\n */\nexport function chooseExpressionCodec(parsed: ParsedExpression): ResultCodec {\n const leaves = expressionLeaves(parsed);\n const expressions = leaves.filter((v): v is BaseExpr => v instanceof BaseExpr);\n const first = expressions[0];\n if (first) {\n for (const other of expressions.slice(1)) {\n if (other === first) continue;\n const a = first.outputType;\n const b = other.outputType;\n if (!a || !b || !compatibleDbTypes(a.dbType, b.dbType) || a.domain !== b.domain || a.idMeta !== b.idMeta) {\n const mismatches =\n !a || !b\n ? [\"unknown codec\"]\n : [\n ...(!compatibleDbTypes(a.dbType, b.dbType) ? [\"SQL type\"] : []),\n ...(a.domain !== b.domain ? [\"domain\"] : []),\n ...(a.idMeta !== b.idMeta ? [\"ID target\"] : []),\n ];\n throw new Error(\n `Expression operands need matching SQL types and codecs: ${describeType(a)} vs ${describeType(b)}; mismatched ${mismatches.join(\", \")}`,\n );\n }\n }\n for (const leaf of leaves) {\n if (!(leaf instanceof BaseExpr)) checkLiteral(leaf.value, first.outputType);\n }\n return first;\n }\n const literals = leaves.filter((v): v is ParsedLiteralExpression => !(v instanceof BaseExpr));\n const types = literals.map((v) => literalType(v.value)).filter((v) => v !== undefined);\n for (const literal of literals) checkLiteral(literal.value, types[0]);\n return new LiteralCodec(types[0] ?? { dbType: \"text\", domain: String });\n}\n\n/** Gives literal-only expressions a SQL type so PostgreSQL does not return numbers as text. */\nclass LiteralCodec {\n constructor(readonly outputType: TypeInfo) {}\n\n encode(value: unknown): unknown {\n return value;\n }\n\n decode(value: unknown): unknown {\n return this.outputType.domain === BigInt ? BigInt(value as string) : value;\n }\n}\n\n/**\n * Finds parsed operands that share a codec, including NULLIF's comparison operand but not CASE conditions.\n * Each kind selects its own value fields; only CASE's THEN and ELSE expressions contribute a result codec.\n */\nfunction expressionLeaves(parsed: ParsedExpression): (BaseExpr | ParsedLiteralExpression)[] {\n if (parsed instanceof BaseExpr) return [parsed];\n switch (parsed.kind) {\n case \"literal\":\n return [parsed];\n case \"coalesce\":\n return parsed.candidates.flatMap((candidate) => expressionLeaves(candidate));\n case \"nullIf\":\n return [...expressionLeaves(parsed.value), ...expressionLeaves(parsed.equals)];\n case \"greatest\":\n case \"least\":\n return parsed.values.flatMap((value) => expressionLeaves(value));\n case \"case\":\n return [\n ...parsed.whens.flatMap((entry) => expressionLeaves(entry.then)),\n ...(parsed.else ? expressionLeaves(parsed.else) : []),\n ];\n default:\n return assertNever(parsed);\n }\n}\n\n/** Supplies predictable PostgreSQL types for standalone primitive literals. */\nfunction literalType(value: unknown): TypeInfo | undefined {\n if (value === null) return undefined;\n if (typeof value === \"string\") return { dbType: \"text\", domain: String, arrayElementSafe: true };\n if (typeof value === \"number\") return { dbType: \"float8\", domain: Number, arrayElementSafe: true };\n if (typeof value === \"boolean\") return { dbType: \"bool\", domain: Boolean, arrayElementSafe: true };\n if (typeof value === \"bigint\") return { dbType: \"int8\", domain: BigInt };\n if (value instanceof Date) return { dbType: \"timestamptz\", domain: Date };\n throw new Error(\"Object and array literals need an expression with a matching codec\");\n}\n\n/** Rejects primitive literals that disagree with the column; custom values are checked by their encoder. */\nfunction checkLiteral(value: unknown, type: TypeInfo | undefined): void {\n if (value === null || !type) return;\n const domain = type.domain;\n if (\n (domain === String && typeof value !== \"string\") ||\n (domain === Number && typeof value !== \"number\") ||\n (domain === Boolean && typeof value !== \"boolean\") ||\n (domain === BigInt && typeof value !== \"bigint\") ||\n (domain === Date && !(value instanceof Date))\n ) {\n throw new Error(\n `Expression values must have compatible types: expected ${describeType(type)}, got ${inspect(value)} (${typeof value})`,\n );\n }\n}\n\n/** Names the storage type, conversion domain, and entity tag involved in a codec mismatch. */\nfunction describeType(type: TypeInfo | undefined): string {\n if (!type) return \"unknown codec\";\n const domain = typeof type.domain === \"function\" ? type.domain.name : inspect(type.domain, { depth: 0 });\n return `${type.dbType} (domain ${domain}${type.idMeta ? `, ID target ${type.idMeta.type}` : \"\"})`;\n}\n\nconst compatibleStringDbTypes = new Set([\"text\", \"varchar\"]);\n\n/** Allows PostgreSQL scalar string types that resolve to a common string result. */\nfunction compatibleDbTypes(a: string, b: string): boolean {\n return a === b || (compatibleStringDbTypes.has(a) && compatibleStringDbTypes.has(b));\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ParsedExpression, ResultCodec } from "./types.cjs";
|
|
2
2
|
//#region src/expressions/codecs.d.ts
|
|
3
3
|
/**
|
|
4
|
-
* Chooses one decoder for all possible result values. Columns must agree on SQL type and domain;
|
|
4
|
+
* Chooses one decoder for all possible result values. Columns must agree on a compatible SQL type and domain;
|
|
5
5
|
* literals use that column's encoder. This is conservative: PostgreSQL may accept other combinations,
|
|
6
6
|
* but Joist cannot safely choose their decoder. I.e. Author.id and Book.id both store integers but use different tags.
|
|
7
7
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ParsedExpression, ResultCodec } from "./types.mjs";
|
|
2
2
|
//#region src/expressions/codecs.d.ts
|
|
3
3
|
/**
|
|
4
|
-
* Chooses one decoder for all possible result values. Columns must agree on SQL type and domain;
|
|
4
|
+
* Chooses one decoder for all possible result values. Columns must agree on a compatible SQL type and domain;
|
|
5
5
|
* literals use that column's encoder. This is conservative: PostgreSQL may accept other combinations,
|
|
6
6
|
* but Joist cannot safely choose their decoder. I.e. Author.id and Book.id both store integers but use different tags.
|
|
7
7
|
*/
|
|
@@ -3,7 +3,7 @@ import { BaseExpr } from "../Expr.js";
|
|
|
3
3
|
import { inspect } from "node:util";
|
|
4
4
|
//#region src/expressions/codecs.ts
|
|
5
5
|
/**
|
|
6
|
-
* Chooses one decoder for all possible result values. Columns must agree on SQL type and domain;
|
|
6
|
+
* Chooses one decoder for all possible result values. Columns must agree on a compatible SQL type and domain;
|
|
7
7
|
* literals use that column's encoder. This is conservative: PostgreSQL may accept other combinations,
|
|
8
8
|
* but Joist cannot safely choose their decoder. I.e. Author.id and Book.id both store integers but use different tags.
|
|
9
9
|
*/
|
|
@@ -16,9 +16,9 @@ function chooseExpressionCodec(parsed) {
|
|
|
16
16
|
if (other === first) continue;
|
|
17
17
|
const a = first.outputType;
|
|
18
18
|
const b = other.outputType;
|
|
19
|
-
if (!a || !b || a.dbType
|
|
19
|
+
if (!a || !b || !compatibleDbTypes(a.dbType, b.dbType) || a.domain !== b.domain || a.idMeta !== b.idMeta) {
|
|
20
20
|
const mismatches = !a || !b ? ["unknown codec"] : [
|
|
21
|
-
|
|
21
|
+
...!compatibleDbTypes(a.dbType, b.dbType) ? ["SQL type"] : [],
|
|
22
22
|
...a.domain !== b.domain ? ["domain"] : [],
|
|
23
23
|
...a.idMeta !== b.idMeta ? ["ID target"] : []
|
|
24
24
|
];
|
|
@@ -105,6 +105,11 @@ function describeType(type) {
|
|
|
105
105
|
const domain = typeof type.domain === "function" ? type.domain.name : inspect(type.domain, { depth: 0 });
|
|
106
106
|
return `${type.dbType} (domain ${domain}${type.idMeta ? `, ID target ${type.idMeta.type}` : ""})`;
|
|
107
107
|
}
|
|
108
|
+
const compatibleStringDbTypes = /* @__PURE__ */ new Set(["text", "varchar"]);
|
|
109
|
+
/** Allows PostgreSQL scalar string types that resolve to a common string result. */
|
|
110
|
+
function compatibleDbTypes(a, b) {
|
|
111
|
+
return a === b || compatibleStringDbTypes.has(a) && compatibleStringDbTypes.has(b);
|
|
112
|
+
}
|
|
108
113
|
//#endregion
|
|
109
114
|
export { chooseExpressionCodec };
|
|
110
115
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codecs.js","names":[],"sources":["../../src/expressions/codecs.ts"],"sourcesContent":["import { inspect } from \"node:util\";\n\nimport { BaseExpr } from \"../Expr.ts\";\nimport type { TypeInfo } from \"../TypeInfo.ts\";\nimport { assertNever } from \"../utils.ts\";\nimport type { ParsedExpression, ParsedLiteralExpression, ResultCodec } from \"./types.ts\";\n\n/**\n * Chooses one decoder for all possible result values. Columns must agree on SQL type and domain;\n * literals use that column's encoder. This is conservative: PostgreSQL may accept other combinations,\n * but Joist cannot safely choose their decoder. I.e. Author.id and Book.id both store integers but use different tags.\n */\nexport function chooseExpressionCodec(parsed: ParsedExpression): ResultCodec {\n const leaves = expressionLeaves(parsed);\n const expressions = leaves.filter((v): v is BaseExpr => v instanceof BaseExpr);\n const first = expressions[0];\n if (first) {\n for (const other of expressions.slice(1)) {\n if (other === first) continue;\n const a = first.outputType;\n const b = other.outputType;\n if (!a || !b || a.dbType
|
|
1
|
+
{"version":3,"file":"codecs.js","names":[],"sources":["../../src/expressions/codecs.ts"],"sourcesContent":["import { inspect } from \"node:util\";\n\nimport { BaseExpr } from \"../Expr.ts\";\nimport type { TypeInfo } from \"../TypeInfo.ts\";\nimport { assertNever } from \"../utils.ts\";\nimport type { ParsedExpression, ParsedLiteralExpression, ResultCodec } from \"./types.ts\";\n\n/**\n * Chooses one decoder for all possible result values. Columns must agree on a compatible SQL type and domain;\n * literals use that column's encoder. This is conservative: PostgreSQL may accept other combinations,\n * but Joist cannot safely choose their decoder. I.e. Author.id and Book.id both store integers but use different tags.\n */\nexport function chooseExpressionCodec(parsed: ParsedExpression): ResultCodec {\n const leaves = expressionLeaves(parsed);\n const expressions = leaves.filter((v): v is BaseExpr => v instanceof BaseExpr);\n const first = expressions[0];\n if (first) {\n for (const other of expressions.slice(1)) {\n if (other === first) continue;\n const a = first.outputType;\n const b = other.outputType;\n if (!a || !b || !compatibleDbTypes(a.dbType, b.dbType) || a.domain !== b.domain || a.idMeta !== b.idMeta) {\n const mismatches =\n !a || !b\n ? [\"unknown codec\"]\n : [\n ...(!compatibleDbTypes(a.dbType, b.dbType) ? [\"SQL type\"] : []),\n ...(a.domain !== b.domain ? [\"domain\"] : []),\n ...(a.idMeta !== b.idMeta ? [\"ID target\"] : []),\n ];\n throw new Error(\n `Expression operands need matching SQL types and codecs: ${describeType(a)} vs ${describeType(b)}; mismatched ${mismatches.join(\", \")}`,\n );\n }\n }\n for (const leaf of leaves) {\n if (!(leaf instanceof BaseExpr)) checkLiteral(leaf.value, first.outputType);\n }\n return first;\n }\n const literals = leaves.filter((v): v is ParsedLiteralExpression => !(v instanceof BaseExpr));\n const types = literals.map((v) => literalType(v.value)).filter((v) => v !== undefined);\n for (const literal of literals) checkLiteral(literal.value, types[0]);\n return new LiteralCodec(types[0] ?? { dbType: \"text\", domain: String });\n}\n\n/** Gives literal-only expressions a SQL type so PostgreSQL does not return numbers as text. */\nclass LiteralCodec {\n constructor(readonly outputType: TypeInfo) {}\n\n encode(value: unknown): unknown {\n return value;\n }\n\n decode(value: unknown): unknown {\n return this.outputType.domain === BigInt ? BigInt(value as string) : value;\n }\n}\n\n/**\n * Finds parsed operands that share a codec, including NULLIF's comparison operand but not CASE conditions.\n * Each kind selects its own value fields; only CASE's THEN and ELSE expressions contribute a result codec.\n */\nfunction expressionLeaves(parsed: ParsedExpression): (BaseExpr | ParsedLiteralExpression)[] {\n if (parsed instanceof BaseExpr) return [parsed];\n switch (parsed.kind) {\n case \"literal\":\n return [parsed];\n case \"coalesce\":\n return parsed.candidates.flatMap((candidate) => expressionLeaves(candidate));\n case \"nullIf\":\n return [...expressionLeaves(parsed.value), ...expressionLeaves(parsed.equals)];\n case \"greatest\":\n case \"least\":\n return parsed.values.flatMap((value) => expressionLeaves(value));\n case \"case\":\n return [\n ...parsed.whens.flatMap((entry) => expressionLeaves(entry.then)),\n ...(parsed.else ? expressionLeaves(parsed.else) : []),\n ];\n default:\n return assertNever(parsed);\n }\n}\n\n/** Supplies predictable PostgreSQL types for standalone primitive literals. */\nfunction literalType(value: unknown): TypeInfo | undefined {\n if (value === null) return undefined;\n if (typeof value === \"string\") return { dbType: \"text\", domain: String, arrayElementSafe: true };\n if (typeof value === \"number\") return { dbType: \"float8\", domain: Number, arrayElementSafe: true };\n if (typeof value === \"boolean\") return { dbType: \"bool\", domain: Boolean, arrayElementSafe: true };\n if (typeof value === \"bigint\") return { dbType: \"int8\", domain: BigInt };\n if (value instanceof Date) return { dbType: \"timestamptz\", domain: Date };\n throw new Error(\"Object and array literals need an expression with a matching codec\");\n}\n\n/** Rejects primitive literals that disagree with the column; custom values are checked by their encoder. */\nfunction checkLiteral(value: unknown, type: TypeInfo | undefined): void {\n if (value === null || !type) return;\n const domain = type.domain;\n if (\n (domain === String && typeof value !== \"string\") ||\n (domain === Number && typeof value !== \"number\") ||\n (domain === Boolean && typeof value !== \"boolean\") ||\n (domain === BigInt && typeof value !== \"bigint\") ||\n (domain === Date && !(value instanceof Date))\n ) {\n throw new Error(\n `Expression values must have compatible types: expected ${describeType(type)}, got ${inspect(value)} (${typeof value})`,\n );\n }\n}\n\n/** Names the storage type, conversion domain, and entity tag involved in a codec mismatch. */\nfunction describeType(type: TypeInfo | undefined): string {\n if (!type) return \"unknown codec\";\n const domain = typeof type.domain === \"function\" ? type.domain.name : inspect(type.domain, { depth: 0 });\n return `${type.dbType} (domain ${domain}${type.idMeta ? `, ID target ${type.idMeta.type}` : \"\"})`;\n}\n\nconst compatibleStringDbTypes = new Set([\"text\", \"varchar\"]);\n\n/** Allows PostgreSQL scalar string types that resolve to a common string result. */\nfunction compatibleDbTypes(a: string, b: string): boolean {\n return a === b || (compatibleStringDbTypes.has(a) && compatibleStringDbTypes.has(b));\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "joist-core",
|
|
3
|
-
"version": "2.3.0-next.
|
|
3
|
+
"version": "2.3.0-next.90",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"build"
|
|
43
43
|
],
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"joist-utils": "2.3.0-next.
|
|
45
|
+
"joist-utils": "2.3.0-next.90"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"ansis": "^4.3.1",
|