sqlstack 1.0.25 → 3.0.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/cjs/adapters/mysql.d.ts.map +1 -1
- package/dist/cjs/adapters/mysql.js +3 -3
- package/dist/cjs/adapters/mysql.js.map +1 -1
- package/dist/cjs/adapters/pg.d.ts.map +1 -1
- package/dist/cjs/adapters/pg.js +3 -3
- package/dist/cjs/adapters/pg.js.map +1 -1
- package/dist/cjs/codegen/cli.d.ts +3 -0
- package/dist/cjs/codegen/cli.d.ts.map +1 -0
- package/dist/cjs/codegen/cli.js +50 -0
- package/dist/cjs/codegen/cli.js.map +1 -0
- package/dist/cjs/codegen/generateManifest.d.ts +72 -0
- package/dist/cjs/codegen/generateManifest.d.ts.map +1 -0
- package/dist/cjs/codegen/generateManifest.js +191 -0
- package/dist/cjs/codegen/generateManifest.js.map +1 -0
- package/dist/cjs/core/loadNodeModule.d.ts +17 -0
- package/dist/cjs/core/loadNodeModule.d.ts.map +1 -0
- package/dist/cjs/core/loadNodeModule.js +36 -0
- package/dist/cjs/core/loadNodeModule.js.map +1 -0
- package/dist/cjs/core/resolver.d.ts +94 -0
- package/dist/cjs/core/resolver.d.ts.map +1 -0
- package/dist/cjs/core/resolver.js +145 -0
- package/dist/cjs/core/resolver.js.map +1 -0
- package/dist/cjs/core/sourceScanResolver.d.ts +25 -0
- package/dist/cjs/core/sourceScanResolver.d.ts.map +1 -0
- package/dist/cjs/core/sourceScanResolver.js +56 -0
- package/dist/cjs/core/sourceScanResolver.js.map +1 -0
- package/dist/cjs/decorators/query.d.ts.map +1 -1
- package/dist/cjs/decorators/query.js +42 -14
- package/dist/cjs/decorators/query.js.map +1 -1
- package/dist/cjs/families/sqliteFamily.d.ts +26 -0
- package/dist/cjs/families/sqliteFamily.d.ts.map +1 -0
- package/dist/cjs/families/sqliteFamily.js +187 -0
- package/dist/cjs/families/sqliteFamily.js.map +1 -0
- package/dist/cjs/family.d.ts +69 -0
- package/dist/cjs/family.d.ts.map +1 -0
- package/dist/cjs/family.js +206 -0
- package/dist/cjs/family.js.map +1 -0
- package/dist/cjs/familyBinding.d.ts +22 -0
- package/dist/cjs/familyBinding.d.ts.map +1 -0
- package/dist/cjs/familyBinding.js +22 -0
- package/dist/cjs/familyBinding.js.map +1 -0
- package/dist/cjs/index.d.ts +10 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +18 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/ioc.d.ts +22 -0
- package/dist/cjs/ioc.d.ts.map +1 -0
- package/dist/cjs/ioc.js +35 -0
- package/dist/cjs/ioc.js.map +1 -0
- package/dist/cjs/runtime.d.ts +25 -0
- package/dist/cjs/runtime.d.ts.map +1 -0
- package/dist/cjs/runtime.js +133 -0
- package/dist/cjs/runtime.js.map +1 -0
- package/dist/cjs/stack.d.ts +101 -0
- package/dist/cjs/stack.d.ts.map +1 -0
- package/dist/cjs/stack.js +288 -0
- package/dist/cjs/stack.js.map +1 -0
- package/dist/cjs/testing/builder.d.ts +29 -0
- package/dist/cjs/testing/builder.d.ts.map +1 -0
- package/dist/cjs/testing/builder.js +131 -0
- package/dist/cjs/testing/builder.js.map +1 -0
- package/dist/cjs/testing/index.d.ts +10 -0
- package/dist/cjs/testing/index.d.ts.map +1 -0
- package/dist/cjs/testing/index.js +18 -0
- package/dist/cjs/testing/index.js.map +1 -0
- package/dist/cjs/testing/postgres/allocator.d.ts +17 -0
- package/dist/cjs/testing/postgres/allocator.d.ts.map +1 -0
- package/dist/cjs/testing/postgres/allocator.js +54 -0
- package/dist/cjs/testing/postgres/allocator.js.map +1 -0
- package/dist/cjs/testing/postgres/database.d.ts +21 -0
- package/dist/cjs/testing/postgres/database.d.ts.map +1 -0
- package/dist/cjs/testing/postgres/database.js +39 -0
- package/dist/cjs/testing/postgres/database.js.map +1 -0
- package/dist/cjs/testing/postgres/loadData.d.ts +31 -0
- package/dist/cjs/testing/postgres/loadData.d.ts.map +1 -0
- package/dist/cjs/testing/postgres/loadData.js +184 -0
- package/dist/cjs/testing/postgres/loadData.js.map +1 -0
- package/dist/cjs/testing/postgres/server.d.ts +19 -0
- package/dist/cjs/testing/postgres/server.d.ts.map +1 -0
- package/dist/cjs/testing/postgres/server.js +78 -0
- package/dist/cjs/testing/postgres/server.js.map +1 -0
- package/dist/cjs/testing/schema/ddl.d.ts +14 -0
- package/dist/cjs/testing/schema/ddl.d.ts.map +1 -0
- package/dist/cjs/testing/schema/ddl.js +54 -0
- package/dist/cjs/testing/schema/ddl.js.map +1 -0
- package/dist/cjs/testing/schema/normalize.d.ts +7 -0
- package/dist/cjs/testing/schema/normalize.d.ts.map +1 -0
- package/dist/cjs/testing/schema/normalize.js +202 -0
- package/dist/cjs/testing/schema/normalize.js.map +1 -0
- package/dist/cjs/testing/schema/parser.d.ts +9 -0
- package/dist/cjs/testing/schema/parser.d.ts.map +1 -0
- package/dist/cjs/testing/schema/parser.js +80 -0
- package/dist/cjs/testing/schema/parser.js.map +1 -0
- package/dist/cjs/testing/schema/types.d.ts +82 -0
- package/dist/cjs/testing/schema/types.d.ts.map +1 -0
- package/dist/cjs/testing/schema/types.js +10 -0
- package/dist/cjs/testing/schema/types.js.map +1 -0
- package/dist/cjs/transactions.d.ts +14 -5
- package/dist/cjs/transactions.d.ts.map +1 -1
- package/dist/cjs/transactions.js +40 -24
- package/dist/cjs/transactions.js.map +1 -1
- package/dist/esm/adapters/mysql.js +3 -3
- package/dist/esm/adapters/mysql.js.map +1 -1
- package/dist/esm/adapters/pg.js +3 -3
- package/dist/esm/adapters/pg.js.map +1 -1
- package/dist/esm/codegen/cli.js +48 -0
- package/dist/esm/codegen/cli.js.map +1 -0
- package/dist/esm/codegen/generateManifest.js +183 -0
- package/dist/esm/codegen/generateManifest.js.map +1 -0
- package/dist/esm/core/loadNodeModule.js +33 -0
- package/dist/esm/core/loadNodeModule.js.map +1 -0
- package/dist/esm/core/resolver.js +132 -0
- package/dist/esm/core/resolver.js.map +1 -0
- package/dist/esm/core/sourceScanResolver.js +51 -0
- package/dist/esm/core/sourceScanResolver.js.map +1 -0
- package/dist/esm/decorators/query.js +43 -15
- package/dist/esm/decorators/query.js.map +1 -1
- package/dist/esm/families/sqliteFamily.js +151 -0
- package/dist/esm/families/sqliteFamily.js.map +1 -0
- package/dist/esm/family.js +202 -0
- package/dist/esm/family.js.map +1 -0
- package/dist/esm/familyBinding.js +18 -0
- package/dist/esm/familyBinding.js.map +1 -0
- package/dist/esm/index.js +8 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/ioc.js +32 -0
- package/dist/esm/ioc.js.map +1 -0
- package/dist/esm/runtime.js +94 -0
- package/dist/esm/runtime.js.map +1 -0
- package/dist/esm/stack.js +251 -0
- package/dist/esm/stack.js.map +1 -0
- package/dist/esm/testing/builder.js +95 -0
- package/dist/esm/testing/builder.js.map +1 -0
- package/dist/esm/testing/index.js +7 -0
- package/dist/esm/testing/index.js.map +1 -0
- package/dist/esm/testing/postgres/allocator.js +49 -0
- package/dist/esm/testing/postgres/allocator.js.map +1 -0
- package/dist/esm/testing/postgres/database.js +36 -0
- package/dist/esm/testing/postgres/database.js.map +1 -0
- package/dist/esm/testing/postgres/loadData.js +176 -0
- package/dist/esm/testing/postgres/loadData.js.map +1 -0
- package/dist/esm/testing/postgres/server.js +69 -0
- package/dist/esm/testing/postgres/server.js.map +1 -0
- package/dist/esm/testing/schema/ddl.js +49 -0
- package/dist/esm/testing/schema/ddl.js.map +1 -0
- package/dist/esm/testing/schema/normalize.js +164 -0
- package/dist/esm/testing/schema/normalize.js.map +1 -0
- package/dist/esm/testing/schema/parser.js +43 -0
- package/dist/esm/testing/schema/parser.js.map +1 -0
- package/dist/esm/testing/schema/types.js +9 -0
- package/dist/esm/testing/schema/types.js.map +1 -0
- package/dist/esm/transactions.js +39 -24
- package/dist/esm/transactions.js.map +1 -1
- package/package.json +29 -4
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.TestSchemaError = void 0;
|
|
37
|
+
exports.normalizeTestSchema = normalizeTestSchema;
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const errors_1 = require("../../core/errors");
|
|
41
|
+
class TestSchemaError extends errors_1.SqlStackError {
|
|
42
|
+
constructor(message, source) {
|
|
43
|
+
super(source ? `${message} (schema source: ${source})` : message);
|
|
44
|
+
this.name = 'TestSchemaError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.TestSchemaError = TestSchemaError;
|
|
48
|
+
const IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
49
|
+
function assertIdentifier(kind, name, source) {
|
|
50
|
+
if (!IDENT.test(name)) {
|
|
51
|
+
throw new TestSchemaError(`Invalid ${kind} name ${JSON.stringify(name)}: names must match /^[A-Za-z_][A-Za-z0-9_]*$/`, source);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function parseReference(raw, where, source) {
|
|
55
|
+
if (typeof raw !== 'string') {
|
|
56
|
+
throw new TestSchemaError(`Invalid "references" at ${where}: expected a string like "table.column"`, source);
|
|
57
|
+
}
|
|
58
|
+
// Accept "table.column" or "table(column)".
|
|
59
|
+
let m = /^([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/.exec(raw);
|
|
60
|
+
if (!m)
|
|
61
|
+
m = /^([A-Za-z_][A-Za-z0-9_]*)\(([A-Za-z_][A-Za-z0-9_]*)\)$/.exec(raw);
|
|
62
|
+
if (!m) {
|
|
63
|
+
throw new TestSchemaError(`Invalid "references" syntax ${JSON.stringify(raw)} at ${where}: use "table.column" or "table(column)"`, source);
|
|
64
|
+
}
|
|
65
|
+
return { table: m[1], column: m[2] };
|
|
66
|
+
}
|
|
67
|
+
const COLUMN_KEYS = new Set(['type', 'nullable', 'primary', 'unique', 'default', 'references']);
|
|
68
|
+
function normalizeColumn(tableName, name, decl, source) {
|
|
69
|
+
const where = `${tableName}.${name}`;
|
|
70
|
+
assertIdentifier('column', name, source);
|
|
71
|
+
let obj;
|
|
72
|
+
if (typeof decl === 'string') {
|
|
73
|
+
obj = { type: decl };
|
|
74
|
+
}
|
|
75
|
+
else if (decl && typeof decl === 'object' && !Array.isArray(decl)) {
|
|
76
|
+
obj = decl;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
throw new TestSchemaError(`Malformed column declaration at ${where}: expected a type string or an object`, source);
|
|
80
|
+
}
|
|
81
|
+
for (const key of Object.keys(obj)) {
|
|
82
|
+
if (!COLUMN_KEYS.has(key)) {
|
|
83
|
+
throw new TestSchemaError(`Unknown column property ${JSON.stringify(key)} at ${where}: supported properties are ${[...COLUMN_KEYS].join(', ')}`, source);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const type = obj.type;
|
|
87
|
+
if (typeof type !== 'string' || type.trim() === '') {
|
|
88
|
+
throw new TestSchemaError(`Missing or invalid "type" at ${where}: a non-empty string is required`, source);
|
|
89
|
+
}
|
|
90
|
+
for (const flag of ['nullable', 'primary', 'unique']) {
|
|
91
|
+
if (obj[flag] !== undefined && typeof obj[flag] !== 'boolean') {
|
|
92
|
+
throw new TestSchemaError(`Invalid "${flag}" at ${where}: expected a boolean`, source);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const def = obj.default;
|
|
96
|
+
if (def !== undefined && !['string', 'number', 'boolean'].includes(typeof def)) {
|
|
97
|
+
throw new TestSchemaError(`Invalid "default" at ${where}: expected a string, number, or boolean`, source);
|
|
98
|
+
}
|
|
99
|
+
const primary = obj.primary === true;
|
|
100
|
+
return {
|
|
101
|
+
name,
|
|
102
|
+
type: type.trim(),
|
|
103
|
+
nullable: obj.nullable === undefined ? !primary : obj.nullable,
|
|
104
|
+
primary,
|
|
105
|
+
unique: obj.unique === true,
|
|
106
|
+
hasDefault: def !== undefined,
|
|
107
|
+
default: def,
|
|
108
|
+
references: obj.references === undefined ? undefined : parseReference(obj.references, where, source),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function normalizeTable(name, decl, source) {
|
|
112
|
+
assertIdentifier('table', name, source);
|
|
113
|
+
if (!decl || typeof decl !== 'object' || Array.isArray(decl)) {
|
|
114
|
+
throw new TestSchemaError(`Malformed table declaration "${name}": expected an object with "columns"`, source);
|
|
115
|
+
}
|
|
116
|
+
const columnsDecl = decl.columns;
|
|
117
|
+
if (!columnsDecl || typeof columnsDecl !== 'object' || Array.isArray(columnsDecl)) {
|
|
118
|
+
throw new TestSchemaError(`Table "${name}" is missing a "columns" map`, source);
|
|
119
|
+
}
|
|
120
|
+
const columns = Object.entries(columnsDecl).map(([colName, colDecl]) => normalizeColumn(name, colName, colDecl, source));
|
|
121
|
+
if (columns.length === 0) {
|
|
122
|
+
throw new TestSchemaError(`Table "${name}" declares no columns`, source);
|
|
123
|
+
}
|
|
124
|
+
const primaryKey = columns.filter((c) => c.primary).map((c) => c.name);
|
|
125
|
+
return { name, columns: Object.freeze(columns), primaryKey: Object.freeze(primaryKey) };
|
|
126
|
+
}
|
|
127
|
+
function normalizeSqlEntry(raw, index, options, source) {
|
|
128
|
+
if (typeof raw !== 'string' || raw.trim() === '') {
|
|
129
|
+
throw new TestSchemaError(`Invalid sql entry #${index}: expected a non-empty string`, source);
|
|
130
|
+
}
|
|
131
|
+
const looksLikeFile = !raw.includes('\n') && /\.sql$/i.test(raw.trim());
|
|
132
|
+
if (!looksLikeFile) {
|
|
133
|
+
return { kind: 'inline', index, sql: raw };
|
|
134
|
+
}
|
|
135
|
+
const authored = raw.trim();
|
|
136
|
+
if (!options.sourceDir) {
|
|
137
|
+
throw new TestSchemaError(`sql entry #${index} references file "${authored}" but no sourceDir is available. ` +
|
|
138
|
+
`Pass the schema as a file path, or provide { sourceDir } so relative .sql paths can be resolved ` +
|
|
139
|
+
`(paths are never resolved against process.cwd() implicitly).`, source);
|
|
140
|
+
}
|
|
141
|
+
const resolvedPath = path.resolve(options.sourceDir, authored);
|
|
142
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
143
|
+
throw new TestSchemaError(`sql entry #${index}: file not found: ${authored} (resolved to ${resolvedPath})`, source);
|
|
144
|
+
}
|
|
145
|
+
return { kind: 'file', index, sourcePath: authored, resolvedPath };
|
|
146
|
+
}
|
|
147
|
+
function normalizeTestSchema(doc, options = {}) {
|
|
148
|
+
const source = options.sourceLabel ?? '<inline schema>';
|
|
149
|
+
if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {
|
|
150
|
+
throw new TestSchemaError('Test schema must be a YAML mapping / object', source);
|
|
151
|
+
}
|
|
152
|
+
const root = doc;
|
|
153
|
+
if (root.version !== 1) {
|
|
154
|
+
throw new TestSchemaError(`Unsupported test schema version: ${JSON.stringify(root.version)} (expected: version: 1)`, source);
|
|
155
|
+
}
|
|
156
|
+
if (root.dialect !== 'postgres') {
|
|
157
|
+
throw new TestSchemaError(`Unsupported test schema dialect: ${JSON.stringify(root.dialect)} (expected: dialect: postgres)`, source);
|
|
158
|
+
}
|
|
159
|
+
for (const key of Object.keys(root)) {
|
|
160
|
+
if (!['version', 'dialect', 'tables', 'sql'].includes(key)) {
|
|
161
|
+
throw new TestSchemaError(`Unknown top-level key ${JSON.stringify(key)} in test schema`, source);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
let tables = [];
|
|
165
|
+
if (root.tables !== undefined) {
|
|
166
|
+
if (!root.tables || typeof root.tables !== 'object' || Array.isArray(root.tables)) {
|
|
167
|
+
throw new TestSchemaError('"tables" must be a mapping of table name to declaration', source);
|
|
168
|
+
}
|
|
169
|
+
tables = Object.entries(root.tables).map(([name, decl]) => normalizeTable(name, decl, source));
|
|
170
|
+
}
|
|
171
|
+
// Validate references that point at structured tables.
|
|
172
|
+
const byName = new Map(tables.map((t) => [t.name, t]));
|
|
173
|
+
for (const t of tables) {
|
|
174
|
+
for (const c of t.columns) {
|
|
175
|
+
const ref = c.references;
|
|
176
|
+
if (ref && byName.has(ref.table)) {
|
|
177
|
+
const target = byName.get(ref.table);
|
|
178
|
+
if (!target.columns.some((tc) => tc.name === ref.column)) {
|
|
179
|
+
throw new TestSchemaError(`Column ${t.name}.${c.name} references ${ref.table}.${ref.column}, but table "${ref.table}" declares no column "${ref.column}"`, source);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
let sql = [];
|
|
185
|
+
if (root.sql !== undefined) {
|
|
186
|
+
if (!Array.isArray(root.sql)) {
|
|
187
|
+
throw new TestSchemaError('"sql" must be a list of inline SQL strings or .sql file paths', source);
|
|
188
|
+
}
|
|
189
|
+
sql = root.sql.map((entry, i) => normalizeSqlEntry(entry, i, options, source));
|
|
190
|
+
}
|
|
191
|
+
if (tables.length === 0 && sql.length === 0) {
|
|
192
|
+
throw new TestSchemaError('Test schema declares no tables and no sql entries', source);
|
|
193
|
+
}
|
|
194
|
+
return Object.freeze({
|
|
195
|
+
version: 1,
|
|
196
|
+
dialect: 'postgres',
|
|
197
|
+
tables: Object.freeze(tables),
|
|
198
|
+
sql: Object.freeze(sql),
|
|
199
|
+
source,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../../src/testing/schema/normalize.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport * as fs from 'fs';\nimport { SqlStackError } from '../../core/errors';\nimport type {\n NormalizedColumn,\n NormalizedReference,\n NormalizedTable,\n NormalizedTestSchema,\n ParseTestSchemaOptions,\n RawSqlEntry,\n} from './types';\n\nexport class TestSchemaError extends SqlStackError {\n constructor(message: string, source?: string) {\n super(source ? `${message} (schema source: ${source})` : message);\n this.name = 'TestSchemaError';\n }\n}\n\nconst IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nfunction assertIdentifier(kind: string, name: string, source: string): void {\n if (!IDENT.test(name)) {\n throw new TestSchemaError(\n `Invalid ${kind} name ${JSON.stringify(name)}: names must match /^[A-Za-z_][A-Za-z0-9_]*$/`,\n source\n );\n }\n}\n\nfunction parseReference(raw: unknown, where: string, source: string): NormalizedReference {\n if (typeof raw !== 'string') {\n throw new TestSchemaError(`Invalid \"references\" at ${where}: expected a string like \"table.column\"`, source);\n }\n // Accept \"table.column\" or \"table(column)\".\n let m = /^([A-Za-z_][A-Za-z0-9_]*)\\.([A-Za-z_][A-Za-z0-9_]*)$/.exec(raw);\n if (!m) m = /^([A-Za-z_][A-Za-z0-9_]*)\\(([A-Za-z_][A-Za-z0-9_]*)\\)$/.exec(raw);\n if (!m) {\n throw new TestSchemaError(\n `Invalid \"references\" syntax ${JSON.stringify(raw)} at ${where}: use \"table.column\" or \"table(column)\"`,\n source\n );\n }\n return { table: m[1]!, column: m[2]! };\n}\n\nconst COLUMN_KEYS = new Set(['type', 'nullable', 'primary', 'unique', 'default', 'references']);\n\nfunction normalizeColumn(tableName: string, name: string, decl: unknown, source: string): NormalizedColumn {\n const where = `${tableName}.${name}`;\n assertIdentifier('column', name, source);\n let obj: Record<string, unknown>;\n if (typeof decl === 'string') {\n obj = { type: decl };\n } else if (decl && typeof decl === 'object' && !Array.isArray(decl)) {\n obj = decl as Record<string, unknown>;\n } else {\n throw new TestSchemaError(\n `Malformed column declaration at ${where}: expected a type string or an object`,\n source\n );\n }\n for (const key of Object.keys(obj)) {\n if (!COLUMN_KEYS.has(key)) {\n throw new TestSchemaError(\n `Unknown column property ${JSON.stringify(key)} at ${where}: supported properties are ${[...COLUMN_KEYS].join(', ')}`,\n source\n );\n }\n }\n const type = obj.type;\n if (typeof type !== 'string' || type.trim() === '') {\n throw new TestSchemaError(`Missing or invalid \"type\" at ${where}: a non-empty string is required`, source);\n }\n for (const flag of ['nullable', 'primary', 'unique'] as const) {\n if (obj[flag] !== undefined && typeof obj[flag] !== 'boolean') {\n throw new TestSchemaError(`Invalid \"${flag}\" at ${where}: expected a boolean`, source);\n }\n }\n const def = obj.default;\n if (def !== undefined && !['string', 'number', 'boolean'].includes(typeof def)) {\n throw new TestSchemaError(`Invalid \"default\" at ${where}: expected a string, number, or boolean`, source);\n }\n const primary = obj.primary === true;\n return {\n name,\n type: type.trim(),\n nullable: obj.nullable === undefined ? !primary : (obj.nullable as boolean),\n primary,\n unique: obj.unique === true,\n hasDefault: def !== undefined,\n default: def as string | number | boolean | undefined,\n references: obj.references === undefined ? undefined : parseReference(obj.references, where, source),\n };\n}\n\nfunction normalizeTable(name: string, decl: unknown, source: string): NormalizedTable {\n assertIdentifier('table', name, source);\n if (!decl || typeof decl !== 'object' || Array.isArray(decl)) {\n throw new TestSchemaError(`Malformed table declaration \"${name}\": expected an object with \"columns\"`, source);\n }\n const columnsDecl = (decl as Record<string, unknown>).columns;\n if (!columnsDecl || typeof columnsDecl !== 'object' || Array.isArray(columnsDecl)) {\n throw new TestSchemaError(`Table \"${name}\" is missing a \"columns\" map`, source);\n }\n const columns = Object.entries(columnsDecl as Record<string, unknown>).map(([colName, colDecl]) =>\n normalizeColumn(name, colName, colDecl, source)\n );\n if (columns.length === 0) {\n throw new TestSchemaError(`Table \"${name}\" declares no columns`, source);\n }\n const primaryKey = columns.filter((c) => c.primary).map((c) => c.name);\n return { name, columns: Object.freeze(columns), primaryKey: Object.freeze(primaryKey) };\n}\n\nfunction normalizeSqlEntry(\n raw: unknown,\n index: number,\n options: ParseTestSchemaOptions,\n source: string\n): RawSqlEntry {\n if (typeof raw !== 'string' || raw.trim() === '') {\n throw new TestSchemaError(`Invalid sql entry #${index}: expected a non-empty string`, source);\n }\n const looksLikeFile = !raw.includes('\\n') && /\\.sql$/i.test(raw.trim());\n if (!looksLikeFile) {\n return { kind: 'inline', index, sql: raw };\n }\n const authored = raw.trim();\n if (!options.sourceDir) {\n throw new TestSchemaError(\n `sql entry #${index} references file \"${authored}\" but no sourceDir is available. ` +\n `Pass the schema as a file path, or provide { sourceDir } so relative .sql paths can be resolved ` +\n `(paths are never resolved against process.cwd() implicitly).`,\n source\n );\n }\n const resolvedPath = path.resolve(options.sourceDir, authored);\n if (!fs.existsSync(resolvedPath)) {\n throw new TestSchemaError(\n `sql entry #${index}: file not found: ${authored} (resolved to ${resolvedPath})`,\n source\n );\n }\n return { kind: 'file', index, sourcePath: authored, resolvedPath };\n}\n\nexport function normalizeTestSchema(\n doc: unknown,\n options: ParseTestSchemaOptions = {}\n): NormalizedTestSchema {\n const source = options.sourceLabel ?? '<inline schema>';\n if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {\n throw new TestSchemaError('Test schema must be a YAML mapping / object', source);\n }\n const root = doc as Record<string, unknown>;\n if (root.version !== 1) {\n throw new TestSchemaError(\n `Unsupported test schema version: ${JSON.stringify(root.version)} (expected: version: 1)`,\n source\n );\n }\n if (root.dialect !== 'postgres') {\n throw new TestSchemaError(\n `Unsupported test schema dialect: ${JSON.stringify(root.dialect)} (expected: dialect: postgres)`,\n source\n );\n }\n for (const key of Object.keys(root)) {\n if (!['version', 'dialect', 'tables', 'sql'].includes(key)) {\n throw new TestSchemaError(`Unknown top-level key ${JSON.stringify(key)} in test schema`, source);\n }\n }\n\n let tables: NormalizedTable[] = [];\n if (root.tables !== undefined) {\n if (!root.tables || typeof root.tables !== 'object' || Array.isArray(root.tables)) {\n throw new TestSchemaError('\"tables\" must be a mapping of table name to declaration', source);\n }\n tables = Object.entries(root.tables as Record<string, unknown>).map(([name, decl]) =>\n normalizeTable(name, decl, source)\n );\n }\n\n // Validate references that point at structured tables.\n const byName = new Map(tables.map((t) => [t.name, t]));\n for (const t of tables) {\n for (const c of t.columns) {\n const ref = c.references;\n if (ref && byName.has(ref.table)) {\n const target = byName.get(ref.table)!;\n if (!target.columns.some((tc) => tc.name === ref.column)) {\n throw new TestSchemaError(\n `Column ${t.name}.${c.name} references ${ref.table}.${ref.column}, but table \"${ref.table}\" declares no column \"${ref.column}\"`,\n source\n );\n }\n }\n }\n }\n\n let sql: RawSqlEntry[] = [];\n if (root.sql !== undefined) {\n if (!Array.isArray(root.sql)) {\n throw new TestSchemaError('\"sql\" must be a list of inline SQL strings or .sql file paths', source);\n }\n sql = root.sql.map((entry, i) => normalizeSqlEntry(entry, i, options, source));\n }\n\n if (tables.length === 0 && sql.length === 0) {\n throw new TestSchemaError('Test schema declares no tables and no sql entries', source);\n }\n\n return Object.freeze({\n version: 1 as const,\n dialect: 'postgres' as const,\n tables: Object.freeze(tables),\n sql: Object.freeze(sql),\n source,\n });\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NormalizedTestSchema, ParseTestSchemaOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a test schema from a YAML string, a plain object, or a .yml/.yaml
|
|
4
|
+
* file path. When given a file path, relative raw .sql entries resolve
|
|
5
|
+
* against the file's own directory unless options.sourceDir overrides it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseTestSchema(input: string | object, options?: ParseTestSchemaOptions): NormalizedTestSchema;
|
|
8
|
+
export declare function isSchemaFilePath(input: string): boolean;
|
|
9
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../src/testing/schema/parser.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAE5E;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,OAAO,GAAE,sBAA2B,GACnC,oBAAoB,CAoBtB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseTestSchema = parseTestSchema;
|
|
37
|
+
exports.isSchemaFilePath = isSchemaFilePath;
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const yaml_1 = require("yaml");
|
|
41
|
+
const normalize_1 = require("./normalize");
|
|
42
|
+
/**
|
|
43
|
+
* Parse a test schema from a YAML string, a plain object, or a .yml/.yaml
|
|
44
|
+
* file path. When given a file path, relative raw .sql entries resolve
|
|
45
|
+
* against the file's own directory unless options.sourceDir overrides it.
|
|
46
|
+
*/
|
|
47
|
+
function parseTestSchema(input, options = {}) {
|
|
48
|
+
if (typeof input === 'object') {
|
|
49
|
+
return (0, normalize_1.normalizeTestSchema)(input, options);
|
|
50
|
+
}
|
|
51
|
+
if (isSchemaFilePath(input)) {
|
|
52
|
+
const filePath = path.resolve(input);
|
|
53
|
+
let text;
|
|
54
|
+
try {
|
|
55
|
+
text = fs.readFileSync(filePath, 'utf8');
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw new normalize_1.TestSchemaError(`Cannot read test schema file: ${filePath} (${err.message})`);
|
|
59
|
+
}
|
|
60
|
+
return parseYamlText(text, {
|
|
61
|
+
sourceDir: options.sourceDir ?? path.dirname(filePath),
|
|
62
|
+
sourceLabel: options.sourceLabel ?? filePath,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return parseYamlText(input, options);
|
|
66
|
+
}
|
|
67
|
+
function isSchemaFilePath(input) {
|
|
68
|
+
return !input.includes('\n') && /\.ya?ml$/i.test(input.trim());
|
|
69
|
+
}
|
|
70
|
+
function parseYamlText(text, options) {
|
|
71
|
+
let doc;
|
|
72
|
+
try {
|
|
73
|
+
doc = (0, yaml_1.parse)(text);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
throw new normalize_1.TestSchemaError(`Failed to parse test schema YAML: ${err.message}`, options.sourceLabel);
|
|
77
|
+
}
|
|
78
|
+
return (0, normalize_1.normalizeTestSchema)(doc, options);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../src/testing/schema/parser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,0CAuBC;AAED,4CAEC;AAtCD,2CAA6B;AAC7B,uCAAyB;AACzB,+BAA0C;AAC1C,2CAAmE;AAGnE;;;;GAIG;AACH,SAAgB,eAAe,CAC7B,KAAsB,EACtB,UAAkC,EAAE;IAEpC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAA,+BAAmB,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,2BAAe,CACvB,iCAAiC,QAAQ,KAAM,GAAa,CAAC,OAAO,GAAG,CACxE,CAAC;QACJ,CAAC;QACD,OAAO,aAAa,CAAC,IAAI,EAAE;YACzB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACtD,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,QAAQ;SAC7C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,OAA+B;IAClE,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAA,YAAS,EAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,2BAAe,CACvB,qCAAsC,GAAa,CAAC,OAAO,EAAE,EAC7D,OAAO,CAAC,WAAW,CACpB,CAAC;IACJ,CAAC;IACD,OAAO,IAAA,+BAAmB,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["import * as path from 'path';\nimport * as fs from 'fs';\nimport { parse as parseYaml } from 'yaml';\nimport { normalizeTestSchema, TestSchemaError } from './normalize';\nimport type { NormalizedTestSchema, ParseTestSchemaOptions } from './types';\n\n/**\n * Parse a test schema from a YAML string, a plain object, or a .yml/.yaml\n * file path. When given a file path, relative raw .sql entries resolve\n * against the file's own directory unless options.sourceDir overrides it.\n */\nexport function parseTestSchema(\n input: string | object,\n options: ParseTestSchemaOptions = {}\n): NormalizedTestSchema {\n if (typeof input === 'object') {\n return normalizeTestSchema(input, options);\n }\n if (isSchemaFilePath(input)) {\n const filePath = path.resolve(input);\n let text: string;\n try {\n text = fs.readFileSync(filePath, 'utf8');\n } catch (err) {\n throw new TestSchemaError(\n `Cannot read test schema file: ${filePath} (${(err as Error).message})`\n );\n }\n return parseYamlText(text, {\n sourceDir: options.sourceDir ?? path.dirname(filePath),\n sourceLabel: options.sourceLabel ?? filePath,\n });\n }\n return parseYamlText(input, options);\n}\n\nexport function isSchemaFilePath(input: string): boolean {\n return !input.includes('\\n') && /\\.ya?ml$/i.test(input.trim());\n}\n\nfunction parseYamlText(text: string, options: ParseTestSchemaOptions): NormalizedTestSchema {\n let doc: unknown;\n try {\n doc = parseYaml(text);\n } catch (err) {\n throw new TestSchemaError(\n `Failed to parse test schema YAML: ${(err as Error).message}`,\n options.sourceLabel\n );\n }\n return normalizeTestSchema(doc, options);\n}\n"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the sqlstack/testing versioned YAML test-schema.
|
|
3
|
+
*
|
|
4
|
+
* The structured vocabulary is intentionally small (type / nullable /
|
|
5
|
+
* primary / unique / default / references). PostgreSQL type strings pass
|
|
6
|
+
* through; raw SQL covers everything the vocabulary cannot express.
|
|
7
|
+
*/
|
|
8
|
+
/** A column declaration after shorthand expansion (scalar string => { type }). */
|
|
9
|
+
export interface TestColumnInput {
|
|
10
|
+
type: string;
|
|
11
|
+
nullable?: boolean;
|
|
12
|
+
primary?: boolean;
|
|
13
|
+
unique?: boolean;
|
|
14
|
+
/** Raw SQL default expression (emitted verbatim into DDL). */
|
|
15
|
+
default?: string | number | boolean;
|
|
16
|
+
/** Reference target: "table.column" or "table(column)". */
|
|
17
|
+
references?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface TestTableInput {
|
|
20
|
+
columns: Record<string, string | TestColumnInput>;
|
|
21
|
+
}
|
|
22
|
+
/** Root YAML document shape. */
|
|
23
|
+
export interface TestSchemaInput {
|
|
24
|
+
version: number;
|
|
25
|
+
dialect: string;
|
|
26
|
+
tables?: Record<string, TestTableInput>;
|
|
27
|
+
sql?: string[];
|
|
28
|
+
}
|
|
29
|
+
/** Normalized (immutable) representations ------------------------------- */
|
|
30
|
+
export interface NormalizedReference {
|
|
31
|
+
readonly table: string;
|
|
32
|
+
readonly column: string;
|
|
33
|
+
}
|
|
34
|
+
export interface NormalizedColumn {
|
|
35
|
+
readonly name: string;
|
|
36
|
+
readonly type: string;
|
|
37
|
+
readonly nullable: boolean;
|
|
38
|
+
readonly primary: boolean;
|
|
39
|
+
readonly unique: boolean;
|
|
40
|
+
readonly hasDefault: boolean;
|
|
41
|
+
readonly default?: string | number | boolean;
|
|
42
|
+
readonly references?: NormalizedReference;
|
|
43
|
+
}
|
|
44
|
+
export interface NormalizedTable {
|
|
45
|
+
readonly name: string;
|
|
46
|
+
/** Authored column order preserved. */
|
|
47
|
+
readonly columns: readonly NormalizedColumn[];
|
|
48
|
+
/** Ordered declared primary-key column names. */
|
|
49
|
+
readonly primaryKey: readonly string[];
|
|
50
|
+
}
|
|
51
|
+
export type RawSqlEntry = {
|
|
52
|
+
readonly kind: 'inline';
|
|
53
|
+
readonly index: number;
|
|
54
|
+
readonly sql: string;
|
|
55
|
+
} | {
|
|
56
|
+
readonly kind: 'file';
|
|
57
|
+
readonly index: number;
|
|
58
|
+
/** Path as authored in the YAML. */
|
|
59
|
+
readonly sourcePath: string;
|
|
60
|
+
/** Absolute resolved path. */
|
|
61
|
+
readonly resolvedPath: string;
|
|
62
|
+
};
|
|
63
|
+
export interface NormalizedTestSchema {
|
|
64
|
+
readonly version: 1;
|
|
65
|
+
readonly dialect: 'postgres';
|
|
66
|
+
/** Authored table order preserved. */
|
|
67
|
+
readonly tables: readonly NormalizedTable[];
|
|
68
|
+
readonly sql: readonly RawSqlEntry[];
|
|
69
|
+
/** Where the schema came from, for diagnostics. */
|
|
70
|
+
readonly source: string;
|
|
71
|
+
}
|
|
72
|
+
export interface ParseTestSchemaOptions {
|
|
73
|
+
/**
|
|
74
|
+
* Directory used to resolve relative .sql file entries. Required when the
|
|
75
|
+
* schema contains file entries and no source file path is known. Never
|
|
76
|
+
* defaults to process.cwd() implicitly.
|
|
77
|
+
*/
|
|
78
|
+
sourceDir?: string;
|
|
79
|
+
/** Label used in diagnostics (e.g. the YAML file path). */
|
|
80
|
+
sourceLabel?: string;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/testing/schema/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACpC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC;CACnD;AAED,gCAAgC;AAChC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACxC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,6EAA6E;AAE7E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,iDAAiD;IACjD,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,8BAA8B;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEN,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,sCAAsC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,GAAG,EAAE,SAAS,WAAW,EAAE,CAAC;IACrC,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Types for the sqlstack/testing versioned YAML test-schema.
|
|
4
|
+
*
|
|
5
|
+
* The structured vocabulary is intentionally small (type / nullable /
|
|
6
|
+
* primary / unique / default / references). PostgreSQL type strings pass
|
|
7
|
+
* through; raw SQL covers everything the vocabulary cannot express.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/testing/schema/types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG","sourcesContent":["/**\n * Types for the sqlstack/testing versioned YAML test-schema.\n *\n * The structured vocabulary is intentionally small (type / nullable /\n * primary / unique / default / references). PostgreSQL type strings pass\n * through; raw SQL covers everything the vocabulary cannot express.\n */\n\n/** A column declaration after shorthand expansion (scalar string => { type }). */\nexport interface TestColumnInput {\n type: string;\n nullable?: boolean;\n primary?: boolean;\n unique?: boolean;\n /** Raw SQL default expression (emitted verbatim into DDL). */\n default?: string | number | boolean;\n /** Reference target: \"table.column\" or \"table(column)\". */\n references?: string;\n}\n\nexport interface TestTableInput {\n columns: Record<string, string | TestColumnInput>;\n}\n\n/** Root YAML document shape. */\nexport interface TestSchemaInput {\n version: number;\n dialect: string;\n tables?: Record<string, TestTableInput>;\n sql?: string[];\n}\n\n/** Normalized (immutable) representations ------------------------------- */\n\nexport interface NormalizedReference {\n readonly table: string;\n readonly column: string;\n}\n\nexport interface NormalizedColumn {\n readonly name: string;\n readonly type: string;\n readonly nullable: boolean;\n readonly primary: boolean;\n readonly unique: boolean;\n readonly hasDefault: boolean;\n readonly default?: string | number | boolean;\n readonly references?: NormalizedReference;\n}\n\nexport interface NormalizedTable {\n readonly name: string;\n /** Authored column order preserved. */\n readonly columns: readonly NormalizedColumn[];\n /** Ordered declared primary-key column names. */\n readonly primaryKey: readonly string[];\n}\n\nexport type RawSqlEntry =\n | {\n readonly kind: 'inline';\n readonly index: number;\n readonly sql: string;\n }\n | {\n readonly kind: 'file';\n readonly index: number;\n /** Path as authored in the YAML. */\n readonly sourcePath: string;\n /** Absolute resolved path. */\n readonly resolvedPath: string;\n };\n\nexport interface NormalizedTestSchema {\n readonly version: 1;\n readonly dialect: 'postgres';\n /** Authored table order preserved. */\n readonly tables: readonly NormalizedTable[];\n readonly sql: readonly RawSqlEntry[];\n /** Where the schema came from, for diagnostics. */\n readonly source: string;\n}\n\nexport interface ParseTestSchemaOptions {\n /**\n * Directory used to resolve relative .sql file entries. Required when the\n * schema contains file entries and no source file path is known. Never\n * defaults to process.cwd() implicitly.\n */\n sourceDir?: string;\n /** Label used in diagnostics (e.g. the YAML file path). */\n sourceLabel?: string;\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Database, QueryResult } from './registry';
|
|
2
|
+
import type { DatabaseEntry } from './stack';
|
|
2
3
|
export type TransactionOptions = {
|
|
3
4
|
db?: string;
|
|
4
5
|
lazy?: boolean;
|
|
@@ -6,8 +7,9 @@ export type TransactionOptions = {
|
|
|
6
7
|
};
|
|
7
8
|
export declare class TransactionHandle {
|
|
8
9
|
#private;
|
|
9
|
-
readonly
|
|
10
|
-
constructor(
|
|
10
|
+
readonly entry: DatabaseEntry;
|
|
11
|
+
constructor(entry: DatabaseEntry, state: TxState, owned: boolean);
|
|
12
|
+
get dbName(): string;
|
|
11
13
|
ensureStarted(): Promise<void>;
|
|
12
14
|
rollbackOnly(errorToThrow?: unknown): void;
|
|
13
15
|
commit(): Promise<void>;
|
|
@@ -17,7 +19,7 @@ export declare class TransactionHandle {
|
|
|
17
19
|
finishOnError(err: unknown): Promise<void>;
|
|
18
20
|
}
|
|
19
21
|
declare class TxState {
|
|
20
|
-
readonly
|
|
22
|
+
readonly entry: DatabaseEntry;
|
|
21
23
|
readonly db: Database;
|
|
22
24
|
readonly options: Required<Pick<TransactionOptions, 'lazy'>> & Pick<TransactionOptions, 'nested'>;
|
|
23
25
|
depth: number;
|
|
@@ -27,7 +29,7 @@ declare class TxState {
|
|
|
27
29
|
rollbackError: unknown | undefined;
|
|
28
30
|
private txDb;
|
|
29
31
|
private releaseFn;
|
|
30
|
-
constructor(
|
|
32
|
+
constructor(entry: DatabaseEntry, options: TransactionOptions | undefined);
|
|
31
33
|
get activeDb(): Database;
|
|
32
34
|
ensureStarted(): Promise<void>;
|
|
33
35
|
query(sql: string, params: unknown[]): Promise<QueryResult>;
|
|
@@ -37,7 +39,14 @@ declare class TxState {
|
|
|
37
39
|
finishOnSuccess(): Promise<void>;
|
|
38
40
|
finishOnError(err: unknown): Promise<void>;
|
|
39
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated Synchronous lookup against the legacy global registry only.
|
|
44
|
+
* Under an active IoC root, use `currentTransactionFor(entry)` with an entry
|
|
45
|
+
* from the root's SqlStack (`stack.getEntry(name)`).
|
|
46
|
+
*/
|
|
40
47
|
export declare function currentTransaction(db?: string): TransactionHandle | undefined;
|
|
48
|
+
/** Active transaction handle for a concrete database entry, if any. */
|
|
49
|
+
export declare function currentTransactionFor(entry: DatabaseEntry): TransactionHandle | undefined;
|
|
41
50
|
export declare function withTransaction<T>(fn: () => Promise<T>, options?: TransactionOptions): Promise<T>;
|
|
42
51
|
export type TransactionDecorator = {
|
|
43
52
|
(target: any, prop: string | symbol, desc: PropertyDescriptor): void;
|
|
@@ -47,6 +56,6 @@ export declare const transaction: TransactionDecorator;
|
|
|
47
56
|
export type ActiveTransaction = {
|
|
48
57
|
query(sql: string, params: unknown[]): Promise<QueryResult>;
|
|
49
58
|
};
|
|
50
|
-
export declare function getActiveTransaction(
|
|
59
|
+
export declare function getActiveTransaction(entry: DatabaseEntry): ActiveTransaction | undefined;
|
|
51
60
|
export {};
|
|
52
61
|
//# sourceMappingURL=transactions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactions.d.ts","sourceRoot":"","sources":["../../src/transactions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"transactions.d.ts","sourceRoot":"","sources":["../../src/transactions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AA6BF,qBAAa,iBAAiB;;IAC5B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;gBAKlB,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;IAMhE,IAAI,MAAM,IAAI,MAAM,CAEnB;IAEK,aAAa;IAInB,YAAY,CAAC,YAAY,CAAC,EAAE,OAAO;IAO7B,MAAM;IAKN,QAAQ;IAKR,OAAO;IAKP,eAAe;IAMf,aAAa,CAAC,GAAG,EAAE,OAAO;CAKjC;AAED,cAAM,OAAO;IACX,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IAClG,KAAK,SAAK;IACV,OAAO,UAAS;IAChB,SAAS,UAAS;IAClB,YAAY,UAAS;IACrB,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;IAEnC,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,SAAS,CAAoC;gBAEzC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,SAAS;IASzE,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAEK,aAAa;IAuCb,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAK3D,eAAe;IAUf,iBAAiB;IAUjB,OAAO;IASP,eAAe;IAaf,aAAa,CAAC,GAAG,EAAE,OAAO;CAWjC;AAuBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAO7E;AAED,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,iBAAiB,GAAG,SAAS,CAKzF;AAED,wBAAsB,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC,CAkBvG;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrE,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACxG,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,oBAYlB,CAAC;AAST,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC7D,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,iBAAiB,GAAG,SAAS,CAGxF"}
|