@andrewheberle/serverless-ssh-ca 0.20.0 → 0.20.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,OAAO,CAAA;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAIhD,oBAAY,eAAe;IAC1B,IAAI,IAAA;IACJ,IAAI,IAAA;CACJ;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,IAAI,CAAA;IACjB,YAAY,EAAE,IAAI,CAAA;IAClB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAA;IACvB,gBAAgB,EAAE,eAAe,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC5B,YAAY,EAAE,iBAAiB,CAAA;CAC/B,CAAA;AAqBD,eAAO,MAAM,SAAS,QAAe,aAAa,kBAsBjD,CAAA;AAED,eAAO,MAAM,iBAAiB,QAAe,aAAa,eAAe,WAAW,SAAS,MAAM,oBAAmB,eAAe,kBA2BpI,CAAA;AAED,eAAO,MAAM,SAAS,QAAe,aAAa,UAAU,MAAM,KAAG,OAAO,CAAC,OAAO,CAYnF,CAAA;AAED,oBAAY,gBAAgB;IAC3B,QAAQ,IAAA;IACR,OAAO,IAAA;IACP,SAAS,IAAA;IACT,WAAW,IAAA;CACX;AAED,eAAO,MAAM,gBAAgB,QAAe,aAAa,UAAU,MAAM,aAAa,MAAM,mBAAmB,eAAe,KAAG,OAAO,CAAC,gBAAgB,CAwBxJ,CAAA;AAED,eAAO,MAAM,iBAAiB,QAAe,aAAa,mBAAmB,eAAe,KAAG,OAAO,CAAC,MAAM,EAAE,CAoB9G,CAAA;AAED,KAAK,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAA;AAE/D,eAAO,MAAM,iBAAiB,QAAe,aAAa,UAAU,MAAM,KAAG,OAAO,CAAC,kBAAkB,EAAE,CAuBxG,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,OAAO,CAAA;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAKhD,oBAAY,eAAe;IAC1B,IAAI,IAAA;IACJ,IAAI,IAAA;CACJ;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,IAAI,CAAA;IACjB,YAAY,EAAE,IAAI,CAAA;IAClB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAA;IACvB,gBAAgB,EAAE,eAAe,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC5B,YAAY,EAAE,iBAAiB,CAAA;CAC/B,CAAA;AAmBD,eAAO,MAAM,SAAS,QAAe,aAAa,kBAsBjD,CAAA;AAED,eAAO,MAAM,iBAAiB,QAAe,aAAa,eAAe,WAAW,SAAS,MAAM,oBAAmB,eAAe,kBA2BpI,CAAA;AAED,eAAO,MAAM,SAAS,QAAe,aAAa,UAAU,MAAM,KAAG,OAAO,CAAC,OAAO,CAYnF,CAAA;AAED,oBAAY,gBAAgB;IAC3B,QAAQ,IAAA;IACR,OAAO,IAAA;IACP,SAAS,IAAA;IACT,WAAW,IAAA;CACX;AAED,eAAO,MAAM,gBAAgB,QAAe,aAAa,UAAU,MAAM,aAAa,MAAM,mBAAmB,eAAe,KAAG,OAAO,CAAC,gBAAgB,CAwBxJ,CAAA;AAED,eAAO,MAAM,iBAAiB,QAAe,aAAa,mBAAmB,eAAe,KAAG,OAAO,CAAC,MAAM,EAAE,CAoB9G,CAAA;AAED,KAAK,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAA;AAE/D,eAAO,MAAM,iBAAiB,QAAe,aAAa,UAAU,MAAM,KAAG,OAAO,CAAC,kBAAkB,EAAE,CAuBxG,CAAA"}
package/dist/db/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { logger } from "../logger.js";
2
2
  import { D1QB } from "workers-qb";
3
+ import { migrateOnce } from "./migrate.js";
3
4
  import { migrations } from "./migrations/index.js";
4
5
  export var CertificateType;
5
6
  (function (CertificateType) {
@@ -10,11 +11,9 @@ const connect = async (env) => {
10
11
  const l = logger(env);
11
12
  try {
12
13
  l.debug("connecting to database");
13
- const qb = new D1QB(env.DB);
14
- const migrationBuilder = qb.migrations({ migrations });
15
- const appliedMigrations = await migrationBuilder.apply();
14
+ const appliedMigrations = await migrateOnce(env.DB, migrations);
16
15
  l.debug("applied database migrations", "migrations", appliedMigrations.length, "migration_names", appliedMigrations.map(m => m.name));
17
- return qb;
16
+ return new D1QB(env.DB);
18
17
  }
19
18
  catch (err) {
20
19
  l.error("error connecting to database", "error", err);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { CaDatabase } from "../types.js";
2
+ /**
3
+ * A database schema migration.
4
+ *
5
+ * Migrations are applied in order and recorded by `name` in the `migrations`
6
+ * table, so a name must never change once released. Each statement must be a
7
+ * single SQL statement.
8
+ */
9
+ export type Migration = {
10
+ /** Unique name recorded once the migration has been applied */
11
+ name: string;
12
+ /** The SQL statements to run, in order, as one transaction */
13
+ statements: string[];
14
+ };
15
+ /**
16
+ * Apply any migrations that have not yet been applied to the database.
17
+ *
18
+ * Each migration is run with {@link CaDatabase.batch} so it applies atomically,
19
+ * and its row in the `migrations` table is inserted first. When several callers
20
+ * race to apply the same migration only one succeeds; the others fail on that
21
+ * insert before running any of the migration's statements and their batch rolls
22
+ * back, so migrations that are not idempotent are safe to apply concurrently.
23
+ *
24
+ * @param db The database to migrate, see {@link CaDatabase}
25
+ * @param migrations The migrations to apply in order, see {@link Migration}
26
+ * @returns The migrations applied by this call, excluding any applied concurrently by another caller
27
+ */
28
+ export declare const applyMigrations: (db: CaDatabase, migrations: readonly Migration[]) => Promise<Migration[]>;
29
+ /**
30
+ * Apply migrations to a database at most once per database binding, see
31
+ * {@link applyMigrations}.
32
+ *
33
+ * Concurrent and later callers share the result of the first call, unless it
34
+ * fails, in which case the next call tries again.
35
+ *
36
+ * @param db The database to migrate, see {@link CaDatabase}
37
+ * @param migrations The migrations to apply in order, see {@link Migration}
38
+ * @returns The migrations applied, or an empty array if this database binding has already been migrated
39
+ */
40
+ export declare const migrateOnce: (db: CaDatabase, migrations: readonly Migration[]) => Promise<Migration[]>;
41
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG;IACvB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAA;IACZ,8DAA8D;IAC9D,UAAU,EAAE,MAAM,EAAE,CAAA;CACpB,CAAA;AAqBD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,OAAc,UAAU,cAAc,SAAS,SAAS,EAAE,KAAG,OAAO,CAAC,SAAS,EAAE,CAyB3G,CAAA;AAID;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,OAAc,UAAU,cAAc,SAAS,SAAS,EAAE,KAAG,OAAO,CAAC,SAAS,EAAE,CAiBvG,CAAA"}
@@ -0,0 +1,84 @@
1
+ import z from "zod";
2
+ // matches the table previously created by workers-qb so existing databases are not migrated again
3
+ const createMigrationsTable = `CREATE TABLE IF NOT EXISTS migrations (
4
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
5
+ name TEXT UNIQUE,
6
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
7
+ )`;
8
+ const MigrationRows = z.array(z.object({ name: z.string() }));
9
+ const appliedNames = async (db) => {
10
+ const { results } = await db.prepare("SELECT name FROM migrations").all();
11
+ return new Set(MigrationRows.parse(results).map(row => row.name));
12
+ };
13
+ const isApplied = async (db, name) => {
14
+ const { results } = await db.prepare("SELECT name FROM migrations WHERE name = ?").bind(name).all();
15
+ return results.length > 0;
16
+ };
17
+ /**
18
+ * Apply any migrations that have not yet been applied to the database.
19
+ *
20
+ * Each migration is run with {@link CaDatabase.batch} so it applies atomically,
21
+ * and its row in the `migrations` table is inserted first. When several callers
22
+ * race to apply the same migration only one succeeds; the others fail on that
23
+ * insert before running any of the migration's statements and their batch rolls
24
+ * back, so migrations that are not idempotent are safe to apply concurrently.
25
+ *
26
+ * @param db The database to migrate, see {@link CaDatabase}
27
+ * @param migrations The migrations to apply in order, see {@link Migration}
28
+ * @returns The migrations applied by this call, excluding any applied concurrently by another caller
29
+ */
30
+ export const applyMigrations = async (db, migrations) => {
31
+ await db.prepare(createMigrationsTable).run();
32
+ const existing = await appliedNames(db);
33
+ const applied = [];
34
+ for (const migration of migrations) {
35
+ if (existing.has(migration.name)) {
36
+ continue;
37
+ }
38
+ try {
39
+ await db.batch([
40
+ db.prepare("INSERT INTO migrations (name) VALUES (?)").bind(migration.name),
41
+ ...migration.statements.map(sql => db.prepare(sql)),
42
+ ]);
43
+ applied.push(migration);
44
+ }
45
+ catch (err) {
46
+ // another caller applying the same migration is not an error
47
+ if (!(await isApplied(db, migration.name))) {
48
+ throw err;
49
+ }
50
+ }
51
+ }
52
+ return applied;
53
+ };
54
+ const migrated = new WeakMap();
55
+ /**
56
+ * Apply migrations to a database at most once per database binding, see
57
+ * {@link applyMigrations}.
58
+ *
59
+ * Concurrent and later callers share the result of the first call, unless it
60
+ * fails, in which case the next call tries again.
61
+ *
62
+ * @param db The database to migrate, see {@link CaDatabase}
63
+ * @param migrations The migrations to apply in order, see {@link Migration}
64
+ * @returns The migrations applied, or an empty array if this database binding has already been migrated
65
+ */
66
+ export const migrateOnce = async (db, migrations) => {
67
+ const pending = migrated.get(db);
68
+ if (pending !== undefined) {
69
+ await pending;
70
+ return [];
71
+ }
72
+ const result = applyMigrations(db, migrations);
73
+ migrated.set(db, result);
74
+ try {
75
+ return await result;
76
+ }
77
+ catch (err) {
78
+ if (migrated.get(db) === result) {
79
+ migrated.delete(db);
80
+ }
81
+ throw err;
82
+ }
83
+ };
84
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { type Migration } from "workers-qb";
1
+ import type { Migration } from "../migrate.js";
2
2
  export declare const migration: Migration;
3
3
  //# sourceMappingURL=0001_initial_schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"0001_initial_schema.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/0001_initial_schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,eAAO,MAAM,SAAS,EAAE,SAsBvB,CAAA"}
1
+ {"version":3,"file":"0001_initial_schema.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/0001_initial_schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,eAAO,MAAM,SAAS,EAAE,SAqBvB,CAAA"}
@@ -1,7 +1,7 @@
1
1
  export const migration = {
2
2
  name: "0001_initial_schema",
3
- sql: `
4
- CREATE TABLE IF NOT EXISTS certificates (
3
+ statements: [
4
+ `CREATE TABLE IF NOT EXISTS certificates (
5
5
  id INTEGER PRIMARY KEY,
6
6
  serial TEXT UNIQUE NOT NULL,
7
7
  key_id TEXT NOT NULL,
@@ -12,13 +12,12 @@ export const migration = {
12
12
  revoked_at TIMESTAMP,
13
13
  certificate_type INTEGER NOT NULL DEFAULT 0,
14
14
  public_key TEXT
15
- );
16
-
17
- CREATE INDEX IF NOT EXISTS idx_certificates_serial ON certificates(serial);
18
- CREATE INDEX IF NOT EXISTS idx_certificates_valid_after ON certificates(valid_after);
19
- CREATE INDEX IF NOT EXISTS idx_certificates_valid_before ON certificates(valid_before);
20
- CREATE INDEX IF NOT EXISTS idx_certificates_revoked_at ON certificates(revoked_at);
21
- CREATE INDEX IF NOT EXISTS idx_certificates_certificate_type ON certificates(certificate_type);
22
- `
15
+ )`,
16
+ "CREATE INDEX IF NOT EXISTS idx_certificates_serial ON certificates(serial)",
17
+ "CREATE INDEX IF NOT EXISTS idx_certificates_valid_after ON certificates(valid_after)",
18
+ "CREATE INDEX IF NOT EXISTS idx_certificates_valid_before ON certificates(valid_before)",
19
+ "CREATE INDEX IF NOT EXISTS idx_certificates_revoked_at ON certificates(revoked_at)",
20
+ "CREATE INDEX IF NOT EXISTS idx_certificates_certificate_type ON certificates(certificate_type)",
21
+ ]
23
22
  };
24
23
  //# sourceMappingURL=0001_initial_schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"0001_initial_schema.js","sourceRoot":"","sources":["../../../src/db/migrations/0001_initial_schema.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAc;IACnC,IAAI,EAAE,qBAAqB;IAC3B,GAAG,EAAE;;;;;;;;;;;;;;;;;;;EAmBJ;CACD,CAAA"}
1
+ {"version":3,"file":"0001_initial_schema.js","sourceRoot":"","sources":["../../../src/db/migrations/0001_initial_schema.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAc;IACnC,IAAI,EAAE,qBAAqB;IAC3B,UAAU,EAAE;QACX;;;;;;;;;;;IAWE;QACF,4EAA4E;QAC5E,sFAAsF;QACtF,wFAAwF;QACxF,oFAAoF;QACpF,gGAAgG;KAChG;CACD,CAAA"}
@@ -1,3 +1,3 @@
1
- import { type Migration } from "workers-qb";
1
+ import type { Migration } from "../migrate.js";
2
2
  export declare const migrations: Migration[];
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAG3C,eAAO,MAAM,UAAU,EAAE,SAAS,EAEjC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAG9C,eAAO,MAAM,UAAU,EAAE,SAAS,EAEjC,CAAA"}
package/dist/types.d.ts CHANGED
@@ -62,8 +62,9 @@ export interface CaPreparedStatement {
62
62
  * compatible database may be used by implementing this interface.
63
63
  *
64
64
  * The SQL the CA runs is SQLite dialect, and statements passed to
65
- * {@link CaDatabase.prepare} may contain more than one SQL statement (as used
66
- * when applying schema migrations).
65
+ * {@link CaDatabase.prepare} may contain more than one SQL statement.
66
+ * Schema migrations rely on {@link CaDatabase.batch} being atomic so they can
67
+ * be applied safely by concurrent requests.
67
68
  */
68
69
  export interface CaDatabase {
69
70
  /** Prepare a SQL query for execution, see {@link CaPreparedStatement} */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrewheberle/serverless-ssh-ca",
3
- "version": "0.20.0",
3
+ "version": "0.20.1",
4
4
  "description": "A serverless SSH CA built for Cloudflare Workers that can also run on Node.js",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
package/src/db/index.ts CHANGED
@@ -2,6 +2,7 @@ import type { Certificate, Format, Identity } from "sshpk"
2
2
  import { logger } from "../logger.js"
3
3
  import type { SshCaBindings } from "../types.js"
4
4
  import { D1QB } from "workers-qb"
5
+ import { migrateOnce } from "./migrate.js"
5
6
  import { migrations } from "./migrations/index.js"
6
7
 
7
8
  export enum CertificateType {
@@ -32,13 +33,11 @@ const connect = async (env: SshCaBindings): Promise<D1QB<DatabaseSchema>> => {
32
33
  try {
33
34
  l.debug("connecting to database")
34
35
 
35
- const qb = new D1QB<DatabaseSchema>(env.DB)
36
- const migrationBuilder = qb.migrations({ migrations })
37
- const appliedMigrations = await migrationBuilder.apply()
36
+ const appliedMigrations = await migrateOnce(env.DB, migrations)
38
37
 
39
38
  l.debug("applied database migrations", "migrations", appliedMigrations.length, "migration_names", appliedMigrations.map(m => m.name))
40
39
 
41
- return qb
40
+ return new D1QB<DatabaseSchema>(env.DB)
42
41
  } catch (err) {
43
42
  l.error("error connecting to database", "error", err)
44
43
  throw err
@@ -0,0 +1,107 @@
1
+ import z from "zod"
2
+ import type { CaDatabase } from "../types.js"
3
+
4
+ /**
5
+ * A database schema migration.
6
+ *
7
+ * Migrations are applied in order and recorded by `name` in the `migrations`
8
+ * table, so a name must never change once released. Each statement must be a
9
+ * single SQL statement.
10
+ */
11
+ export type Migration = {
12
+ /** Unique name recorded once the migration has been applied */
13
+ name: string
14
+ /** The SQL statements to run, in order, as one transaction */
15
+ statements: string[]
16
+ }
17
+
18
+ // matches the table previously created by workers-qb so existing databases are not migrated again
19
+ const createMigrationsTable = `CREATE TABLE IF NOT EXISTS migrations (
20
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
21
+ name TEXT UNIQUE,
22
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
23
+ )`
24
+
25
+ const MigrationRows = z.array(z.object({ name: z.string() }))
26
+
27
+ const appliedNames = async (db: CaDatabase): Promise<Set<string>> => {
28
+ const { results } = await db.prepare("SELECT name FROM migrations").all()
29
+ return new Set(MigrationRows.parse(results).map(row => row.name))
30
+ }
31
+
32
+ const isApplied = async (db: CaDatabase, name: string): Promise<boolean> => {
33
+ const { results } = await db.prepare("SELECT name FROM migrations WHERE name = ?").bind(name).all()
34
+ return results.length > 0
35
+ }
36
+
37
+ /**
38
+ * Apply any migrations that have not yet been applied to the database.
39
+ *
40
+ * Each migration is run with {@link CaDatabase.batch} so it applies atomically,
41
+ * and its row in the `migrations` table is inserted first. When several callers
42
+ * race to apply the same migration only one succeeds; the others fail on that
43
+ * insert before running any of the migration's statements and their batch rolls
44
+ * back, so migrations that are not idempotent are safe to apply concurrently.
45
+ *
46
+ * @param db The database to migrate, see {@link CaDatabase}
47
+ * @param migrations The migrations to apply in order, see {@link Migration}
48
+ * @returns The migrations applied by this call, excluding any applied concurrently by another caller
49
+ */
50
+ export const applyMigrations = async (db: CaDatabase, migrations: readonly Migration[]): Promise<Migration[]> => {
51
+ await db.prepare(createMigrationsTable).run()
52
+ const existing = await appliedNames(db)
53
+
54
+ const applied: Migration[] = []
55
+ for (const migration of migrations) {
56
+ if (existing.has(migration.name)) {
57
+ continue
58
+ }
59
+
60
+ try {
61
+ await db.batch([
62
+ db.prepare("INSERT INTO migrations (name) VALUES (?)").bind(migration.name),
63
+ ...migration.statements.map(sql => db.prepare(sql)),
64
+ ])
65
+ applied.push(migration)
66
+ } catch (err) {
67
+ // another caller applying the same migration is not an error
68
+ if (!(await isApplied(db, migration.name))) {
69
+ throw err
70
+ }
71
+ }
72
+ }
73
+
74
+ return applied
75
+ }
76
+
77
+ const migrated = new WeakMap<CaDatabase, Promise<Migration[]>>()
78
+
79
+ /**
80
+ * Apply migrations to a database at most once per database binding, see
81
+ * {@link applyMigrations}.
82
+ *
83
+ * Concurrent and later callers share the result of the first call, unless it
84
+ * fails, in which case the next call tries again.
85
+ *
86
+ * @param db The database to migrate, see {@link CaDatabase}
87
+ * @param migrations The migrations to apply in order, see {@link Migration}
88
+ * @returns The migrations applied, or an empty array if this database binding has already been migrated
89
+ */
90
+ export const migrateOnce = async (db: CaDatabase, migrations: readonly Migration[]): Promise<Migration[]> => {
91
+ const pending = migrated.get(db)
92
+ if (pending !== undefined) {
93
+ await pending
94
+ return []
95
+ }
96
+
97
+ const result = applyMigrations(db, migrations)
98
+ migrated.set(db, result)
99
+ try {
100
+ return await result
101
+ } catch (err) {
102
+ if (migrated.get(db) === result) {
103
+ migrated.delete(db)
104
+ }
105
+ throw err
106
+ }
107
+ }
@@ -1,9 +1,9 @@
1
- import { type Migration } from "workers-qb";
1
+ import type { Migration } from "../migrate.js"
2
2
 
3
3
  export const migration: Migration = {
4
4
  name: "0001_initial_schema",
5
- sql: `
6
- CREATE TABLE IF NOT EXISTS certificates (
5
+ statements: [
6
+ `CREATE TABLE IF NOT EXISTS certificates (
7
7
  id INTEGER PRIMARY KEY,
8
8
  serial TEXT UNIQUE NOT NULL,
9
9
  key_id TEXT NOT NULL,
@@ -14,12 +14,11 @@ export const migration: Migration = {
14
14
  revoked_at TIMESTAMP,
15
15
  certificate_type INTEGER NOT NULL DEFAULT 0,
16
16
  public_key TEXT
17
- );
18
-
19
- CREATE INDEX IF NOT EXISTS idx_certificates_serial ON certificates(serial);
20
- CREATE INDEX IF NOT EXISTS idx_certificates_valid_after ON certificates(valid_after);
21
- CREATE INDEX IF NOT EXISTS idx_certificates_valid_before ON certificates(valid_before);
22
- CREATE INDEX IF NOT EXISTS idx_certificates_revoked_at ON certificates(revoked_at);
23
- CREATE INDEX IF NOT EXISTS idx_certificates_certificate_type ON certificates(certificate_type);
24
- `
17
+ )`,
18
+ "CREATE INDEX IF NOT EXISTS idx_certificates_serial ON certificates(serial)",
19
+ "CREATE INDEX IF NOT EXISTS idx_certificates_valid_after ON certificates(valid_after)",
20
+ "CREATE INDEX IF NOT EXISTS idx_certificates_valid_before ON certificates(valid_before)",
21
+ "CREATE INDEX IF NOT EXISTS idx_certificates_revoked_at ON certificates(revoked_at)",
22
+ "CREATE INDEX IF NOT EXISTS idx_certificates_certificate_type ON certificates(certificate_type)",
23
+ ]
25
24
  }
@@ -1,4 +1,4 @@
1
- import { type Migration } from "workers-qb"
1
+ import type { Migration } from "../migrate.js"
2
2
  import { migration as initialSchema0001 } from "./0001_initial_schema.js"
3
3
 
4
4
  export const migrations: Migration[] = [
package/src/types.ts CHANGED
@@ -72,8 +72,9 @@ export interface CaPreparedStatement {
72
72
  * compatible database may be used by implementing this interface.
73
73
  *
74
74
  * The SQL the CA runs is SQLite dialect, and statements passed to
75
- * {@link CaDatabase.prepare} may contain more than one SQL statement (as used
76
- * when applying schema migrations).
75
+ * {@link CaDatabase.prepare} may contain more than one SQL statement.
76
+ * Schema migrations rely on {@link CaDatabase.batch} being atomic so they can
77
+ * be applied safely by concurrent requests.
77
78
  */
78
79
  export interface CaDatabase {
79
80
  /** Prepare a SQL query for execution, see {@link CaPreparedStatement} */