@fougere/adapter-sql 0.12.6-alpha.0 → 0.13.1-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.
@@ -1 +1 @@
1
- {"version":3,"file":"Dialect.d.ts","sourceRoot":"","sources":["../../src/dialect/Dialect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,WAAW,CAAC;IAClB,6BAA6B;IAC7B,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACtD;;;OAGG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,sFAAsF;IACtF,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,MAAM,EAAE,aAAa,GAAG,kBAAkB,GAAG,KAAK,CAAC;IACnD,oEAAoE;IACpE,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CAC5C;AAoBD,eAAO,MAAM,aAAa,EAAE,OAqB3B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,OA0BvB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,OAwB1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,OAwB1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAKjD,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAKzD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAEzF"}
1
+ {"version":3,"file":"Dialect.d.ts","sourceRoot":"","sources":["../../src/dialect/Dialect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,WAAW,CAAC;IAClB,6BAA6B;IAC7B,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACtD;;;OAGG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,sFAAsF;IACtF,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,MAAM,EAAE,aAAa,GAAG,kBAAkB,GAAG,KAAK,CAAC;IACnD,oEAAoE;IACpE,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CAC5C;AAoBD,eAAO,MAAM,aAAa,EAAE,OAqB3B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,OA4BvB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,OAwB1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,OAwB1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAKjD,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAKzD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAEzF"}
@@ -52,6 +52,8 @@ export const pgDialect = {
52
52
  return 'double precision';
53
53
  case 'boolean':
54
54
  return 'boolean';
55
+ case 'date':
56
+ return 'timestamptz';
55
57
  case 'object':
56
58
  case 'array':
57
59
  return 'jsonb';
@@ -1 +1 @@
1
- {"version":3,"file":"Dialect.js","sourceRoot":"","sources":["../../src/dialect/Dialect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Dialect.js","sourceRoot":"","sources":["../../src/dialect/Dialect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { type Dialect as KyselyDialect } from 'kysely';
2
+ import type { Engine } from '../fields/Engine.js';
3
+ /**
4
+ * The packages each engine opens with. The APP installs them, never this package, so a
5
+ * project that opens no SQL installs no driver — and nothing native.
6
+ *
7
+ * Documented: [sources](https://fougere.dev/docs/infra/sources).
8
+ */
9
+ export declare const PACKAGES: Record<Engine, string[]>;
10
+ /** The Kysely dialect an engine builds from a url, over its packages. SQLite opens a path. */
11
+ export type Driver = (url: string, modules: any[]) => KyselyDialect;
12
+ export declare const DRIVERS: Record<Exclude<Engine, 'sqlite'>, Driver>;
13
+ /**
14
+ * The packages of `engine`, resolved from the app — loaded at the moment it opens, not before.
15
+ * What is not installed and what is installed but will not load are two refusals, and each
16
+ * names what to do.
17
+ */
18
+ export declare function modulesOf(engine: Engine, from?: string): any[];
19
+ export declare function messageOf(error: unknown): string;
20
+ /** The dialect `url` names, over the driver the app installed beside it. */
21
+ export declare function dialectFor(engine: Exclude<Engine, 'sqlite'>, url: string, from?: string): KyselyDialect;
22
+ /** `mssql://user:password@host:1433/database` — tedious takes an object and reads no url. */
23
+ export declare function tediousConfig(url: string): {
24
+ server: string;
25
+ authentication: {
26
+ type: string;
27
+ options: {
28
+ userName: string;
29
+ password: string;
30
+ };
31
+ };
32
+ options: {
33
+ port: number;
34
+ database: string | undefined;
35
+ trustServerCertificate: boolean;
36
+ };
37
+ };
38
+ //# sourceMappingURL=Driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Driver.d.ts","sourceRoot":"","sources":["../../src/driver/Driver.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+C,KAAK,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAC;AACpG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAK7C,CAAC;AAEF,8FAA8F;AAC9F,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,aAAa,CAAC;AAEpE,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAO7D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,SAAgB,GAAG,GAAG,EAAE,CAqBrE;AAgBD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,SAAgB,GAAG,aAAa,CAE9G;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM;;;;;YAM1B,QAAQ;YAAuC,QAAQ;;;;;;;;EAIrE"}
@@ -0,0 +1,76 @@
1
+ import { createRequire } from 'node:module';
2
+ import { join } from 'node:path';
3
+ import { MssqlDialect, MysqlDialect, PostgresDialect } from 'kysely';
4
+ /**
5
+ * The packages each engine opens with. The APP installs them, never this package, so a
6
+ * project that opens no SQL installs no driver — and nothing native.
7
+ *
8
+ * Documented: [sources](https://fougere.dev/docs/infra/sources).
9
+ */
10
+ export const PACKAGES = {
11
+ sqlite: ['better-sqlite3'],
12
+ pg: ['pg'],
13
+ mysql: ['mysql2'],
14
+ mssql: ['tedious', 'tarn'],
15
+ };
16
+ export const DRIVERS = {
17
+ pg: (url, [pg]) => new PostgresDialect({ pool: new pg.Pool({ connectionString: url }) }),
18
+ mysql: (url, [mysql]) => new MysqlDialect({ pool: mysql.createPool(url) }),
19
+ mssql: (url, [tedious, tarn]) => new MssqlDialect({
20
+ tarn: { ...tarn, options: { min: 0, max: 10 } },
21
+ tedious: { ...tedious, connectionFactory: () => new tedious.Connection(tediousConfig(url)) },
22
+ }),
23
+ };
24
+ /**
25
+ * The packages of `engine`, resolved from the app — loaded at the moment it opens, not before.
26
+ * What is not installed and what is installed but will not load are two refusals, and each
27
+ * names what to do.
28
+ */
29
+ export function modulesOf(engine, from = process.cwd()) {
30
+ const require = createRequire(join(from, 'package.json'));
31
+ const packages = PACKAGES[engine];
32
+ const missing = packages.filter((name) => !resolves(require, name));
33
+ if (missing.length) {
34
+ throw new Error(`The ${engine} engine opens through ${quoted(packages)}, and ${quoted(missing)} is not installed beside the app (${from}).\n`
35
+ + `Install it there: pnpm add ${missing.join(' ')}`);
36
+ }
37
+ return packages.map((name) => {
38
+ try {
39
+ return require(name);
40
+ }
41
+ catch (error) {
42
+ throw new Error(`The ${engine} engine opens through '${name}', which is installed beside the app (${from}) but does not load: ${messageOf(error)}`, { cause: error });
43
+ }
44
+ });
45
+ }
46
+ function resolves(require, name) {
47
+ try {
48
+ require.resolve(name);
49
+ return true;
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ }
55
+ function quoted(names) {
56
+ return names.map((name) => `'${name}'`).join(' and ');
57
+ }
58
+ export function messageOf(error) {
59
+ return error instanceof Error ? error.message.split('\n')[0] : String(error);
60
+ }
61
+ /** The dialect `url` names, over the driver the app installed beside it. */
62
+ export function dialectFor(engine, url, from = process.cwd()) {
63
+ return DRIVERS[engine](url, modulesOf(engine, from));
64
+ }
65
+ /** `mssql://user:password@host:1433/database` — tedious takes an object and reads no url. */
66
+ export function tediousConfig(url) {
67
+ const parsed = new URL(url);
68
+ const port = parsed.port ? Number(parsed.port) : 1433;
69
+ const database = decodeURIComponent(parsed.pathname.slice(1)) || undefined;
70
+ const authentication = {
71
+ type: 'default',
72
+ options: { userName: decodeURIComponent(parsed.username), password: decodeURIComponent(parsed.password) },
73
+ };
74
+ return { server: parsed.hostname, authentication, options: { port, database, trustServerCertificate: true } };
75
+ }
76
+ //# sourceMappingURL=Driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Driver.js","sourceRoot":"","sources":["../../src/driver/Driver.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import Database from 'better-sqlite3';
1
+ import type BetterSqlite from 'better-sqlite3';
2
2
  import { type SqlSource } from '../source/SqlSource.js';
3
3
  import type { SqliteSourceOptions } from './SqliteSourceOptions.js';
4
4
  export interface SqliteSource extends SqlSource {
5
5
  /** The raw handle, for pragmas and synchronous exec. */
6
- sqlite: Database.Database;
6
+ sqlite: BetterSqlite.Database;
7
7
  }
8
8
  export declare function createSqliteSource(opts?: SqliteSourceOptions): SqliteSource;
9
9
  //# sourceMappingURL=SqliteSource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SqliteSource.d.ts","sourceRoot":"","sources":["../../src/sqlite/SqliteSource.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAI9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,wDAAwD;IACxD,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CA6B/E"}
1
+ {"version":3,"file":"SqliteSource.d.ts","sourceRoot":"","sources":["../../src/sqlite/SqliteSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,YAAY,MAAM,gBAAgB,CAAC;AAI/C,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAMlG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,wDAAwD;IACxD,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC;CAC/B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CA6B/E"}
@@ -1,11 +1,12 @@
1
1
  import { mkdirSync } from 'node:fs';
2
2
  import { dirname } from 'node:path';
3
3
  import { Kysely, SqliteDialect } from 'kysely';
4
- import Database from 'better-sqlite3';
5
4
  import { createStorageFactory } from '../crud/SqlStorage.js';
6
5
  import { logQueries } from '../query/QuerySink.js';
7
6
  import { drift, driftReport } from '../drift.js';
8
- import { sqlEnforces, sqlSink } from '../source/SqlSource.js';
7
+ import { createKyselySource, sqlEnforces, sqlSink } from '../source/SqlSource.js';
8
+ import { DRIVERS, dialectFor, messageOf, modulesOf } from '../driver/Driver.js';
9
+ import { ENGINES } from '../fields/Engine.js';
9
10
  import { desiredTables, migrate } from '../diff/Change.js';
10
11
  import { toTableName } from '../table/TableDef.js';
11
12
  import { Sources } from '@fougere/core';
@@ -14,7 +15,7 @@ export function createSqliteSource(opts = {}) {
14
15
  // A file-backed DB needs its directory — SQLite won't create it.
15
16
  if (path !== ':memory:')
16
17
  mkdirSync(dirname(path), { recursive: true });
17
- const sqlite = new Database(path);
18
+ const sqlite = open(path);
18
19
  sqlite.pragma('journal_mode = WAL');
19
20
  sqlite.pragma('foreign_keys = ON');
20
21
  const db = new Kysely({ dialect: new SqliteDialect({ database: sqlite }), log: logQueries(opts.name ?? path) });
@@ -38,14 +39,42 @@ export function createSqliteSource(opts = {}) {
38
39
  transacted: (fn) => db.transaction().execute((trx) => fn(createStorageFactory(trx, opts.storageFactoryOptions, 'sqlite'))),
39
40
  };
40
41
  }
42
+ function open(path) {
43
+ const [Database] = modulesOf('sqlite');
44
+ try {
45
+ return new Database(path);
46
+ }
47
+ catch (error) {
48
+ throw new Error(unopened(error, path), { cause: error });
49
+ }
50
+ }
51
+ function unopened(error, path) {
52
+ const code = error.code;
53
+ const rebuild = 'Build it from its sources: cd node_modules/better-sqlite3 && npx node-gyp rebuild';
54
+ if (code === 'MODULE_NOT_FOUND' && messageOf(error).includes('better_sqlite3.node')) {
55
+ return `'better-sqlite3' ships no native binary for ${process.platform}-${process.arch} — its prebuilt ones cover `
56
+ + `linux, macOS and Windows on x64 and arm64. ${rebuild}`;
57
+ }
58
+ if (code === 'ERR_DLOPEN_FAILED') {
59
+ return `The native binary of 'better-sqlite3' does not load under Node ${process.version}: ${messageOf(error)}. ${rebuild}`;
60
+ }
61
+ return `SQLite could not open '${path}': ${messageOf(error)}`;
62
+ }
41
63
  /** `source. */
42
64
  Sources.register('sql', (conf) => {
43
65
  const dialect = conf.dialect;
44
- if (dialect !== undefined && dialect !== 'sqlite') {
45
- throw new Error(`source 'sql', dialect '${dialect}': cannot be built from a name — only 'sqlite' can, `
46
- + 'because it is the one driver this package owns. Build the Kysely dialect yourself and '
47
- + `call createKyselySource(dialect, '${dialect}'), then hand it in as a source.`);
66
+ const name = conf.name;
67
+ if (dialect === undefined || dialect === 'sqlite')
68
+ return createSqliteSource({ path: conf.path, name });
69
+ if (!isDriven(dialect)) {
70
+ throw new Error(`source 'sql': no dialect '${dialect}'. It answers ${ENGINES.join(', ')}.`);
48
71
  }
49
- return createSqliteSource({ path: conf.path, name: conf.name });
72
+ const url = conf.url;
73
+ if (typeof url !== 'string')
74
+ throw new Error(`source 'sql', dialect '${dialect}': states no \`url\`.`);
75
+ return createKyselySource(dialectFor(dialect, url), dialect, { name });
50
76
  });
77
+ function isDriven(dialect) {
78
+ return dialect in DRIVERS;
79
+ }
51
80
  //# sourceMappingURL=SqliteSource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SqliteSource.js","sourceRoot":"","sources":["../../src/sqlite/SqliteSource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SqliteSource.js","sourceRoot":"","sources":["../../src/sqlite/SqliteSource.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.12.6-alpha.0",
3
+ "version": "0.13.1-alpha.0",
4
4
  "description": "Entity → SQL tables through Kysely (SQLite, PostgreSQL, MySQL, SQL Server).",
5
5
  "keywords": [
6
6
  "fougere",
@@ -37,19 +37,19 @@
37
37
  "src"
38
38
  ],
39
39
  "dependencies": {
40
- "better-sqlite3": "^13.0.3",
41
- "dequal": "^2.0.3",
42
- "@fougere/core": "0.12.6-alpha.0",
43
- "@fougere/schema": "0.12.6-alpha.0"
40
+ "@fougere/core": "0.13.1-alpha.0",
41
+ "@fougere/schema": "0.13.1-alpha.0",
42
+ "dequal": "^2.0.3"
44
43
  },
45
44
  "peerDependencies": {
46
45
  "kysely": ">=0.28.17"
47
46
  },
48
47
  "devDependencies": {
48
+ "@fougere/core": "0.13.1-alpha.0",
49
+ "better-sqlite3": "^13.0.3",
49
50
  "@types/better-sqlite3": "^7.6.13",
50
51
  "@types/node": "^22.0.0",
51
- "kysely": "^0.28.17",
52
- "@fougere/core": "0.12.6-alpha.0"
52
+ "kysely": "^0.28.17"
53
53
  },
54
54
  "publishConfig": {
55
55
  "access": "public"
@@ -78,6 +78,8 @@ export const pgDialect: Dialect = {
78
78
  return 'double precision';
79
79
  case 'boolean':
80
80
  return 'boolean';
81
+ case 'date':
82
+ return 'timestamptz';
81
83
  case 'object':
82
84
  case 'array':
83
85
  return 'jsonb';
@@ -0,0 +1,93 @@
1
+ import { createRequire } from 'node:module';
2
+ import { join } from 'node:path';
3
+ import { MssqlDialect, MysqlDialect, PostgresDialect, type Dialect as KyselyDialect } from 'kysely';
4
+ import type { Engine } from '../fields/Engine.js';
5
+
6
+ /**
7
+ * The packages each engine opens with. The APP installs them, never this package, so a
8
+ * project that opens no SQL installs no driver — and nothing native.
9
+ *
10
+ * Documented: [sources](https://fougere.dev/docs/infra/sources).
11
+ */
12
+ export const PACKAGES: Record<Engine, string[]> = {
13
+ sqlite: ['better-sqlite3'],
14
+ pg: ['pg'],
15
+ mysql: ['mysql2'],
16
+ mssql: ['tedious', 'tarn'],
17
+ };
18
+
19
+ /** The Kysely dialect an engine builds from a url, over its packages. SQLite opens a path. */
20
+ export type Driver = (url: string, modules: any[]) => KyselyDialect;
21
+
22
+ export const DRIVERS: Record<Exclude<Engine, 'sqlite'>, Driver> = {
23
+ pg: (url, [pg]) => new PostgresDialect({ pool: new pg.Pool({ connectionString: url }) }),
24
+ mysql: (url, [mysql]) => new MysqlDialect({ pool: mysql.createPool(url) }),
25
+ mssql: (url, [tedious, tarn]) => new MssqlDialect({
26
+ tarn: { ...tarn, options: { min: 0, max: 10 } },
27
+ tedious: { ...tedious, connectionFactory: () => new tedious.Connection(tediousConfig(url)) },
28
+ }),
29
+ };
30
+
31
+ /**
32
+ * The packages of `engine`, resolved from the app — loaded at the moment it opens, not before.
33
+ * What is not installed and what is installed but will not load are two refusals, and each
34
+ * names what to do.
35
+ */
36
+ export function modulesOf(engine: Engine, from = process.cwd()): any[] {
37
+ const require = createRequire(join(from, 'package.json'));
38
+ const packages = PACKAGES[engine];
39
+ const missing = packages.filter((name) => !resolves(require, name));
40
+ if (missing.length) {
41
+ throw new Error(
42
+ `The ${engine} engine opens through ${quoted(packages)}, and ${quoted(missing)} is not installed beside the app (${from}).\n`
43
+ + `Install it there: pnpm add ${missing.join(' ')}`,
44
+ );
45
+ }
46
+
47
+ return packages.map((name) => {
48
+ try {
49
+ return require(name);
50
+ } catch (error) {
51
+ throw new Error(
52
+ `The ${engine} engine opens through '${name}', which is installed beside the app (${from}) but does not load: ${messageOf(error)}`,
53
+ { cause: error },
54
+ );
55
+ }
56
+ });
57
+ }
58
+
59
+ function resolves(require: NodeJS.Require, name: string): boolean {
60
+ try {
61
+ require.resolve(name);
62
+
63
+ return true;
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
68
+
69
+ function quoted(names: string[]): string {
70
+ return names.map((name) => `'${name}'`).join(' and ');
71
+ }
72
+
73
+ export function messageOf(error: unknown): string {
74
+ return error instanceof Error ? error.message.split('\n')[0] : String(error);
75
+ }
76
+
77
+ /** The dialect `url` names, over the driver the app installed beside it. */
78
+ export function dialectFor(engine: Exclude<Engine, 'sqlite'>, url: string, from = process.cwd()): KyselyDialect {
79
+ return DRIVERS[engine](url, modulesOf(engine, from));
80
+ }
81
+
82
+ /** `mssql://user:password@host:1433/database` — tedious takes an object and reads no url. */
83
+ export function tediousConfig(url: string) {
84
+ const parsed = new URL(url);
85
+ const port = parsed.port ? Number(parsed.port) : 1433;
86
+ const database = decodeURIComponent(parsed.pathname.slice(1)) || undefined;
87
+ const authentication = {
88
+ type: 'default',
89
+ options: { userName: decodeURIComponent(parsed.username), password: decodeURIComponent(parsed.password) },
90
+ };
91
+
92
+ return { server: parsed.hostname, authentication, options: { port, database, trustServerCertificate: true } };
93
+ }
@@ -1,11 +1,13 @@
1
1
  import { mkdirSync } from 'node:fs';
2
2
  import { dirname } from 'node:path';
3
3
  import { Kysely, SqliteDialect } from 'kysely';
4
- import Database from 'better-sqlite3';
4
+ import type BetterSqlite from 'better-sqlite3';
5
5
  import { createStorageFactory } from '../crud/SqlStorage.js';
6
6
  import { logQueries } from '../query/QuerySink.js';
7
7
  import { drift, driftReport } from '../drift.js';
8
- import { sqlEnforces, sqlSink, type SqlSource } from '../source/SqlSource.js';
8
+ import { createKyselySource, sqlEnforces, sqlSink, type SqlSource } from '../source/SqlSource.js';
9
+ import { DRIVERS, dialectFor, messageOf, modulesOf } from '../driver/Driver.js';
10
+ import { ENGINES } from '../fields/Engine.js';
9
11
  import { desiredTables, migrate } from '../diff/Change.js';
10
12
  import { toTableName } from '../table/TableDef.js';
11
13
  import { Sources, type Source, type SourceConfig, type SourceView } from '@fougere/core';
@@ -13,14 +15,14 @@ import type { SqliteSourceOptions } from './SqliteSourceOptions.js';
13
15
 
14
16
  export interface SqliteSource extends SqlSource {
15
17
  /** The raw handle, for pragmas and synchronous exec. */
16
- sqlite: Database.Database;
18
+ sqlite: BetterSqlite.Database;
17
19
  }
18
20
 
19
21
  export function createSqliteSource(opts: SqliteSourceOptions = {}): SqliteSource {
20
22
  const path = opts.path ?? 'fougere.db';
21
23
  // A file-backed DB needs its directory — SQLite won't create it.
22
24
  if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true });
23
- const sqlite = new Database(path);
25
+ const sqlite = open(path);
24
26
  sqlite.pragma('journal_mode = WAL');
25
27
  sqlite.pragma('foreign_keys = ON');
26
28
  const db = new Kysely<any>({ dialect: new SqliteDialect({ database: sqlite }), log: logQueries(opts.name ?? path) });
@@ -47,16 +49,44 @@ export function createSqliteSource(opts: SqliteSourceOptions = {}): SqliteSource
47
49
  };
48
50
  }
49
51
 
52
+ function open(path: string): BetterSqlite.Database {
53
+ const [Database] = modulesOf('sqlite') as [typeof BetterSqlite];
54
+ try {
55
+ return new Database(path);
56
+ } catch (error) {
57
+ throw new Error(unopened(error, path), { cause: error });
58
+ }
59
+ }
60
+
61
+ function unopened(error: unknown, path: string): string {
62
+ const code = (error as { code?: string }).code;
63
+ const rebuild = 'Build it from its sources: cd node_modules/better-sqlite3 && npx node-gyp rebuild';
64
+ if (code === 'MODULE_NOT_FOUND' && messageOf(error).includes('better_sqlite3.node')) {
65
+ return `'better-sqlite3' ships no native binary for ${process.platform}-${process.arch} — its prebuilt ones cover `
66
+ + `linux, macOS and Windows on x64 and arm64. ${rebuild}`;
67
+ }
68
+ if (code === 'ERR_DLOPEN_FAILED') {
69
+ return `The native binary of 'better-sqlite3' does not load under Node ${process.version}: ${messageOf(error)}. ${rebuild}`;
70
+ }
71
+
72
+ return `SQLite could not open '${path}': ${messageOf(error)}`;
73
+ }
74
+
50
75
  /** `source. */
51
76
  Sources.register('sql', (conf: SourceConfig): Source => {
52
77
  const dialect = conf.dialect as string | undefined;
53
- if (dialect !== undefined && dialect !== 'sqlite') {
54
- throw new Error(
55
- `source 'sql', dialect '${dialect}': cannot be built from a name — only 'sqlite' can, `
56
- + 'because it is the one driver this package owns. Build the Kysely dialect yourself and '
57
- + `call createKyselySource(dialect, '${dialect}'), then hand it in as a source.`,
58
- );
78
+ const name = conf.name as string | undefined;
79
+ if (dialect === undefined || dialect === 'sqlite') return createSqliteSource({ path: conf.path as string | undefined, name });
80
+
81
+ if (!isDriven(dialect)) {
82
+ throw new Error(`source 'sql': no dialect '${dialect}'. It answers ${ENGINES.join(', ')}.`);
59
83
  }
84
+ const url = conf.url;
85
+ if (typeof url !== 'string') throw new Error(`source 'sql', dialect '${dialect}': states no \`url\`.`);
60
86
 
61
- return createSqliteSource({ path: conf.path as string | undefined, name: conf.name as string | undefined });
87
+ return createKyselySource(dialectFor(dialect, url), dialect, { name });
62
88
  });
89
+
90
+ function isDriven(dialect: string): dialect is keyof typeof DRIVERS {
91
+ return dialect in DRIVERS;
92
+ }