@kubun/store-connector 0.16.0 → 0.17.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/lib/api.d.ts CHANGED
@@ -24,6 +24,11 @@ export type PendingAuthRecord = {
24
24
  /** A recovery recipient's DID in a form that can be encrypted to. See the table type. */
25
25
  controllerWrappableDID?: string | null;
26
26
  createdAt: number;
27
+ /** The callback's redirect target, needed to complete the token exchange. */
28
+ redirectURL: string;
29
+ /** The scopes requested at authorize time. */
30
+ scopes: Array<string>;
31
+ expiresAt: number;
27
32
  };
28
33
  export type ConnectorStoreAPI = {
29
34
  getSyncState(connectorName: string, ownerDID: string): Promise<SyncState | null>;
package/lib/api.js CHANGED
@@ -91,7 +91,10 @@ export function createConnectorStore(db, _adapter) {
91
91
  owner_did: record.ownerDID,
92
92
  owner_wrappable_did: record.ownerWrappableDID ?? null,
93
93
  controller_wrappable_did: record.controllerWrappableDID ?? null,
94
- created_at: record.createdAt
94
+ created_at: record.createdAt,
95
+ redirect_url: record.redirectURL,
96
+ scopes: JSON.stringify(record.scopes),
97
+ expires_at: record.expiresAt
95
98
  }).execute();
96
99
  },
97
100
  async consumePendingAuth (state) {
@@ -106,11 +109,23 @@ export function createConnectorStore(db, _adapter) {
106
109
  ownerDID: row.owner_did,
107
110
  ownerWrappableDID: row.owner_wrappable_did,
108
111
  controllerWrappableDID: row.controller_wrappable_did,
109
- createdAt: row.created_at
112
+ createdAt: row.created_at,
113
+ redirectURL: row.redirect_url,
114
+ // ParseJSONResultsPlugin may have already parsed this column, same as
115
+ // `checkpoint` in `rowToSyncState`.
116
+ scopes: typeof row.scopes === 'string' ? JSON.parse(row.scopes) : row.scopes,
117
+ expiresAt: row.expires_at
110
118
  };
111
119
  },
112
120
  async deleteExpiredPendingAuth (cutoffMs) {
113
- await db.deleteFrom('kubun_connector_pending_auth').where('created_at', '<', cutoffMs).execute();
121
+ // Strict `<` matches @kokuin/oauth `completeAuthorization`, which treats a
122
+ // record as expired only when `expiresAt < now`. A record at exactly
123
+ // `expiresAt === cutoffMs` is therefore still consumable and is kept here
124
+ // (the next sweep, once `now > expiresAt`, removes it). This intentionally
125
+ // keeps one more record than the `PendingAuthStore.deleteExpired` port doc
126
+ // ("at or before nowMs") so the sweep and the consume check agree on the
127
+ // expiry boundary.
128
+ await db.deleteFrom('kubun_connector_pending_auth').where('expires_at', '<', cutoffMs).execute();
114
129
  }
115
130
  };
116
131
  }
package/lib/migrations.js CHANGED
@@ -19,7 +19,14 @@ export function getConnectorMigrations(ctx) {
19
19
  // callback so the mint can add the controller recovery wrap.
20
20
  .addColumn('controller_wrappable_did', t.text)// ms-epoch (Date.now) overflows int32 on Postgres; bigint holds it and
21
21
  // the adapter's int8 parser reads it back as a JS number.
22
- .addColumn('created_at', t.bigint, (col)=>col.notNull()).execute();
22
+ .addColumn('created_at', t.bigint, (col)=>col.notNull())// The callback's redirect target and the scopes requested at authorize
23
+ // time, both needed to complete the token exchange and to fill in
24
+ // `PendingAuthRecord`'s required fields.
25
+ .addColumn('redirect_url', t.text, (col)=>col.notNull())// JSON-encoded `Array<string>`.
26
+ .addColumn('scopes', t.text, (col)=>col.notNull())// ms-epoch (Date.now) overflows int32 on Postgres; bigint holds it and
27
+ // the adapter's int8 parser reads it back as a JS number. The sweep in
28
+ // `deleteExpiredPendingAuth` keys off this column, not `created_at`.
29
+ .addColumn('expires_at', t.bigint, (col)=>col.notNull()).execute();
23
30
  },
24
31
  async down (db) {
25
32
  await db.schema.dropTable('kubun_connector_pending_auth').ifExists().execute();
package/lib/tables.d.ts CHANGED
@@ -28,6 +28,10 @@ export type ConnectorPendingAuthTable = {
28
28
  */
29
29
  controller_wrappable_did: string | null;
30
30
  created_at: number;
31
+ redirect_url: string;
32
+ /** JSON-encoded `Array<string>`. See `PendingAuthRecord.scopes`. */
33
+ scopes: string;
34
+ expires_at: number;
31
35
  };
32
36
  export type ConnectorPendingAuth = Selectable<ConnectorPendingAuthTable>;
33
37
  export type ConnectorTables = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubun/store-connector",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "keywords": [],
5
5
  "license": "see LICENSE.md",
6
6
  "sideEffects": false,
@@ -15,13 +15,13 @@
15
15
  "LICENSE.md"
16
16
  ],
17
17
  "dependencies": {
18
- "@kubun/db": "^0.16.0",
19
- "@kubun/db-adapter": "^0.16.0",
18
+ "@kubun/db": "^0.17.0",
19
+ "@kubun/db-adapter": "^0.17.0",
20
20
  "kysely": "^0.29.5"
21
21
  },
22
22
  "devDependencies": {
23
- "@kubun/db-better-sqlite": "^0.16.0",
24
- "@kubun/db-postgres": "^0.16.0",
23
+ "@kubun/db-better-sqlite": "^0.17.0",
24
+ "@kubun/db-postgres": "^0.17.0",
25
25
  "@testcontainers/postgresql": "^12.1.0"
26
26
  },
27
27
  "publishConfig": {
@@ -30,8 +30,8 @@
30
30
  "scripts": {
31
31
  "build": "pnpm run build:clean && pnpm run build:js && pnpm run build:types",
32
32
  "build:clean": "del lib",
33
- "build:js": "swc src -d ./lib --config-file ../../node_modules/@kigu/dev/swc.json --strip-leading-paths",
34
- "build:types": "tsc --emitDeclarationOnly --skipLibCheck",
33
+ "build:js": "del 'lib/**/*.js' && swc src -d ./lib --config-file ../../node_modules/@kigu/dev/swc.json --strip-leading-paths",
34
+ "build:types": "del 'lib/**/*.d.ts' 'lib/**/*.d.ts.map' && tsc --emitDeclarationOnly --skipLibCheck",
35
35
  "build:types:ci": "tsc --emitDeclarationOnly --declarationMap false",
36
36
  "test": "pnpm run test:types && pnpm run test:unit",
37
37
  "test:types": "tsc --noEmit -p tsconfig.test.json",