@persql/sdk 1.2.1 → 1.4.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
@@ -4,6 +4,8 @@ interface RawQueryResult {
4
4
  rows: unknown[][];
5
5
  rowsRead: number;
6
6
  rowsWritten: number;
7
+ changes?: number;
8
+ lastInsertRowid?: number;
7
9
  }
8
10
  /** In-process driver backing `new PerSQL({ local })` — runs SQL through `better-sqlite3` instead of the HTTP API. */
9
11
  declare class LocalDriver {
@@ -36,6 +38,60 @@ declare class LocalDriver {
36
38
  close(): void;
37
39
  }
38
40
 
41
+ interface AuthorizeUrlOptions {
42
+ /** The OAuth app's client_id (`psqlrp_…`). */
43
+ clientId: string;
44
+ /** Exact-match redirect URI registered for the app (HTTPS or loopback). */
45
+ redirectUri: string;
46
+ /**
47
+ * Space-separated scopes. Defaults to `"database"`; add `"openid"`
48
+ * (`"openid database"`) to also receive an `id_token` for sign-in.
49
+ */
50
+ scope?: string;
51
+ /** API origin. Defaults to https://api.persql.com */
52
+ baseURL?: string;
53
+ /** CSRF state. Defaults to a random value (returned so you can match it). */
54
+ state?: string;
55
+ /** Bring your own PKCE verifier. Defaults to a fresh random one. */
56
+ codeVerifier?: string;
57
+ }
58
+ interface AuthorizeRequest {
59
+ /** Open this in a browser / in-app browser / AuthSession. */
60
+ url: string;
61
+ /** Stash this until the redirect comes back — it's required to exchange the code. */
62
+ codeVerifier: string;
63
+ /** Compare against the `state` on the redirect to defeat CSRF. */
64
+ state: string;
65
+ }
66
+ interface ExchangeCodeOptions {
67
+ clientId: string;
68
+ redirectUri: string;
69
+ /** The `code` query param from the redirect. */
70
+ code: string;
71
+ /** The verifier from the matching {@link AuthorizeRequest}. */
72
+ codeVerifier: string;
73
+ baseURL?: string;
74
+ /** Confidential (server-side) clients only — never ship a secret in an app. */
75
+ clientSecret?: string;
76
+ fetch?: typeof fetch;
77
+ }
78
+ interface DatabaseGrant {
79
+ /** A `psql_live_…` token scoped to exactly this user's database. */
80
+ accessToken: string;
81
+ /** `"<namespace>/<database>"` — pass straight to `persql.database(...)`. */
82
+ database: string;
83
+ /** API base URL to construct the client with. */
84
+ apiUrl: string;
85
+ /** The scopes actually granted. */
86
+ scope: string;
87
+ /** Present only when `openid` was requested. */
88
+ idToken?: string;
89
+ /** The signed-in user's email (RFC 6749 §5.1 extra member). */
90
+ userEmail?: string;
91
+ }
92
+ declare function createAuthorizeUrl(opts: AuthorizeUrlOptions): Promise<AuthorizeRequest>;
93
+ declare function exchangeAuthorizationCode(opts: ExchangeCodeOptions): Promise<DatabaseGrant>;
94
+
39
95
  /**
40
96
  * @persql/sdk — Talk to your PerSQL databases from anywhere.
41
97
  *
@@ -105,6 +161,14 @@ interface QueryResult<T = Record<string, unknown>> {
105
161
  data: T[];
106
162
  rowsRead: number;
107
163
  rowsWritten: number;
164
+ /**
165
+ * SQLite `changes()` after a write statement — the exact affected-row
166
+ * count ORMs expect (`rowsWritten` also counts index writes). Absent
167
+ * on reads, DDL, and servers older than this field.
168
+ */
169
+ changes?: number;
170
+ /** SQLite `last_insert_rowid()` after a write statement. Absent on reads and DDL. */
171
+ lastInsertRowid?: number;
108
172
  /**
109
173
  * Per-call usage and cost the server echoes on `query()`. Undefined in
110
174
  * local mode (no server) and on the per-statement results of `batch()`
@@ -397,6 +461,30 @@ declare class PerSQL {
397
461
  }): Promise<PerSQL & {
398
462
  handedOff: HandoffClaim;
399
463
  }>;
464
+ /**
465
+ * Step 1 of the `database`-scope sign-in (user-owned app databases):
466
+ * build the `/oauth/authorize` URL plus the PKCE verifier + state to
467
+ * keep. Open `url` in a browser / in-app browser / Expo AuthSession,
468
+ * then call {@link PerSQL.completeConnect} with the returned `code`.
469
+ *
470
+ * const req = await PerSQL.beginConnect({
471
+ * clientId, redirectUri, scope: "openid database",
472
+ * });
473
+ * // open req.url, capture { code, state }; verify state === req.state
474
+ */
475
+ static beginConnect(opts: AuthorizeUrlOptions): Promise<AuthorizeRequest>;
476
+ /**
477
+ * Step 2: exchange the redirect's `code` for a scoped database token and
478
+ * get back a ready client. The granted database is on `.grant.database`.
479
+ *
480
+ * const persql = await PerSQL.completeConnect({
481
+ * clientId, redirectUri, code, codeVerifier: req.codeVerifier,
482
+ * });
483
+ * const db = persql.database(persql.grant.database);
484
+ */
485
+ static completeConnect(opts: ExchangeCodeOptions): Promise<PerSQL & {
486
+ grant: DatabaseGrant;
487
+ }>;
400
488
  /**
401
489
  * Reference a database by its `<namespace>/<slug>` path.
402
490
  * Both forms work: `db("acme/orders")` or `db("acme", "orders")`.
@@ -1283,4 +1371,4 @@ type SqliteProxyDriver = (sql: string, params: unknown[], method: "all" | "run"
1283
1371
  rows: unknown;
1284
1372
  }>;
1285
1373
 
1286
- export { type AiSdkTool, type AnthropicTool, type ApprovalEvent, ApprovalRequiredError, type ApprovalRule, type ApprovalRuleHit, type ApprovalStatus, type BatchExpect, type BatchOptions, type BranchInfo, type BranchMergeMode, type BranchMergeOptions, type BranchMergePlanStep, type BranchMergeResult, type BranchUpsertOptions, type ClaimBranchOptions, type ClaimedBranch, type CreateApprovalRuleInput, type CreateDatabaseOptions, type CreateSupportTicketOptions, type DatabaseInfo, type DatabaseSchema, type DatabaseToolBundle, type DescribeBundle, type HandoffClaim, type LangChainTool, type MastraTool, type OpenAiAgentsTool, type OpenAiTool, PerSQL, PerSQLApprovalRules, PerSQLApprovals, PerSQLBranches, PerSQLDatabase, PerSQLDatabases, PerSQLError, type PerSQLOptions, PerSQLProposals, type PollApprovalOptions, type ProposalPlan, type ProposeOptions, type QueryLogEntry, type QueryMeta, type QueryOptions, type QueryResult, RateLimitError, type RawQueryResult, type SchemaDoctorReport, type SchemaSearchResponse, type SingleToolBundle, type SqlErrorDetail, type SqlErrorKind, type SqliteProxyDriver, type Statement, type SubscribeApprovalOptions, type SubscribeChange, type SubscribeChangeKind, type SubscribeOptions, SupportClient, type TableInfo, type TableSample, type ValidateResult, type WhoamiInfo };
1374
+ export { type AiSdkTool, type AnthropicTool, type ApprovalEvent, ApprovalRequiredError, type ApprovalRule, type ApprovalRuleHit, type ApprovalStatus, type AuthorizeRequest, type AuthorizeUrlOptions, type BatchExpect, type BatchOptions, type BranchInfo, type BranchMergeMode, type BranchMergeOptions, type BranchMergePlanStep, type BranchMergeResult, type BranchUpsertOptions, type ClaimBranchOptions, type ClaimedBranch, type CreateApprovalRuleInput, type CreateDatabaseOptions, type CreateSupportTicketOptions, type DatabaseGrant, type DatabaseInfo, type DatabaseSchema, type DatabaseToolBundle, type DescribeBundle, type ExchangeCodeOptions, type HandoffClaim, type LangChainTool, type MastraTool, type OpenAiAgentsTool, type OpenAiTool, PerSQL, PerSQLApprovalRules, PerSQLApprovals, PerSQLBranches, PerSQLDatabase, PerSQLDatabases, PerSQLError, type PerSQLOptions, PerSQLProposals, type PollApprovalOptions, type ProposalPlan, type ProposeOptions, type QueryLogEntry, type QueryMeta, type QueryOptions, type QueryResult, RateLimitError, type RawQueryResult, type SchemaDoctorReport, type SchemaSearchResponse, type SingleToolBundle, type SqlErrorDetail, type SqlErrorKind, type SqliteProxyDriver, type Statement, type SubscribeApprovalOptions, type SubscribeChange, type SubscribeChangeKind, type SubscribeOptions, SupportClient, type TableInfo, type TableSample, type ValidateResult, type WhoamiInfo, createAuthorizeUrl, exchangeAuthorizationCode };
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ interface RawQueryResult {
4
4
  rows: unknown[][];
5
5
  rowsRead: number;
6
6
  rowsWritten: number;
7
+ changes?: number;
8
+ lastInsertRowid?: number;
7
9
  }
8
10
  /** In-process driver backing `new PerSQL({ local })` — runs SQL through `better-sqlite3` instead of the HTTP API. */
9
11
  declare class LocalDriver {
@@ -36,6 +38,60 @@ declare class LocalDriver {
36
38
  close(): void;
37
39
  }
38
40
 
41
+ interface AuthorizeUrlOptions {
42
+ /** The OAuth app's client_id (`psqlrp_…`). */
43
+ clientId: string;
44
+ /** Exact-match redirect URI registered for the app (HTTPS or loopback). */
45
+ redirectUri: string;
46
+ /**
47
+ * Space-separated scopes. Defaults to `"database"`; add `"openid"`
48
+ * (`"openid database"`) to also receive an `id_token` for sign-in.
49
+ */
50
+ scope?: string;
51
+ /** API origin. Defaults to https://api.persql.com */
52
+ baseURL?: string;
53
+ /** CSRF state. Defaults to a random value (returned so you can match it). */
54
+ state?: string;
55
+ /** Bring your own PKCE verifier. Defaults to a fresh random one. */
56
+ codeVerifier?: string;
57
+ }
58
+ interface AuthorizeRequest {
59
+ /** Open this in a browser / in-app browser / AuthSession. */
60
+ url: string;
61
+ /** Stash this until the redirect comes back — it's required to exchange the code. */
62
+ codeVerifier: string;
63
+ /** Compare against the `state` on the redirect to defeat CSRF. */
64
+ state: string;
65
+ }
66
+ interface ExchangeCodeOptions {
67
+ clientId: string;
68
+ redirectUri: string;
69
+ /** The `code` query param from the redirect. */
70
+ code: string;
71
+ /** The verifier from the matching {@link AuthorizeRequest}. */
72
+ codeVerifier: string;
73
+ baseURL?: string;
74
+ /** Confidential (server-side) clients only — never ship a secret in an app. */
75
+ clientSecret?: string;
76
+ fetch?: typeof fetch;
77
+ }
78
+ interface DatabaseGrant {
79
+ /** A `psql_live_…` token scoped to exactly this user's database. */
80
+ accessToken: string;
81
+ /** `"<namespace>/<database>"` — pass straight to `persql.database(...)`. */
82
+ database: string;
83
+ /** API base URL to construct the client with. */
84
+ apiUrl: string;
85
+ /** The scopes actually granted. */
86
+ scope: string;
87
+ /** Present only when `openid` was requested. */
88
+ idToken?: string;
89
+ /** The signed-in user's email (RFC 6749 §5.1 extra member). */
90
+ userEmail?: string;
91
+ }
92
+ declare function createAuthorizeUrl(opts: AuthorizeUrlOptions): Promise<AuthorizeRequest>;
93
+ declare function exchangeAuthorizationCode(opts: ExchangeCodeOptions): Promise<DatabaseGrant>;
94
+
39
95
  /**
40
96
  * @persql/sdk — Talk to your PerSQL databases from anywhere.
41
97
  *
@@ -105,6 +161,14 @@ interface QueryResult<T = Record<string, unknown>> {
105
161
  data: T[];
106
162
  rowsRead: number;
107
163
  rowsWritten: number;
164
+ /**
165
+ * SQLite `changes()` after a write statement — the exact affected-row
166
+ * count ORMs expect (`rowsWritten` also counts index writes). Absent
167
+ * on reads, DDL, and servers older than this field.
168
+ */
169
+ changes?: number;
170
+ /** SQLite `last_insert_rowid()` after a write statement. Absent on reads and DDL. */
171
+ lastInsertRowid?: number;
108
172
  /**
109
173
  * Per-call usage and cost the server echoes on `query()`. Undefined in
110
174
  * local mode (no server) and on the per-statement results of `batch()`
@@ -397,6 +461,30 @@ declare class PerSQL {
397
461
  }): Promise<PerSQL & {
398
462
  handedOff: HandoffClaim;
399
463
  }>;
464
+ /**
465
+ * Step 1 of the `database`-scope sign-in (user-owned app databases):
466
+ * build the `/oauth/authorize` URL plus the PKCE verifier + state to
467
+ * keep. Open `url` in a browser / in-app browser / Expo AuthSession,
468
+ * then call {@link PerSQL.completeConnect} with the returned `code`.
469
+ *
470
+ * const req = await PerSQL.beginConnect({
471
+ * clientId, redirectUri, scope: "openid database",
472
+ * });
473
+ * // open req.url, capture { code, state }; verify state === req.state
474
+ */
475
+ static beginConnect(opts: AuthorizeUrlOptions): Promise<AuthorizeRequest>;
476
+ /**
477
+ * Step 2: exchange the redirect's `code` for a scoped database token and
478
+ * get back a ready client. The granted database is on `.grant.database`.
479
+ *
480
+ * const persql = await PerSQL.completeConnect({
481
+ * clientId, redirectUri, code, codeVerifier: req.codeVerifier,
482
+ * });
483
+ * const db = persql.database(persql.grant.database);
484
+ */
485
+ static completeConnect(opts: ExchangeCodeOptions): Promise<PerSQL & {
486
+ grant: DatabaseGrant;
487
+ }>;
400
488
  /**
401
489
  * Reference a database by its `<namespace>/<slug>` path.
402
490
  * Both forms work: `db("acme/orders")` or `db("acme", "orders")`.
@@ -1283,4 +1371,4 @@ type SqliteProxyDriver = (sql: string, params: unknown[], method: "all" | "run"
1283
1371
  rows: unknown;
1284
1372
  }>;
1285
1373
 
1286
- export { type AiSdkTool, type AnthropicTool, type ApprovalEvent, ApprovalRequiredError, type ApprovalRule, type ApprovalRuleHit, type ApprovalStatus, type BatchExpect, type BatchOptions, type BranchInfo, type BranchMergeMode, type BranchMergeOptions, type BranchMergePlanStep, type BranchMergeResult, type BranchUpsertOptions, type ClaimBranchOptions, type ClaimedBranch, type CreateApprovalRuleInput, type CreateDatabaseOptions, type CreateSupportTicketOptions, type DatabaseInfo, type DatabaseSchema, type DatabaseToolBundle, type DescribeBundle, type HandoffClaim, type LangChainTool, type MastraTool, type OpenAiAgentsTool, type OpenAiTool, PerSQL, PerSQLApprovalRules, PerSQLApprovals, PerSQLBranches, PerSQLDatabase, PerSQLDatabases, PerSQLError, type PerSQLOptions, PerSQLProposals, type PollApprovalOptions, type ProposalPlan, type ProposeOptions, type QueryLogEntry, type QueryMeta, type QueryOptions, type QueryResult, RateLimitError, type RawQueryResult, type SchemaDoctorReport, type SchemaSearchResponse, type SingleToolBundle, type SqlErrorDetail, type SqlErrorKind, type SqliteProxyDriver, type Statement, type SubscribeApprovalOptions, type SubscribeChange, type SubscribeChangeKind, type SubscribeOptions, SupportClient, type TableInfo, type TableSample, type ValidateResult, type WhoamiInfo };
1374
+ export { type AiSdkTool, type AnthropicTool, type ApprovalEvent, ApprovalRequiredError, type ApprovalRule, type ApprovalRuleHit, type ApprovalStatus, type AuthorizeRequest, type AuthorizeUrlOptions, type BatchExpect, type BatchOptions, type BranchInfo, type BranchMergeMode, type BranchMergeOptions, type BranchMergePlanStep, type BranchMergeResult, type BranchUpsertOptions, type ClaimBranchOptions, type ClaimedBranch, type CreateApprovalRuleInput, type CreateDatabaseOptions, type CreateSupportTicketOptions, type DatabaseGrant, type DatabaseInfo, type DatabaseSchema, type DatabaseToolBundle, type DescribeBundle, type ExchangeCodeOptions, type HandoffClaim, type LangChainTool, type MastraTool, type OpenAiAgentsTool, type OpenAiTool, PerSQL, PerSQLApprovalRules, PerSQLApprovals, PerSQLBranches, PerSQLDatabase, PerSQLDatabases, PerSQLError, type PerSQLOptions, PerSQLProposals, type PollApprovalOptions, type ProposalPlan, type ProposeOptions, type QueryLogEntry, type QueryMeta, type QueryOptions, type QueryResult, RateLimitError, type RawQueryResult, type SchemaDoctorReport, type SchemaSearchResponse, type SingleToolBundle, type SqlErrorDetail, type SqlErrorKind, type SqliteProxyDriver, type Statement, type SubscribeApprovalOptions, type SubscribeChange, type SubscribeChangeKind, type SubscribeOptions, SupportClient, type TableInfo, type TableSample, type ValidateResult, type WhoamiInfo, createAuthorizeUrl, exchangeAuthorizationCode };
package/dist/index.js CHANGED
@@ -9,8 +9,10 @@ import {
9
9
  PerSQLError,
10
10
  PerSQLProposals,
11
11
  RateLimitError,
12
- SupportClient
13
- } from "./chunk-VJ776W3K.js";
12
+ SupportClient,
13
+ createAuthorizeUrl,
14
+ exchangeAuthorizationCode
15
+ } from "./chunk-5ELQCDXS.js";
14
16
  export {
15
17
  ApprovalRequiredError,
16
18
  PerSQL,
@@ -22,6 +24,8 @@ export {
22
24
  PerSQLError,
23
25
  PerSQLProposals,
24
26
  RateLimitError,
25
- SupportClient
27
+ SupportClient,
28
+ createAuthorizeUrl,
29
+ exchangeAuthorizationCode
26
30
  };
27
31
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@persql/sdk",
3
- "version": "1.2.1",
3
+ "version": "1.4.0",
4
4
  "description": "TypeScript SDK for PerSQL — SQLite databases on the edge for AI agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,7 +30,7 @@
30
30
  "vitest": "^3.1.1"
31
31
  },
32
32
  "peerDependencies": {
33
- "better-sqlite3": "^11.0.0"
33
+ "better-sqlite3": "^11.0.0 || ^12.0.0"
34
34
  },
35
35
  "peerDependenciesMeta": {
36
36
  "better-sqlite3": {