@coffre/db 0.11.0 → 0.12.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.
@@ -113,6 +113,13 @@
113
113
  "when": 1792803757926,
114
114
  "tag": "0015_workload_access",
115
115
  "breakpoints": true
116
+ },
117
+ {
118
+ "idx": 16,
119
+ "version": "6",
120
+ "when": 1792835446455,
121
+ "tag": "0016_capped_alerts",
122
+ "breakpoints": true
116
123
  }
117
124
  ]
118
125
  }
@@ -1,5 +1,5 @@
1
- import { h as schema_d_exports } from "./schema-DG2t57Kf.js";
2
- import { t as Database } from "./database-Dh4W2pAj.js";
1
+ import { g as schema_d_exports } from "./schema-DcVkJhCf.js";
2
+ import { t as Database } from "./database-Ds1Y79h6.js";
3
3
  import { t as schema_sqlite_d_exports } from "./schema-sqlite.js";
4
4
  import { LibSQLDatabase } from "drizzle-orm/libsql";
5
5
  //#region src/portable.d.ts
@@ -1,5 +1,5 @@
1
1
  declare namespace schema_d_exports {
2
- export { auditChainHead, auditLog, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, vaultGrants, vaultMembers };
2
+ export { auditChainHead, auditLog, cappedAlerts, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, vaultGrants, vaultMembers };
3
3
  }
4
4
  declare const projects: import("drizzle-orm/pg-core").PgTableWithColumns<{
5
5
  name: "projects";
@@ -2464,6 +2464,72 @@ declare const consumedTokens: import("drizzle-orm/pg-core").PgTableWithColumns<{
2464
2464
  };
2465
2465
  dialect: "pg";
2466
2466
  }>;
2467
+ /**
2468
+ * When a service's capped alert was last raised, by kind: the refusal of a
2469
+ * token signed by a key its uploaded keys lack (`unknown_key`) alerts once
2470
+ * an hour, however many isolates see it. One conditional write per refusal
2471
+ * decides (`claimAlert`), so that the many it caps never reach the log's
2472
+ * head. Only a request that a binding of the service on the token's issuer
2473
+ * gets as far as its keys writes here: a row per service, at most, per kind.
2474
+ */
2475
+ declare const cappedAlerts: import("drizzle-orm/pg-core").PgTableWithColumns<{
2476
+ name: "capped_alerts";
2477
+ schema: undefined;
2478
+ columns: {
2479
+ service: import("drizzle-orm/pg-core").PgColumn<{
2480
+ name: "service";
2481
+ tableName: "capped_alerts";
2482
+ dataType: "string";
2483
+ columnType: "PgText";
2484
+ data: string;
2485
+ driverParam: string;
2486
+ notNull: true;
2487
+ hasDefault: false;
2488
+ isPrimaryKey: false;
2489
+ isAutoincrement: false;
2490
+ hasRuntimeDefault: false;
2491
+ enumValues: [string, ...string[]];
2492
+ baseColumn: never;
2493
+ identity: undefined;
2494
+ generated: undefined;
2495
+ }, {}, {}>;
2496
+ kind: import("drizzle-orm/pg-core").PgColumn<{
2497
+ name: "kind";
2498
+ tableName: "capped_alerts";
2499
+ dataType: "string";
2500
+ columnType: "PgText";
2501
+ data: string;
2502
+ driverParam: string;
2503
+ notNull: true;
2504
+ hasDefault: false;
2505
+ isPrimaryKey: false;
2506
+ isAutoincrement: false;
2507
+ hasRuntimeDefault: false;
2508
+ enumValues: [string, ...string[]];
2509
+ baseColumn: never;
2510
+ identity: undefined;
2511
+ generated: undefined;
2512
+ }, {}, {}>;
2513
+ raisedAt: import("drizzle-orm/pg-core").PgColumn<{
2514
+ name: "raised_at";
2515
+ tableName: "capped_alerts";
2516
+ dataType: "date";
2517
+ columnType: "PgTimestamp";
2518
+ data: Date;
2519
+ driverParam: string;
2520
+ notNull: true;
2521
+ hasDefault: false;
2522
+ isPrimaryKey: false;
2523
+ isAutoincrement: false;
2524
+ hasRuntimeDefault: false;
2525
+ enumValues: undefined;
2526
+ baseColumn: never;
2527
+ identity: undefined;
2528
+ generated: undefined;
2529
+ }, {}, {}>;
2530
+ };
2531
+ dialect: "pg";
2532
+ }>;
2467
2533
  /**
2468
2534
  * MCP clients that registered themselves (RFC 7591), the fallback to Client
2469
2535
  * ID Metadata Documents, which need no row. The ID is the client's
@@ -4059,4 +4125,4 @@ declare const environmentsRelations: import("drizzle-orm").Relations<"environmen
4059
4125
  environment: import("drizzle-orm").One<"environments", true>;
4060
4126
  }>;
4061
4127
  //#endregion
4062
- export { vaultMembers as S, secretVersions as _, deviceAuthorizations as a, serviceBindings as b, environments as c, mcpApprovals as d, mcpConnections as f, secretReferences as g, schema_d_exports as h, credentials as i, environmentsRelations as l, projects as m, auditLog as n, dismissedKeys as o, oauthClients as p, consumedTokens as r, enrollments as s, auditChainHead as t, identities as u, secrets as v, vaultGrants as x, secretsRelations as y };
4128
+ export { vaultMembers as C, vaultGrants as S, secretReferences as _, credentials as a, secretsRelations as b, enrollments as c, identities as d, mcpApprovals as f, schema_d_exports as g, projects as h, consumedTokens as i, environments as l, oauthClients as m, auditLog as n, deviceAuthorizations as o, mcpConnections as p, cappedAlerts as r, dismissedKeys as s, auditChainHead as t, environmentsRelations as u, secretVersions as v, serviceBindings as x, secrets as y };
@@ -1,5 +1,5 @@
1
1
  declare namespace schema_sqlite_d_exports {
2
- export { auditChainHead, auditLog, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, vaultGrants, vaultMembers };
2
+ export { auditChainHead, auditLog, cappedAlerts, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, vaultGrants, vaultMembers };
3
3
  }
4
4
  export declare const projects: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
5
5
  name: "projects";
@@ -2571,6 +2571,68 @@ export declare const consumedTokens: import("drizzle-orm/sqlite-core").SQLiteTab
2571
2571
  };
2572
2572
  dialect: "sqlite";
2573
2573
  }>;
2574
+ export declare const cappedAlerts: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
2575
+ name: "capped_alerts";
2576
+ schema: undefined;
2577
+ columns: {
2578
+ service: import("drizzle-orm/sqlite-core").SQLiteColumn<{
2579
+ name: "service";
2580
+ tableName: "capped_alerts";
2581
+ dataType: "string";
2582
+ columnType: "SQLiteText";
2583
+ data: string;
2584
+ driverParam: string;
2585
+ notNull: true;
2586
+ hasDefault: false;
2587
+ isPrimaryKey: false;
2588
+ isAutoincrement: false;
2589
+ hasRuntimeDefault: false;
2590
+ enumValues: [string, ...string[]];
2591
+ baseColumn: never;
2592
+ identity: undefined;
2593
+ generated: undefined;
2594
+ }, {}, {
2595
+ length: undefined;
2596
+ }>;
2597
+ kind: import("drizzle-orm/sqlite-core").SQLiteColumn<{
2598
+ name: "kind";
2599
+ tableName: "capped_alerts";
2600
+ dataType: "string";
2601
+ columnType: "SQLiteText";
2602
+ data: string;
2603
+ driverParam: string;
2604
+ notNull: true;
2605
+ hasDefault: false;
2606
+ isPrimaryKey: false;
2607
+ isAutoincrement: false;
2608
+ hasRuntimeDefault: false;
2609
+ enumValues: [string, ...string[]];
2610
+ baseColumn: never;
2611
+ identity: undefined;
2612
+ generated: undefined;
2613
+ }, {}, {
2614
+ length: undefined;
2615
+ }>;
2616
+ raisedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
2617
+ name: string;
2618
+ tableName: "capped_alerts";
2619
+ dataType: "date";
2620
+ columnType: "SQLiteTimestamp";
2621
+ data: Date;
2622
+ driverParam: number;
2623
+ notNull: true;
2624
+ hasDefault: false;
2625
+ isPrimaryKey: false;
2626
+ isAutoincrement: false;
2627
+ hasRuntimeDefault: false;
2628
+ enumValues: undefined;
2629
+ baseColumn: never;
2630
+ identity: undefined;
2631
+ generated: undefined;
2632
+ }, {}, {}>;
2633
+ };
2634
+ dialect: "sqlite";
2635
+ }>;
2574
2636
  /**
2575
2637
  * MCP clients that registered themselves (RFC 7591), the fallback to Client
2576
2638
  * ID Metadata Documents, which need no row. The ID is the client's
@@ -392,6 +392,14 @@ const consumedTokens = sqliteTable("consumed_tokens", {
392
392
  hash: bytes("hash").primaryKey(),
393
393
  consumedAt: time("consumed_at").notNull().default(now)
394
394
  }, (table) => [check("consumed_tokens_hash_check", sql`octet_length(${table.hash}) = 32`)]);
395
+ const cappedAlerts = sqliteTable("capped_alerts", {
396
+ service: text().notNull(),
397
+ kind: text().notNull(),
398
+ raisedAt: time("raised_at").notNull()
399
+ }, (table) => [primaryKey({
400
+ name: "capped_alerts_pkey",
401
+ columns: [table.service, table.kind]
402
+ })]);
395
403
  /**
396
404
  * MCP clients that registered themselves (RFC 7591), the fallback to Client
397
405
  * ID Metadata Documents, which need no row. The ID is the client's
@@ -608,4 +616,4 @@ const { environmentsRelations, secretsRelations } = relationsOf(asPostgres({
608
616
  secretVersions
609
617
  }));
610
618
  //#endregion
611
- export { auditChainHead, auditLog, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, vaultGrants, vaultMembers };
619
+ export { auditChainHead, auditLog, cappedAlerts, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, vaultGrants, vaultMembers };
@@ -1,4 +1,4 @@
1
- import { i as Queryable } from "./database-Dh4W2pAj.js";
1
+ import { i as Queryable } from "./database-Ds1Y79h6.js";
2
2
  import { Engine } from "./dialect.js";
3
3
  //#region src/schema-version.d.ts
4
4
  /**
@@ -127,6 +127,13 @@ const KNOWN_MIGRATIONS = {
127
127
  "when": 1792814038307,
128
128
  "tag": "0016_spent_tokens",
129
129
  "breakpoints": true
130
+ },
131
+ {
132
+ "idx": 17,
133
+ "version": "7",
134
+ "when": 1792835445795,
135
+ "tag": "0017_capped_alerts",
136
+ "breakpoints": true
130
137
  }
131
138
  ].map((entry) => entry.tag),
132
139
  sqlite: [
@@ -241,6 +248,13 @@ const KNOWN_MIGRATIONS = {
241
248
  "when": 1792803757926,
242
249
  "tag": "0015_workload_access",
243
250
  "breakpoints": true
251
+ },
252
+ {
253
+ "idx": 16,
254
+ "version": "6",
255
+ "when": 1792835446455,
256
+ "tag": "0016_capped_alerts",
257
+ "breakpoints": true
244
258
  }
245
259
  ].map((entry) => entry.tag)
246
260
  };
package/dist/schema.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { S as vaultMembers, _ as secretVersions, a as deviceAuthorizations, b as serviceBindings, c as environments, d as mcpApprovals, f as mcpConnections, g as secretReferences, i as credentials, l as environmentsRelations, m as projects, n as auditLog, o as dismissedKeys, p as oauthClients, r as consumedTokens, s as enrollments, t as auditChainHead, u as identities, v as secrets, x as vaultGrants, y as secretsRelations } from "./schema-DG2t57Kf.js";
2
- export { auditChainHead, auditLog, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, vaultGrants, vaultMembers };
1
+ import { C as vaultMembers, S as vaultGrants, _ as secretReferences, a as credentials, b as secretsRelations, c as enrollments, d as identities, f as mcpApprovals, h as projects, i as consumedTokens, l as environments, m as oauthClients, n as auditLog, o as deviceAuthorizations, p as mcpConnections, r as cappedAlerts, s as dismissedKeys, t as auditChainHead, u as environmentsRelations, v as secretVersions, x as serviceBindings, y as secrets } from "./schema-DcVkJhCf.js";
2
+ export { auditChainHead, auditLog, cappedAlerts, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, vaultGrants, vaultMembers };
package/dist/schema.js CHANGED
@@ -6,6 +6,7 @@ import { bigint, boolean, check, customType, foreignKey, index, integer, pgTable
6
6
  var schema_exports = /* @__PURE__ */ __exportAll({
7
7
  auditChainHead: () => auditChainHead,
8
8
  auditLog: () => auditLog,
9
+ cappedAlerts: () => cappedAlerts,
9
10
  consumedTokens: () => consumedTokens,
10
11
  credentials: () => credentials,
11
12
  deviceAuthorizations: () => deviceAuthorizations,
@@ -447,6 +448,22 @@ const consumedTokens = pgTable("consumed_tokens", {
447
448
  consumedAt: timestamp("consumed_at", { withTimezone: true }).notNull().defaultNow()
448
449
  }, (table) => [check("consumed_tokens_hash_check", sql`octet_length(${table.hash}) = 32`)]);
449
450
  /**
451
+ * When a service's capped alert was last raised, by kind: the refusal of a
452
+ * token signed by a key its uploaded keys lack (`unknown_key`) alerts once
453
+ * an hour, however many isolates see it. One conditional write per refusal
454
+ * decides (`claimAlert`), so that the many it caps never reach the log's
455
+ * head. Only a request that a binding of the service on the token's issuer
456
+ * gets as far as its keys writes here: a row per service, at most, per kind.
457
+ */
458
+ const cappedAlerts = pgTable("capped_alerts", {
459
+ service: text().notNull(),
460
+ kind: text().notNull(),
461
+ raisedAt: timestamp("raised_at", { withTimezone: true }).notNull()
462
+ }, (table) => [primaryKey({
463
+ name: "capped_alerts_pkey",
464
+ columns: [table.service, table.kind]
465
+ })]);
466
+ /**
450
467
  * MCP clients that registered themselves (RFC 7591), the fallback to Client
451
468
  * ID Metadata Documents, which need no row. The ID is the client's
452
469
  * `client_id`. Its redirects are under its MAC: a database writer cannot add
@@ -681,4 +698,4 @@ const { environmentsRelations, secretsRelations } = relationsOf({
681
698
  secretVersions
682
699
  });
683
700
  //#endregion
684
- export { auditChainHead, auditLog, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, schema_exports as t, vaultGrants, vaultMembers };
701
+ export { auditChainHead, auditLog, cappedAlerts, consumedTokens, credentials, deviceAuthorizations, dismissedKeys, enrollments, environments, environmentsRelations, identities, mcpApprovals, mcpConnections, oauthClients, projects, secretReferences, secretVersions, secrets, secretsRelations, serviceBindings, schema_exports as t, vaultGrants, vaultMembers };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffre/db",
3
- "version": "0.11.0",
3
+ "version": "0.12.1",
4
4
  "description": "coffre's database: the schema, its migrations and the connections, on Postgres or SQLite.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -79,7 +79,7 @@
79
79
  "drizzle-orm": "0.45.2",
80
80
  "pg": "8.16.3",
81
81
  "pg-connection-string": "2.14.0",
82
- "@coffre/core": "0.11.0"
82
+ "@coffre/core": "0.12.1"
83
83
  },
84
84
  "devDependencies": {
85
85
  "@types/node": "26.1.1",
@@ -0,0 +1,10 @@
1
+ -- Capped alerts (T98): when a service's sign-in was last refused `unknown_key` with an alert, so that the next alerts an hour later at the soonest, whichever isolate sees it. It only adds: the release before neither reads nor writes it.
2
+ CREATE TABLE "capped_alerts" (
3
+ "service" text NOT NULL,
4
+ "kind" text NOT NULL,
5
+ "raised_at" timestamp with time zone NOT NULL,
6
+ CONSTRAINT "capped_alerts_pkey" PRIMARY KEY("service","kind")
7
+ );
8
+ --> statement-breakpoint
9
+ -- The app moves a row's time on, and deletes none.
10
+ GRANT SELECT, INSERT, UPDATE (raised_at) ON capped_alerts TO coffre_app;