@supawatch/verify 0.7.1 → 0.8.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.
- package/dist/harness.d.ts +4 -0
- package/dist/harness.js +63 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +29 -28
package/dist/harness.d.ts
CHANGED
|
@@ -38,7 +38,11 @@ export interface HarnessResult {
|
|
|
38
38
|
export declare const DRIVER_DELTAS: readonly [{
|
|
39
39
|
readonly id: "int8-bigint-vs-string";
|
|
40
40
|
readonly detail: "PGlite parses int8 to a JS BigInt; postgres.js returns its decimal string. Normalized: BigInt -> String(value).";
|
|
41
|
+
}, {
|
|
42
|
+
readonly id: "enum-array-literal-vs-array";
|
|
43
|
+
readonly detail: "PGlite returns enum arrays as the raw pg literal; a fresh postgres.js connection parses them to real arrays (measured; parsers are fetched at connect). Normalized: literal -> parsed array on enum-array columns.";
|
|
41
44
|
}];
|
|
45
|
+
export declare function parsePgTextArray(literal: string): string[];
|
|
42
46
|
export declare function runHarness(opts: {
|
|
43
47
|
targets: HarnessTarget[];
|
|
44
48
|
workDir: string;
|
package/dist/harness.js
CHANGED
|
@@ -11,7 +11,57 @@ export const DRIVER_DELTAS = [
|
|
|
11
11
|
id: "int8-bigint-vs-string",
|
|
12
12
|
detail: "PGlite parses int8 to a JS BigInt; postgres.js returns its decimal string. Normalized: BigInt -> String(value).",
|
|
13
13
|
},
|
|
14
|
+
{
|
|
15
|
+
id: "enum-array-literal-vs-array",
|
|
16
|
+
detail: "PGlite returns enum arrays as the raw pg literal; a fresh postgres.js connection parses them to real arrays (measured; parsers are fetched at connect). Normalized: literal -> parsed array on enum-array columns.",
|
|
17
|
+
},
|
|
14
18
|
];
|
|
19
|
+
// Minimal pg array-literal parser for the enum-array delta: handles
|
|
20
|
+
// quoted elements, doubled quotes, and backslash escapes.
|
|
21
|
+
export function parsePgTextArray(literal) {
|
|
22
|
+
const inner = literal.slice(1, -1);
|
|
23
|
+
if (inner === "")
|
|
24
|
+
return [];
|
|
25
|
+
const out = [];
|
|
26
|
+
let cur = "";
|
|
27
|
+
let quoted = false;
|
|
28
|
+
let wasQuoted = false;
|
|
29
|
+
for (let i = 0; i < inner.length; i++) {
|
|
30
|
+
const ch = inner[i];
|
|
31
|
+
if (quoted) {
|
|
32
|
+
if (ch === "\\") {
|
|
33
|
+
cur += inner[++i];
|
|
34
|
+
}
|
|
35
|
+
else if (ch === '"') {
|
|
36
|
+
if (inner[i + 1] === '"') {
|
|
37
|
+
cur += '"';
|
|
38
|
+
i++;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
quoted = false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
cur += ch;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (ch === '"') {
|
|
49
|
+
quoted = true;
|
|
50
|
+
wasQuoted = true;
|
|
51
|
+
}
|
|
52
|
+
else if (ch === ",") {
|
|
53
|
+
out.push(cur);
|
|
54
|
+
cur = "";
|
|
55
|
+
wasQuoted = false;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
cur += ch;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
out.push(cur);
|
|
62
|
+
void wasQuoted;
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
15
65
|
function normalize(value) {
|
|
16
66
|
if (typeof value === "bigint")
|
|
17
67
|
return value.toString();
|
|
@@ -101,6 +151,19 @@ export async function runHarness(opts) {
|
|
|
101
151
|
const parity = [];
|
|
102
152
|
for (const table of snapshot.tables) {
|
|
103
153
|
const rows = await query(`select * from "${table.name}" limit 10`);
|
|
154
|
+
// The enum-array-literal-vs-array delta: PGlite hands back the raw
|
|
155
|
+
// literal, generated schemas expect the parsed array that a fresh
|
|
156
|
+
// postgres.js connection returns.
|
|
157
|
+
for (const col of table.columns) {
|
|
158
|
+
if (col.runtime.kind !== "array" || col.runtime.element.kind !== "enum")
|
|
159
|
+
continue;
|
|
160
|
+
for (const row of rows) {
|
|
161
|
+
const v = row[col.name];
|
|
162
|
+
if (typeof v === "string") {
|
|
163
|
+
row[col.name] = parsePgTextArray(v);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
104
167
|
// Ground truth: every real row must be accepted by every target.
|
|
105
168
|
for (const [name, { schemaByTable, verifier }] of loaded) {
|
|
106
169
|
const schema = schemaByTable.get(table.name);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { runHarness, DRIVER_DELTAS, type AllowedDivergence, type GroundTruthRow, type HarnessResult, type HarnessTarget, type NegativeResult, type ParityCase, } from "./harness.js";
|
|
1
|
+
export { runHarness, DRIVER_DELTAS, parsePgTextArray, type AllowedDivergence, type GroundTruthRow, type HarnessResult, type HarnessTarget, type NegativeResult, type ParityCase, } from "./harness.js";
|
|
2
2
|
export { FIXTURE_SQL, assertFixtureCompleteness } from "./fixture.js";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { runHarness, DRIVER_DELTAS, } from "./harness.js";
|
|
1
|
+
export { runHarness, DRIVER_DELTAS, parsePgTextArray, } from "./harness.js";
|
|
2
2
|
export { FIXTURE_SQL, assertFixtureCompleteness } from "./fixture.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supawatch/verify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "The supawatch verification harness: ground truth against real rows, cross-target parity, and a must-fire divergence ledger.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"supabase",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@electric-sql/pglite": "^0.3.0",
|
|
37
|
-
"@supawatch/core": "0.
|
|
37
|
+
"@supawatch/core": "0.8.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
@@ -52,32 +52,33 @@
|
|
|
52
52
|
"typescript": "^5.9.0",
|
|
53
53
|
"valibot": "^1.1.0",
|
|
54
54
|
"zod": "^4.0.0",
|
|
55
|
-
"@supawatch/target-ai-tools": "0.
|
|
56
|
-
"@supawatch/target-arktype": "0.
|
|
57
|
-
"@supawatch/target-dictionary": "0.
|
|
58
|
-
"@supawatch/target-effect": "0.
|
|
59
|
-
"@supawatch/target-erd": "0.
|
|
60
|
-
"@supawatch/target-factories": "0.
|
|
61
|
-
"@supawatch/target-fast-check": "0.
|
|
62
|
-
"@supawatch/target-forms": "0.
|
|
63
|
-
"@supawatch/target-graphql": "0.
|
|
64
|
-
"@supawatch/target-json-schema": "0.
|
|
65
|
-
"@supawatch/target-mcp": "0.
|
|
66
|
-
"@supawatch/target-orpc": "0.
|
|
67
|
-
"@supawatch/target-pgmq": "0.
|
|
68
|
-
"@supawatch/target-pgtap": "0.
|
|
69
|
-
"@supawatch/target-realtime": "0.
|
|
70
|
-
"@supawatch/target-rest": "0.
|
|
71
|
-
"@supawatch/target-rls": "0.
|
|
72
|
-
"@supawatch/target-schema-card": "0.
|
|
73
|
-
"@supawatch/target-schema-lock": "0.
|
|
74
|
-
"@supawatch/target-seed": "0.
|
|
75
|
-
"@supawatch/target-service": "0.
|
|
76
|
-
"@supawatch/target-supabase-types": "0.
|
|
77
|
-
"@supawatch/target-trpc": "0.
|
|
78
|
-
"@supawatch/target-typebox": "0.
|
|
79
|
-
"@supawatch/target-valibot": "0.
|
|
80
|
-
"@supawatch/target-zod": "0.
|
|
55
|
+
"@supawatch/target-ai-tools": "0.8.0",
|
|
56
|
+
"@supawatch/target-arktype": "0.8.0",
|
|
57
|
+
"@supawatch/target-dictionary": "0.8.0",
|
|
58
|
+
"@supawatch/target-effect": "0.8.0",
|
|
59
|
+
"@supawatch/target-erd": "0.8.0",
|
|
60
|
+
"@supawatch/target-factories": "0.8.0",
|
|
61
|
+
"@supawatch/target-fast-check": "0.8.0",
|
|
62
|
+
"@supawatch/target-forms": "0.8.0",
|
|
63
|
+
"@supawatch/target-graphql": "0.8.0",
|
|
64
|
+
"@supawatch/target-json-schema": "0.8.0",
|
|
65
|
+
"@supawatch/target-mcp": "0.8.0",
|
|
66
|
+
"@supawatch/target-orpc": "0.8.0",
|
|
67
|
+
"@supawatch/target-pgmq": "0.8.0",
|
|
68
|
+
"@supawatch/target-pgtap": "0.8.0",
|
|
69
|
+
"@supawatch/target-realtime": "0.8.0",
|
|
70
|
+
"@supawatch/target-rest": "0.8.0",
|
|
71
|
+
"@supawatch/target-rls": "0.8.0",
|
|
72
|
+
"@supawatch/target-schema-card": "0.8.0",
|
|
73
|
+
"@supawatch/target-schema-lock": "0.8.0",
|
|
74
|
+
"@supawatch/target-seed": "0.8.0",
|
|
75
|
+
"@supawatch/target-service": "0.8.0",
|
|
76
|
+
"@supawatch/target-supabase-types": "0.8.0",
|
|
77
|
+
"@supawatch/target-trpc": "0.8.0",
|
|
78
|
+
"@supawatch/target-typebox": "0.8.0",
|
|
79
|
+
"@supawatch/target-valibot": "0.8.0",
|
|
80
|
+
"@supawatch/target-zod": "0.8.0",
|
|
81
|
+
"@supawatch/watch": "0.8.0"
|
|
81
82
|
},
|
|
82
83
|
"scripts": {
|
|
83
84
|
"build": "tsc -p tsconfig.json"
|