@objectstack/service-datasource 10.2.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -523,7 +523,100 @@ declare class DatasourceAdminServicePlugin implements Plugin {
523
523
  * lazily so a host that never builds (e.g.) a mongo connection doesn't pay for
524
524
  * the mongo SDK.
525
525
  */
526
- declare function createDefaultDatasourceDriverFactory(): IDatasourceDriverFactory;
526
+ interface DefaultDatasourceDriverFactoryOptions {
527
+ /**
528
+ * Enables the dev-only native-`better-sqlite3` → wasm → in-memory step-down
529
+ * for sqlite construction (#2229). When omitted, defaults per call to
530
+ * `process.env.NODE_ENV === 'development'`. In production a native load
531
+ * failure is NOT silently swapped for a different engine (fail-closed).
532
+ */
533
+ dev?: boolean;
534
+ }
535
+ declare function createDefaultDatasourceDriverFactory(options?: DefaultDatasourceDriverFactoryOptions): IDatasourceDriverFactory;
536
+
537
+ /**
538
+ * Shared native-`better-sqlite3` → wasm SQLite → in-memory step-down for any
539
+ * sqlite-via-`better-sqlite3` construction (issue #2229).
540
+ *
541
+ * ## Why a probe is necessary
542
+ *
543
+ * `better-sqlite3` loads its native `.node` addon LAZILY — not at
544
+ * `require('better-sqlite3')`, and not even at knex construction, but at the
545
+ * first pool-connection acquire (`new Database(file)`), i.e. the first query.
546
+ * So an ABI mismatch (a cached prebuilt binary built for a different Node
547
+ * version — `NODE_MODULE_VERSION` mismatch) is invisible at boot and only
548
+ * surfaces much later as a runtime `Find operation failed` on the first read.
549
+ *
550
+ * This helper makes the failure observable up-front by actively probing: it
551
+ * opens a connection and runs a cheap `SELECT 1`, which forces the native addon
552
+ * to load. (`connect()` alone is NOT a reliable probe: for SQLite it only runs
553
+ * `mkdir` + a `PRAGMA` whose error is swallowed internally — so we additionally
554
+ * issue a raw `SELECT 1`, which propagates the load error.) On failure it steps
555
+ * down:
556
+ *
557
+ * 1. native `better-sqlite3` — fast, real SQL
558
+ * 2. wasm SQLite — pure-JS, real SQL + on-disk persistence, slower [dev only]
559
+ * 3. in-memory (mingo) — neither real SQL nor persistent [dev only, last resort]
560
+ *
561
+ * ## Dev vs production
562
+ *
563
+ * The wasm + in-memory step-down is GATED to dev. In production a native load
564
+ * failure is NOT silently swapped for a different engine: the error is re-thrown
565
+ * so it surfaces loudly (fail-closed) instead of an operator unknowingly running
566
+ * on wasm/mingo. This mirrors the existing `serve.ts` default-dev fallback and
567
+ * hoists it into one place shared by every sqlite construction site.
568
+ */
569
+ /** Which engine the resolver ultimately produced. */
570
+ type SqliteFallbackEngine = 'better-sqlite3' | 'sqlite-wasm' | 'memory';
571
+ interface ResolveSqliteDriverOptions {
572
+ /**
573
+ * SQLite filename — `:memory:` for an ephemeral database, or an absolute /
574
+ * relative path for a persistent file. Preserved across the wasm fallback so
575
+ * a persistent `file:` database keeps its on-disk persistence through wasm.
576
+ * Pass the raw filename (callers strip any `file:` / `sqlite:` scheme first).
577
+ */
578
+ filename: string;
579
+ /**
580
+ * Gates the wasm + in-memory step-down. When `true` (dev) a native ABI/load
581
+ * failure steps down the chain with a warning. When `false` (production) the
582
+ * native driver is returned unprobed so a failure surfaces loudly at first use
583
+ * (fail-closed) — we never silently degrade behind the operator's back.
584
+ * Defaults to `process.env.NODE_ENV === 'development'`.
585
+ */
586
+ dev?: boolean;
587
+ /** Forwarded to the native SqlDriver (dev loosen-only self-heal, #2186). */
588
+ autoMigrate?: 'off' | 'safe';
589
+ /** Forwarded to the SQL drivers (external schema mode, ADR-0015). */
590
+ schemaMode?: string;
591
+ /**
592
+ * Warning sink for the step-down messages. Defaults to `console.warn`.
593
+ * `serve.ts` passes a `chalk.yellow` wrapper so the banner stays consistent.
594
+ */
595
+ warn?: (message: string) => void;
596
+ }
597
+ interface ResolvedSqliteDriver {
598
+ /** The concrete engine driver to register (e.g. via `DriverPlugin`). */
599
+ driver: any;
600
+ /** Which engine actually resolved. */
601
+ engine: SqliteFallbackEngine;
602
+ /** Banner label, matching `serve.ts`'s existing strings. */
603
+ label: string;
604
+ }
605
+ /**
606
+ * Warning emitted when native `better-sqlite3` is unavailable but wasm SQLite
607
+ * loads. Kept byte-for-byte identical to the original `serve.ts` text so the
608
+ * dev experience is the same regardless of which construction site triggers it.
609
+ */
610
+ declare const NATIVE_SQLITE_WASM_FALLBACK_WARNING: string;
611
+ /** Warning emitted when neither native nor wasm SQLite loads (dev last resort). */
612
+ declare const NATIVE_SQLITE_MEMORY_FALLBACK_WARNING: string;
613
+ /**
614
+ * Probe a `better-sqlite3` SQLite construction and, in dev, step down to wasm
615
+ * SQLite (then in-memory) when the native addon cannot load.
616
+ *
617
+ * @see {@link ResolveSqliteDriverOptions}
618
+ */
619
+ declare function resolveSqliteDriver(opts: ResolveSqliteDriverOptions): Promise<ResolvedSqliteDriver>;
527
620
 
528
621
  /**
529
622
  * Default datasource SecretBinder — persists a runtime datasource's cleartext
@@ -611,4 +704,4 @@ declare function createDatasourceSecretBinder(deps: DatasourceSecretBinderDeps):
611
704
  */
612
705
  declare function registerDatasourceAdminRoutes(server: IHttpServer, ctx: PluginContext, basePath?: string): void;
613
706
 
614
- export { type ConnectResult, type ConnectStatus, type ConnectableDatasource, type ConnectionEngineLike, type ConnectionSecretResolver, DatasourceAdminService, type DatasourceAdminServiceConfig, DatasourceAdminServicePlugin, type DatasourceAdminServicePluginOptions, type DatasourceBoundObject, DatasourceConnectContext, DatasourceConnectPolicy, DatasourceConnectionService, type DatasourceConnectionServiceConfig, DatasourceDraft, type DatasourceLike, type DatasourceSecretBinder, type DatasourceSecretBinderDeps, DatasourceSummary, ExternalDatasourceService, type ExternalDatasourceServiceConfig, ExternalDatasourceServicePlugin, type ExternalDatasourceServicePluginOptions, IDatasourceAdminService, IDatasourceDriverFactory, type Logger$1 as Logger, type ObjectLike, type ProbeInput, type SecretBinder, SecretInput, type SecretStoreEngineLike, type StoredDatasource, TestConnectionResult, createDatasourceSecretBinder, createDefaultDatasourceDriverFactory, isDatasourceAddressed, parseCredentialsRef, registerDatasourceAdminRoutes, toCredentialsRef };
707
+ export { type ConnectResult, type ConnectStatus, type ConnectableDatasource, type ConnectionEngineLike, type ConnectionSecretResolver, DatasourceAdminService, type DatasourceAdminServiceConfig, DatasourceAdminServicePlugin, type DatasourceAdminServicePluginOptions, type DatasourceBoundObject, DatasourceConnectContext, DatasourceConnectPolicy, DatasourceConnectionService, type DatasourceConnectionServiceConfig, DatasourceDraft, type DatasourceLike, type DatasourceSecretBinder, type DatasourceSecretBinderDeps, DatasourceSummary, ExternalDatasourceService, type ExternalDatasourceServiceConfig, ExternalDatasourceServicePlugin, type ExternalDatasourceServicePluginOptions, IDatasourceAdminService, IDatasourceDriverFactory, type Logger$1 as Logger, NATIVE_SQLITE_MEMORY_FALLBACK_WARNING, NATIVE_SQLITE_WASM_FALLBACK_WARNING, type ObjectLike, type ProbeInput, type ResolveSqliteDriverOptions, type ResolvedSqliteDriver, type SecretBinder, SecretInput, type SecretStoreEngineLike, type SqliteFallbackEngine, type StoredDatasource, TestConnectionResult, createDatasourceSecretBinder, createDefaultDatasourceDriverFactory, isDatasourceAddressed, parseCredentialsRef, registerDatasourceAdminRoutes, resolveSqliteDriver, toCredentialsRef };
package/dist/index.d.ts CHANGED
@@ -523,7 +523,100 @@ declare class DatasourceAdminServicePlugin implements Plugin {
523
523
  * lazily so a host that never builds (e.g.) a mongo connection doesn't pay for
524
524
  * the mongo SDK.
525
525
  */
526
- declare function createDefaultDatasourceDriverFactory(): IDatasourceDriverFactory;
526
+ interface DefaultDatasourceDriverFactoryOptions {
527
+ /**
528
+ * Enables the dev-only native-`better-sqlite3` → wasm → in-memory step-down
529
+ * for sqlite construction (#2229). When omitted, defaults per call to
530
+ * `process.env.NODE_ENV === 'development'`. In production a native load
531
+ * failure is NOT silently swapped for a different engine (fail-closed).
532
+ */
533
+ dev?: boolean;
534
+ }
535
+ declare function createDefaultDatasourceDriverFactory(options?: DefaultDatasourceDriverFactoryOptions): IDatasourceDriverFactory;
536
+
537
+ /**
538
+ * Shared native-`better-sqlite3` → wasm SQLite → in-memory step-down for any
539
+ * sqlite-via-`better-sqlite3` construction (issue #2229).
540
+ *
541
+ * ## Why a probe is necessary
542
+ *
543
+ * `better-sqlite3` loads its native `.node` addon LAZILY — not at
544
+ * `require('better-sqlite3')`, and not even at knex construction, but at the
545
+ * first pool-connection acquire (`new Database(file)`), i.e. the first query.
546
+ * So an ABI mismatch (a cached prebuilt binary built for a different Node
547
+ * version — `NODE_MODULE_VERSION` mismatch) is invisible at boot and only
548
+ * surfaces much later as a runtime `Find operation failed` on the first read.
549
+ *
550
+ * This helper makes the failure observable up-front by actively probing: it
551
+ * opens a connection and runs a cheap `SELECT 1`, which forces the native addon
552
+ * to load. (`connect()` alone is NOT a reliable probe: for SQLite it only runs
553
+ * `mkdir` + a `PRAGMA` whose error is swallowed internally — so we additionally
554
+ * issue a raw `SELECT 1`, which propagates the load error.) On failure it steps
555
+ * down:
556
+ *
557
+ * 1. native `better-sqlite3` — fast, real SQL
558
+ * 2. wasm SQLite — pure-JS, real SQL + on-disk persistence, slower [dev only]
559
+ * 3. in-memory (mingo) — neither real SQL nor persistent [dev only, last resort]
560
+ *
561
+ * ## Dev vs production
562
+ *
563
+ * The wasm + in-memory step-down is GATED to dev. In production a native load
564
+ * failure is NOT silently swapped for a different engine: the error is re-thrown
565
+ * so it surfaces loudly (fail-closed) instead of an operator unknowingly running
566
+ * on wasm/mingo. This mirrors the existing `serve.ts` default-dev fallback and
567
+ * hoists it into one place shared by every sqlite construction site.
568
+ */
569
+ /** Which engine the resolver ultimately produced. */
570
+ type SqliteFallbackEngine = 'better-sqlite3' | 'sqlite-wasm' | 'memory';
571
+ interface ResolveSqliteDriverOptions {
572
+ /**
573
+ * SQLite filename — `:memory:` for an ephemeral database, or an absolute /
574
+ * relative path for a persistent file. Preserved across the wasm fallback so
575
+ * a persistent `file:` database keeps its on-disk persistence through wasm.
576
+ * Pass the raw filename (callers strip any `file:` / `sqlite:` scheme first).
577
+ */
578
+ filename: string;
579
+ /**
580
+ * Gates the wasm + in-memory step-down. When `true` (dev) a native ABI/load
581
+ * failure steps down the chain with a warning. When `false` (production) the
582
+ * native driver is returned unprobed so a failure surfaces loudly at first use
583
+ * (fail-closed) — we never silently degrade behind the operator's back.
584
+ * Defaults to `process.env.NODE_ENV === 'development'`.
585
+ */
586
+ dev?: boolean;
587
+ /** Forwarded to the native SqlDriver (dev loosen-only self-heal, #2186). */
588
+ autoMigrate?: 'off' | 'safe';
589
+ /** Forwarded to the SQL drivers (external schema mode, ADR-0015). */
590
+ schemaMode?: string;
591
+ /**
592
+ * Warning sink for the step-down messages. Defaults to `console.warn`.
593
+ * `serve.ts` passes a `chalk.yellow` wrapper so the banner stays consistent.
594
+ */
595
+ warn?: (message: string) => void;
596
+ }
597
+ interface ResolvedSqliteDriver {
598
+ /** The concrete engine driver to register (e.g. via `DriverPlugin`). */
599
+ driver: any;
600
+ /** Which engine actually resolved. */
601
+ engine: SqliteFallbackEngine;
602
+ /** Banner label, matching `serve.ts`'s existing strings. */
603
+ label: string;
604
+ }
605
+ /**
606
+ * Warning emitted when native `better-sqlite3` is unavailable but wasm SQLite
607
+ * loads. Kept byte-for-byte identical to the original `serve.ts` text so the
608
+ * dev experience is the same regardless of which construction site triggers it.
609
+ */
610
+ declare const NATIVE_SQLITE_WASM_FALLBACK_WARNING: string;
611
+ /** Warning emitted when neither native nor wasm SQLite loads (dev last resort). */
612
+ declare const NATIVE_SQLITE_MEMORY_FALLBACK_WARNING: string;
613
+ /**
614
+ * Probe a `better-sqlite3` SQLite construction and, in dev, step down to wasm
615
+ * SQLite (then in-memory) when the native addon cannot load.
616
+ *
617
+ * @see {@link ResolveSqliteDriverOptions}
618
+ */
619
+ declare function resolveSqliteDriver(opts: ResolveSqliteDriverOptions): Promise<ResolvedSqliteDriver>;
527
620
 
528
621
  /**
529
622
  * Default datasource SecretBinder — persists a runtime datasource's cleartext
@@ -611,4 +704,4 @@ declare function createDatasourceSecretBinder(deps: DatasourceSecretBinderDeps):
611
704
  */
612
705
  declare function registerDatasourceAdminRoutes(server: IHttpServer, ctx: PluginContext, basePath?: string): void;
613
706
 
614
- export { type ConnectResult, type ConnectStatus, type ConnectableDatasource, type ConnectionEngineLike, type ConnectionSecretResolver, DatasourceAdminService, type DatasourceAdminServiceConfig, DatasourceAdminServicePlugin, type DatasourceAdminServicePluginOptions, type DatasourceBoundObject, DatasourceConnectContext, DatasourceConnectPolicy, DatasourceConnectionService, type DatasourceConnectionServiceConfig, DatasourceDraft, type DatasourceLike, type DatasourceSecretBinder, type DatasourceSecretBinderDeps, DatasourceSummary, ExternalDatasourceService, type ExternalDatasourceServiceConfig, ExternalDatasourceServicePlugin, type ExternalDatasourceServicePluginOptions, IDatasourceAdminService, IDatasourceDriverFactory, type Logger$1 as Logger, type ObjectLike, type ProbeInput, type SecretBinder, SecretInput, type SecretStoreEngineLike, type StoredDatasource, TestConnectionResult, createDatasourceSecretBinder, createDefaultDatasourceDriverFactory, isDatasourceAddressed, parseCredentialsRef, registerDatasourceAdminRoutes, toCredentialsRef };
707
+ export { type ConnectResult, type ConnectStatus, type ConnectableDatasource, type ConnectionEngineLike, type ConnectionSecretResolver, DatasourceAdminService, type DatasourceAdminServiceConfig, DatasourceAdminServicePlugin, type DatasourceAdminServicePluginOptions, type DatasourceBoundObject, DatasourceConnectContext, DatasourceConnectPolicy, DatasourceConnectionService, type DatasourceConnectionServiceConfig, DatasourceDraft, type DatasourceLike, type DatasourceSecretBinder, type DatasourceSecretBinderDeps, DatasourceSummary, ExternalDatasourceService, type ExternalDatasourceServiceConfig, ExternalDatasourceServicePlugin, type ExternalDatasourceServicePluginOptions, IDatasourceAdminService, IDatasourceDriverFactory, type Logger$1 as Logger, NATIVE_SQLITE_MEMORY_FALLBACK_WARNING, NATIVE_SQLITE_WASM_FALLBACK_WARNING, type ObjectLike, type ProbeInput, type ResolveSqliteDriverOptions, type ResolvedSqliteDriver, type SecretBinder, SecretInput, type SecretStoreEngineLike, type SqliteFallbackEngine, type StoredDatasource, TestConnectionResult, createDatasourceSecretBinder, createDefaultDatasourceDriverFactory, isDatasourceAddressed, parseCredentialsRef, registerDatasourceAdminRoutes, resolveSqliteDriver, toCredentialsRef };
package/dist/index.js CHANGED
@@ -1,6 +1,11 @@
1
1
  import {
2
2
  allowAllConnectPolicy
3
3
  } from "./chunk-XLS4RP7B.js";
4
+ import {
5
+ NATIVE_SQLITE_MEMORY_FALLBACK_WARNING,
6
+ NATIVE_SQLITE_WASM_FALLBACK_WARNING,
7
+ resolveSqliteDriver
8
+ } from "./chunk-JRBGOCRJ.js";
4
9
 
5
10
  // src/external-datasource-service.ts
6
11
  import {
@@ -1114,7 +1119,7 @@ function buildMongoUrl(spec) {
1114
1119
  const auth = user ? `${encodeURIComponent(user)}:${encodeURIComponent(spec.secret ?? "")}@` : "";
1115
1120
  return `mongodb://${auth}${host}:${port}/${db}`;
1116
1121
  }
1117
- function createDefaultDatasourceDriverFactory() {
1122
+ function createDefaultDatasourceDriverFactory(options = {}) {
1118
1123
  return {
1119
1124
  supports(driverId) {
1120
1125
  return resolveKind(driverId) !== void 0;
@@ -1136,14 +1141,14 @@ function createDefaultDatasourceDriverFactory() {
1136
1141
  return toHandle(driver, () => sqlServerVersion(driver, "pg"));
1137
1142
  }
1138
1143
  if (kind === "sqlite") {
1139
- const { SqlDriver } = await import("@objectstack/driver-sql");
1140
- const driver = new SqlDriver({
1141
- client: "better-sqlite3",
1142
- connection: buildSqlConnection(spec, "better-sqlite3"),
1143
- useNullAsDefault: true,
1144
+ const conn = buildSqlConnection(spec, "better-sqlite3");
1145
+ const { resolveSqliteDriver: resolveSqliteDriver2 } = await import("./sqlite-driver-fallback-BPFQYLX7.js");
1146
+ const resolved = await resolveSqliteDriver2({
1147
+ filename: conn.filename ?? ":memory:",
1148
+ dev: options.dev,
1144
1149
  ...schemaMode ? { schemaMode } : {}
1145
1150
  });
1146
- return toHandle(driver, () => sqlServerVersion(driver, "sqlite"));
1151
+ return toHandle(resolved.driver, () => sqlServerVersion(resolved.driver, "sqlite"));
1147
1152
  }
1148
1153
  if (kind === "mongodb") {
1149
1154
  let MongoDBDriver;
@@ -1450,12 +1455,15 @@ export {
1450
1455
  DatasourceConnectionService,
1451
1456
  ExternalDatasourceService,
1452
1457
  ExternalDatasourceServicePlugin,
1458
+ NATIVE_SQLITE_MEMORY_FALLBACK_WARNING,
1459
+ NATIVE_SQLITE_WASM_FALLBACK_WARNING,
1453
1460
  allowAllConnectPolicy,
1454
1461
  createDatasourceSecretBinder,
1455
1462
  createDefaultDatasourceDriverFactory,
1456
1463
  isDatasourceAddressed,
1457
1464
  parseCredentialsRef,
1458
1465
  registerDatasourceAdminRoutes,
1466
+ resolveSqliteDriver,
1459
1467
  toCredentialsRef
1460
1468
  };
1461
1469
  //# sourceMappingURL=index.js.map