sqlstack 3.3.0 → 3.5.0-dev.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/sqlite.d.ts.map +1 -1
- package/dist/cjs/adapters/sqlite.js +4 -1
- package/dist/cjs/adapters/sqlite.js.map +1 -1
- package/dist/cjs/codegen/generateManifest.d.ts +3 -1
- package/dist/cjs/codegen/generateManifest.d.ts.map +1 -1
- package/dist/cjs/codegen/generateManifest.js +195 -3
- package/dist/cjs/codegen/generateManifest.js.map +1 -1
- package/dist/cjs/core/errors.d.ts +9 -0
- package/dist/cjs/core/errors.d.ts.map +1 -1
- package/dist/cjs/core/errors.js +10 -0
- package/dist/cjs/core/errors.js.map +1 -1
- package/dist/cjs/core/fileResolution.d.ts +7 -0
- package/dist/cjs/core/fileResolution.d.ts.map +1 -1
- package/dist/cjs/core/fileResolution.js +53 -14
- package/dist/cjs/core/fileResolution.js.map +1 -1
- package/dist/cjs/core/metadata.d.ts +5 -0
- package/dist/cjs/core/metadata.d.ts.map +1 -1
- package/dist/cjs/core/metadata.js.map +1 -1
- package/dist/cjs/core/resources.d.ts +36 -0
- package/dist/cjs/core/resources.d.ts.map +1 -0
- package/dist/cjs/core/resources.js +98 -0
- package/dist/cjs/core/resources.js.map +1 -0
- package/dist/cjs/core/sourceScanResolver.d.ts +8 -14
- package/dist/cjs/core/sourceScanResolver.d.ts.map +1 -1
- package/dist/cjs/core/sourceScanResolver.js +8 -20
- package/dist/cjs/core/sourceScanResolver.js.map +1 -1
- package/dist/cjs/decorators/query.d.ts +14 -0
- package/dist/cjs/decorators/query.d.ts.map +1 -1
- package/dist/cjs/decorators/query.js +208 -40
- package/dist/cjs/decorators/query.js.map +1 -1
- package/dist/cjs/family.d.ts.map +1 -1
- package/dist/cjs/family.js +3 -1
- package/dist/cjs/family.js.map +1 -1
- package/dist/cjs/index.d.ts +4 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/run.d.ts +180 -6
- package/dist/cjs/run.d.ts.map +1 -1
- package/dist/cjs/run.js +158 -17
- package/dist/cjs/run.js.map +1 -1
- package/dist/cjs/runtime.d.ts +14 -0
- package/dist/cjs/runtime.d.ts.map +1 -1
- package/dist/cjs/runtime.js +30 -0
- package/dist/cjs/runtime.js.map +1 -1
- package/dist/cjs/sql.d.ts +19 -0
- package/dist/cjs/sql.d.ts.map +1 -1
- package/dist/cjs/sql.js +66 -28
- package/dist/cjs/sql.js.map +1 -1
- package/dist/cjs/stack.d.ts +16 -0
- package/dist/cjs/stack.d.ts.map +1 -1
- package/dist/cjs/stack.js +60 -27
- package/dist/cjs/stack.js.map +1 -1
- package/dist/cjs/testing/builder.d.ts.map +1 -1
- package/dist/cjs/testing/builder.js +14 -5
- package/dist/cjs/testing/builder.js.map +1 -1
- package/dist/cjs/testing/fixture-provenance.d.ts +3 -0
- package/dist/cjs/testing/fixture-provenance.d.ts.map +1 -0
- package/dist/cjs/testing/fixture-provenance.js +21 -0
- package/dist/cjs/testing/fixture-provenance.js.map +1 -0
- package/dist/cjs/testing/index.d.ts +2 -0
- package/dist/cjs/testing/index.d.ts.map +1 -1
- package/dist/cjs/testing/index.js +5 -1
- package/dist/cjs/testing/index.js.map +1 -1
- package/dist/cjs/testing/postgres/database.d.ts +9 -1
- package/dist/cjs/testing/postgres/database.d.ts.map +1 -1
- package/dist/cjs/testing/postgres/database.js +17 -13
- package/dist/cjs/testing/postgres/database.js.map +1 -1
- package/dist/cjs/testing/resource.d.ts +76 -0
- package/dist/cjs/testing/resource.d.ts.map +1 -0
- package/dist/cjs/testing/resource.js +117 -0
- package/dist/cjs/testing/resource.js.map +1 -0
- package/dist/cjs/testing/sqlite/builder.d.ts.map +1 -1
- package/dist/cjs/testing/sqlite/builder.js +10 -2
- package/dist/cjs/testing/sqlite/builder.js.map +1 -1
- package/dist/cjs/testing/sqlite/database.d.ts +11 -1
- package/dist/cjs/testing/sqlite/database.d.ts.map +1 -1
- package/dist/cjs/testing/sqlite/database.js +32 -18
- package/dist/cjs/testing/sqlite/database.js.map +1 -1
- package/dist/cjs/transactions.d.ts +66 -0
- package/dist/cjs/transactions.d.ts.map +1 -1
- package/dist/cjs/transactions.js +584 -3
- package/dist/cjs/transactions.js.map +1 -1
- package/dist/esm/adapters/sqlite.js +4 -1
- package/dist/esm/adapters/sqlite.js.map +1 -1
- package/dist/esm/codegen/generateManifest.js +195 -3
- package/dist/esm/codegen/generateManifest.js.map +1 -1
- package/dist/esm/core/errors.js +10 -0
- package/dist/esm/core/errors.js.map +1 -1
- package/dist/esm/core/fileResolution.js +52 -14
- package/dist/esm/core/fileResolution.js.map +1 -1
- package/dist/esm/core/metadata.js.map +1 -1
- package/dist/esm/core/resources.js +91 -0
- package/dist/esm/core/resources.js.map +1 -0
- package/dist/esm/core/sourceScanResolver.js +8 -19
- package/dist/esm/core/sourceScanResolver.js.map +1 -1
- package/dist/esm/decorators/query.js +214 -46
- package/dist/esm/decorators/query.js.map +1 -1
- package/dist/esm/family.js +3 -1
- package/dist/esm/family.js.map +1 -1
- package/dist/esm/index.js +4 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/run.js +153 -18
- package/dist/esm/run.js.map +1 -1
- package/dist/esm/runtime.js +28 -0
- package/dist/esm/runtime.js.map +1 -1
- package/dist/esm/sql.js +63 -27
- package/dist/esm/sql.js.map +1 -1
- package/dist/esm/stack.js +61 -28
- package/dist/esm/stack.js.map +1 -1
- package/dist/esm/testing/builder.js +14 -5
- package/dist/esm/testing/builder.js.map +1 -1
- package/dist/esm/testing/fixture-provenance.js +15 -0
- package/dist/esm/testing/fixture-provenance.js.map +1 -0
- package/dist/esm/testing/index.js +1 -0
- package/dist/esm/testing/index.js.map +1 -1
- package/dist/esm/testing/postgres/database.js +17 -13
- package/dist/esm/testing/postgres/database.js.map +1 -1
- package/dist/esm/testing/resource.js +106 -0
- package/dist/esm/testing/resource.js.map +1 -0
- package/dist/esm/testing/sqlite/builder.js +10 -2
- package/dist/esm/testing/sqlite/builder.js.map +1 -1
- package/dist/esm/testing/sqlite/database.js +32 -18
- package/dist/esm/testing/sqlite/database.js.map +1 -1
- package/dist/esm/transactions.js +579 -3
- package/dist/esm/transactions.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +201 -171
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/testing/builder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/testing/builder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuHA,oCAOC;AA9HD,uCAAyB;AACzB,yCAA0E;AAC1E,6DAA4D;AAC5D,4CAAkD;AAClD,sCAA2C;AAE3C,oDAAwD;AACxD,kDAAiF;AACjF,oDAAoD;AACpD,8CAA+E;AAC/E,kDAAgG;AAyBhG,SAAS,UAAU,CAAC,MAA4B;IAC9C,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,EAAE,KAAK,EAAE,cAAc,KAAK,CAAC,KAAK,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;QACzE,CAAC;QACD,IAAI,CAAC;YACH,IAAA,yCAAoB,EAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACzC,OAAO;gBACL,KAAK,EAAE,cAAc,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,UAAU,GAAG;gBACxD,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC;aACjD,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,gCAAuB,CAC/B,2CAA2C,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,YAAY,GAAG;gBAC9E,iBAAiB,KAAK,CAAC,UAAU,QAAQ,MAAM,CAAC,MAAM,MAAO,GAAa,CAAC,OAAO,EAAE,CACvF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,KAAmB;IACtC,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,IAAI,CAAC,IAA2B;YAC9B,MAAM,MAAM,GAAG,IAAA,uBAAY,EAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAChD,OAAO,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,CAAC,KAAK;YACT,kEAAkE;YAClE,6CAA6C;YAC7C,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,GAAG,GAAG,IAAA,iBAAW,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACtC,MAAM,SAAS,GAAG,IAAA,sBAAW,EAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAEvD,MAAM,SAAS,GAAG,MAAM,IAAA,4BAAgB,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACxD,IAAI,MAA2D,CAAC;YAChE,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,IAAA,+BAAoB,EAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC9D,KAAK,MAAM,SAAS,IAAI,GAAG,EAAE,CAAC;oBAC5B,IAAI,CAAC;wBACH,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;oBACtC,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,IAAI,gCAAuB,CAC/B,uCAAuC,KAAK,CAAC,MAAM,CAAC,MAAM,KAAM,GAAa,CAAC,OAAO,IAAI;4BACvF,eAAe,SAAS,EAAE,CAC7B,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,IAAI,CAAC;wBACH,gEAAgE;wBAChE,kDAAkD;wBAClD,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACtC,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,IAAI,gCAAuB,CAC/B,uBAAuB,KAAK,CAAC,KAAK,SAAS,KAAK,CAAC,MAAM,CAAC,MAAM,KAAM,GAAa,CAAC,OAAO,EAAE,CAC5F,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,MAAM,IAAA,qBAAU,EAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,MAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;gBAC7F,OAAO,IAAA,+BAAoB,EAAC,MAAM,CAAC,CAAC;YACtC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,qEAAqE;gBACrE,wEAAwE;gBACxE,IAAI,CAAC;oBACH,IAAI,MAAM;wBAAE,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;;wBAC9B,MAAM,IAAA,wBAAY,EAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzD,CAAC;gBAAC,OAAO,OAAO,EAAE,CAAC;oBACjB,MAAM,IAAI,iCAAsB,CAAC,6CAA6C,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;gBAChG,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,YAAY,CAC1B,MAAuB,EACvB,UAA+B,EAAE;IAEjC,MAAM,UAAU,GACd,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,wBAAe,EAAC,MAAyB,EAAE,OAAO,CAAC,CAAC;IAC5F,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9F,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,CACL,CAAC,CAAC,KAAK;QACP,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,OAAO,CAAE,KAA8B,CAAC,MAAM,CAAC;QACrD,KAAK,CAAC,OAAO,CAAE,KAA8B,CAAC,GAAG,CAAC;QAClD,OAAQ,KAA8B,CAAC,MAAM,KAAK,QAAQ,CAC3D,CAAC;AACJ,CAAC","sourcesContent":["import * as fs from 'fs';\nimport { adoptFixtureResource, TestDatabaseBuildError } from './resource';\nimport { assertFixtureSqlFile } from './fixture-provenance';\nimport { parseTestSchema } from './schema/parser';\nimport { generateDdl } from './schema/ddl';\nimport type { NormalizedTestSchema, ParseTestSchemaOptions } from './schema/types';\nimport { allocateDatabase } from './postgres/allocator';\nimport { createDatabaseHandle, TestPostgresDatabase } from './postgres/database';\nimport { dropDatabase } from './postgres/allocator';\nimport { TestPostgresServerError, TestServerOptions } from './postgres/server';\nimport { composeRows, DataOperation, insertRows, Row, toOperations } from './postgres/loadData';\n\nexport interface TestPostgresOptions extends TestServerOptions, ParseTestSchemaOptions {}\n\nexport interface TestPostgresBuilder {\n /** The normalized immutable schema (useful for assertions/diagnostics). */\n readonly schema: NormalizedTestSchema;\n /** @internal Accumulated row operations (exposed for pure tests). */\n readonly ops: readonly DataOperation[];\n /** Returns a NEW derived builder; this builder is unchanged. */\n data(rows: Record<string, Row[]>): TestPostgresBuilder;\n /**\n * Create a fresh isolated PostgreSQL database, apply DDL + raw SQL,\n * insert effective scenario rows, and return the handle. Does not\n * consume the builder: building twice yields two independent databases.\n */\n build(): Promise<TestPostgresDatabase>;\n}\n\ninterface BuilderState {\n readonly schema: NormalizedTestSchema;\n readonly ops: readonly DataOperation[];\n readonly options: Readonly<TestPostgresOptions>;\n}\n\nfunction readRawSql(schema: NormalizedTestSchema): { label: string; sql: string }[] {\n return schema.sql.map((entry) => {\n if (entry.kind === 'inline') {\n return { label: `sql entry #${entry.index} (inline)`, sql: entry.sql };\n }\n try {\n assertFixtureSqlFile(entry.resolvedPath);\n return {\n label: `sql entry #${entry.index} (${entry.sourcePath})`,\n sql: fs.readFileSync(entry.resolvedPath, 'utf8'),\n };\n } catch (err) {\n throw new TestPostgresServerError(\n `Cannot read raw SQL file for sql entry #${entry.index}: ${entry.resolvedPath} ` +\n `(authored as \"${entry.sourcePath}\" in ${schema.source}): ${(err as Error).message}`\n );\n }\n });\n}\n\nfunction makeBuilder(state: BuilderState): TestPostgresBuilder {\n return {\n schema: state.schema,\n ops: state.ops,\n data(rows: Record<string, Row[]>): TestPostgresBuilder {\n const newOps = toOperations(state.schema, rows);\n return makeBuilder({ ...state, ops: [...state.ops, ...newOps] });\n },\n async build(): Promise<TestPostgresDatabase> {\n // Fail on pure planning errors (cycles, raw SQL file readability)\n // before touching the server where possible.\n const rawSql = readRawSql(state.schema);\n const ddl = generateDdl(state.schema);\n const effective = composeRows(state.schema, state.ops);\n\n const allocated = await allocateDatabase(state.options);\n let handle: (TestPostgresDatabase & { _pool: any }) | undefined;\n try {\n handle = await createDatabaseHandle(allocated, state.options);\n for (const statement of ddl) {\n try {\n await handle._pool.query(statement);\n } catch (err) {\n throw new TestPostgresServerError(\n `Failed to apply structured DDL from ${state.schema.source}: ${(err as Error).message}\\n` +\n `Statement:\\n${statement}`\n );\n }\n }\n for (const entry of rawSql) {\n try {\n // Simple-query protocol: the pg driver executes multi-statement\n // scripts directly when no parameters are passed.\n await handle._pool.query(entry.sql);\n } catch (err) {\n throw new TestPostgresServerError(\n `Failed to apply raw ${entry.label} from ${state.schema.source}: ${(err as Error).message}`\n );\n }\n }\n await insertRows((sql, params) => handle!._pool.query(sql, params), state.schema, effective);\n return adoptFixtureResource(handle);\n } catch (err) {\n // Use the handle's all-steps disposer and retire its provenance even\n // after failed DDL/data. Preserve allocation and every cleanup failure.\n try {\n if (handle) await handle.dispose();\n else await dropDatabase(allocated.name, state.options);\n } catch (cleanup) {\n throw new TestDatabaseBuildError('PostgreSQL fixture build and cleanup failed', err, cleanup);\n }\n throw err;\n }\n },\n };\n}\n\n/**\n * Persistent immutable test database builder.\n *\n * `schema` may be a parsed schema object, a YAML string, or a path to a\n * .yml/.yaml file (raw .sql entries then resolve relative to that file's\n * directory unless options.sourceDir overrides it).\n */\nexport function testPostgres(\n schema: string | object,\n options: TestPostgresOptions = {}\n): TestPostgresBuilder {\n const normalized =\n isNormalizedSchema(schema) ? schema : parseTestSchema(schema as string | object, options);\n return makeBuilder({ schema: normalized, ops: [], options: Object.freeze({ ...options }) });\n}\n\nfunction isNormalizedSchema(input: unknown): input is NormalizedTestSchema {\n return (\n !!input &&\n typeof input === 'object' &&\n Array.isArray((input as NormalizedTestSchema).tables) &&\n Array.isArray((input as NormalizedTestSchema).sql) &&\n typeof (input as NormalizedTestSchema).source === 'string'\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture-provenance.d.ts","sourceRoot":"","sources":["../../../src/testing/fixture-provenance.ts"],"names":[],"mappings":"AAIA,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAWvD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.assertFixtureSqlFile = assertFixtureSqlFile;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const errors_1 = require("../core/errors");
|
|
10
|
+
/** File provenance guard; inline SQL still requires architecture/source review. */
|
|
11
|
+
function assertFixtureSqlFile(file) {
|
|
12
|
+
const resolved = (0, node_fs_1.realpathSync)(file);
|
|
13
|
+
for (const candidate of [file, resolved]) {
|
|
14
|
+
const segments = candidate.split(/[\\/]/);
|
|
15
|
+
if (segments.some(segment => /^migrations?$/i.test(segment))
|
|
16
|
+
|| /\.(up|down)\.(sql|[cm]?js|ts)$/i.test(node_path_1.default.basename(candidate))) {
|
|
17
|
+
throw new errors_1.SqlStackError(`Application fixtures cannot read migration file ${file}; use explicit schema/plain data and keep migration transitions in @noego/proper/testing.`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=fixture-provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture-provenance.js","sourceRoot":"","sources":["../../../src/testing/fixture-provenance.ts"],"names":[],"mappings":";;;;;AAKA,oDAWC;AAhBD,0DAA6B;AAC7B,qCAAuC;AACvC,2CAA+C;AAE/C,mFAAmF;AACnF,SAAgB,oBAAoB,CAAC,IAAY;IAC/C,MAAM,QAAQ,GAAG,IAAA,sBAAY,EAAC,IAAI,CAAC,CAAC;IACpC,KAAK,MAAM,SAAS,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;eACvD,iCAAiC,CAAC,IAAI,CAAC,mBAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,sBAAa,CACrB,mDAAmD,IAAI,2FAA2F,CACnJ,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import path from 'node:path';\nimport { realpathSync } from 'node:fs';\nimport { SqlStackError } from '../core/errors';\n\n/** File provenance guard; inline SQL still requires architecture/source review. */\nexport function assertFixtureSqlFile(file: string): void {\n const resolved = realpathSync(file);\n for (const candidate of [file, resolved]) {\n const segments = candidate.split(/[\\\\/]/);\n if (segments.some(segment => /^migrations?$/i.test(segment))\n || /\\.(up|down)\\.(sql|[cm]?js|ts)$/i.test(path.basename(candidate))) {\n throw new SqlStackError(\n `Application fixtures cannot read migration file ${file}; use explicit schema/plain data and keep migration transitions in @noego/proper/testing.`,\n );\n }\n }\n}\n"]}
|
|
@@ -5,6 +5,8 @@ export { testSqlite } from './sqlite/builder';
|
|
|
5
5
|
export type { TestSqliteBuilder, TestSqliteOptions } from './sqlite/builder';
|
|
6
6
|
export { TestSqliteError } from './sqlite/database';
|
|
7
7
|
export type { TestSqliteDatabase } from './sqlite/database';
|
|
8
|
+
export { isDisposableTestDatabase, TestDatabaseDisposeError, TestDatabaseBuildError } from './resource';
|
|
9
|
+
export type { DisposableTestDatabase } from './resource';
|
|
8
10
|
export { parseTestSchema } from './schema/parser';
|
|
9
11
|
export { normalizeTestSchema, TestSchemaError } from './schema/normalize';
|
|
10
12
|
export { generateDdl } from './schema/ddl';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC1E,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,sBAAsB,GACvB,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC1E,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACxG,YAAY,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,sBAAsB,GACvB,MAAM,gBAAgB,CAAC"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_ADMIN_URL = exports.TestPostgresServerError = exports.TestDataError = exports.generateDdl = exports.TestSchemaError = exports.normalizeTestSchema = exports.parseTestSchema = exports.TestSqliteError = exports.testSqlite = exports.testPostgres = void 0;
|
|
3
|
+
exports.DEFAULT_ADMIN_URL = exports.TestPostgresServerError = exports.TestDataError = exports.generateDdl = exports.TestSchemaError = exports.normalizeTestSchema = exports.parseTestSchema = exports.TestDatabaseBuildError = exports.TestDatabaseDisposeError = exports.isDisposableTestDatabase = exports.TestSqliteError = exports.testSqlite = exports.testPostgres = void 0;
|
|
4
4
|
var builder_1 = require("./builder");
|
|
5
5
|
Object.defineProperty(exports, "testPostgres", { enumerable: true, get: function () { return builder_1.testPostgres; } });
|
|
6
6
|
var builder_2 = require("./sqlite/builder");
|
|
7
7
|
Object.defineProperty(exports, "testSqlite", { enumerable: true, get: function () { return builder_2.testSqlite; } });
|
|
8
8
|
var database_1 = require("./sqlite/database");
|
|
9
9
|
Object.defineProperty(exports, "TestSqliteError", { enumerable: true, get: function () { return database_1.TestSqliteError; } });
|
|
10
|
+
var resource_1 = require("./resource");
|
|
11
|
+
Object.defineProperty(exports, "isDisposableTestDatabase", { enumerable: true, get: function () { return resource_1.isDisposableTestDatabase; } });
|
|
12
|
+
Object.defineProperty(exports, "TestDatabaseDisposeError", { enumerable: true, get: function () { return resource_1.TestDatabaseDisposeError; } });
|
|
13
|
+
Object.defineProperty(exports, "TestDatabaseBuildError", { enumerable: true, get: function () { return resource_1.TestDatabaseBuildError; } });
|
|
10
14
|
var parser_1 = require("./schema/parser");
|
|
11
15
|
Object.defineProperty(exports, "parseTestSchema", { enumerable: true, get: function () { return parser_1.parseTestSchema; } });
|
|
12
16
|
var normalize_1 = require("./schema/normalize");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":";;;AAAA,qCAAyC;AAAhC,uGAAA,YAAY,OAAA;AAGrB,4CAA8C;AAArC,qGAAA,UAAU,OAAA;AAEnB,8CAAoD;AAA3C,2GAAA,eAAe,OAAA;AAExB,0CAAkD;AAAzC,yGAAA,eAAe,OAAA;AACxB,gDAA0E;AAAjE,gHAAA,mBAAmB,OAAA;AAAE,4GAAA,eAAe,OAAA;AAC7C,oCAA2C;AAAlC,kGAAA,WAAW,OAAA;AACpB,gDAAoD;AAA3C,yGAAA,aAAa,OAAA;AACtB,4CAA+E;AAAtE,iHAAA,uBAAuB,OAAA;AAAE,2GAAA,iBAAiB,OAAA","sourcesContent":["export { testPostgres } from './builder';\nexport type { TestPostgresBuilder, TestPostgresOptions } from './builder';\nexport type { TestPostgresDatabase } from './postgres/database';\nexport { testSqlite } from './sqlite/builder';\nexport type { TestSqliteBuilder, TestSqliteOptions } from './sqlite/builder';\nexport { TestSqliteError } from './sqlite/database';\nexport type { TestSqliteDatabase } from './sqlite/database';\nexport { parseTestSchema } from './schema/parser';\nexport { normalizeTestSchema, TestSchemaError } from './schema/normalize';\nexport { generateDdl } from './schema/ddl';\nexport { TestDataError } from './postgres/loadData';\nexport { TestPostgresServerError, DEFAULT_ADMIN_URL } from './postgres/server';\nexport type {\n NormalizedTestSchema,\n NormalizedTable,\n NormalizedColumn,\n RawSqlEntry,\n ParseTestSchemaOptions,\n} from './schema/types';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":";;;AAAA,qCAAyC;AAAhC,uGAAA,YAAY,OAAA;AAGrB,4CAA8C;AAArC,qGAAA,UAAU,OAAA;AAEnB,8CAAoD;AAA3C,2GAAA,eAAe,OAAA;AAExB,uCAAwG;AAA/F,oHAAA,wBAAwB,OAAA;AAAE,oHAAA,wBAAwB,OAAA;AAAE,kHAAA,sBAAsB,OAAA;AAEnF,0CAAkD;AAAzC,yGAAA,eAAe,OAAA;AACxB,gDAA0E;AAAjE,gHAAA,mBAAmB,OAAA;AAAE,4GAAA,eAAe,OAAA;AAC7C,oCAA2C;AAAlC,kGAAA,WAAW,OAAA;AACpB,gDAAoD;AAA3C,yGAAA,aAAa,OAAA;AACtB,4CAA+E;AAAtE,iHAAA,uBAAuB,OAAA;AAAE,2GAAA,iBAAiB,OAAA","sourcesContent":["export { testPostgres } from './builder';\nexport type { TestPostgresBuilder, TestPostgresOptions } from './builder';\nexport type { TestPostgresDatabase } from './postgres/database';\nexport { testSqlite } from './sqlite/builder';\nexport type { TestSqliteBuilder, TestSqliteOptions } from './sqlite/builder';\nexport { TestSqliteError } from './sqlite/database';\nexport type { TestSqliteDatabase } from './sqlite/database';\nexport { isDisposableTestDatabase, TestDatabaseDisposeError, TestDatabaseBuildError } from './resource';\nexport type { DisposableTestDatabase } from './resource';\nexport { parseTestSchema } from './schema/parser';\nexport { normalizeTestSchema, TestSchemaError } from './schema/normalize';\nexport { generateDdl } from './schema/ddl';\nexport { TestDataError } from './postgres/loadData';\nexport { TestPostgresServerError, DEFAULT_ADMIN_URL } from './postgres/server';\nexport type {\n NormalizedTestSchema,\n NormalizedTable,\n NormalizedColumn,\n RawSqlEntry,\n ParseTestSchemaOptions,\n} from './schema/types';\n"]}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { TestServerOptions } from './server';
|
|
2
2
|
/** The built test database handle. */
|
|
3
3
|
export interface TestPostgresDatabase {
|
|
4
|
+
/** Engine discriminator for SQLStack-minted disposable test databases. */
|
|
5
|
+
readonly engine: 'postgres';
|
|
6
|
+
/** Fresh per-allocation identifier; never reused within a process. */
|
|
7
|
+
readonly resourceId: string;
|
|
4
8
|
/** Normal PostgreSQL connection string identifying only this database. */
|
|
5
9
|
readonly url: string;
|
|
6
10
|
query(sql: string, params?: readonly unknown[]): Promise<unknown>;
|
|
7
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Close helper connections and drop the owned database. Idempotent:
|
|
13
|
+
* concurrent and repeated calls share one outcome. Every cleanup step is
|
|
14
|
+
* attempted; failures are aggregated into a `TestDatabaseDisposeError`.
|
|
15
|
+
*/
|
|
8
16
|
dispose(): Promise<void>;
|
|
9
17
|
}
|
|
10
18
|
export interface OwnedDatabase {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../../src/testing/postgres/database.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,iBAAiB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../../src/testing/postgres/database.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG9E,sCAAsC;AACtC,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,oBAAoB,GAAG;IAAE,KAAK,EAAE,GAAG,CAAA;CAAE,CAAC,CAkChD"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createDatabaseHandle = createDatabaseHandle;
|
|
4
4
|
const allocator_1 = require("./allocator");
|
|
5
5
|
const server_1 = require("./server");
|
|
6
|
+
const resource_1 = require("../resource");
|
|
6
7
|
/**
|
|
7
8
|
* Connect a helper pool to an allocated database and produce the handle.
|
|
8
9
|
* The handle owns exactly this database and drops it on dispose.
|
|
@@ -11,29 +12,32 @@ async function createDatabaseHandle(owned, options = {}) {
|
|
|
11
12
|
const pg = await (0, server_1.loadPg)();
|
|
12
13
|
const Pool = pg.Pool ?? pg.default?.Pool;
|
|
13
14
|
const pool = new Pool({ connectionString: owned.url, max: 4 });
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const resourceId = (0, resource_1.mintResourceId)('postgres');
|
|
16
|
+
let disposal;
|
|
17
|
+
const handle = {
|
|
18
|
+
engine: 'postgres',
|
|
19
|
+
resourceId,
|
|
16
20
|
url: owned.url,
|
|
17
21
|
_pool: pool,
|
|
18
22
|
async query(sql, params = []) {
|
|
19
|
-
if (
|
|
23
|
+
if (disposal) {
|
|
20
24
|
throw new server_1.TestPostgresServerError(`Test database "${owned.name}" has been disposed; no further queries are possible.`);
|
|
21
25
|
}
|
|
22
26
|
const res = await pool.query(sql, params);
|
|
23
27
|
return res.rows;
|
|
24
28
|
},
|
|
25
|
-
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
dispose() {
|
|
30
|
+
if (!disposal) {
|
|
31
|
+
(0, resource_1.retireResource)(handle);
|
|
32
|
+
disposal = Promise.resolve().then(() => (0, resource_1.runCleanupSteps)(`Test database "${owned.name}"`, [
|
|
33
|
+
() => pool.end(),
|
|
34
|
+
() => (0, allocator_1.dropDatabase)(owned.name, options),
|
|
35
|
+
]));
|
|
31
36
|
}
|
|
32
|
-
|
|
33
|
-
/* pool may already be closed */
|
|
34
|
-
}
|
|
35
|
-
await (0, allocator_1.dropDatabase)(owned.name, options);
|
|
37
|
+
return disposal;
|
|
36
38
|
},
|
|
37
39
|
};
|
|
40
|
+
(0, resource_1.registerResource)(handle, { engine: 'postgres', resourceId });
|
|
41
|
+
return handle;
|
|
38
42
|
}
|
|
39
43
|
//# sourceMappingURL=database.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../../src/testing/postgres/database.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../../src/testing/postgres/database.ts"],"names":[],"mappings":";;AA8BA,oDAqCC;AAnED,2CAA2C;AAC3C,qCAA8E;AAC9E,0CAAgG;AAwBhG;;;GAGG;AACI,KAAK,UAAU,oBAAoB,CACxC,KAAoB,EACpB,UAA6B,EAAE;IAE/B,MAAM,EAAE,GAAG,MAAM,IAAA,eAAM,GAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAA,yBAAc,EAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,QAAmC,CAAC;IAExC,MAAM,MAAM,GAA0C;QACpD,MAAM,EAAE,UAAU;QAClB,UAAU;QACV,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,KAAK,EAAE,IAAI;QACX,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,SAA6B,EAAE;YACtD,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,IAAI,gCAAuB,CAC/B,kBAAkB,KAAK,CAAC,IAAI,uDAAuD,CACpF,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,MAAmB,CAAC,CAAC;YACvD,OAAO,GAAG,CAAC,IAAI,CAAC;QAClB,CAAC;QACD,OAAO;YACL,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAA,yBAAc,EAAC,MAAM,CAAC,CAAC;gBACvB,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAA,0BAAe,EAAC,kBAAkB,KAAK,CAAC,IAAI,GAAG,EAAE;oBACvF,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;oBAChB,GAAG,EAAE,CAAC,IAAA,wBAAY,EAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC;iBACxC,CAAC,CAAC,CAAC;YACN,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;KACF,CAAC;IACF,IAAA,2BAAgB,EAAC,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7D,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { dropDatabase } from './allocator';\nimport { loadPg, TestPostgresServerError, TestServerOptions } from './server';\nimport { mintResourceId, registerResource, retireResource, runCleanupSteps } from '../resource';\n\n/** The built test database handle. */\nexport interface TestPostgresDatabase {\n /** Engine discriminator for SQLStack-minted disposable test databases. */\n readonly engine: 'postgres';\n /** Fresh per-allocation identifier; never reused within a process. */\n readonly resourceId: string;\n /** Normal PostgreSQL connection string identifying only this database. */\n readonly url: string;\n query(sql: string, params?: readonly unknown[]): Promise<unknown>;\n /**\n * Close helper connections and drop the owned database. Idempotent:\n * concurrent and repeated calls share one outcome. Every cleanup step is\n * attempted; failures are aggregated into a `TestDatabaseDisposeError`.\n */\n dispose(): Promise<void>;\n}\n\nexport interface OwnedDatabase {\n readonly name: string;\n readonly url: string;\n}\n\n/**\n * Connect a helper pool to an allocated database and produce the handle.\n * The handle owns exactly this database and drops it on dispose.\n */\nexport async function createDatabaseHandle(\n owned: OwnedDatabase,\n options: TestServerOptions = {}\n): Promise<TestPostgresDatabase & { _pool: any }> {\n const pg = await loadPg();\n const Pool = pg.Pool ?? pg.default?.Pool;\n const pool = new Pool({ connectionString: owned.url, max: 4 });\n const resourceId = mintResourceId('postgres');\n let disposal: Promise<void> | undefined;\n\n const handle: TestPostgresDatabase & { _pool: any } = {\n engine: 'postgres',\n resourceId,\n url: owned.url,\n _pool: pool,\n async query(sql: string, params: readonly unknown[] = []) {\n if (disposal) {\n throw new TestPostgresServerError(\n `Test database \"${owned.name}\" has been disposed; no further queries are possible.`\n );\n }\n const res = await pool.query(sql, params as unknown[]);\n return res.rows;\n },\n dispose() {\n if (!disposal) {\n retireResource(handle);\n disposal = Promise.resolve().then(() => runCleanupSteps(`Test database \"${owned.name}\"`, [\n () => pool.end(),\n () => dropDatabase(owned.name, options),\n ]));\n }\n return disposal;\n },\n };\n registerResource(handle, { engine: 'postgres', resourceId });\n return handle;\n}\n"]}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { SqlStackError } from '../core/errors';
|
|
2
|
+
import type { TestPostgresDatabase } from './postgres/database';
|
|
3
|
+
import type { TestSqliteDatabase } from './sqlite/database';
|
|
4
|
+
/**
|
|
5
|
+
* Internal provenance for SQLStack-minted disposable test databases.
|
|
6
|
+
*
|
|
7
|
+
* Every handle allocated by a SQLStack fixture builder is registered here at
|
|
8
|
+
* allocation time and retired on dispose. Membership is module-private:
|
|
9
|
+
* nothing outside this package can mint, register, or extend a handle's
|
|
10
|
+
* lifetime, and structural copies (spread, `{ ...handle }`, hand-built
|
|
11
|
+
* lookalikes) never validate because verification is by object identity.
|
|
12
|
+
*/
|
|
13
|
+
/** A disposable test database minted by a SQLStack fixture allocation. */
|
|
14
|
+
export type DisposableTestDatabase = (TestPostgresDatabase & {
|
|
15
|
+
readonly engine: 'postgres';
|
|
16
|
+
readonly resourceId: string;
|
|
17
|
+
}) | (TestSqliteDatabase & {
|
|
18
|
+
readonly engine: 'sqlite';
|
|
19
|
+
readonly resourceId: string;
|
|
20
|
+
readonly storage: 'memory' | 'file';
|
|
21
|
+
});
|
|
22
|
+
export type DisposableEngine = DisposableTestDatabase['engine'];
|
|
23
|
+
interface ResourceRecord {
|
|
24
|
+
readonly engine: DisposableEngine;
|
|
25
|
+
readonly resourceId: string;
|
|
26
|
+
readonly storage?: 'memory' | 'file';
|
|
27
|
+
readonly url?: unknown;
|
|
28
|
+
readonly db?: unknown;
|
|
29
|
+
readonly conn?: unknown;
|
|
30
|
+
readonly path?: unknown;
|
|
31
|
+
readonly query?: unknown;
|
|
32
|
+
readonly dispose?: unknown;
|
|
33
|
+
}
|
|
34
|
+
/** Fresh, process-unique identifier for one allocation. */
|
|
35
|
+
export declare function mintResourceId(engine: DisposableEngine): string;
|
|
36
|
+
/**
|
|
37
|
+
* Register a freshly allocated handle as an active SQLStack resource.
|
|
38
|
+
* Only fixture allocation code paths call this; it is never exported from
|
|
39
|
+
* `sqlstack/testing`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function registerResource(handle: object, record: ResourceRecord): void;
|
|
42
|
+
/**
|
|
43
|
+
* Optional shared testing resource-scope ABI. SQLStack remains independently
|
|
44
|
+
* usable; it never creates a scope or imports a test runner.
|
|
45
|
+
* Called within the builder's rollback boundary before returning a fixture.
|
|
46
|
+
*/
|
|
47
|
+
export declare function adoptFixtureResource<T extends {
|
|
48
|
+
dispose(): unknown;
|
|
49
|
+
}>(handle: T): T;
|
|
50
|
+
/** Mark a handle's owned resources as released. Verification fails from now on. */
|
|
51
|
+
export declare function retireResource(handle: object): void;
|
|
52
|
+
/**
|
|
53
|
+
* True only for a handle object that was minted by a SQLStack fixture
|
|
54
|
+
* allocation in this process and has not been disposed. Field checks are a
|
|
55
|
+
* consistency guard on top of identity membership, never a substitute for it.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isDisposableTestDatabase(value: unknown): value is DisposableTestDatabase;
|
|
58
|
+
/** Failed fixture construction plus failed rollback, preserving both causes. */
|
|
59
|
+
export declare class TestDatabaseBuildError extends SqlStackError {
|
|
60
|
+
readonly cause: unknown;
|
|
61
|
+
readonly errors: readonly unknown[];
|
|
62
|
+
constructor(message: string, cause: unknown, cleanup: unknown);
|
|
63
|
+
}
|
|
64
|
+
/** Raised by `dispose()` when one or more owned cleanup steps failed. */
|
|
65
|
+
export declare class TestDatabaseDisposeError extends SqlStackError {
|
|
66
|
+
/** Every cleanup failure, in attempt order. Nothing is swallowed. */
|
|
67
|
+
readonly errors: readonly unknown[];
|
|
68
|
+
constructor(message: string, errors: readonly unknown[]);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Run every cleanup step, retaining each failure, then either resolve or
|
|
72
|
+
* reject once with all retained errors.
|
|
73
|
+
*/
|
|
74
|
+
export declare function runCleanupSteps(label: string, steps: readonly (() => Promise<void> | void)[]): Promise<void>;
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../../src/testing/resource.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D;;;;;;;;GAQG;AAEH,0EAA0E;AAC1E,MAAM,MAAM,sBAAsB,GAC9B,CAAC,oBAAoB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,GACrF,CAAC,kBAAkB,GAAG;IACpB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAC;CACrC,CAAC,CAAC;AAEP,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;AAEhE,UAAU,cAAc;IACtB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AASD,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAG/D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAK7E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,OAAO,IAAI,OAAO,CAAA;CAAE,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAOnF;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,sBAAsB,CAcxF;AAED,gFAAgF;AAChF,qBAAa,sBAAuB,SAAQ,aAAa;IAE1B,QAAQ,CAAC,KAAK,EAAE,OAAO;IADpD,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;gBACxB,OAAO,EAAE,MAAM,EAAW,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;CAKvE;AAED,yEAAyE;AACzE,qBAAa,wBAAyB,SAAQ,aAAa;IACzD,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;gBAExB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,OAAO,EAAE;CAKxD;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,SAAS,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,GAC7C,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestDatabaseDisposeError = exports.TestDatabaseBuildError = void 0;
|
|
4
|
+
exports.mintResourceId = mintResourceId;
|
|
5
|
+
exports.registerResource = registerResource;
|
|
6
|
+
exports.adoptFixtureResource = adoptFixtureResource;
|
|
7
|
+
exports.retireResource = retireResource;
|
|
8
|
+
exports.isDisposableTestDatabase = isDisposableTestDatabase;
|
|
9
|
+
exports.runCleanupSteps = runCleanupSteps;
|
|
10
|
+
const node_crypto_1 = require("node:crypto");
|
|
11
|
+
const errors_1 = require("../core/errors");
|
|
12
|
+
/** Handles whose owned resources are currently allocated (not yet disposed). */
|
|
13
|
+
const active = new WeakSet();
|
|
14
|
+
/** Provenance recorded at mint time, kept for the handle's whole lifetime. */
|
|
15
|
+
const provenance = new WeakMap();
|
|
16
|
+
let counter = 0;
|
|
17
|
+
/** Fresh, process-unique identifier for one allocation. */
|
|
18
|
+
function mintResourceId(engine) {
|
|
19
|
+
counter += 1;
|
|
20
|
+
return `${engine}-${(0, node_crypto_1.randomBytes)(6).toString('hex')}-${counter}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register a freshly allocated handle as an active SQLStack resource.
|
|
24
|
+
* Only fixture allocation code paths call this; it is never exported from
|
|
25
|
+
* `sqlstack/testing`.
|
|
26
|
+
*/
|
|
27
|
+
function registerResource(handle, record) {
|
|
28
|
+
const locator = handle;
|
|
29
|
+
provenance.set(handle, Object.freeze({ ...record, url: locator.url, db: locator.db,
|
|
30
|
+
conn: locator.conn, path: locator.path, query: locator.query, dispose: locator.dispose }));
|
|
31
|
+
active.add(handle);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Optional shared testing resource-scope ABI. SQLStack remains independently
|
|
35
|
+
* usable; it never creates a scope or imports a test runner.
|
|
36
|
+
* Called within the builder's rollback boundary before returning a fixture.
|
|
37
|
+
*/
|
|
38
|
+
function adoptFixtureResource(handle) {
|
|
39
|
+
const channel = globalThis[Symbol.for('@noego/testing.resource-scope.v1')];
|
|
40
|
+
if (channel) {
|
|
41
|
+
if (typeof channel.getStore !== 'function')
|
|
42
|
+
throw new Error('Incompatible NoEgo resource-scope v1 channel');
|
|
43
|
+
channel.getStore()?.own(handle, 'sqlstack fixture');
|
|
44
|
+
}
|
|
45
|
+
return handle;
|
|
46
|
+
}
|
|
47
|
+
/** Mark a handle's owned resources as released. Verification fails from now on. */
|
|
48
|
+
function retireResource(handle) {
|
|
49
|
+
active.delete(handle);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* True only for a handle object that was minted by a SQLStack fixture
|
|
53
|
+
* allocation in this process and has not been disposed. Field checks are a
|
|
54
|
+
* consistency guard on top of identity membership, never a substitute for it.
|
|
55
|
+
*/
|
|
56
|
+
function isDisposableTestDatabase(value) {
|
|
57
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function'))
|
|
58
|
+
return false;
|
|
59
|
+
const handle = value;
|
|
60
|
+
if (!active.has(handle))
|
|
61
|
+
return false;
|
|
62
|
+
const record = provenance.get(handle);
|
|
63
|
+
if (!record)
|
|
64
|
+
return false;
|
|
65
|
+
const candidate = handle;
|
|
66
|
+
if (candidate.engine !== record.engine || candidate.resourceId !== record.resourceId)
|
|
67
|
+
return false;
|
|
68
|
+
if (record.engine === 'sqlite' && candidate.storage !== record.storage)
|
|
69
|
+
return false;
|
|
70
|
+
const locator = handle;
|
|
71
|
+
for (const key of ['url', 'db', 'conn', 'path', 'query', 'dispose']) {
|
|
72
|
+
if (locator[key] !== record[key])
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
/** Failed fixture construction plus failed rollback, preserving both causes. */
|
|
78
|
+
class TestDatabaseBuildError extends errors_1.SqlStackError {
|
|
79
|
+
constructor(message, cause, cleanup) {
|
|
80
|
+
super(message);
|
|
81
|
+
this.cause = cause;
|
|
82
|
+
this.name = 'TestDatabaseBuildError';
|
|
83
|
+
this.errors = Object.freeze([cause, cleanup]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.TestDatabaseBuildError = TestDatabaseBuildError;
|
|
87
|
+
/** Raised by `dispose()` when one or more owned cleanup steps failed. */
|
|
88
|
+
class TestDatabaseDisposeError extends errors_1.SqlStackError {
|
|
89
|
+
constructor(message, errors) {
|
|
90
|
+
super(message);
|
|
91
|
+
this.name = 'TestDatabaseDisposeError';
|
|
92
|
+
this.errors = Object.freeze([...errors]);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.TestDatabaseDisposeError = TestDatabaseDisposeError;
|
|
96
|
+
/**
|
|
97
|
+
* Run every cleanup step, retaining each failure, then either resolve or
|
|
98
|
+
* reject once with all retained errors.
|
|
99
|
+
*/
|
|
100
|
+
async function runCleanupSteps(label, steps) {
|
|
101
|
+
const errors = [];
|
|
102
|
+
for (const step of steps) {
|
|
103
|
+
try {
|
|
104
|
+
await step();
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
errors.push(err);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (errors.length === 0)
|
|
111
|
+
return;
|
|
112
|
+
const detail = errors
|
|
113
|
+
.map((err, index) => ` [${index + 1}] ${err instanceof Error ? err.message : String(err)}`)
|
|
114
|
+
.join('\n');
|
|
115
|
+
throw new TestDatabaseDisposeError(`${label}: ${errors.length} cleanup step(s) failed while disposing:\n${detail}`, errors);
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../../../src/testing/resource.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { SqlStackError } from '../core/errors';\nimport type { TestPostgresDatabase } from './postgres/database';\nimport type { TestSqliteDatabase } from './sqlite/database';\n\n/**\n * Internal provenance for SQLStack-minted disposable test databases.\n *\n * Every handle allocated by a SQLStack fixture builder is registered here at\n * allocation time and retired on dispose. Membership is module-private:\n * nothing outside this package can mint, register, or extend a handle's\n * lifetime, and structural copies (spread, `{ ...handle }`, hand-built\n * lookalikes) never validate because verification is by object identity.\n */\n\n/** A disposable test database minted by a SQLStack fixture allocation. */\nexport type DisposableTestDatabase =\n | (TestPostgresDatabase & { readonly engine: 'postgres'; readonly resourceId: string })\n | (TestSqliteDatabase & {\n readonly engine: 'sqlite';\n readonly resourceId: string;\n readonly storage: 'memory' | 'file';\n });\n\nexport type DisposableEngine = DisposableTestDatabase['engine'];\n\ninterface ResourceRecord {\n readonly engine: DisposableEngine;\n readonly resourceId: string;\n readonly storage?: 'memory' | 'file';\n readonly url?: unknown;\n readonly db?: unknown;\n readonly conn?: unknown;\n readonly path?: unknown;\n readonly query?: unknown;\n readonly dispose?: unknown;\n}\n\n/** Handles whose owned resources are currently allocated (not yet disposed). */\nconst active = new WeakSet<object>();\n/** Provenance recorded at mint time, kept for the handle's whole lifetime. */\nconst provenance = new WeakMap<object, ResourceRecord>();\n\nlet counter = 0;\n\n/** Fresh, process-unique identifier for one allocation. */\nexport function mintResourceId(engine: DisposableEngine): string {\n counter += 1;\n return `${engine}-${randomBytes(6).toString('hex')}-${counter}`;\n}\n\n/**\n * Register a freshly allocated handle as an active SQLStack resource.\n * Only fixture allocation code paths call this; it is never exported from\n * `sqlstack/testing`.\n */\nexport function registerResource(handle: object, record: ResourceRecord): void {\n const locator = handle as Record<string, unknown>;\n provenance.set(handle, Object.freeze({ ...record, url: locator.url, db: locator.db,\n conn: locator.conn, path: locator.path, query: locator.query, dispose: locator.dispose }));\n active.add(handle);\n}\n\n/**\n * Optional shared testing resource-scope ABI. SQLStack remains independently\n * usable; it never creates a scope or imports a test runner.\n * Called within the builder's rollback boundary before returning a fixture.\n */\nexport function adoptFixtureResource<T extends { dispose(): unknown }>(handle: T): T {\n const channel = (globalThis as Record<PropertyKey, any>)[Symbol.for('@noego/testing.resource-scope.v1')];\n if (channel) {\n if (typeof channel.getStore !== 'function') throw new Error('Incompatible NoEgo resource-scope v1 channel');\n channel.getStore()?.own(handle, 'sqlstack fixture');\n }\n return handle;\n}\n\n/** Mark a handle's owned resources as released. Verification fails from now on. */\nexport function retireResource(handle: object): void {\n active.delete(handle);\n}\n\n/**\n * True only for a handle object that was minted by a SQLStack fixture\n * allocation in this process and has not been disposed. Field checks are a\n * consistency guard on top of identity membership, never a substitute for it.\n */\nexport function isDisposableTestDatabase(value: unknown): value is DisposableTestDatabase {\n if (value === null || (typeof value !== 'object' && typeof value !== 'function')) return false;\n const handle = value as object;\n if (!active.has(handle)) return false;\n const record = provenance.get(handle);\n if (!record) return false;\n const candidate = handle as { engine?: unknown; resourceId?: unknown; storage?: unknown };\n if (candidate.engine !== record.engine || candidate.resourceId !== record.resourceId) return false;\n if (record.engine === 'sqlite' && candidate.storage !== record.storage) return false;\n const locator = handle as Record<string, unknown>;\n for (const key of ['url', 'db', 'conn', 'path', 'query', 'dispose'] as const) {\n if (locator[key] !== record[key]) return false;\n }\n return true;\n}\n\n/** Failed fixture construction plus failed rollback, preserving both causes. */\nexport class TestDatabaseBuildError extends SqlStackError {\n readonly errors: readonly unknown[];\n constructor(message: string, readonly cause: unknown, cleanup: unknown) {\n super(message);\n this.name = 'TestDatabaseBuildError';\n this.errors = Object.freeze([cause, cleanup]);\n }\n}\n\n/** Raised by `dispose()` when one or more owned cleanup steps failed. */\nexport class TestDatabaseDisposeError extends SqlStackError {\n /** Every cleanup failure, in attempt order. Nothing is swallowed. */\n readonly errors: readonly unknown[];\n\n constructor(message: string, errors: readonly unknown[]) {\n super(message);\n this.name = 'TestDatabaseDisposeError';\n this.errors = Object.freeze([...errors]);\n }\n}\n\n/**\n * Run every cleanup step, retaining each failure, then either resolve or\n * reject once with all retained errors.\n */\nexport async function runCleanupSteps(\n label: string,\n steps: readonly (() => Promise<void> | void)[]\n): Promise<void> {\n const errors: unknown[] = [];\n for (const step of steps) {\n try {\n await step();\n } catch (err) {\n errors.push(err);\n }\n }\n if (errors.length === 0) return;\n const detail = errors\n .map((err, index) => ` [${index + 1}] ${err instanceof Error ? err.message : String(err)}`)\n .join('\\n');\n throw new TestDatabaseDisposeError(\n `${label}: ${errors.length} cleanup step(s) failed while disposing:\\n${detail}`,\n errors\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../src/testing/sqlite/builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../src/testing/sqlite/builder.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAwB,kBAAkB,EAAmB,MAAM,YAAY,CAAC;AACvF,OAAO,EAAe,aAAa,EAAc,GAAG,EAAgB,MAAM,YAAY,CAAC;AAEvF,MAAM,WAAW,iBAAkB,SAAQ,sBAAsB;IAC/D;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,SAAS,aAAa,EAAE,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,iBAAiB,CAAC;IACrD,KAAK,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACtC;AAsFD,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,OAAO,GAAE,iBAAsB,GAC9B,iBAAiB,CAcnB"}
|
|
@@ -35,6 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.testSqlite = testSqlite;
|
|
37
37
|
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const resource_1 = require("../resource");
|
|
39
|
+
const fixture_provenance_1 = require("../fixture-provenance");
|
|
38
40
|
const ddl_1 = require("../schema/ddl");
|
|
39
41
|
const parser_1 = require("../schema/parser");
|
|
40
42
|
const database_1 = require("./database");
|
|
@@ -45,6 +47,7 @@ function readRawSql(schema) {
|
|
|
45
47
|
return { label: `sql entry #${entry.index} (inline)`, sql: entry.sql };
|
|
46
48
|
}
|
|
47
49
|
try {
|
|
50
|
+
(0, fixture_provenance_1.assertFixtureSqlFile)(entry.resolvedPath);
|
|
48
51
|
return {
|
|
49
52
|
label: `sql entry #${entry.index} (${entry.sourcePath})`,
|
|
50
53
|
sql: fs.readFileSync(entry.resolvedPath, 'utf8'),
|
|
@@ -102,10 +105,15 @@ function makeBuilder(state) {
|
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
await (0, loadData_1.insertRows)((sql, params) => handle.db.query(sql, params), state.schema, effective);
|
|
105
|
-
return handle;
|
|
108
|
+
return (0, resource_1.adoptFixtureResource)(handle);
|
|
106
109
|
}
|
|
107
110
|
catch (err) {
|
|
108
|
-
|
|
111
|
+
try {
|
|
112
|
+
await handle.dispose();
|
|
113
|
+
}
|
|
114
|
+
catch (cleanup) {
|
|
115
|
+
throw new resource_1.TestDatabaseBuildError('SQLite fixture build and cleanup failed', err, cleanup);
|
|
116
|
+
}
|
|
109
117
|
throw err;
|
|
110
118
|
}
|
|
111
119
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../../src/testing/sqlite/builder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../../src/testing/sqlite/builder.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport { adoptFixtureResource, TestDatabaseBuildError } from '../resource';\nimport { assertFixtureSqlFile } from '../fixture-provenance';\nimport { generateDdl } from '../schema/ddl';\nimport { parseTestSchema } from '../schema/parser';\nimport type { NormalizedTestSchema, ParseTestSchemaOptions } from '../schema/types';\nimport { createDatabaseHandle, TestSqliteDatabase, TestSqliteError } from './database';\nimport { composeRows, DataOperation, insertRows, Row, toOperations } from './loadData';\n\nexport interface TestSqliteOptions extends ParseTestSchemaOptions {\n /**\n * Storage for the test database. Defaults to `'file'`: an owned temporary\n * file, removed on `dispose()`. Pass `'memory'` to opt back into an isolated\n * `:memory:` database — only worth it for a test that opens many databases\n * and never touches restart behavior.\n */\n mode?: 'memory' | 'file';\n /** Legacy alias for `mode`. `false` selects `:memory:`. */\n fileBacked?: boolean;\n /** Legacy alias for `mode`. `false` selects `:memory:`. */\n tempFile?: boolean;\n}\n\nexport interface TestSqliteBuilder {\n readonly schema: NormalizedTestSchema;\n readonly ops: readonly DataOperation[];\n data(rows: Record<string, Row[]>): TestSqliteBuilder;\n build(): Promise<TestSqliteDatabase>;\n}\n\ninterface BuilderState {\n readonly schema: NormalizedTestSchema;\n readonly ops: readonly DataOperation[];\n readonly options: Readonly<TestSqliteOptions>;\n}\n\nfunction readRawSql(schema: NormalizedTestSchema): { label: string; sql: string }[] {\n return schema.sql.map((entry) => {\n if (entry.kind === 'inline') {\n return { label: `sql entry #${entry.index} (inline)`, sql: entry.sql };\n }\n try {\n assertFixtureSqlFile(entry.resolvedPath);\n return {\n label: `sql entry #${entry.index} (${entry.sourcePath})`,\n sql: fs.readFileSync(entry.resolvedPath, 'utf8'),\n };\n } catch (err) {\n throw new TestSqliteError(\n `Cannot read raw SQL file for sql entry #${entry.index}: ${entry.resolvedPath} ` +\n `(authored as \"${entry.sourcePath}\" in ${schema.source}): ${(err as Error).message}`\n );\n }\n });\n}\n\nasync function executeRaw(handle: TestSqliteDatabase, sql: string): Promise<void> {\n const conn = handle.conn as { exec?: (sql: string) => unknown };\n if (typeof conn?.exec === 'function') {\n await conn.exec(sql);\n } else {\n await handle.db.query(sql, []);\n }\n}\n\nfunction makeBuilder(state: BuilderState): TestSqliteBuilder {\n return {\n schema: state.schema,\n ops: state.ops,\n data(rows: Record<string, Row[]>): TestSqliteBuilder {\n return makeBuilder({\n ...state,\n ops: [...state.ops, ...toOperations(state.schema, rows)],\n });\n },\n async build(): Promise<TestSqliteDatabase> {\n const rawSql = readRawSql(state.schema);\n const ddl = generateDdl(state.schema);\n const effective = composeRows(state.schema, state.ops);\n const fileBacked = state.options.mode\n ? state.options.mode === 'file'\n : state.options.fileBacked !== false && state.options.tempFile !== false;\n const handle = await createDatabaseHandle(fileBacked);\n try {\n for (const statement of ddl) {\n try {\n await handle.db.query(statement, []);\n } catch (err) {\n throw new TestSqliteError(\n `Failed to apply structured DDL from ${state.schema.source}: ${(err as Error).message}\\n` +\n `Statement:\\n${statement}`\n );\n }\n }\n for (const entry of rawSql) {\n try {\n await executeRaw(handle, entry.sql);\n } catch (err) {\n throw new TestSqliteError(\n `Failed to apply raw ${entry.label} from ${state.schema.source}: ${(err as Error).message}`\n );\n }\n }\n await insertRows((sql, params) => handle.db.query(sql, params), state.schema, effective);\n return adoptFixtureResource(handle);\n } catch (err) {\n try { await handle.dispose(); }\n catch (cleanup) { throw new TestDatabaseBuildError('SQLite fixture build and cleanup failed', err, cleanup); }\n throw err;\n }\n },\n };\n}\n\nexport function testSqlite(\n schema: string | object,\n options: TestSqliteOptions = {}\n): TestSqliteBuilder {\n const normalized = isNormalizedSchema(schema)\n ? schema\n : parseTestSchema(schema as string | object, options);\n if (normalized.dialect !== 'sqlite') {\n throw new TestSqliteError(\n `testSqlite requires a schema with dialect: sqlite (received: ${normalized.dialect})`\n );\n }\n return makeBuilder({\n schema: normalized,\n ops: [],\n options: Object.freeze({ ...options }),\n });\n}\n\nfunction isNormalizedSchema(input: unknown): input is NormalizedTestSchema {\n return (\n !!input &&\n typeof input === 'object' &&\n Array.isArray((input as NormalizedTestSchema).tables) &&\n Array.isArray((input as NormalizedTestSchema).sql) &&\n typeof (input as NormalizedTestSchema).source === 'string'\n );\n}\n"]}
|
|
@@ -4,6 +4,12 @@ export declare class TestSqliteError extends SqlStackError {
|
|
|
4
4
|
constructor(message: string);
|
|
5
5
|
}
|
|
6
6
|
export interface TestSqliteDatabase {
|
|
7
|
+
/** Engine discriminator for SQLStack-minted disposable test databases. */
|
|
8
|
+
readonly engine: 'sqlite';
|
|
9
|
+
/** Fresh per-allocation identifier; never reused within a process. */
|
|
10
|
+
readonly resourceId: string;
|
|
11
|
+
/** Explicit storage: an owned temporary file, or an isolated `:memory:` db. */
|
|
12
|
+
readonly storage: 'memory' | 'file';
|
|
7
13
|
/** The live sqlstack SQLite adapter, suitable for direct injection. */
|
|
8
14
|
readonly db: Database;
|
|
9
15
|
/** The underlying better-sqlite3 (or sqlite3) connection. */
|
|
@@ -11,7 +17,11 @@ export interface TestSqliteDatabase {
|
|
|
11
17
|
/** Absolute database path in file mode; undefined for :memory:. */
|
|
12
18
|
readonly path?: string;
|
|
13
19
|
query(sql: string, params?: readonly unknown[]): Promise<unknown>;
|
|
14
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Close the connection and remove owned temporary files. Idempotent:
|
|
22
|
+
* concurrent and repeated calls share one outcome. Every cleanup step is
|
|
23
|
+
* attempted; failures are aggregated into a `TestDatabaseDisposeError`.
|
|
24
|
+
*/
|
|
15
25
|
dispose(): Promise<void>;
|
|
16
26
|
}
|
|
17
27
|
export declare function createDatabaseHandle(fileBacked: boolean): Promise<TestSqliteDatabase>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../../src/testing/sqlite/database.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../../src/testing/sqlite/database.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAC;IACpC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAgCD,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,OAAO,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAsD7B"}
|