@fougere/adapter-sql 0.4.0-alpha.0 → 0.5.0-alpha.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/README.md +4 -2
- package/dist/fields.d.ts +2 -2
- package/dist/fields.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/query.d.ts +34 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +44 -0
- package/dist/query.js.map +1 -0
- package/dist/setup.d.ts +8 -0
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +2 -1
- package/dist/setup.js.map +1 -1
- package/dist/sqlite.d.ts.map +1 -1
- package/dist/sqlite.js +2 -1
- package/dist/sqlite.js.map +1 -1
- package/dist/table.d.ts +0 -13
- package/dist/table.d.ts.map +1 -1
- package/dist/table.js +23 -29
- package/dist/table.js.map +1 -1
- package/package.json +4 -4
- package/src/fields.ts +2 -2
- package/src/index.ts +1 -0
- package/src/query.ts +64 -0
- package/src/setup.ts +10 -1
- package/src/sqlite.ts +2 -1
- package/src/table.ts +24 -43
package/README.md
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
The SQL realization of the schema: the tables, the additive migration and the
|
|
4
4
|
per-entity scoped ORM. Four dialects — SQLite, PostgreSQL, MySQL, SQL Server.
|
|
5
5
|
|
|
6
|
-
Validation judges, storage realizes: this ORM
|
|
7
|
-
|
|
6
|
+
Validation judges, storage realizes: this ORM decides nothing of its own — it applies
|
|
7
|
+
the `lifecycle` rules on the way in. The shape is still held on this path, twice: the
|
|
8
|
+
DDL emits a `CHECK` for `oneOf`, `min` and `max`, and core's `StorageGuard` judges every
|
|
9
|
+
write through the port. `orm.client` meets neither.
|
|
8
10
|
|
|
9
11
|
## Installation
|
|
10
12
|
```bash
|
package/dist/fields.d.ts
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { DialectName } from './dialect.js';
|
|
11
11
|
/** What sql holds, addressed by field — the shape every augmentation of the registry takes. */
|
|
12
|
-
export type SqlFields<K extends string> = Partial<Record<K, SqlField
|
|
12
|
+
export type SqlFields<K extends string> = Readonly<Partial<Record<K, SqlField>>>;
|
|
13
13
|
export interface SqlField {
|
|
14
14
|
/** The column type to emit, per engine. An engine absent here keeps the shape's own. */
|
|
15
|
-
columnType?: Partial<Record<DialectName, string
|
|
15
|
+
readonly columnType?: Readonly<Partial<Record<DialectName, string>>>;
|
|
16
16
|
}
|
|
17
17
|
declare module '@fougere/schema' {
|
|
18
18
|
interface FougereEntityAdapters<K extends string> {
|
package/dist/fields.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,+FAA+F;AAC/F,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,+FAA+F;AAC/F,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,MAAM,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AAEjF,MAAM,WAAW,QAAQ;IACvB,wFAAwF;IACxF,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CACtE;AAED,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,qBAAqB,CAAC,CAAC,SAAS,MAAM;QAC9C,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;KACpB;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createTableSQL, createIndexSQL, indexSQL, addForeignKeyConstraintSQL, generateSQL, autoMigrate, compiler } from './ddl.js';
|
|
2
|
+
export { onQuery, logQueries, type QueryEvent, type QuerySink } from './query.js';
|
|
2
3
|
export type { GenerateOptions, SqlSink } from './ddl.js';
|
|
3
4
|
export { toTable, toTables, toTableName, toSnakeCase, isKeyed, orderTables } from './table.js';
|
|
4
5
|
export type { TableDef, ColumnDef, ColumnShape, ColumnReference, RelationResolve, FkEdge, TableOrder, EntityEntry, FrondLike, AppLike, } from './table.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,0BAA0B,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpI,YAAY,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/F,YAAY,EACV,QAAQ,EACR,SAAS,EACT,WAAW,EACX,eAAe,EACf,eAAe,EACf,MAAM,EACN,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,GACR,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,EACb,SAAS,EACT,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI9C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/G,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACxE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,0BAA0B,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpI,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAClF,YAAY,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/F,YAAY,EACV,QAAQ,EACR,SAAS,EACT,WAAW,EACX,eAAe,EACf,eAAe,EACf,MAAM,EACN,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,GACR,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,EACb,SAAS,EACT,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI9C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/G,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACxE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createTableSQL, createIndexSQL, indexSQL, addForeignKeyConstraintSQL, generateSQL, autoMigrate, compiler } from './ddl.js';
|
|
2
|
+
export { onQuery, logQueries } from './query.js';
|
|
2
3
|
export { toTable, toTables, toTableName, toSnakeCase, isKeyed, orderTables } from './table.js';
|
|
3
4
|
export { columnTypeFor, dialects, resolveDialect, sqliteDialect, pgDialect, mysqlDialect, mssqlDialect, } from './dialect.js';
|
|
4
5
|
export { SqlEntityOrm, createOrmFactory } from './crud.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,0BAA0B,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,0BAA0B,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpI,OAAO,EAAE,OAAO,EAAE,UAAU,EAAmC,MAAM,YAAY,CAAC;AAElF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAa/F,OAAO,EACL,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,EACb,SAAS,EACT,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD,0FAA0F;AAC1F,wFAAwF;AACxF,uEAAuE;AACvE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE/G,wEAAwE;AACxE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/query.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { LogEvent } from 'kysely';
|
|
2
|
+
/** One statement this process ran, and what it cost. */
|
|
3
|
+
export interface QueryEvent {
|
|
4
|
+
/** Which storage ran it — a process may open several (`sources:`). */
|
|
5
|
+
storage: string;
|
|
6
|
+
sql: string;
|
|
7
|
+
/**
|
|
8
|
+
* How MANY parameters, never their values.
|
|
9
|
+
*
|
|
10
|
+
* They are user data nobody chose to expose — the rule the call log states for a body.
|
|
11
|
+
* The count is what a reader needs anyway: it is how you see an `IN (?, ?, ?)` grow.
|
|
12
|
+
*/
|
|
13
|
+
parameters: number;
|
|
14
|
+
/** Rounded to three decimals: a sub-microsecond statement reports 17 digits otherwise. */
|
|
15
|
+
ms: number;
|
|
16
|
+
failed: boolean;
|
|
17
|
+
at: number;
|
|
18
|
+
}
|
|
19
|
+
export type QuerySink = (event: QueryEvent) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Be told about every statement this process runs, and get the unsubscription back.
|
|
22
|
+
*
|
|
23
|
+
* A subscription and not an option, for one reason that decides it: Kysely takes its `log`
|
|
24
|
+
* at CONSTRUCTION, and the storage is built during the boot — before any extension's
|
|
25
|
+
* `up(app)` runs. So the only way to subscribe afterwards is for the log to be installed
|
|
26
|
+
* from the start and route to whoever is listening.
|
|
27
|
+
*
|
|
28
|
+
* The same shape core states for `onLog` and observability for `onSpan`. Costs nothing when
|
|
29
|
+
* nobody listens: `logQueries` returns on an empty list before touching the event.
|
|
30
|
+
*/
|
|
31
|
+
export declare function onQuery(sink: QuerySink): () => void;
|
|
32
|
+
/** The `log` every Kysely is built with. Named by storage, since a sink sees them all. */
|
|
33
|
+
export declare function logQueries(storage: string): (event: LogEvent) => void;
|
|
34
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAIpD;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,IAAI,CAOnD;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAkBrE"}
|
package/dist/query.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const sinks = [];
|
|
2
|
+
/**
|
|
3
|
+
* Be told about every statement this process runs, and get the unsubscription back.
|
|
4
|
+
*
|
|
5
|
+
* A subscription and not an option, for one reason that decides it: Kysely takes its `log`
|
|
6
|
+
* at CONSTRUCTION, and the storage is built during the boot — before any extension's
|
|
7
|
+
* `up(app)` runs. So the only way to subscribe afterwards is for the log to be installed
|
|
8
|
+
* from the start and route to whoever is listening.
|
|
9
|
+
*
|
|
10
|
+
* The same shape core states for `onLog` and observability for `onSpan`. Costs nothing when
|
|
11
|
+
* nobody listens: `logQueries` returns on an empty list before touching the event.
|
|
12
|
+
*/
|
|
13
|
+
export function onQuery(sink) {
|
|
14
|
+
sinks.push(sink);
|
|
15
|
+
return () => {
|
|
16
|
+
const at = sinks.indexOf(sink);
|
|
17
|
+
if (at !== -1)
|
|
18
|
+
sinks.splice(at, 1);
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** The `log` every Kysely is built with. Named by storage, since a sink sees them all. */
|
|
22
|
+
export function logQueries(storage) {
|
|
23
|
+
return (event) => {
|
|
24
|
+
if (sinks.length === 0)
|
|
25
|
+
return;
|
|
26
|
+
const told = {
|
|
27
|
+
storage,
|
|
28
|
+
sql: event.query.sql,
|
|
29
|
+
parameters: event.query.parameters.length,
|
|
30
|
+
ms: Math.round(event.queryDurationMillis * 1000) / 1000,
|
|
31
|
+
failed: event.level === 'error',
|
|
32
|
+
at: Date.now(),
|
|
33
|
+
};
|
|
34
|
+
// A listener's own failure is not the query's problem — the rule `DispatchLifecycle`
|
|
35
|
+
// applies to an observer, and `Log` in Kysely would otherwise reject the query.
|
|
36
|
+
for (const sink of sinks) {
|
|
37
|
+
try {
|
|
38
|
+
sink(told);
|
|
39
|
+
}
|
|
40
|
+
catch { /* observational */ }
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAsBA,MAAM,KAAK,GAAgB,EAAE,CAAC;AAE9B;;;;;;;;;;GAUG;AACH,MAAM,UAAU,OAAO,CAAC,IAAe;IACrC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEjB,OAAO,GAAG,EAAE;QACV,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE/B,MAAM,IAAI,GAAe;YACvB,OAAO;YACP,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG;YACpB,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM;YACzC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,IAAI;YACvD,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,OAAO;YAC/B,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;SACf,CAAC;QACF,qFAAqF;QACrF,gFAAgF;QAChF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC;QACnD,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/setup.d.ts
CHANGED
|
@@ -14,6 +14,14 @@ import type { SqlSink } from './ddl.js';
|
|
|
14
14
|
export interface SetupOptions {
|
|
15
15
|
/** Override naming for specific entities (e.g. better-auth wants singular table names). */
|
|
16
16
|
ormFactoryOptions?: OrmFactoryOptions;
|
|
17
|
+
/**
|
|
18
|
+
* What to call this storage when a query is reported.
|
|
19
|
+
*
|
|
20
|
+
* A process may open several (`sources:`), and a module-level sink sees them all — without
|
|
21
|
+
* a name, two statements from two databases read as one stream. Defaults to what
|
|
22
|
+
* distinguishes them anyway: the engine here, the file path for SQLite.
|
|
23
|
+
*/
|
|
24
|
+
name?: string;
|
|
17
25
|
}
|
|
18
26
|
export interface Setup {
|
|
19
27
|
dialect: DialectName;
|
package/dist/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAO,KAAK,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAO,KAAK,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAErE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAChD,+DAA+D;IAC/D,IAAI,EAAE,OAAO,CAAC;IACd;;;;;;OAMG;IACH,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAChB;;;;;;;OAOG;IACH,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAChG;AAED,0EAA0E;AAC1E,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAEhD;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CACzB,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,WAAW,EACpB,IAAI,GAAE,YAAiB,GACtB,KAAK,CASP"}
|
package/dist/setup.js
CHANGED
|
@@ -9,13 +9,14 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { Kysely, sql } from 'kysely';
|
|
11
11
|
import { createOrmFactory } from './crud.js';
|
|
12
|
+
import { logQueries } from './query.js';
|
|
12
13
|
/** A sink that runs statements through Kysely — works on every engine. */
|
|
13
14
|
export function sqlSink(db) {
|
|
14
15
|
return { execute: (statement) => sql.raw(statement).execute(db) };
|
|
15
16
|
}
|
|
16
17
|
/** Wrap any Kysely dialect — Postgres, MySQL, SQL Server. */
|
|
17
18
|
export function setupKysely(kyselyDialect, dialect, opts = {}) {
|
|
18
|
-
const db = new Kysely({ dialect: kyselyDialect });
|
|
19
|
+
const db = new Kysely({ dialect: kyselyDialect, log: logQueries(opts.name ?? dialect) });
|
|
19
20
|
return {
|
|
20
21
|
db,
|
|
21
22
|
dialect,
|
package/dist/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAE,GAAG,EAAiC,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAA0B,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAE,GAAG,EAAiC,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAA0B,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAyCxC,0EAA0E;AAC1E,MAAM,UAAU,OAAO,CAAC,EAAe;IACrC,OAAO,EAAE,OAAO,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,WAAW,CACzB,aAA4B,EAC5B,OAAoB,EACpB,IAAI,GAAiB,EAAE;IAEvB,MAAM,EAAE,GAAG,IAAI,MAAM,CAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9F,OAAO;QACL,EAAE;QACF,OAAO;QACP,UAAU,EAAE,gBAAgB,CAAC,EAAE,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC;QACjE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;QACjB,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,CAAC;KAClH,CAAC;AACJ,CAAC"}
|
package/dist/sqlite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAYA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAYA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAGtC,OAAO,EAAW,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAY,SAAQ,KAAK;IACxC,wDAAwD;IACxD,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;CAC3B;AAED,wBAAgB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,WAAW,CAgBtE"}
|
package/dist/sqlite.js
CHANGED
|
@@ -12,6 +12,7 @@ import { dirname } from 'node:path';
|
|
|
12
12
|
import { Kysely, SqliteDialect } from 'kysely';
|
|
13
13
|
import Database from 'better-sqlite3';
|
|
14
14
|
import { createOrmFactory } from './crud.js';
|
|
15
|
+
import { logQueries } from './query.js';
|
|
15
16
|
import { sqlSink } from './setup.js';
|
|
16
17
|
export function setupSqlite(opts = {}) {
|
|
17
18
|
const path = opts.path ?? 'fougere.db';
|
|
@@ -21,7 +22,7 @@ export function setupSqlite(opts = {}) {
|
|
|
21
22
|
const sqlite = new Database(path);
|
|
22
23
|
sqlite.pragma('journal_mode = WAL');
|
|
23
24
|
sqlite.pragma('foreign_keys = ON');
|
|
24
|
-
const db = new Kysely({ dialect: new SqliteDialect({ database: sqlite }) });
|
|
25
|
+
const db = new Kysely({ dialect: new SqliteDialect({ database: sqlite }), log: logQueries(opts.name ?? path) });
|
|
25
26
|
return {
|
|
26
27
|
db,
|
|
27
28
|
sqlite,
|
package/dist/sqlite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAiC,MAAM,YAAY,CAAC;AAYpE,MAAM,UAAU,WAAW,CAAC,IAAI,GAAuB,EAAE;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC;IACvC,iEAAiE;IACjE,IAAI,IAAI,KAAK,UAAU;QAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACpC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,MAAM,CAAM,EAAE,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,OAAO,EAAiC,MAAM,YAAY,CAAC;AAYpE,MAAM,UAAU,WAAW,CAAC,IAAI,GAAuB,EAAE;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC;IACvC,iEAAiE;IACjE,IAAI,IAAI,KAAK,UAAU;QAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACpC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,MAAM,CAAM,EAAE,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IACrH,OAAO;QACL,EAAE;QACF,MAAM;QACN,OAAO,EAAE,QAAQ;QACjB,UAAU,EAAE,gBAAgB,CAAC,EAAE,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC;QAClE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;QACjB,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC,CAAC;KACnH,CAAC;AACJ,CAAC"}
|
package/dist/table.d.ts
CHANGED
|
@@ -129,19 +129,6 @@ export interface AppLike {
|
|
|
129
129
|
* one source, where a miss can only be a mistake.
|
|
130
130
|
*/
|
|
131
131
|
elsewhere?: string[];
|
|
132
|
-
/**
|
|
133
|
-
* The DERIVATIONS this app stores — registration names.
|
|
134
|
-
*
|
|
135
|
-
* A derivation makes no table by default: `Post.pick('id','title')` describes an
|
|
136
|
-
* answer, not a place rows live, and one dropped under `entities/` used to get a
|
|
137
|
-
* table of its own — measured on a real app, where a projection of an archived
|
|
138
|
-
* entity created a duplicate in the OTHER database.
|
|
139
|
-
*
|
|
140
|
-
* Naming it in `sources:` is the opt-in, and it changes what the thing is: a stored
|
|
141
|
-
* derivation is a dated COPY, not a projection, and it owes what any copy owes —
|
|
142
|
-
* who fills it, and how old it is.
|
|
143
|
-
*/
|
|
144
|
-
materialize?: string[];
|
|
145
132
|
}
|
|
146
133
|
/**
|
|
147
134
|
* Every entity an app hosts, as FK-aware tables — the shared middle step behind
|
package/dist/table.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"AACA;;;;;;;;;;GAUG;AACH,OAAO,EAA4F,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9I,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,kEAAkE;AAClE,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uFAAuF;IACvF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;CAChD;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,0EAA0E;IAC1E,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC;CAC1B;AAED,6BAA6B;AAC7B,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAoHD,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,yFAAyF;IACzF,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAClC,yFAAyF;IACzF,WAAW,CAAC,EAAE,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACxC,0FAA0F;IAC1F,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,yFAAyF;AACzF,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,0FAA0F;IAC1F,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,eAAe,GAAG,QAAQ,CAmCtG;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAKnE;AAID,sCAAsC;AACtC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,WAAW,EAAE,YAAY,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gFAAgF;IAChF,IAAI,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;KAAE,CAAC;IAClD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AA2CD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,QAAQ,EAAE,CAOpF;AAID,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,kFAAkF;IAClF,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,8FAA8F;IAC9F,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAsC1D"}
|
package/dist/table.js
CHANGED
|
@@ -190,47 +190,41 @@ export function toTableName(name) {
|
|
|
190
190
|
return name.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`) + 's';
|
|
191
191
|
}
|
|
192
192
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
193
|
+
* A schema says whether it holds rows; this adapter decides what to emit for it.
|
|
194
|
+
*
|
|
195
|
+
* A root always did. A derivation describes ANOTHER's rows — `Post.pick('id','title')` is
|
|
196
|
+
* a shape, and one dropped under `entities/` used to get a table of its own: measured on a
|
|
197
|
+
* real app, where a projection of an archived entity created a duplicate in the OTHER
|
|
198
|
+
* database. `.anchor()` is what says otherwise, and it is the entity's own word, never a
|
|
199
|
+
* key of the app's config: a frond stays mountable without its host knowing.
|
|
196
200
|
*/
|
|
197
|
-
function
|
|
198
|
-
|
|
201
|
+
function verdictOn(entry) {
|
|
202
|
+
const schema = schemaOf(entry.entityClass);
|
|
203
|
+
return !schema.derivation || schema.anchored ? 'table' : 'answer';
|
|
199
204
|
}
|
|
200
205
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
* design exists to refuse: rows from yesterday typed exactly like rows from now. The
|
|
205
|
-
* vocabulary already carries the answer — a field with `update: 'now'` records when
|
|
206
|
-
* this row last changed HERE, which for a copy is when it was last pulled. So nothing
|
|
207
|
-
* new is declared; what is new is that forgetting it is refused, at boot, by name.
|
|
208
|
-
*
|
|
209
|
-
* An entity is untouched: it is not a copy of anything, and its rows are the truth.
|
|
206
|
+
* Every entity this app hosts, once each. The same class reaches here under one
|
|
207
|
+
* registration name from two lists — a frond's `entities/` and the auth runtime's map —
|
|
208
|
+
* and two entries for one name are two CREATE TABLE for one table.
|
|
210
209
|
*/
|
|
211
|
-
function refuseUndated(name, source) {
|
|
212
|
-
const dated = Object.values(fieldsOf(source)).some((field) => Lifecycle.of(field).stampedOnUpdate);
|
|
213
|
-
if (dated)
|
|
214
|
-
return;
|
|
215
|
-
throw new Error(`${name} is stored as a derivation but carries no \`updated()\` field — a copy that ` +
|
|
216
|
-
`cannot say when it was pulled reads exactly like live rows. Add one, or drop it from \`sources\`.`);
|
|
217
|
-
}
|
|
218
210
|
function collectEntities(app) {
|
|
219
|
-
const stored = new Set((app.materialize ?? []).map((name) => lowerFirst(name)));
|
|
220
211
|
const entries = [];
|
|
212
|
+
const held = new Set();
|
|
213
|
+
const hold = (entry) => {
|
|
214
|
+
if (held.has(lowerFirst(entry.name)))
|
|
215
|
+
return;
|
|
216
|
+
held.add(lowerFirst(entry.name));
|
|
217
|
+
entries.push(entry);
|
|
218
|
+
};
|
|
221
219
|
for (const frond of app.fronds) {
|
|
222
220
|
for (const entry of frond.entities) {
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
continue;
|
|
226
|
-
refuseUndated(entry.name, entry.entityClass);
|
|
227
|
-
}
|
|
228
|
-
entries.push(entry);
|
|
221
|
+
if (verdictOn(entry) === 'table')
|
|
222
|
+
hold(entry);
|
|
229
223
|
}
|
|
230
224
|
}
|
|
231
225
|
if (app.auth?.entities) {
|
|
232
226
|
for (const [name, entityClass] of Object.entries(app.auth.entities))
|
|
233
|
-
|
|
227
|
+
hold({ name, entityClass });
|
|
234
228
|
}
|
|
235
229
|
return entries;
|
|
236
230
|
}
|
package/dist/table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fougere/adapter-sql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-alpha.0",
|
|
4
4
|
"description": "Entity → SQL tables through Kysely (SQLite, PostgreSQL, MySQL, SQL Server).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fougere",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"better-sqlite3": "^13.0.3",
|
|
41
41
|
"dequal": "^2.0.3",
|
|
42
|
-
"@fougere/core": "0.
|
|
43
|
-
"@fougere/schema": "0.
|
|
42
|
+
"@fougere/core": "0.5.0-alpha.0",
|
|
43
|
+
"@fougere/schema": "0.5.0-alpha.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"kysely": ">=0.28.17"
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@types/better-sqlite3": "^7.6.13",
|
|
50
50
|
"@types/node": "^22.0.0",
|
|
51
51
|
"kysely": "^0.28.17",
|
|
52
|
-
"@fougere/core": "0.
|
|
52
|
+
"@fougere/core": "0.5.0-alpha.0"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public"
|
package/src/fields.ts
CHANGED
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
import type { DialectName } from './dialect.js';
|
|
11
11
|
|
|
12
12
|
/** What sql holds, addressed by field — the shape every augmentation of the registry takes. */
|
|
13
|
-
export type SqlFields<K extends string> = Partial<Record<K, SqlField
|
|
13
|
+
export type SqlFields<K extends string> = Readonly<Partial<Record<K, SqlField>>>;
|
|
14
14
|
|
|
15
15
|
export interface SqlField {
|
|
16
16
|
/** The column type to emit, per engine. An engine absent here keeps the shape's own. */
|
|
17
|
-
columnType?: Partial<Record<DialectName, string
|
|
17
|
+
readonly columnType?: Readonly<Partial<Record<DialectName, string>>>;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
declare module '@fougere/schema' {
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createTableSQL, createIndexSQL, indexSQL, addForeignKeyConstraintSQL, generateSQL, autoMigrate, compiler } from './ddl.js';
|
|
2
|
+
export { onQuery, logQueries, type QueryEvent, type QuerySink } from './query.js';
|
|
2
3
|
export type { GenerateOptions, SqlSink } from './ddl.js';
|
|
3
4
|
export { toTable, toTables, toTableName, toSnakeCase, isKeyed, orderTables } from './table.js';
|
|
4
5
|
export type {
|
package/src/query.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { LogEvent } from 'kysely';
|
|
2
|
+
|
|
3
|
+
/** One statement this process ran, and what it cost. */
|
|
4
|
+
export interface QueryEvent {
|
|
5
|
+
/** Which storage ran it — a process may open several (`sources:`). */
|
|
6
|
+
storage: string;
|
|
7
|
+
sql: string;
|
|
8
|
+
/**
|
|
9
|
+
* How MANY parameters, never their values.
|
|
10
|
+
*
|
|
11
|
+
* They are user data nobody chose to expose — the rule the call log states for a body.
|
|
12
|
+
* The count is what a reader needs anyway: it is how you see an `IN (?, ?, ?)` grow.
|
|
13
|
+
*/
|
|
14
|
+
parameters: number;
|
|
15
|
+
/** Rounded to three decimals: a sub-microsecond statement reports 17 digits otherwise. */
|
|
16
|
+
ms: number;
|
|
17
|
+
failed: boolean;
|
|
18
|
+
at: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type QuerySink = (event: QueryEvent) => void;
|
|
22
|
+
|
|
23
|
+
const sinks: QuerySink[] = [];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Be told about every statement this process runs, and get the unsubscription back.
|
|
27
|
+
*
|
|
28
|
+
* A subscription and not an option, for one reason that decides it: Kysely takes its `log`
|
|
29
|
+
* at CONSTRUCTION, and the storage is built during the boot — before any extension's
|
|
30
|
+
* `up(app)` runs. So the only way to subscribe afterwards is for the log to be installed
|
|
31
|
+
* from the start and route to whoever is listening.
|
|
32
|
+
*
|
|
33
|
+
* The same shape core states for `onLog` and observability for `onSpan`. Costs nothing when
|
|
34
|
+
* nobody listens: `logQueries` returns on an empty list before touching the event.
|
|
35
|
+
*/
|
|
36
|
+
export function onQuery(sink: QuerySink): () => void {
|
|
37
|
+
sinks.push(sink);
|
|
38
|
+
|
|
39
|
+
return () => {
|
|
40
|
+
const at = sinks.indexOf(sink);
|
|
41
|
+
if (at !== -1) sinks.splice(at, 1);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The `log` every Kysely is built with. Named by storage, since a sink sees them all. */
|
|
46
|
+
export function logQueries(storage: string): (event: LogEvent) => void {
|
|
47
|
+
return (event) => {
|
|
48
|
+
if (sinks.length === 0) return;
|
|
49
|
+
|
|
50
|
+
const told: QueryEvent = {
|
|
51
|
+
storage,
|
|
52
|
+
sql: event.query.sql,
|
|
53
|
+
parameters: event.query.parameters.length,
|
|
54
|
+
ms: Math.round(event.queryDurationMillis * 1000) / 1000,
|
|
55
|
+
failed: event.level === 'error',
|
|
56
|
+
at: Date.now(),
|
|
57
|
+
};
|
|
58
|
+
// A listener's own failure is not the query's problem — the rule `DispatchLifecycle`
|
|
59
|
+
// applies to an observer, and `Log` in Kysely would otherwise reject the query.
|
|
60
|
+
for (const sink of sinks) {
|
|
61
|
+
try { sink(told); } catch { /* observational */ }
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
package/src/setup.ts
CHANGED
|
@@ -9,12 +9,21 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { Kysely, sql, type Dialect as KyselyDialect } from 'kysely';
|
|
11
11
|
import { createOrmFactory, type OrmFactoryOptions } from './crud.js';
|
|
12
|
+
import { logQueries } from './query.js';
|
|
12
13
|
import type { DialectName } from './dialect.js';
|
|
13
14
|
import type { SqlSink } from './ddl.js';
|
|
14
15
|
|
|
15
16
|
export interface SetupOptions {
|
|
16
17
|
/** Override naming for specific entities (e.g. better-auth wants singular table names). */
|
|
17
18
|
ormFactoryOptions?: OrmFactoryOptions;
|
|
19
|
+
/**
|
|
20
|
+
* What to call this storage when a query is reported.
|
|
21
|
+
*
|
|
22
|
+
* A process may open several (`sources:`), and a module-level sink sees them all — without
|
|
23
|
+
* a name, two statements from two databases read as one stream. Defaults to what
|
|
24
|
+
* distinguishes them anyway: the engine here, the file path for SQLite.
|
|
25
|
+
*/
|
|
26
|
+
name?: string;
|
|
18
27
|
}
|
|
19
28
|
|
|
20
29
|
export interface Setup {
|
|
@@ -52,7 +61,7 @@ export function setupKysely(
|
|
|
52
61
|
dialect: DialectName,
|
|
53
62
|
opts: SetupOptions = {},
|
|
54
63
|
): Setup {
|
|
55
|
-
const db = new Kysely<any>({ dialect: kyselyDialect });
|
|
64
|
+
const db = new Kysely<any>({ dialect: kyselyDialect, log: logQueries(opts.name ?? dialect) });
|
|
56
65
|
return {
|
|
57
66
|
db,
|
|
58
67
|
dialect,
|
package/src/sqlite.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { dirname } from 'node:path';
|
|
|
12
12
|
import { Kysely, SqliteDialect } from 'kysely';
|
|
13
13
|
import Database from 'better-sqlite3';
|
|
14
14
|
import { createOrmFactory } from './crud.js';
|
|
15
|
+
import { logQueries } from './query.js';
|
|
15
16
|
import { sqlSink, type Setup, type SetupOptions } from './setup.js';
|
|
16
17
|
|
|
17
18
|
export interface SqliteSetupOptions extends SetupOptions {
|
|
@@ -31,7 +32,7 @@ export function setupSqlite(opts: SqliteSetupOptions = {}): SqliteSetup {
|
|
|
31
32
|
const sqlite = new Database(path);
|
|
32
33
|
sqlite.pragma('journal_mode = WAL');
|
|
33
34
|
sqlite.pragma('foreign_keys = ON');
|
|
34
|
-
const db = new Kysely<any>({ dialect: new SqliteDialect({ database: sqlite }) });
|
|
35
|
+
const db = new Kysely<any>({ dialect: new SqliteDialect({ database: sqlite }), log: logQueries(opts.name ?? path) });
|
|
35
36
|
return {
|
|
36
37
|
db,
|
|
37
38
|
sqlite,
|
package/src/table.ts
CHANGED
|
@@ -301,65 +301,46 @@ export interface AppLike {
|
|
|
301
301
|
* one source, where a miss can only be a mistake.
|
|
302
302
|
*/
|
|
303
303
|
elsewhere?: string[];
|
|
304
|
-
/**
|
|
305
|
-
* The DERIVATIONS this app stores — registration names.
|
|
306
|
-
*
|
|
307
|
-
* A derivation makes no table by default: `Post.pick('id','title')` describes an
|
|
308
|
-
* answer, not a place rows live, and one dropped under `entities/` used to get a
|
|
309
|
-
* table of its own — measured on a real app, where a projection of an archived
|
|
310
|
-
* entity created a duplicate in the OTHER database.
|
|
311
|
-
*
|
|
312
|
-
* Naming it in `sources:` is the opt-in, and it changes what the thing is: a stored
|
|
313
|
-
* derivation is a dated COPY, not a projection, and it owes what any copy owes —
|
|
314
|
-
* who fills it, and how old it is.
|
|
315
|
-
*/
|
|
316
|
-
materialize?: string[];
|
|
317
304
|
}
|
|
318
305
|
|
|
319
306
|
/**
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
307
|
+
* A schema says whether it holds rows; this adapter decides what to emit for it.
|
|
308
|
+
*
|
|
309
|
+
* A root always did. A derivation describes ANOTHER's rows — `Post.pick('id','title')` is
|
|
310
|
+
* a shape, and one dropped under `entities/` used to get a table of its own: measured on a
|
|
311
|
+
* real app, where a projection of an archived entity created a duplicate in the OTHER
|
|
312
|
+
* database. `.anchor()` is what says otherwise, and it is the entity's own word, never a
|
|
313
|
+
* key of the app's config: a frond stays mountable without its host knowing.
|
|
323
314
|
*/
|
|
324
|
-
function
|
|
325
|
-
|
|
315
|
+
function verdictOn(entry: EntityEntry): 'table' | 'answer' {
|
|
316
|
+
const schema = schemaOf(entry.entityClass);
|
|
317
|
+
|
|
318
|
+
return !schema.derivation || schema.anchored ? 'table' : 'answer';
|
|
326
319
|
}
|
|
327
320
|
|
|
328
321
|
/**
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
* design exists to refuse: rows from yesterday typed exactly like rows from now. The
|
|
333
|
-
* vocabulary already carries the answer — a field with `update: 'now'` records when
|
|
334
|
-
* this row last changed HERE, which for a copy is when it was last pulled. So nothing
|
|
335
|
-
* new is declared; what is new is that forgetting it is refused, at boot, by name.
|
|
336
|
-
*
|
|
337
|
-
* An entity is untouched: it is not a copy of anything, and its rows are the truth.
|
|
322
|
+
* Every entity this app hosts, once each. The same class reaches here under one
|
|
323
|
+
* registration name from two lists — a frond's `entities/` and the auth runtime's map —
|
|
324
|
+
* and two entries for one name are two CREATE TABLE for one table.
|
|
338
325
|
*/
|
|
339
|
-
function refuseUndated(name: string, source: SchemaOrCard): void {
|
|
340
|
-
const dated = Object.values(fieldsOf(source)).some((field) => Lifecycle.of(field).stampedOnUpdate);
|
|
341
|
-
if (dated) return;
|
|
342
|
-
throw new Error(
|
|
343
|
-
`${name} is stored as a derivation but carries no \`updated()\` field — a copy that ` +
|
|
344
|
-
`cannot say when it was pulled reads exactly like live rows. Add one, or drop it from \`sources\`.`,
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
326
|
function collectEntities(app: AppLike): EntityEntry[] {
|
|
349
|
-
const stored = new Set((app.materialize ?? []).map((name) => lowerFirst(name)));
|
|
350
327
|
const entries: EntityEntry[] = [];
|
|
328
|
+
const held = new Set<string>();
|
|
329
|
+
const hold = (entry: EntityEntry) => {
|
|
330
|
+
if (held.has(lowerFirst(entry.name))) return;
|
|
331
|
+
held.add(lowerFirst(entry.name));
|
|
332
|
+
entries.push(entry);
|
|
333
|
+
};
|
|
334
|
+
|
|
351
335
|
for (const frond of app.fronds) {
|
|
352
336
|
for (const entry of frond.entities) {
|
|
353
|
-
if (
|
|
354
|
-
if (!stored.has(lowerFirst(entry.name))) continue;
|
|
355
|
-
refuseUndated(entry.name, entry.entityClass);
|
|
356
|
-
}
|
|
357
|
-
entries.push(entry);
|
|
337
|
+
if (verdictOn(entry) === 'table') hold(entry);
|
|
358
338
|
}
|
|
359
339
|
}
|
|
360
340
|
if (app.auth?.entities) {
|
|
361
|
-
for (const [name, entityClass] of Object.entries(app.auth.entities))
|
|
341
|
+
for (const [name, entityClass] of Object.entries(app.auth.entities)) hold({ name, entityClass });
|
|
362
342
|
}
|
|
343
|
+
|
|
363
344
|
return entries;
|
|
364
345
|
}
|
|
365
346
|
|