@adminiumjs/engine 0.1.0-rc.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/LICENSE +661 -0
- package/dist/adapter-registry.d.ts +62 -0
- package/dist/adapter-registry.d.ts.map +1 -0
- package/dist/adapter-registry.js +75 -0
- package/dist/adapter-registry.js.map +1 -0
- package/dist/adapter.d.ts +384 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +54 -0
- package/dist/adapter.js.map +1 -0
- package/dist/capabilities.d.ts +57 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +131 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/classify/columns.d.ts +57 -0
- package/dist/classify/columns.d.ts.map +1 -0
- package/dist/classify/columns.js +535 -0
- package/dist/classify/columns.js.map +1 -0
- package/dist/classify/index.d.ts +29 -0
- package/dist/classify/index.d.ts.map +1 -0
- package/dist/classify/index.js +44 -0
- package/dist/classify/index.js.map +1 -0
- package/dist/classify/names.d.ts +11 -0
- package/dist/classify/names.d.ts.map +1 -0
- package/dist/classify/names.js +19 -0
- package/dist/classify/names.js.map +1 -0
- package/dist/classify/pii.d.ts +29 -0
- package/dist/classify/pii.d.ts.map +1 -0
- package/dist/classify/pii.js +55 -0
- package/dist/classify/pii.js.map +1 -0
- package/dist/classify/tables.d.ts +64 -0
- package/dist/classify/tables.d.ts.map +1 -0
- package/dist/classify/tables.js +303 -0
- package/dist/classify/tables.js.map +1 -0
- package/dist/config-schema/envelope.d.ts +83 -0
- package/dist/config-schema/envelope.d.ts.map +1 -0
- package/dist/config-schema/envelope.js +87 -0
- package/dist/config-schema/envelope.js.map +1 -0
- package/dist/config-schema/index.d.ts +14 -0
- package/dist/config-schema/index.d.ts.map +1 -0
- package/dist/config-schema/index.js +15 -0
- package/dist/config-schema/index.js.map +1 -0
- package/dist/config-schema/migrations.d.ts +44 -0
- package/dist/config-schema/migrations.d.ts.map +1 -0
- package/dist/config-schema/migrations.js +62 -0
- package/dist/config-schema/migrations.js.map +1 -0
- package/dist/generate/archetype.d.ts +76 -0
- package/dist/generate/archetype.d.ts.map +1 -0
- package/dist/generate/archetype.js +250 -0
- package/dist/generate/archetype.js.map +1 -0
- package/dist/generate/crud.d.ts +36 -0
- package/dist/generate/crud.d.ts.map +1 -0
- package/dist/generate/crud.js +45 -0
- package/dist/generate/crud.js.map +1 -0
- package/dist/generate/dashboard.d.ts +43 -0
- package/dist/generate/dashboard.d.ts.map +1 -0
- package/dist/generate/dashboard.js +61 -0
- package/dist/generate/dashboard.js.map +1 -0
- package/dist/generate/domains.d.ts +29 -0
- package/dist/generate/domains.d.ts.map +1 -0
- package/dist/generate/domains.js +145 -0
- package/dist/generate/domains.js.map +1 -0
- package/dist/generate/index.d.ts +78 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +301 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/generate/util.d.ts +46 -0
- package/dist/generate/util.d.ts.map +1 -0
- package/dist/generate/util.js +123 -0
- package/dist/generate/util.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/schema-model.d.ts +1853 -0
- package/dist/schema-model.d.ts.map +1 -0
- package/dist/schema-model.js +463 -0
- package/dist/schema-model.js.map +1 -0
- package/dist/snapshot/diff.d.ts +258 -0
- package/dist/snapshot/diff.d.ts.map +1 -0
- package/dist/snapshot/diff.js +151 -0
- package/dist/snapshot/diff.js.map +1 -0
- package/dist/snapshot/hash.d.ts +23 -0
- package/dist/snapshot/hash.d.ts.map +1 -0
- package/dist/snapshot/hash.js +47 -0
- package/dist/snapshot/hash.js.map +1 -0
- package/dist/snapshot/index.d.ts +28 -0
- package/dist/snapshot/index.d.ts.map +1 -0
- package/dist/snapshot/index.js +26 -0
- package/dist/snapshot/index.js.map +1 -0
- package/dist/snapshot/sha256.d.ts +14 -0
- package/dist/snapshot/sha256.d.ts.map +1 -0
- package/dist/snapshot/sha256.js +99 -0
- package/dist/snapshot/sha256.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter registry mechanics + the typed adapter error — the acyclic leaf
|
|
3
|
+
* under ./adapter.ts (the repo forbids circular imports, 01 §2.3).
|
|
4
|
+
*
|
|
5
|
+
* The public import path for everything here is `@adminium/engine/adapter`,
|
|
6
|
+
* which re-exports this module and binds the process-wide singleton
|
|
7
|
+
* `adapterRegistry` to the concrete `AdapterProvider` contract
|
|
8
|
+
* (01-architecture.md §2.3.1):
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { adapterRegistry } from '@adminium/engine/adapter';
|
|
12
|
+
* import { postgresAdapter } from '@adminium/adapter-postgres';
|
|
13
|
+
*
|
|
14
|
+
* adapterRegistry.register(postgresAdapter); // dialect: 'postgres'
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* v1.x adapters (MongoDB, MSSQL) plug into the same registry without
|
|
18
|
+
* touching engine internals.
|
|
19
|
+
*/
|
|
20
|
+
import type { Dialect } from './schema-model.js';
|
|
21
|
+
export declare const ADAPTER_ERROR_CODES: readonly ["AUTH", "HOST_UNREACHABLE", "TLS", "PERMISSION", "TIMEOUT", "SCHEMA_DRIFT", "UNSUPPORTED", "UNKNOWN"];
|
|
22
|
+
export type AdapterErrorCode = (typeof ADAPTER_ERROR_CODES)[number];
|
|
23
|
+
/**
|
|
24
|
+
* The only error type adapter methods may reject with. The Studio wizard and
|
|
25
|
+
* the `diagnostics-readout` widget map `code` to remediation copy (e.g. the
|
|
26
|
+
* allowlist-IP hint per designs/System States).
|
|
27
|
+
*/
|
|
28
|
+
export declare class AdapterError extends Error {
|
|
29
|
+
readonly code: AdapterErrorCode;
|
|
30
|
+
/** Machine-oriented details (driver error code, host, …). */
|
|
31
|
+
readonly detail: string | null;
|
|
32
|
+
/** Human remediation hint. */
|
|
33
|
+
readonly hint: string | null;
|
|
34
|
+
constructor(code: AdapterErrorCode, message: string, options?: {
|
|
35
|
+
detail?: string;
|
|
36
|
+
hint?: string;
|
|
37
|
+
cause?: unknown;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** The minimal shape the registry keys on; the full contract is `AdapterProvider` (./adapter.ts). */
|
|
41
|
+
export interface DialectKeyed {
|
|
42
|
+
readonly dialect: Dialect;
|
|
43
|
+
}
|
|
44
|
+
export declare class AdapterRegistry<Provider extends DialectKeyed = DialectKeyed> {
|
|
45
|
+
#private;
|
|
46
|
+
/**
|
|
47
|
+
* Register a provider for its dialect. Registering the same dialect twice
|
|
48
|
+
* is a boot-composition bug and throws; call `unregister` first if a test
|
|
49
|
+
* genuinely needs to swap providers.
|
|
50
|
+
*/
|
|
51
|
+
register(provider: Provider): void;
|
|
52
|
+
/** Look up a provider; throws a typed UNSUPPORTED error when absent. */
|
|
53
|
+
get(dialect: Dialect): Provider;
|
|
54
|
+
has(dialect: Dialect): boolean;
|
|
55
|
+
/** Registered dialects, in registration order. */
|
|
56
|
+
list(): Dialect[];
|
|
57
|
+
/** Remove one provider (tests, hot-swap). Returns whether it existed. */
|
|
58
|
+
unregister(dialect: Dialect): boolean;
|
|
59
|
+
/** Remove everything (tests only). */
|
|
60
|
+
clear(): void;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=adapter-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAMjD,eAAO,MAAM,mBAAmB,iHAStB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;gBAG3B,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAQpE;AAMD,qGAAqG;AACrG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,qBAAa,eAAe,CAAC,QAAQ,SAAS,YAAY,GAAG,YAAY;;IAGvE;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAOlC,wEAAwE;IACxE,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ;IAc/B,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAI9B,kDAAkD;IAClD,IAAI,IAAI,OAAO,EAAE;IAIjB,yEAAyE;IACzE,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAIrC,sCAAsC;IACtC,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Typed errors (05 §3)
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
export const ADAPTER_ERROR_CODES = [
|
|
5
|
+
'AUTH',
|
|
6
|
+
'HOST_UNREACHABLE',
|
|
7
|
+
'TLS',
|
|
8
|
+
'PERMISSION',
|
|
9
|
+
'TIMEOUT',
|
|
10
|
+
'SCHEMA_DRIFT',
|
|
11
|
+
'UNSUPPORTED',
|
|
12
|
+
'UNKNOWN',
|
|
13
|
+
];
|
|
14
|
+
/**
|
|
15
|
+
* The only error type adapter methods may reject with. The Studio wizard and
|
|
16
|
+
* the `diagnostics-readout` widget map `code` to remediation copy (e.g. the
|
|
17
|
+
* allowlist-IP hint per designs/System States).
|
|
18
|
+
*/
|
|
19
|
+
export class AdapterError extends Error {
|
|
20
|
+
code;
|
|
21
|
+
/** Machine-oriented details (driver error code, host, …). */
|
|
22
|
+
detail;
|
|
23
|
+
/** Human remediation hint. */
|
|
24
|
+
hint;
|
|
25
|
+
constructor(code, message, options = {}) {
|
|
26
|
+
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
27
|
+
this.name = 'AdapterError';
|
|
28
|
+
this.code = code;
|
|
29
|
+
this.detail = options.detail ?? null;
|
|
30
|
+
this.hint = options.hint ?? null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class AdapterRegistry {
|
|
34
|
+
#providers = new Map();
|
|
35
|
+
/**
|
|
36
|
+
* Register a provider for its dialect. Registering the same dialect twice
|
|
37
|
+
* is a boot-composition bug and throws; call `unregister` first if a test
|
|
38
|
+
* genuinely needs to swap providers.
|
|
39
|
+
*/
|
|
40
|
+
register(provider) {
|
|
41
|
+
if (this.#providers.has(provider.dialect)) {
|
|
42
|
+
throw new Error(`adapter for dialect "${provider.dialect}" is already registered`);
|
|
43
|
+
}
|
|
44
|
+
this.#providers.set(provider.dialect, provider);
|
|
45
|
+
}
|
|
46
|
+
/** Look up a provider; throws a typed UNSUPPORTED error when absent. */
|
|
47
|
+
get(dialect) {
|
|
48
|
+
const provider = this.#providers.get(dialect);
|
|
49
|
+
if (provider === undefined) {
|
|
50
|
+
const known = this.list();
|
|
51
|
+
throw new AdapterError('UNSUPPORTED', `no adapter registered for dialect "${dialect}"`, {
|
|
52
|
+
hint: known.length > 0
|
|
53
|
+
? `registered dialects: ${known.join(', ')}`
|
|
54
|
+
: 'no adapters registered — did the server boot call register()?',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return provider;
|
|
58
|
+
}
|
|
59
|
+
has(dialect) {
|
|
60
|
+
return this.#providers.has(dialect);
|
|
61
|
+
}
|
|
62
|
+
/** Registered dialects, in registration order. */
|
|
63
|
+
list() {
|
|
64
|
+
return [...this.#providers.keys()];
|
|
65
|
+
}
|
|
66
|
+
/** Remove one provider (tests, hot-swap). Returns whether it existed. */
|
|
67
|
+
unregister(dialect) {
|
|
68
|
+
return this.#providers.delete(dialect);
|
|
69
|
+
}
|
|
70
|
+
/** Remove everything (tests only). */
|
|
71
|
+
clear() {
|
|
72
|
+
this.#providers.clear();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=adapter-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAqBA,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,MAAM;IACN,kBAAkB;IAClB,KAAK;IACL,YAAY;IACZ,SAAS;IACT,cAAc;IACd,aAAa;IACb,SAAS;CACD,CAAC;AAGX;;;;GAIG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAmB;IAChC,6DAA6D;IACpD,MAAM,CAAgB;IAC/B,8BAA8B;IACrB,IAAI,CAAgB;IAE7B,YACE,IAAsB,EACtB,OAAe,EACf,UAA+D,EAAE;QAEjE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;IACnC,CAAC;CACF;AAWD,MAAM,OAAO,eAAe;IACjB,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEnD;;;;OAIG;IACH,QAAQ,CAAC,QAAkB;QACzB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,CAAC,OAAO,yBAAyB,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,wEAAwE;IACxE,GAAG,CAAC,OAAgB;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,IAAI,YAAY,CAAC,aAAa,EAAE,sCAAsC,OAAO,GAAG,EAAE;gBACtF,IAAI,EACF,KAAK,CAAC,MAAM,GAAG,CAAC;oBACd,CAAC,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBAC5C,CAAC,CAAC,+DAA+D;aACtE,CAAC,CAAC;QACL,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,GAAG,CAAC,OAAgB;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,kDAAkD;IAClD,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,yEAAyE;IACzE,UAAU,CAAC,OAAgB;QACzB,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,sCAAsC;IACtC,KAAK;QACH,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `DatabaseAdapter` contract — 05-introspection-engine.md §3, with the
|
|
3
|
+
* three-connection privilege model of 01-architecture.md §3.
|
|
4
|
+
*
|
|
5
|
+
* `@adminium/engine` defines this interface but never imports adapter
|
|
6
|
+
* packages; `@adminium/server` composes concrete adapters at boot through
|
|
7
|
+
* the registry (01-architecture.md §2.3.1, ./adapter-registry.ts). Adapter
|
|
8
|
+
* packages (`@adminium/adapter-postgres`, …) import ONLY
|
|
9
|
+
* `@adminium/engine/adapter` — this module — which re-exports the
|
|
10
|
+
* SchemaModel types they need.
|
|
11
|
+
*
|
|
12
|
+
* THE "SCHEMA ONLY" INVARIANT (05 §10): `introspect()` reads catalog
|
|
13
|
+
* metadata exclusively — never user rows. Row-touching methods (`sample`,
|
|
14
|
+
* `sampleColumn`, `query`, `mutate`, `count`) exist only on the post-setup
|
|
15
|
+
* `data`-role instance and are compile-time blocked on the `introspect`
|
|
16
|
+
* instance via `this` typing on the role-branded interface below (plus a
|
|
17
|
+
* runtime guard every implementation must add — tested by the shared
|
|
18
|
+
* adapter test kit, 05-T02).
|
|
19
|
+
*/
|
|
20
|
+
import { AdapterRegistry } from './adapter-registry.js';
|
|
21
|
+
import type { AdapterError } from './adapter-registry.js';
|
|
22
|
+
import type { AdapterCapabilities, DatabaseModel, Dialect, LogicalType } from './schema-model.js';
|
|
23
|
+
/**
|
|
24
|
+
* The three logical connections per source (01-architecture.md §3):
|
|
25
|
+
* `introspect` (schema metadata only), `data` (CRUD on included tables),
|
|
26
|
+
* `meta` (adminium_* tables; owned by @adminium/meta and never handed to
|
|
27
|
+
* adapters in v1 — listed for completeness of the brand).
|
|
28
|
+
*/
|
|
29
|
+
export type ConnectionRole = 'introspect' | 'data' | 'meta';
|
|
30
|
+
/**
|
|
31
|
+
* Role-branded connection config. The brand is what makes `introspect()`
|
|
32
|
+
* uncallable on a data-role instance (and vice versa) at compile time.
|
|
33
|
+
*/
|
|
34
|
+
export interface ConnectionConfig<Role extends ConnectionRole = ConnectionRole> {
|
|
35
|
+
readonly role: Role;
|
|
36
|
+
/**
|
|
37
|
+
* DSN for network dialects (`postgres://…`, `mysql://…`). SQLite accepts
|
|
38
|
+
* `sqlite:///abs/path.db`, `file:abs/path.db`, or a plain path via `file`.
|
|
39
|
+
*/
|
|
40
|
+
readonly dsn?: string;
|
|
41
|
+
/** SQLite: absolute database file path (or ':memory:' for demo/test). */
|
|
42
|
+
readonly file?: string;
|
|
43
|
+
/** SQLite open mode; introspect instances always open readonly. */
|
|
44
|
+
readonly mode?: 'readonly' | 'readwrite';
|
|
45
|
+
/** Pool size hint (pg introspect role defaults to 5 — 05 §4.1). */
|
|
46
|
+
readonly poolMax?: number;
|
|
47
|
+
/** Per-statement timeout; defaults per dialect (05 §4). */
|
|
48
|
+
readonly statementTimeoutMs?: number;
|
|
49
|
+
}
|
|
50
|
+
export type IntrospectConnectionConfig = ConnectionConfig<'introspect'>;
|
|
51
|
+
export type DataConnectionConfig = ConnectionConfig<'data'>;
|
|
52
|
+
/** Result of `test()` — 05 §3. */
|
|
53
|
+
export interface TestResult {
|
|
54
|
+
ok: boolean;
|
|
55
|
+
latencyMs: number;
|
|
56
|
+
serverVersion: string | null;
|
|
57
|
+
currentUser: string | null;
|
|
58
|
+
canWrite: boolean;
|
|
59
|
+
ssl: boolean;
|
|
60
|
+
error?: AdapterError;
|
|
61
|
+
}
|
|
62
|
+
/** Dialect-specific privilege probes (01-architecture.md §3). */
|
|
63
|
+
export interface PrivilegeProbe {
|
|
64
|
+
canReadSchema: boolean;
|
|
65
|
+
canRead: boolean;
|
|
66
|
+
canWrite: boolean;
|
|
67
|
+
canDDL: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Result of `probeCapabilities()` — persisted on the connection row and
|
|
71
|
+
* driving UI honesty (a read-only data role renders the app read-only).
|
|
72
|
+
*/
|
|
73
|
+
export interface CapabilityProbeResult {
|
|
74
|
+
capabilities: AdapterCapabilities;
|
|
75
|
+
privileges: PrivilegeProbe;
|
|
76
|
+
serverVersion: string;
|
|
77
|
+
/** Current role/user with read-only detection for the connected role. */
|
|
78
|
+
currentRole: {
|
|
79
|
+
name: string;
|
|
80
|
+
readOnly: boolean;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export interface IntrospectOptions {
|
|
84
|
+
/** Default: all non-system (pg) / the connected db (mysql) / 'main' (sqlite). */
|
|
85
|
+
schemas?: string[];
|
|
86
|
+
/** Optional include-predicate applied after enumeration (e.g. > 2,000-table guard). */
|
|
87
|
+
tableFilter?: (table: {
|
|
88
|
+
schema: string;
|
|
89
|
+
name: string;
|
|
90
|
+
}) => boolean;
|
|
91
|
+
/** Default true — ESTIMATES only, never COUNT during setup (05 §10). */
|
|
92
|
+
collectRowEstimates?: boolean;
|
|
93
|
+
/** Default true where supported. */
|
|
94
|
+
collectActivityStats?: boolean;
|
|
95
|
+
/** Default 30_000 total, 15_000 per statement. */
|
|
96
|
+
timeoutMs?: number;
|
|
97
|
+
}
|
|
98
|
+
export interface TableRef {
|
|
99
|
+
/** null for dialects without schemas (mysql/sqlite). */
|
|
100
|
+
schema: string | null;
|
|
101
|
+
name: string;
|
|
102
|
+
}
|
|
103
|
+
/** Filter ops are whitelisted per LogicalType by the engine before compile. */
|
|
104
|
+
export type FilterOp = 'eq' | 'neq' | 'lt' | 'lte' | 'gt' | 'gte' | 'in' | 'not-in' | 'like' | 'ilike' | 'contains' | 'starts-with' | 'ends-with' | 'between' | 'is-null' | 'is-not-null';
|
|
105
|
+
/** AND/OR tree of column predicates (05 §3). Values always bind as parameters. */
|
|
106
|
+
export type FilterSpec = {
|
|
107
|
+
and: FilterSpec[];
|
|
108
|
+
} | {
|
|
109
|
+
or: FilterSpec[];
|
|
110
|
+
} | {
|
|
111
|
+
not: FilterSpec;
|
|
112
|
+
} | {
|
|
113
|
+
column: string;
|
|
114
|
+
op: FilterOp;
|
|
115
|
+
value?: unknown;
|
|
116
|
+
};
|
|
117
|
+
/** Declarative SELECT/aggregate for widgets & grids — compiled through Kysely. */
|
|
118
|
+
export interface QuerySpec {
|
|
119
|
+
table: TableRef;
|
|
120
|
+
/** Default: non-secret columns. */
|
|
121
|
+
select?: string[];
|
|
122
|
+
aggregates?: {
|
|
123
|
+
fn: 'count' | 'sum' | 'avg' | 'min' | 'max';
|
|
124
|
+
column?: string;
|
|
125
|
+
as: string;
|
|
126
|
+
}[];
|
|
127
|
+
groupBy?: (string | {
|
|
128
|
+
bucket: 'day' | 'week' | 'month';
|
|
129
|
+
column: string;
|
|
130
|
+
})[];
|
|
131
|
+
filter?: FilterSpec;
|
|
132
|
+
orderBy?: {
|
|
133
|
+
column: string;
|
|
134
|
+
dir: 'asc' | 'desc';
|
|
135
|
+
}[];
|
|
136
|
+
/** Hard-capped at 1_000 by the engine. */
|
|
137
|
+
limit?: number;
|
|
138
|
+
offset?: number;
|
|
139
|
+
}
|
|
140
|
+
export type Row = Record<string, unknown>;
|
|
141
|
+
export interface QueryResult {
|
|
142
|
+
rows: Row[];
|
|
143
|
+
/** Column meta for serialization quirks (e.g. mysql unsigned bigint → string). */
|
|
144
|
+
columns: {
|
|
145
|
+
name: string;
|
|
146
|
+
logicalType: LogicalType;
|
|
147
|
+
}[];
|
|
148
|
+
warnings?: string[];
|
|
149
|
+
}
|
|
150
|
+
export type MutationSpec = {
|
|
151
|
+
kind: 'insert';
|
|
152
|
+
table: TableRef;
|
|
153
|
+
values: Row | Row[];
|
|
154
|
+
} | {
|
|
155
|
+
kind: 'update';
|
|
156
|
+
table: TableRef;
|
|
157
|
+
filter: FilterSpec;
|
|
158
|
+
values: Row;
|
|
159
|
+
} | {
|
|
160
|
+
kind: 'delete';
|
|
161
|
+
table: TableRef;
|
|
162
|
+
filter: FilterSpec;
|
|
163
|
+
};
|
|
164
|
+
export interface MutationResult {
|
|
165
|
+
affected: number;
|
|
166
|
+
/** Mutated rows where the dialect supports RETURNING; null otherwise. */
|
|
167
|
+
returning: Row[] | null;
|
|
168
|
+
}
|
|
169
|
+
/** Sampling caps enforced by every implementation (05 §10). */
|
|
170
|
+
export interface SampleOptions {
|
|
171
|
+
/** Default: non-secret, PII-masked columns. */
|
|
172
|
+
columns?: string[];
|
|
173
|
+
/** LIMIT ≤ 100; values truncated at 256 chars. */
|
|
174
|
+
limit?: number;
|
|
175
|
+
/** Recorded in adminium_audit_log. */
|
|
176
|
+
purpose: 'preview' | 'classify' | 'llm';
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Options for the optional single-column sampler. `optIn: true` is a
|
|
180
|
+
* deliberate speed bump: row values leave the database ONLY when the caller
|
|
181
|
+
* explicitly acknowledges it (the user-facing "schema only, never your rows"
|
|
182
|
+
* promise applies to setup — this method must never run during setup and is
|
|
183
|
+
* always audit-logged).
|
|
184
|
+
*/
|
|
185
|
+
export interface ColumnSampleOptions {
|
|
186
|
+
/** Must be literally `true` — there is no implicit sampling. */
|
|
187
|
+
optIn: true;
|
|
188
|
+
/** LIMIT ≤ 100; values truncated at 256 chars. */
|
|
189
|
+
limit?: number;
|
|
190
|
+
purpose: 'preview' | 'classify' | 'llm';
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Per-column metadata the caller hands to
|
|
194
|
+
* {@link DatabaseAdapter.collectTableStats}. The adapter needs the logical
|
|
195
|
+
* type (to decide ordered-type min/max and the distinct-count strategy) and
|
|
196
|
+
* the heuristic privacy flags: PII-suspected and secret columns NEVER
|
|
197
|
+
* contribute sampled cell values, even when sampling is opted in (06 §4.2).
|
|
198
|
+
*/
|
|
199
|
+
export interface StatsColumnInput {
|
|
200
|
+
name: string;
|
|
201
|
+
logicalType: LogicalType;
|
|
202
|
+
/** Heuristic PII suspicion (05 §7.2) — never yields sampled values. */
|
|
203
|
+
piiSuspected?: boolean;
|
|
204
|
+
/** Secret column (05 §7.1) — excluded from every value-touching statistic. */
|
|
205
|
+
secret?: boolean;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Options for {@link DatabaseAdapter.collectTableStats}. Sample-free by
|
|
209
|
+
* default: with `sampling` unset NO cell value ever leaves the database —
|
|
210
|
+
* only the aggregate statistics (row count, null fraction, distinct count)
|
|
211
|
+
* the shared-contract invariant permits (06 §1 invariant 5, §4.2).
|
|
212
|
+
*/
|
|
213
|
+
export interface CollectStatsOptions {
|
|
214
|
+
/**
|
|
215
|
+
* Columns to profile. When omitted the adapter returns only the row-count
|
|
216
|
+
* estimate — callers pass the classified column set so privacy flags and
|
|
217
|
+
* logical types are known without a second round trip.
|
|
218
|
+
*/
|
|
219
|
+
columns?: StatsColumnInput[];
|
|
220
|
+
/**
|
|
221
|
+
* Sampling opt-in. `null`/omitted ⇒ sample-free (default): null-fraction and
|
|
222
|
+
* distinct-count aggregates only, never a single cell value. When set, up to
|
|
223
|
+
* `maxValuesPerColumn` most-common values plus min/max on ordered
|
|
224
|
+
* (numeric/temporal) types are collected — but NEVER for PII-suspected or
|
|
225
|
+
* secret columns.
|
|
226
|
+
*/
|
|
227
|
+
sampling?: {
|
|
228
|
+
maxValuesPerColumn: number;
|
|
229
|
+
} | null;
|
|
230
|
+
/**
|
|
231
|
+
* Row-count ceiling above which per-column null-fraction / distinct-count
|
|
232
|
+
* fall back to `null` (unknown) instead of a full scan (06 §4.2 "capped
|
|
233
|
+
* tables → NULL"). Defaults to {@link STATS_MAX_SCAN_ROWS}.
|
|
234
|
+
*/
|
|
235
|
+
maxScanRows?: number;
|
|
236
|
+
}
|
|
237
|
+
/** A JSON-native scalar a sampled/extent cell can hold (strings truncated). */
|
|
238
|
+
export type StatsScalar = string | number | boolean | null;
|
|
239
|
+
/** Per-column aggregate statistics (06 §4.2). */
|
|
240
|
+
export interface ColumnStats {
|
|
241
|
+
column: string;
|
|
242
|
+
/** Fraction of NULL rows in `[0,1]`; `null` when not cheaply available. */
|
|
243
|
+
nullFraction: number | null;
|
|
244
|
+
/** Estimated distinct value count; `null` when unknown or capped. */
|
|
245
|
+
distinctCount: number | null;
|
|
246
|
+
/**
|
|
247
|
+
* Ordered-type extent. Present ONLY under sampling opt-in, for
|
|
248
|
+
* numeric/temporal columns, and NEVER for PII/secret columns. Lossless:
|
|
249
|
+
* bigint and decimal travel as strings.
|
|
250
|
+
*/
|
|
251
|
+
min?: StatsScalar;
|
|
252
|
+
max?: StatsScalar;
|
|
253
|
+
/**
|
|
254
|
+
* Most-common values, most-frequent first. Present ONLY under sampling
|
|
255
|
+
* opt-in and NEVER for PII-suspected or secret columns (06 §4.2 privacy
|
|
256
|
+
* rule). Each value truncated at {@link STATS_SAMPLE_VALUE_MAX_CHARS} chars.
|
|
257
|
+
*/
|
|
258
|
+
sampleValues?: StatsScalar[];
|
|
259
|
+
}
|
|
260
|
+
/** Result of {@link DatabaseAdapter.collectTableStats}. */
|
|
261
|
+
export interface StatsResult {
|
|
262
|
+
table: TableRef;
|
|
263
|
+
/** Row-count estimate (may be exact — see `rowCountExact`); `null` if unknown. */
|
|
264
|
+
rowCountEstimate: number | null;
|
|
265
|
+
/** True when `rowCountEstimate` is an exact `COUNT(*)`, not an estimate. */
|
|
266
|
+
rowCountExact: boolean;
|
|
267
|
+
/** Per-column aggregates — one entry per requested column, in input order. */
|
|
268
|
+
columns: ColumnStats[];
|
|
269
|
+
/** True when any sampled values / min-max are present (opt-in was honored). */
|
|
270
|
+
sampled: boolean;
|
|
271
|
+
/** Non-fatal degradations (estimate unavailable, capped, permission gap). */
|
|
272
|
+
warnings?: string[];
|
|
273
|
+
}
|
|
274
|
+
/** Default cap on most-common sampled values per column (06 §4.2). */
|
|
275
|
+
export declare const STATS_DEFAULT_SAMPLE_VALUES = 20;
|
|
276
|
+
/** Sampled string values are truncated at this many characters (mirrors 05 §10). */
|
|
277
|
+
export declare const STATS_SAMPLE_VALUE_MAX_CHARS = 256;
|
|
278
|
+
/** Default row-count ceiling for full-scan null/distinct aggregates (06 §4.2). */
|
|
279
|
+
export declare const STATS_MAX_SCAN_ROWS = 1000000;
|
|
280
|
+
/** At/below this estimate an adapter prefers an exact COUNT(*) over a stale estimate (06 §4.2). */
|
|
281
|
+
export declare const STATS_EXACT_COUNT_THRESHOLD = 50000;
|
|
282
|
+
/** Per-LogicalType value converters between JS and the wire format. */
|
|
283
|
+
export interface TypeSerializer {
|
|
284
|
+
/** JS value → driver parameter (e.g. bigint → string for mysql). */
|
|
285
|
+
toDb(value: unknown): unknown;
|
|
286
|
+
/** Driver value → serializable JS (int8/decimal → string, timestamps → ISO-8601 UTC). */
|
|
287
|
+
fromDb(value: unknown): unknown;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* What `createQueryEngine()` hands the CRUD layer (08-server-api.md §3.7):
|
|
291
|
+
* everything dynamic Kysely needs for the data connection. The engine
|
|
292
|
+
* package does not depend on `kysely`, so the dialect is typed opaquely —
|
|
293
|
+
* `@adminium/server` (which owns the Kysely dependency) casts it to
|
|
294
|
+
* `kysely.Dialect` at the composition boundary.
|
|
295
|
+
*/
|
|
296
|
+
export interface QueryEngine {
|
|
297
|
+
/** A Kysely `Dialect` instance for the pooled data connection. */
|
|
298
|
+
dialect: unknown;
|
|
299
|
+
/** Identifier quoting rules — identifiers are still snapshot-validated first. */
|
|
300
|
+
identifiers: {
|
|
301
|
+
quote(identifier: string): string;
|
|
302
|
+
maxLength: number;
|
|
303
|
+
};
|
|
304
|
+
serializers: Partial<Record<LogicalType, TypeSerializer>>;
|
|
305
|
+
/** Tear down the underlying pool. */
|
|
306
|
+
destroy(): Promise<void>;
|
|
307
|
+
}
|
|
308
|
+
/** Workplan alias — 08-server-api.md calls this the CRUD "query port". */
|
|
309
|
+
export type QueryPort = QueryEngine;
|
|
310
|
+
/**
|
|
311
|
+
* One instance per logical connection (role). Methods carry `this` types so
|
|
312
|
+
* that `introspect()` type-checks only on an `'introspect'`-role instance
|
|
313
|
+
* and row-touching methods only on a `'data'`-role instance. Every method
|
|
314
|
+
* rejects with {@link AdapterError} on failure.
|
|
315
|
+
*
|
|
316
|
+
* No raw SQL escape hatch: identifiers are validated against the current
|
|
317
|
+
* schema snapshot before compilation (unknown table/column → typed
|
|
318
|
+
* `SCHEMA_DRIFT`), values are always parameterized.
|
|
319
|
+
*/
|
|
320
|
+
export interface DatabaseAdapter<Role extends ConnectionRole = ConnectionRole> {
|
|
321
|
+
readonly dialect: Dialect;
|
|
322
|
+
/** Static, dialect-level capabilities (probe refines per-connection). */
|
|
323
|
+
readonly capabilities: AdapterCapabilities;
|
|
324
|
+
readonly role: Role;
|
|
325
|
+
/** Lazy pool; throws AdapterError with a typed code. */
|
|
326
|
+
connect(config: ConnectionConfig<Role>): Promise<void>;
|
|
327
|
+
test(): Promise<TestResult>;
|
|
328
|
+
/** Runs on every connect/test; results persist on the connection row. */
|
|
329
|
+
probeCapabilities(): Promise<CapabilityProbeResult>;
|
|
330
|
+
/** SCHEMA ONLY — reads catalog/pragma namespaces exclusively (05 §10). */
|
|
331
|
+
introspect(this: DatabaseAdapter<'introspect'>, opts?: IntrospectOptions): Promise<DatabaseModel>;
|
|
332
|
+
/** Capped count: `cap` (default 100_001) renders as "100,000+". */
|
|
333
|
+
count(this: DatabaseAdapter<'data'>, table: TableRef, filter?: FilterSpec, opts?: {
|
|
334
|
+
cap?: number;
|
|
335
|
+
}): Promise<{
|
|
336
|
+
value: number;
|
|
337
|
+
capped: boolean;
|
|
338
|
+
}>;
|
|
339
|
+
/** Post-setup only; caps per 05 §10 (LIMIT ≤ 100, truncation, secret exclusion, PII masking). */
|
|
340
|
+
sample(this: DatabaseAdapter<'data'>, table: TableRef, opts: SampleOptions): Promise<Row[]>;
|
|
341
|
+
/** Optional single-column sampler; see {@link ColumnSampleOptions}. */
|
|
342
|
+
sampleColumn?(this: DatabaseAdapter<'data'>, table: TableRef, column: string, opts: ColumnSampleOptions): Promise<unknown[]>;
|
|
343
|
+
query(this: DatabaseAdapter<'data'>, spec: QuerySpec): Promise<QueryResult>;
|
|
344
|
+
/** insert/update/delete, returning rows where supported. */
|
|
345
|
+
mutate(this: DatabaseAdapter<'data'>, spec: MutationSpec): Promise<MutationResult>;
|
|
346
|
+
/**
|
|
347
|
+
* Collect aggregate statistics for LLM enrichment (06-llm-assist.md §4.2).
|
|
348
|
+
* Sample-free by default: with `opts.sampling` unset the result carries row
|
|
349
|
+
* counts, null fractions and distinct counts only — never a single cell
|
|
350
|
+
* value. Opt-in sampling adds most-common values and ordered min/max, but
|
|
351
|
+
* NEVER for PII-suspected or secret columns. Cheap-first per dialect
|
|
352
|
+
* (catalog estimates where available, bounded exact scans as fallback);
|
|
353
|
+
* an unavailable estimate returns `null`, never a wrong number.
|
|
354
|
+
*/
|
|
355
|
+
collectTableStats(this: DatabaseAdapter<'data'>, table: TableRef, opts?: CollectStatsOptions): Promise<StatsResult>;
|
|
356
|
+
/** Release pools/handles; idempotent. */
|
|
357
|
+
close(): Promise<void>;
|
|
358
|
+
}
|
|
359
|
+
export type IntrospectAdapter = DatabaseAdapter<'introspect'>;
|
|
360
|
+
export type DataAdapter = DatabaseAdapter<'data'>;
|
|
361
|
+
/**
|
|
362
|
+
* What an adapter package exports and the server registers at boot
|
|
363
|
+
* (01-architecture.md §2.3.1): a factory keyed by dialect, plus the
|
|
364
|
+
* QueryPort factory the CRUD layer uses to obtain a Kysely dialect for the
|
|
365
|
+
* data connection without holding a full adapter instance.
|
|
366
|
+
*/
|
|
367
|
+
export interface AdapterProvider {
|
|
368
|
+
readonly dialect: Dialect;
|
|
369
|
+
/** Build an adapter instance for one role-branded connection. */
|
|
370
|
+
create<Role extends ConnectionRole>(config: ConnectionConfig<Role>): DatabaseAdapter<Role> | Promise<DatabaseAdapter<Role>>;
|
|
371
|
+
/** Build the CRUD query port for a data-role connection (08 §3.7). */
|
|
372
|
+
createQueryEngine(config: DataConnectionConfig): QueryEngine | Promise<QueryEngine>;
|
|
373
|
+
}
|
|
374
|
+
/** The process-wide registry the server boot sequence populates. */
|
|
375
|
+
export declare const adapterRegistry: AdapterRegistry<AdapterProvider>;
|
|
376
|
+
/** Convenience wrapper over {@link adapterRegistry}.register. */
|
|
377
|
+
export declare function registerAdapter(provider: AdapterProvider): void;
|
|
378
|
+
export declare function registerAdapter(dialect: Dialect, factory: Omit<AdapterProvider, 'dialect'>): void;
|
|
379
|
+
/** Convenience wrapper over {@link adapterRegistry}.get. */
|
|
380
|
+
export declare function getAdapter(dialect: Dialect): AdapterProvider;
|
|
381
|
+
export * from './schema-model.js';
|
|
382
|
+
export * from './capabilities.js';
|
|
383
|
+
export * from './adapter-registry.js';
|
|
384
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMlG;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,IAAI,SAAS,cAAc,GAAG,cAAc;IAC5E,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IACzC,mEAAmE;IACnE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,MAAM,0BAA0B,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACxE,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAM5D,kCAAkC;AAClC,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,mBAAmB,CAAC;IAClC,UAAU,EAAE,cAAc,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;CAClD;AAMD,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,uFAAuF;IACvF,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;IACnE,wEAAwE;IACxE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oCAAoC;IACpC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAChB,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,aAAa,GACb,WAAW,GACX,SAAS,GACT,SAAS,GACT,aAAa,CAAC;AAElB,kFAAkF;AAClF,MAAM,MAAM,UAAU,GAClB;IAAE,GAAG,EAAE,UAAU,EAAE,CAAA;CAAE,GACrB;IAAE,EAAE,EAAE,UAAU,EAAE,CAAA;CAAE,GACpB;IAAE,GAAG,EAAE,UAAU,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtD,kFAAkF;AAClF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,QAAQ,CAAC;IAChB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE;QAAE,EAAE,EAAE,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5F,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG;QAAE,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAC5E,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,EAAE,CAAC;IACpD,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,kFAAkF;IAClF,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,SAAS,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CACzB;AAED,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;CACzC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,KAAK,EAAE,IAAI,CAAC;IACZ,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;CACzC;AAOD;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;IACzB,uEAAuE;IACvE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QAAE,kBAAkB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,+EAA+E;AAC/E,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE3D,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,qEAAqE;IACrE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;OAIG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;CAC9B;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,kFAAkF;IAClF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,4EAA4E;IAC5E,aAAa,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,+EAA+E;IAC/E,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,sEAAsE;AACtE,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAC9C,oFAAoF;AACpF,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAC7C,mGAAmG;AACnG,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAMlD,uEAAuE;AACvE,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAC9B,yFAAyF;IACzF,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,WAAW,EAAE;QAAE,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;IAC1D,qCAAqC;IACrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,0EAA0E;AAC1E,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC;AAMpC;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe,CAAC,IAAI,SAAS,cAAc,GAAG,cAAc;IAC3E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAEpB,wDAAwD;IACxD,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5B,yEAAyE;IACzE,iBAAiB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAEpD,0EAA0E;IAC1E,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAElG,mEAAmE;IACnE,KAAK,CACH,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAC7B,KAAK,EAAE,QAAQ,EACf,MAAM,CAAC,EAAE,UAAU,EACnB,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GACtB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/C,iGAAiG;IACjG,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5F,uEAAuE;IACvE,YAAY,CAAC,CACX,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAC7B,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACtB,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5E,4DAA4D;IAC5D,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEnF;;;;;;;;OAQG;IACH,iBAAiB,CACf,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAC7B,KAAK,EAAE,QAAQ,EACf,IAAI,CAAC,EAAE,mBAAmB,GACzB,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB,yCAAyC;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;AAC9D,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;AAElD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,iEAAiE;IACjE,MAAM,CAAC,IAAI,SAAS,cAAc,EAChC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAC7B,eAAe,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,sEAAsE;IACtE,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,GAAG,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACrF;AAMD,oEAAoE;AACpE,eAAO,MAAM,eAAe,kCAAyC,CAAC;AAEtE,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;AACjE,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC;AAenG,4DAA4D;AAC5D,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAE5D;AAKD,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC"}
|
package/dist/adapter.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `DatabaseAdapter` contract — 05-introspection-engine.md §3, with the
|
|
3
|
+
* three-connection privilege model of 01-architecture.md §3.
|
|
4
|
+
*
|
|
5
|
+
* `@adminium/engine` defines this interface but never imports adapter
|
|
6
|
+
* packages; `@adminium/server` composes concrete adapters at boot through
|
|
7
|
+
* the registry (01-architecture.md §2.3.1, ./adapter-registry.ts). Adapter
|
|
8
|
+
* packages (`@adminium/adapter-postgres`, …) import ONLY
|
|
9
|
+
* `@adminium/engine/adapter` — this module — which re-exports the
|
|
10
|
+
* SchemaModel types they need.
|
|
11
|
+
*
|
|
12
|
+
* THE "SCHEMA ONLY" INVARIANT (05 §10): `introspect()` reads catalog
|
|
13
|
+
* metadata exclusively — never user rows. Row-touching methods (`sample`,
|
|
14
|
+
* `sampleColumn`, `query`, `mutate`, `count`) exist only on the post-setup
|
|
15
|
+
* `data`-role instance and are compile-time blocked on the `introspect`
|
|
16
|
+
* instance via `this` typing on the role-branded interface below (plus a
|
|
17
|
+
* runtime guard every implementation must add — tested by the shared
|
|
18
|
+
* adapter test kit, 05-T02).
|
|
19
|
+
*/
|
|
20
|
+
import { AdapterRegistry } from './adapter-registry.js';
|
|
21
|
+
/** Default cap on most-common sampled values per column (06 §4.2). */
|
|
22
|
+
export const STATS_DEFAULT_SAMPLE_VALUES = 20;
|
|
23
|
+
/** Sampled string values are truncated at this many characters (mirrors 05 §10). */
|
|
24
|
+
export const STATS_SAMPLE_VALUE_MAX_CHARS = 256;
|
|
25
|
+
/** Default row-count ceiling for full-scan null/distinct aggregates (06 §4.2). */
|
|
26
|
+
export const STATS_MAX_SCAN_ROWS = 1_000_000;
|
|
27
|
+
/** At/below this estimate an adapter prefers an exact COUNT(*) over a stale estimate (06 §4.2). */
|
|
28
|
+
export const STATS_EXACT_COUNT_THRESHOLD = 50_000;
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Registry binding (01-architecture.md §2.3.1)
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/** The process-wide registry the server boot sequence populates. */
|
|
33
|
+
export const adapterRegistry = new AdapterRegistry();
|
|
34
|
+
export function registerAdapter(providerOrDialect, factory) {
|
|
35
|
+
if (typeof providerOrDialect === 'string') {
|
|
36
|
+
if (factory === undefined) {
|
|
37
|
+
throw new Error('registerAdapter(dialect, factory) requires a factory');
|
|
38
|
+
}
|
|
39
|
+
adapterRegistry.register({ dialect: providerOrDialect, ...factory });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
adapterRegistry.register(providerOrDialect);
|
|
43
|
+
}
|
|
44
|
+
/** Convenience wrapper over {@link adapterRegistry}.get. */
|
|
45
|
+
export function getAdapter(dialect) {
|
|
46
|
+
return adapterRegistry.get(dialect);
|
|
47
|
+
}
|
|
48
|
+
// The './adapter' subpath is the single entry point adapter packages may
|
|
49
|
+
// import (dep-cruiser matrix, 01-architecture.md §2.3) — re-export the
|
|
50
|
+
// SchemaModel types, the capability matrix and the registry mechanics here.
|
|
51
|
+
export * from './schema-model.js';
|
|
52
|
+
export * from './capabilities.js';
|
|
53
|
+
export * from './adapter-registry.js';
|
|
54
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAqRxD,sEAAsE;AACtE,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAC9C,oFAAoF;AACpF,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAChD,kFAAkF;AAClF,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAC7C,mGAAmG;AACnG,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC;AAyHlD,8EAA8E;AAC9E,+CAA+C;AAC/C,8EAA8E;AAE9E,oEAAoE;AACpE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,eAAe,EAAmB,CAAC;AAKtE,MAAM,UAAU,eAAe,CAC7B,iBAA4C,EAC5C,OAA0C;IAE1C,IAAI,OAAO,iBAAiB,KAAK,QAAQ,EAAE,CAAC;QAC1C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,eAAe,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IACD,eAAe,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAC9C,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,yEAAyE;AACzE,uEAAuE;AACvE,4EAA4E;AAC5E,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-engine capability matrix — 05-introspection-engine.md §2.1/§4,
|
|
3
|
+
* research/gap-analysis.md §2.1 (M9-T04).
|
|
4
|
+
*
|
|
5
|
+
* The canonical static dialect-level `AdapterCapabilities` per source engine.
|
|
6
|
+
* Adapter packages re-export their slice (`POSTGRES_CAPABILITIES` etc. are
|
|
7
|
+
* `ENGINE_CAPABILITY_MATRIX.<dialect>`) so the wizard, the remap editor, and
|
|
8
|
+
* the adapters all degrade from the SAME facts; per-connection probes refine
|
|
9
|
+
* these at runtime (e.g. MariaDB 10.5+ RETURNING) but never contradict the
|
|
10
|
+
* static shape shown during setup.
|
|
11
|
+
*
|
|
12
|
+
* Alongside the raw flags, this module derives DEGRADATION NOTES — stable
|
|
13
|
+
* codes for the honesty copy Studio shows ("MySQL row counts are estimates",
|
|
14
|
+
* "SQLite enums are synthesized from CHECK constraints", "schema files have
|
|
15
|
+
* no live health"). Codes, not copy: user-facing text lives behind the
|
|
16
|
+
* dashboard's i18n layer.
|
|
17
|
+
*/
|
|
18
|
+
import type { AdapterCapabilities } from './schema-model.js';
|
|
19
|
+
/** Engines a live connection can use ('generic' is import-only). */
|
|
20
|
+
export declare const SOURCE_ENGINES: readonly ["postgres", "mysql", "sqlite"];
|
|
21
|
+
export type SourceEngine = (typeof SOURCE_ENGINES)[number];
|
|
22
|
+
/**
|
|
23
|
+
* Where a model's metadata came from, for degradation purposes: a live
|
|
24
|
+
* engine connection or a parsed schema file (no live database at all).
|
|
25
|
+
*/
|
|
26
|
+
export type CapabilitySource = {
|
|
27
|
+
kind: 'live';
|
|
28
|
+
engine: SourceEngine;
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'import';
|
|
31
|
+
};
|
|
32
|
+
/** The matrix (gap-analysis §2.1): one column per live engine. */
|
|
33
|
+
export declare const ENGINE_CAPABILITY_MATRIX: Readonly<Record<SourceEngine, AdapterCapabilities>>;
|
|
34
|
+
/** Import baseline (see above) — exported for parsers and the wizard. */
|
|
35
|
+
export declare const IMPORT_BASE_CAPABILITIES: AdapterCapabilities;
|
|
36
|
+
/** Static capabilities for a source (live engine column or import baseline). */
|
|
37
|
+
export declare function capabilitiesForSource(source: CapabilitySource): AdapterCapabilities;
|
|
38
|
+
/**
|
|
39
|
+
* Stable degradation-note codes. The dashboard maps each to translated copy;
|
|
40
|
+
* anything not listed for a source needs no caveat there.
|
|
41
|
+
*/
|
|
42
|
+
export declare const CAPABILITY_NOTE_CODES: readonly ["mysql-approximate-row-estimates", "mysql-weaker-fk-enum-metadata", "sqlite-check-enum-synthesis", "sqlite-no-comments", "import-no-row-counts", "import-no-live-health"];
|
|
43
|
+
export type CapabilityNoteCode = (typeof CAPABILITY_NOTE_CODES)[number];
|
|
44
|
+
/**
|
|
45
|
+
* Degradation notes for a source, derived from the matrix flags where the
|
|
46
|
+
* flags express the fact, with the per-engine specials (estimate drift,
|
|
47
|
+
* MyISAM) keyed explicitly. Order = display order.
|
|
48
|
+
*/
|
|
49
|
+
export declare function capabilityNotesForSource(source: CapabilitySource): CapabilityNoteCode[];
|
|
50
|
+
/**
|
|
51
|
+
* How trustworthy `rowCountEstimate` is for a source — drives the wizard's
|
|
52
|
+
* row-count column: 'estimate' renders plain, 'approximate' with a leading ≈,
|
|
53
|
+
* 'none' as an em-dash with an explanation (never wrong data).
|
|
54
|
+
*/
|
|
55
|
+
export type RowEstimateQuality = 'estimate' | 'approximate' | 'none';
|
|
56
|
+
export declare function rowEstimateQualityForSource(source: CapabilitySource): RowEstimateQuality;
|
|
57
|
+
//# sourceMappingURL=capabilities.d.ts.map
|