sqlstack 3.5.0 → 3.6.0-dev.1
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/index.d.ts +2 -0
- package/dist/cjs/adapters/index.d.ts.map +1 -1
- package/dist/cjs/adapters/index.js +3 -1
- package/dist/cjs/adapters/index.js.map +1 -1
- package/dist/cjs/adapters/sqlego.d.ts +41 -0
- package/dist/cjs/adapters/sqlego.d.ts.map +1 -0
- package/dist/cjs/adapters/sqlego.js +116 -0
- package/dist/cjs/adapters/sqlego.js.map +1 -0
- package/dist/cjs/adapters/sqlite.d.ts +2 -0
- package/dist/cjs/adapters/sqlite.d.ts.map +1 -1
- package/dist/cjs/adapters/sqlite.js +2 -0
- 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/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.map +1 -1
- package/dist/cjs/decorators/query.js +96 -35
- 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 +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/run.d.ts +44 -4
- package/dist/cjs/run.d.ts.map +1 -1
- package/dist/cjs/run.js +38 -7
- package/dist/cjs/run.js.map +1 -1
- package/dist/cjs/runtime.d.ts +6 -0
- package/dist/cjs/runtime.d.ts.map +1 -1
- package/dist/cjs/runtime.js +18 -0
- package/dist/cjs/runtime.js.map +1 -1
- package/dist/cjs/stack.d.ts +14 -0
- package/dist/cjs/stack.d.ts.map +1 -1
- package/dist/cjs/stack.js +20 -0
- package/dist/cjs/stack.js.map +1 -1
- package/dist/cjs/transactions.d.ts +52 -0
- package/dist/cjs/transactions.d.ts.map +1 -1
- package/dist/cjs/transactions.js +557 -3
- package/dist/cjs/transactions.js.map +1 -1
- package/dist/esm/adapters/index.js +1 -0
- package/dist/esm/adapters/index.js.map +1 -1
- package/dist/esm/adapters/sqlego.js +80 -0
- package/dist/esm/adapters/sqlego.js.map +1 -0
- package/dist/esm/adapters/sqlite.js +2 -2
- 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/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 +101 -40
- 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 +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/run.js +38 -8
- package/dist/esm/run.js.map +1 -1
- package/dist/esm/runtime.js +17 -0
- package/dist/esm/runtime.js.map +1 -1
- package/dist/esm/stack.js +21 -1
- package/dist/esm/stack.js.map +1 -1
- package/dist/esm/transactions.js +554 -3
- package/dist/esm/transactions.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +74 -133
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { createSqliteDb } from './sqlite';
|
|
2
2
|
export { createPgDb } from './pg';
|
|
3
3
|
export { createMysqlDb } from './mysql';
|
|
4
|
+
export { createSqlegoDb } from './sqlego';
|
|
5
|
+
export type { SqlegoClientLike, SqlegoTransactionLike, SqlegoDbOptions } from './sqlego';
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createMysqlDb = exports.createPgDb = exports.createSqliteDb = void 0;
|
|
3
|
+
exports.createSqlegoDb = exports.createMysqlDb = exports.createPgDb = exports.createSqliteDb = void 0;
|
|
4
4
|
var sqlite_1 = require("./sqlite");
|
|
5
5
|
Object.defineProperty(exports, "createSqliteDb", { enumerable: true, get: function () { return sqlite_1.createSqliteDb; } });
|
|
6
6
|
var pg_1 = require("./pg");
|
|
7
7
|
Object.defineProperty(exports, "createPgDb", { enumerable: true, get: function () { return pg_1.createPgDb; } });
|
|
8
8
|
var mysql_1 = require("./mysql");
|
|
9
9
|
Object.defineProperty(exports, "createMysqlDb", { enumerable: true, get: function () { return mysql_1.createMysqlDb; } });
|
|
10
|
+
var sqlego_1 = require("./sqlego");
|
|
11
|
+
Object.defineProperty(exports, "createSqlegoDb", { enumerable: true, get: function () { return sqlego_1.createSqlegoDb; } });
|
|
10
12
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":";;;AAAA,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AACvB,2BAAkC;AAAzB,gGAAA,UAAU,OAAA;AACnB,iCAAwC;AAA/B,sGAAA,aAAa,OAAA","sourcesContent":["export { createSqliteDb } from './sqlite';\nexport { createPgDb } from './pg';\nexport { createMysqlDb } from './mysql';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":";;;AAAA,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AACvB,2BAAkC;AAAzB,gGAAA,UAAU,OAAA;AACnB,iCAAwC;AAA/B,sGAAA,aAAa,OAAA;AACtB,mCAA0C;AAAjC,wGAAA,cAAc,OAAA","sourcesContent":["export { createSqliteDb } from './sqlite';\nexport { createPgDb } from './pg';\nexport { createMysqlDb } from './mysql';\nexport { createSqlegoDb } from './sqlego';\nexport type { SqlegoClientLike, SqlegoTransactionLike, SqlegoDbOptions } from './sqlego';\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Database } from '../registry';
|
|
2
|
+
/**
|
|
3
|
+
* The subset of `@noego/sqlego`'s `SqlegoClient` this adapter uses. Typed
|
|
4
|
+
* structurally so sqlstack carries no hard dependency on sqlego.
|
|
5
|
+
*/
|
|
6
|
+
export interface SqlegoClientLike {
|
|
7
|
+
query(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;
|
|
8
|
+
run(sql: string, params?: readonly unknown[]): Promise<{
|
|
9
|
+
changes: number;
|
|
10
|
+
lastInsertRowid: number | bigint;
|
|
11
|
+
}>;
|
|
12
|
+
begin(options?: {
|
|
13
|
+
mode?: 'deferred' | 'immediate';
|
|
14
|
+
leaseMs?: number;
|
|
15
|
+
}): Promise<SqlegoTransactionLike>;
|
|
16
|
+
close(): Promise<void> | void;
|
|
17
|
+
}
|
|
18
|
+
export interface SqlegoTransactionLike {
|
|
19
|
+
query(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;
|
|
20
|
+
run(sql: string, params?: readonly unknown[]): Promise<{
|
|
21
|
+
changes: number;
|
|
22
|
+
lastInsertRowid: number | bigint;
|
|
23
|
+
}>;
|
|
24
|
+
commit(): Promise<void>;
|
|
25
|
+
rollback(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export interface SqlegoDbOptions {
|
|
28
|
+
/** Lease requested for each transaction (the server caps it). */
|
|
29
|
+
leaseMs?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* SQLite through a sqlego owner process. Behaves like a single SQLite
|
|
33
|
+
* connection: `BEGIN` opens a leased sqlego transaction and every statement
|
|
34
|
+
* runs inside it until `COMMIT`/`ROLLBACK`, so sqlstack transactions,
|
|
35
|
+
* savepoints, `rollback()` and `afterCommit` work unchanged.
|
|
36
|
+
*
|
|
37
|
+
* Pass a connected `SqlegoClient`, or a database file path (requires the
|
|
38
|
+
* optional `@noego/sqlego` package).
|
|
39
|
+
*/
|
|
40
|
+
export declare function createSqlegoDb(fileOrClient: string | SqlegoClientLike, options?: SqlegoDbOptions): Promise<Database>;
|
|
41
|
+
//# sourceMappingURL=sqlego.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlego.d.ts","sourceRoot":"","sources":["../../../src/adapters/sqlego.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,aAAa,CAAC;AAGzD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACpF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9G,KAAK,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACpF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9G,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAeD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,gBAAgB,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkD9H"}
|
|
@@ -0,0 +1,116 @@
|
|
|
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.createSqlegoDb = createSqlegoDb;
|
|
37
|
+
const sqlite_1 = require("./sqlite");
|
|
38
|
+
// Top-level transaction control only; `ROLLBACK TO [SAVEPOINT] x`, SAVEPOINT
|
|
39
|
+
// and RELEASE are ordinary SQL inside a sqlego transaction.
|
|
40
|
+
function transactionControl(sql) {
|
|
41
|
+
const text = (0, sqlite_1.stripLeadingComments)(String(sql)).trim().replace(/;\s*$/, '').trim().toUpperCase().replace(/\s+/g, ' ');
|
|
42
|
+
const begin = /^BEGIN(?: (DEFERRED|IMMEDIATE|EXCLUSIVE))?(?: TRANSACTION)?$/.exec(text);
|
|
43
|
+
if (begin)
|
|
44
|
+
return { kind: 'begin', mode: begin[1] === undefined || begin[1] === 'DEFERRED' ? 'deferred' : 'immediate' };
|
|
45
|
+
if (/^(?:COMMIT|END)(?: TRANSACTION)?$/.test(text))
|
|
46
|
+
return { kind: 'commit' };
|
|
47
|
+
if (/^ROLLBACK(?: TRANSACTION)?$/.test(text))
|
|
48
|
+
return { kind: 'rollback' };
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* SQLite through a sqlego owner process. Behaves like a single SQLite
|
|
53
|
+
* connection: `BEGIN` opens a leased sqlego transaction and every statement
|
|
54
|
+
* runs inside it until `COMMIT`/`ROLLBACK`, so sqlstack transactions,
|
|
55
|
+
* savepoints, `rollback()` and `afterCommit` work unchanged.
|
|
56
|
+
*
|
|
57
|
+
* Pass a connected `SqlegoClient`, or a database file path (requires the
|
|
58
|
+
* optional `@noego/sqlego` package).
|
|
59
|
+
*/
|
|
60
|
+
async function createSqlegoDb(fileOrClient, options = {}) {
|
|
61
|
+
let client;
|
|
62
|
+
let owned = false;
|
|
63
|
+
if (typeof fileOrClient === 'string') {
|
|
64
|
+
let mod;
|
|
65
|
+
try {
|
|
66
|
+
const packageName = '@noego/sqlego';
|
|
67
|
+
mod = await Promise.resolve(`${packageName}`).then(s => __importStar(require(s)));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new Error('createSqlegoDb(file) requires the @noego/sqlego package. Install it or pass a connected SqlegoClient.');
|
|
71
|
+
}
|
|
72
|
+
const SqlegoClient = mod.SqlegoClient ?? mod.default?.SqlegoClient;
|
|
73
|
+
client = await SqlegoClient.connect(fileOrClient);
|
|
74
|
+
owned = true;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
client = fileOrClient;
|
|
78
|
+
}
|
|
79
|
+
let tx;
|
|
80
|
+
async function execute(target, sql, params) {
|
|
81
|
+
if ((0, sqlite_1.producesRows)(sql))
|
|
82
|
+
return await target.query(sql, params);
|
|
83
|
+
const info = await target.run(sql, params);
|
|
84
|
+
return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
dialect: 'sqlite',
|
|
88
|
+
async query(sql, params) {
|
|
89
|
+
const control = transactionControl(sql);
|
|
90
|
+
if (control?.kind === 'begin') {
|
|
91
|
+
if (tx)
|
|
92
|
+
throw new Error('cannot start a transaction within a transaction');
|
|
93
|
+
tx = await client.begin({ mode: control.mode, leaseMs: options.leaseMs });
|
|
94
|
+
return { rowsAffected: 0 };
|
|
95
|
+
}
|
|
96
|
+
if (control) {
|
|
97
|
+
const open = tx;
|
|
98
|
+
if (!open)
|
|
99
|
+
throw new Error(`cannot ${control.kind} - no transaction is active`);
|
|
100
|
+
tx = undefined;
|
|
101
|
+
if (control.kind === 'commit')
|
|
102
|
+
await open.commit();
|
|
103
|
+
else
|
|
104
|
+
await open.rollback();
|
|
105
|
+
return { rowsAffected: 0 };
|
|
106
|
+
}
|
|
107
|
+
return await execute(tx ?? client, sql, params);
|
|
108
|
+
},
|
|
109
|
+
conn: client,
|
|
110
|
+
async close() {
|
|
111
|
+
if (owned)
|
|
112
|
+
await client.close();
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=sqlego.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlego.js","sourceRoot":"","sources":["../../../src/adapters/sqlego.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database, QueryResult } from '../registry';\nimport { producesRows, stripLeadingComments } from './sqlite';\n\n/**\n * The subset of `@noego/sqlego`'s `SqlegoClient` this adapter uses. Typed\n * structurally so sqlstack carries no hard dependency on sqlego.\n */\nexport interface SqlegoClientLike {\n query(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;\n run(sql: string, params?: readonly unknown[]): Promise<{ changes: number; lastInsertRowid: number | bigint }>;\n begin(options?: { mode?: 'deferred' | 'immediate'; leaseMs?: number }): Promise<SqlegoTransactionLike>;\n close(): Promise<void> | void;\n}\n\nexport interface SqlegoTransactionLike {\n query(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;\n run(sql: string, params?: readonly unknown[]): Promise<{ changes: number; lastInsertRowid: number | bigint }>;\n commit(): Promise<void>;\n rollback(): Promise<void>;\n}\n\nexport interface SqlegoDbOptions {\n /** Lease requested for each transaction (the server caps it). */\n leaseMs?: number;\n}\n\ntype Control = { kind: 'begin'; mode: 'deferred' | 'immediate' } | { kind: 'commit' } | { kind: 'rollback' };\n\n// Top-level transaction control only; `ROLLBACK TO [SAVEPOINT] x`, SAVEPOINT\n// and RELEASE are ordinary SQL inside a sqlego transaction.\nfunction transactionControl(sql: string): Control | null {\n const text = stripLeadingComments(String(sql)).trim().replace(/;\\s*$/, '').trim().toUpperCase().replace(/\\s+/g, ' ');\n const begin = /^BEGIN(?: (DEFERRED|IMMEDIATE|EXCLUSIVE))?(?: TRANSACTION)?$/.exec(text);\n if (begin) return { kind: 'begin', mode: begin[1] === undefined || begin[1] === 'DEFERRED' ? 'deferred' : 'immediate' };\n if (/^(?:COMMIT|END)(?: TRANSACTION)?$/.test(text)) return { kind: 'commit' };\n if (/^ROLLBACK(?: TRANSACTION)?$/.test(text)) return { kind: 'rollback' };\n return null;\n}\n\n/**\n * SQLite through a sqlego owner process. Behaves like a single SQLite\n * connection: `BEGIN` opens a leased sqlego transaction and every statement\n * runs inside it until `COMMIT`/`ROLLBACK`, so sqlstack transactions,\n * savepoints, `rollback()` and `afterCommit` work unchanged.\n *\n * Pass a connected `SqlegoClient`, or a database file path (requires the\n * optional `@noego/sqlego` package).\n */\nexport async function createSqlegoDb(fileOrClient: string | SqlegoClientLike, options: SqlegoDbOptions = {}): Promise<Database> {\n let client: SqlegoClientLike;\n let owned = false;\n if (typeof fileOrClient === 'string') {\n let mod: any;\n try {\n const packageName = '@noego/sqlego';\n mod = await import(/* @vite-ignore */ packageName);\n } catch {\n throw new Error('createSqlegoDb(file) requires the @noego/sqlego package. Install it or pass a connected SqlegoClient.');\n }\n const SqlegoClient = mod.SqlegoClient ?? mod.default?.SqlegoClient;\n client = await SqlegoClient.connect(fileOrClient);\n owned = true;\n } else {\n client = fileOrClient;\n }\n\n let tx: SqlegoTransactionLike | undefined;\n\n async function execute(target: SqlegoClientLike | SqlegoTransactionLike, sql: string, params: unknown[]): Promise<QueryResult> {\n if (producesRows(sql)) return await target.query(sql, params);\n const info = await target.run(sql, params);\n return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };\n }\n\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const control = transactionControl(sql);\n if (control?.kind === 'begin') {\n if (tx) throw new Error('cannot start a transaction within a transaction');\n tx = await client.begin({ mode: control.mode, leaseMs: options.leaseMs });\n return { rowsAffected: 0 };\n }\n if (control) {\n const open = tx;\n if (!open) throw new Error(`cannot ${control.kind} - no transaction is active`);\n tx = undefined;\n if (control.kind === 'commit') await open.commit();\n else await open.rollback();\n return { rowsAffected: 0 };\n }\n return await execute(tx ?? client, sql, params);\n },\n conn: client,\n async close() {\n if (owned) await client.close();\n },\n } as Database;\n}\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { Database } from '../registry';
|
|
2
|
+
export declare function stripLeadingComments(sql: string): string;
|
|
3
|
+
export declare function producesRows(sql: string): boolean;
|
|
2
4
|
export declare function createSqliteDb(filenameOrDb: string | any): Promise<Database>;
|
|
3
5
|
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqE5C,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAuBxD;AAKD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGjD;AAOD,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwJlF"}
|
|
@@ -33,6 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.stripLeadingComments = stripLeadingComments;
|
|
37
|
+
exports.producesRows = producesRows;
|
|
36
38
|
exports.createSqliteDb = createSqliteDb;
|
|
37
39
|
function isPromiseLike(value) {
|
|
38
40
|
return !!value && typeof value.then === 'function';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from '../registry';\n\nfunction isPromiseLike<T>(value: unknown): value is Promise<T> {\n return !!value && typeof (value as Promise<T>).then === 'function';\n}\n\nasync function prepareStatement(db: any, sql: string) {\n const stmt = db.prepare(sql);\n return isPromiseLike(stmt) ? await stmt : stmt;\n}\n\nasync function finalizeStatement(stmt: any) {\n if (!stmt || typeof stmt.finalize !== 'function') return;\n const result = stmt.finalize();\n if (isPromiseLike(result)) {\n await result;\n }\n}\n\nasync function statementAll(stmt: any, params: unknown[]) {\n if (typeof stmt.all !== 'function') {\n throw new Error('SQLite statement missing all()');\n }\n if (stmt.all.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n };\n try {\n if (params.length > 0) {\n stmt.all(params, callback);\n } else {\n stmt.all(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.all(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nasync function statementRun(stmt: any, params: unknown[]) {\n if (typeof stmt.run !== 'function') {\n throw new Error('SQLite statement missing run()');\n }\n if (stmt.run.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ changes: this?.changes ?? 0, lastInsertId: this?.lastID });\n };\n try {\n if (params.length > 0) {\n stmt.run(params, callback);\n } else {\n stmt.run(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.run(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nfunction stripLeadingComments(sql: string): string {\n let i = 0;\n const n = sql.length;\n if (sql.charCodeAt(0) === 0xfeff) i = 1; // BOM\n while (i < n) {\n while (i < n && /\\s/.test(sql[i]!)) i++;\n if (i + 1 < n && sql[i] === '-' && sql[i + 1] === '-') {\n // -- line comment\n i += 2;\n while (i < n && sql[i] !== '\\n') i++;\n continue;\n }\n if (i + 1 < n && sql[i] === '/' && sql[i + 1] === '*') {\n // /* block comment */\n i += 2;\n const end = sql.indexOf('*/', i);\n if (end === -1) return '';\n i = end + 2;\n continue;\n }\n break;\n }\n return sql.slice(i);\n}\n\n// Text-based fallback for drivers that do not expose statement metadata\n// (the sqlite3 callback API). SELECT, CTEs, and `... RETURNING` all produce\n// a result set and must be executed with all(), not run().\nfunction producesRows(sql: string): boolean {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n return text.startsWith('SELECT') || text.startsWith('WITH') || /\\bRETURNING\\b/.test(text);\n}\n\n// better-sqlite3 exposes `stmt.reader` (true when the statement returns rows).\nfunction statementReturnsRows(stmt: any, sql: string): boolean {\n return typeof stmt?.reader === 'boolean' ? stmt.reader : producesRows(sql);\n}\n\nexport async function createSqliteDb(filenameOrDb: string | any): Promise<Database> {\n // If a pre-created connection is provided\n if (typeof filenameOrDb !== 'string' && filenameOrDb) {\n const db = filenameOrDb;\n\n // better-sqlite3 shape\n if (typeof db.prepare === 'function') {\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = await prepareStatement(db, sql);\n try {\n if (statementReturnsRows(stmt, sql)) {\n const rows = await statementAll(stmt, params);\n return rows;\n }\n const info = await statementRun(stmt, params);\n const rowsAffected = Number(info?.changes ?? info?.rowsAffected ?? 0);\n const lastInsertId = info?.lastInsertRowid ?? info?.lastID ?? info?.lastInsertId;\n return { rowsAffected, lastInsertId };\n } finally {\n await finalizeStatement(stmt);\n }\n },\n conn: db,\n // Do not close externally provided connection\n async close() {\n if (typeof db.close === 'function') {\n const res = db.close();\n if (isPromiseLike(res)) {\n await res;\n }\n }\n },\n } as Database;\n }\n\n // sqlite3 shape\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n if (producesRows(sql)) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n return new Promise((resolve, reject) => {\n // Use function callback to access `this` for metadata\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n // Do not close externally provided connection\n close() {},\n } as Database;\n }\n\n const filename = filenameOrDb as string;\n\n let BetterSqlite3: any;\n if (typeof require === 'function') {\n try {\n BetterSqlite3 = require('better-sqlite3');\n } catch {\n BetterSqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('better-sqlite3');\n BetterSqlite3 = (mod as any).default ?? mod;\n } catch {\n BetterSqlite3 = null;\n }\n }\n\n if (BetterSqlite3) {\n const db = new BetterSqlite3(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = db.prepare(sql);\n if (statementReturnsRows(stmt, sql)) {\n return stmt.all(...params);\n }\n const info = stmt.run(...params);\n return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };\n },\n conn: db,\n close() {\n db.close();\n },\n } as Database;\n }\n\n let sqlite3: any;\n if (typeof require === 'function') {\n try {\n sqlite3 = require('sqlite3');\n } catch {\n sqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n // Optional fallback: defer resolution to runtime rather than making\n // bundlers require sqlite3 when the preferred driver is installed.\n const packageName = 'sqlite3';\n const mod = await import(/* @vite-ignore */ packageName);\n sqlite3 = (mod as any).default ?? mod;\n } catch {\n sqlite3 = null;\n }\n }\n\n if (sqlite3) {\n const db = new sqlite3.Database(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n if (producesRows(sql)) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n // Non-SELECT statements\n return new Promise((resolve, reject) => {\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n close() {\n return new Promise<void>((resolve, reject) => {\n db.close((err: Error | null) => (err ? reject(err) : resolve()));\n });\n },\n } as Database;\n }\n\n throw new Error('No SQLite driver available. Install either better-sqlite3 or sqlite3.');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from '../registry';\n\nfunction isPromiseLike<T>(value: unknown): value is Promise<T> {\n return !!value && typeof (value as Promise<T>).then === 'function';\n}\n\nasync function prepareStatement(db: any, sql: string) {\n const stmt = db.prepare(sql);\n return isPromiseLike(stmt) ? await stmt : stmt;\n}\n\nasync function finalizeStatement(stmt: any) {\n if (!stmt || typeof stmt.finalize !== 'function') return;\n const result = stmt.finalize();\n if (isPromiseLike(result)) {\n await result;\n }\n}\n\nasync function statementAll(stmt: any, params: unknown[]) {\n if (typeof stmt.all !== 'function') {\n throw new Error('SQLite statement missing all()');\n }\n if (stmt.all.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n };\n try {\n if (params.length > 0) {\n stmt.all(params, callback);\n } else {\n stmt.all(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.all(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nasync function statementRun(stmt: any, params: unknown[]) {\n if (typeof stmt.run !== 'function') {\n throw new Error('SQLite statement missing run()');\n }\n if (stmt.run.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ changes: this?.changes ?? 0, lastInsertId: this?.lastID });\n };\n try {\n if (params.length > 0) {\n stmt.run(params, callback);\n } else {\n stmt.run(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.run(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nexport function stripLeadingComments(sql: string): string {\n let i = 0;\n const n = sql.length;\n if (sql.charCodeAt(0) === 0xfeff) i = 1; // BOM\n while (i < n) {\n while (i < n && /\\s/.test(sql[i]!)) i++;\n if (i + 1 < n && sql[i] === '-' && sql[i + 1] === '-') {\n // -- line comment\n i += 2;\n while (i < n && sql[i] !== '\\n') i++;\n continue;\n }\n if (i + 1 < n && sql[i] === '/' && sql[i + 1] === '*') {\n // /* block comment */\n i += 2;\n const end = sql.indexOf('*/', i);\n if (end === -1) return '';\n i = end + 2;\n continue;\n }\n break;\n }\n return sql.slice(i);\n}\n\n// Text-based fallback for drivers that do not expose statement metadata\n// (the sqlite3 callback API). SELECT, CTEs, and `... RETURNING` all produce\n// a result set and must be executed with all(), not run().\nexport function producesRows(sql: string): boolean {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n return text.startsWith('SELECT') || text.startsWith('WITH') || /\\bRETURNING\\b/.test(text);\n}\n\n// better-sqlite3 exposes `stmt.reader` (true when the statement returns rows).\nfunction statementReturnsRows(stmt: any, sql: string): boolean {\n return typeof stmt?.reader === 'boolean' ? stmt.reader : producesRows(sql);\n}\n\nexport async function createSqliteDb(filenameOrDb: string | any): Promise<Database> {\n // If a pre-created connection is provided\n if (typeof filenameOrDb !== 'string' && filenameOrDb) {\n const db = filenameOrDb;\n\n // better-sqlite3 shape\n if (typeof db.prepare === 'function') {\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = await prepareStatement(db, sql);\n try {\n if (statementReturnsRows(stmt, sql)) {\n const rows = await statementAll(stmt, params);\n return rows;\n }\n const info = await statementRun(stmt, params);\n const rowsAffected = Number(info?.changes ?? info?.rowsAffected ?? 0);\n const lastInsertId = info?.lastInsertRowid ?? info?.lastID ?? info?.lastInsertId;\n return { rowsAffected, lastInsertId };\n } finally {\n await finalizeStatement(stmt);\n }\n },\n conn: db,\n // Do not close externally provided connection\n async close() {\n if (typeof db.close === 'function') {\n const res = db.close();\n if (isPromiseLike(res)) {\n await res;\n }\n }\n },\n } as Database;\n }\n\n // sqlite3 shape\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n if (producesRows(sql)) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n return new Promise((resolve, reject) => {\n // Use function callback to access `this` for metadata\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n // Do not close externally provided connection\n close() {},\n } as Database;\n }\n\n const filename = filenameOrDb as string;\n\n let BetterSqlite3: any;\n if (typeof require === 'function') {\n try {\n BetterSqlite3 = require('better-sqlite3');\n } catch {\n BetterSqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('better-sqlite3');\n BetterSqlite3 = (mod as any).default ?? mod;\n } catch {\n BetterSqlite3 = null;\n }\n }\n\n if (BetterSqlite3) {\n const db = new BetterSqlite3(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = db.prepare(sql);\n if (statementReturnsRows(stmt, sql)) {\n return stmt.all(...params);\n }\n const info = stmt.run(...params);\n return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };\n },\n conn: db,\n close() {\n db.close();\n },\n } as Database;\n }\n\n let sqlite3: any;\n if (typeof require === 'function') {\n try {\n sqlite3 = require('sqlite3');\n } catch {\n sqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n // Optional fallback: defer resolution to runtime rather than making\n // bundlers require sqlite3 when the preferred driver is installed.\n const packageName = 'sqlite3';\n const mod = await import(/* @vite-ignore */ packageName);\n sqlite3 = (mod as any).default ?? mod;\n } catch {\n sqlite3 = null;\n }\n }\n\n if (sqlite3) {\n const db = new sqlite3.Database(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n if (producesRows(sql)) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n // Non-SELECT statements\n return new Promise((resolve, reject) => {\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n close() {\n return new Promise<void>((resolve, reject) => {\n db.close((err: Error | null) => (err ? reject(err) : resolve()));\n });\n },\n } as Database;\n }\n\n throw new Error('No SQLite driver available. Install either better-sqlite3 or sqlite3.');\n}\n"]}
|
|
@@ -48,7 +48,9 @@ type DiscoveredMethod = {
|
|
|
48
48
|
* Regex-based discovery: each @Query method is attributed to the nearest
|
|
49
49
|
* preceding `class` declaration in the same file. Inline queries are detected
|
|
50
50
|
* by a `sql:` property in the decorator arguments (see docs/codegen.md for the
|
|
51
|
-
* documented limitations of this heuristic).
|
|
51
|
+
* documented limitations of this heuristic). Comments and string/template/
|
|
52
|
+
* regex literal contents are masked first (positions preserved), so prose
|
|
53
|
+
* cannot declare classes or @Query methods.
|
|
52
54
|
*/
|
|
53
55
|
export declare function scanSourceForQueryMethods(source: string, sourcePath: string): DiscoveredMethod[];
|
|
54
56
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateManifest.d.ts","sourceRoot":"","sources":["../../../src/codegen/generateManifest.ts"],"names":[],"mappings":"AA6BA,MAAM,MAAM,0BAA0B,GAAG;IACvC,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACtB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gGAAgG;IAChG,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,6FAA6F;IAC7F,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"generateManifest.d.ts","sourceRoot":"","sources":["../../../src/codegen/generateManifest.ts"],"names":[],"mappings":"AA6BA,MAAM,MAAM,0BAA0B,GAAG;IACvC,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACtB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gGAAgG;IAChG,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,6FAA6F;IAC7F,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAsLF;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,gBAAgB,EAAE,CA0BhG;AAyBD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,yBAAyB,CAAC,CAcpC;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,qBAAqB,CA6DnG"}
|
|
@@ -55,21 +55,213 @@ function walkSourceFiles(rootDir, exclude) {
|
|
|
55
55
|
}
|
|
56
56
|
const CLASS_RE = /(?:^|[\s;{}(])class\s+([A-Za-z_$][\w$]*)/g;
|
|
57
57
|
const QUERY_RE = /@Query\s*(?:\(([^)]*)\))?\s*(?:public\s+|private\s+|protected\s+)?(?:async\s+)?([A-Za-z_$][\w$]*)\s*[(<]/g;
|
|
58
|
+
/** Punctuators after which a `/` starts a regex literal rather than division. */
|
|
59
|
+
const REGEX_AFTER_PUNCT = new Set('(,=:[!&|?{};+-*%<>~^'.split(''));
|
|
60
|
+
/** Keywords after which a `/` starts a regex literal rather than division. */
|
|
61
|
+
const REGEX_AFTER_KEYWORD = new Set([
|
|
62
|
+
'return', 'typeof', 'instanceof', 'in', 'of', 'new', 'delete', 'void',
|
|
63
|
+
'throw', 'case', 'do', 'else', 'yield', 'await',
|
|
64
|
+
]);
|
|
65
|
+
const IDENT_CHAR = /[A-Za-z0-9_$]/;
|
|
66
|
+
/**
|
|
67
|
+
* Returns `source` with comments and the contents of string, template and
|
|
68
|
+
* regex literals replaced by spaces (newlines kept), so every index still
|
|
69
|
+
* points at the same position in the original text. Literal delimiters are
|
|
70
|
+
* kept, so decorator arguments such as `{ sql: '...' }` keep their shape and
|
|
71
|
+
* the `sql:` key stays detectable, while prose like "the same class with" or
|
|
72
|
+
* "@Query() foo(" inside a comment or string can no longer match CLASS_RE or
|
|
73
|
+
* QUERY_RE. Lexical heuristic only (no TS compiler dependency).
|
|
74
|
+
*/
|
|
75
|
+
function maskNonCode(source) {
|
|
76
|
+
const n = source.length;
|
|
77
|
+
const out = source.split('');
|
|
78
|
+
const blank = (from, to) => {
|
|
79
|
+
for (let k = from; k < to; k++) {
|
|
80
|
+
const c = source[k];
|
|
81
|
+
if (c !== '\n' && c !== '\r')
|
|
82
|
+
out[k] = ' ';
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const lineEnd = (from) => {
|
|
86
|
+
const at = source.indexOf('\n', from);
|
|
87
|
+
return at < 0 ? n : at;
|
|
88
|
+
};
|
|
89
|
+
const blockEnd = (from) => {
|
|
90
|
+
const at = source.indexOf('*/', from + 2);
|
|
91
|
+
return at < 0 ? n : at + 2;
|
|
92
|
+
};
|
|
93
|
+
/** Index after the closing quote (closed) or at the newline/EOF (unterminated). */
|
|
94
|
+
const stringEnd = (from) => {
|
|
95
|
+
const quote = source[from];
|
|
96
|
+
let j = from + 1;
|
|
97
|
+
while (j < n) {
|
|
98
|
+
const c = source[j];
|
|
99
|
+
if (c === '\\') {
|
|
100
|
+
j += 2;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (c === quote)
|
|
104
|
+
return { end: j + 1, closed: true };
|
|
105
|
+
if (c === '\n')
|
|
106
|
+
return { end: j, closed: false };
|
|
107
|
+
j++;
|
|
108
|
+
}
|
|
109
|
+
return { end: n, closed: false };
|
|
110
|
+
};
|
|
111
|
+
const templateEnd = (from) => {
|
|
112
|
+
let j = from + 1;
|
|
113
|
+
while (j < n) {
|
|
114
|
+
const c = source[j];
|
|
115
|
+
if (c === '\\') {
|
|
116
|
+
j += 2;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (c === '`')
|
|
120
|
+
return { end: j + 1, closed: true };
|
|
121
|
+
if (c === '$' && source[j + 1] === '{') {
|
|
122
|
+
j = expressionEnd(j + 2);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
j++;
|
|
126
|
+
}
|
|
127
|
+
return { end: n, closed: false };
|
|
128
|
+
};
|
|
129
|
+
/** Skips a `${ ... }` substitution body (nested literals/comments aware). */
|
|
130
|
+
const expressionEnd = (from) => {
|
|
131
|
+
let depth = 1;
|
|
132
|
+
let j = from;
|
|
133
|
+
while (j < n) {
|
|
134
|
+
const c = source[j];
|
|
135
|
+
const next = source[j + 1];
|
|
136
|
+
if (c === '/' && next === '/') {
|
|
137
|
+
j = lineEnd(j);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (c === '/' && next === '*') {
|
|
141
|
+
j = blockEnd(j);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (c === '\'' || c === '"') {
|
|
145
|
+
j = stringEnd(j).end;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (c === '`') {
|
|
149
|
+
j = templateEnd(j).end;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (c === '{')
|
|
153
|
+
depth++;
|
|
154
|
+
else if (c === '}' && --depth === 0)
|
|
155
|
+
return j + 1;
|
|
156
|
+
j++;
|
|
157
|
+
}
|
|
158
|
+
return n;
|
|
159
|
+
};
|
|
160
|
+
/** Regex literal starting at `from`, or null when it is not a single-line regex. */
|
|
161
|
+
const regexEnd = (from) => {
|
|
162
|
+
let inClass = false;
|
|
163
|
+
let j = from + 1;
|
|
164
|
+
while (j < n) {
|
|
165
|
+
const c = source[j];
|
|
166
|
+
if (c === '\n' || c === '\r')
|
|
167
|
+
return null;
|
|
168
|
+
if (c === '\\') {
|
|
169
|
+
j += 2;
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (inClass) {
|
|
173
|
+
if (c === ']')
|
|
174
|
+
inClass = false;
|
|
175
|
+
}
|
|
176
|
+
else if (c === '[') {
|
|
177
|
+
inClass = true;
|
|
178
|
+
}
|
|
179
|
+
else if (c === '/') {
|
|
180
|
+
let k = j + 1;
|
|
181
|
+
while (k < n && /[A-Za-z]/.test(source[k]))
|
|
182
|
+
k++;
|
|
183
|
+
return { bodyEnd: j, end: k };
|
|
184
|
+
}
|
|
185
|
+
j++;
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
};
|
|
189
|
+
// Last significant token: a punctuator char, 'value' after a literal or
|
|
190
|
+
// identifier, or '' at start of input; lastWord holds the identifier text.
|
|
191
|
+
let last = '';
|
|
192
|
+
let lastWord = '';
|
|
193
|
+
let i = 0;
|
|
194
|
+
while (i < n) {
|
|
195
|
+
const c = source[i];
|
|
196
|
+
const next = source[i + 1];
|
|
197
|
+
if (c === '/' && next === '/') {
|
|
198
|
+
const end = lineEnd(i);
|
|
199
|
+
blank(i, end);
|
|
200
|
+
i = end;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (c === '/' && next === '*') {
|
|
204
|
+
const end = blockEnd(i);
|
|
205
|
+
blank(i, end);
|
|
206
|
+
i = end;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (c === '\'' || c === '"' || c === '`') {
|
|
210
|
+
const { end, closed } = c === '`' ? templateEnd(i) : stringEnd(i);
|
|
211
|
+
blank(i + 1, closed ? end - 1 : end);
|
|
212
|
+
i = end;
|
|
213
|
+
last = 'value';
|
|
214
|
+
lastWord = '';
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (c === '/') {
|
|
218
|
+
const regexAllowed = last === '' || REGEX_AFTER_PUNCT.has(last) || (last === 'value' && REGEX_AFTER_KEYWORD.has(lastWord));
|
|
219
|
+
const re = regexAllowed ? regexEnd(i) : null;
|
|
220
|
+
if (re) {
|
|
221
|
+
blank(i + 1, re.bodyEnd);
|
|
222
|
+
i = re.end;
|
|
223
|
+
last = 'value';
|
|
224
|
+
lastWord = '';
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (/\s/.test(c)) {
|
|
229
|
+
i++;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (IDENT_CHAR.test(c)) {
|
|
233
|
+
let j = i + 1;
|
|
234
|
+
while (j < n && IDENT_CHAR.test(source[j]))
|
|
235
|
+
j++;
|
|
236
|
+
lastWord = source.slice(i, j);
|
|
237
|
+
last = 'value';
|
|
238
|
+
i = j;
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
last = c;
|
|
242
|
+
lastWord = '';
|
|
243
|
+
i++;
|
|
244
|
+
}
|
|
245
|
+
return out.join('');
|
|
246
|
+
}
|
|
58
247
|
/**
|
|
59
248
|
* Regex-based discovery: each @Query method is attributed to the nearest
|
|
60
249
|
* preceding `class` declaration in the same file. Inline queries are detected
|
|
61
250
|
* by a `sql:` property in the decorator arguments (see docs/codegen.md for the
|
|
62
|
-
* documented limitations of this heuristic).
|
|
251
|
+
* documented limitations of this heuristic). Comments and string/template/
|
|
252
|
+
* regex literal contents are masked first (positions preserved), so prose
|
|
253
|
+
* cannot declare classes or @Query methods.
|
|
63
254
|
*/
|
|
64
255
|
function scanSourceForQueryMethods(source, sourcePath) {
|
|
256
|
+
const code = maskNonCode(source);
|
|
65
257
|
const classes = [];
|
|
66
|
-
for (const m of
|
|
258
|
+
for (const m of code.matchAll(CLASS_RE)) {
|
|
67
259
|
classes.push({ name: m[1], index: m.index ?? 0 });
|
|
68
260
|
}
|
|
69
261
|
if (!classes.length)
|
|
70
262
|
return [];
|
|
71
263
|
const found = [];
|
|
72
|
-
for (const m of
|
|
264
|
+
for (const m of code.matchAll(QUERY_RE)) {
|
|
73
265
|
const at = m.index ?? 0;
|
|
74
266
|
let owner;
|
|
75
267
|
for (const c of classes) {
|