@fragno-dev/project-connector-fragment 0.0.0-stage → 0.0.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.
Files changed (77) hide show
  1. package/LICENSE.md +16 -0
  2. package/README.md +285 -2
  3. package/bin/run.js +4 -0
  4. package/dist/browser/client/react.d.ts +174 -0
  5. package/dist/browser/client/react.d.ts.map +1 -0
  6. package/dist/browser/client/react.js +195 -0
  7. package/dist/browser/client/react.js.map +1 -0
  8. package/dist/browser/client/solid.d.ts +177 -0
  9. package/dist/browser/client/solid.d.ts.map +1 -0
  10. package/dist/browser/client/solid.js +130 -0
  11. package/dist/browser/client/solid.js.map +1 -0
  12. package/dist/browser/client/svelte.d.ts +177 -0
  13. package/dist/browser/client/svelte.d.ts.map +1 -0
  14. package/dist/browser/client/svelte.js +132 -0
  15. package/dist/browser/client/svelte.js.map +1 -0
  16. package/dist/browser/client/vanilla.d.ts +204 -0
  17. package/dist/browser/client/vanilla.d.ts.map +1 -0
  18. package/dist/browser/client/vanilla.js +160 -0
  19. package/dist/browser/client/vanilla.js.map +1 -0
  20. package/dist/browser/client/vue.d.ts +177 -0
  21. package/dist/browser/client/vue.d.ts.map +1 -0
  22. package/dist/browser/client/vue.js +128 -0
  23. package/dist/browser/client/vue.js.map +1 -0
  24. package/dist/browser/client-BCzNDSlW.d.ts +711 -0
  25. package/dist/browser/client-BCzNDSlW.d.ts.map +1 -0
  26. package/dist/browser/index.d.ts +504 -0
  27. package/dist/browser/index.d.ts.map +1 -0
  28. package/dist/browser/index.js +2 -0
  29. package/dist/browser/src-CSPQuoKz.js +2286 -0
  30. package/dist/browser/src-CSPQuoKz.js.map +1 -0
  31. package/dist/cli/authorization-browser.js +20 -0
  32. package/dist/cli/authorization-browser.js.map +1 -0
  33. package/dist/cli/cli.d.ts +6 -0
  34. package/dist/cli/cli.d.ts.map +1 -0
  35. package/dist/cli/cli.js +258 -0
  36. package/dist/cli/cli.js.map +1 -0
  37. package/dist/cli/definition.js +13 -0
  38. package/dist/cli/definition.js.map +1 -0
  39. package/dist/cli/index.js +14 -0
  40. package/dist/cli/index.js.map +1 -0
  41. package/dist/cli/project-connector-client.js +235 -0
  42. package/dist/cli/project-connector-client.js.map +1 -0
  43. package/dist/cli/project-connector-contracts.js +125 -0
  44. package/dist/cli/project-connector-contracts.js.map +1 -0
  45. package/dist/cli/routes.js +449 -0
  46. package/dist/cli/routes.js.map +1 -0
  47. package/dist/cli/schema.js +18 -0
  48. package/dist/cli/schema.js.map +1 -0
  49. package/dist/node/definition.d.ts +170 -0
  50. package/dist/node/definition.d.ts.map +1 -0
  51. package/dist/node/definition.js +13 -0
  52. package/dist/node/definition.js.map +1 -0
  53. package/dist/node/index.d.ts +456 -0
  54. package/dist/node/index.d.ts.map +1 -0
  55. package/dist/node/index.js +36 -0
  56. package/dist/node/index.js.map +1 -0
  57. package/dist/node/project-connector-client.d.ts +13 -0
  58. package/dist/node/project-connector-client.d.ts.map +1 -0
  59. package/dist/node/project-connector-client.js +235 -0
  60. package/dist/node/project-connector-client.js.map +1 -0
  61. package/dist/node/project-connector-contracts.d.ts +179 -0
  62. package/dist/node/project-connector-contracts.d.ts.map +1 -0
  63. package/dist/node/project-connector-contracts.js +125 -0
  64. package/dist/node/project-connector-contracts.js.map +1 -0
  65. package/dist/node/routes.d.ts +307 -0
  66. package/dist/node/routes.d.ts.map +1 -0
  67. package/dist/node/routes.js +449 -0
  68. package/dist/node/routes.js.map +1 -0
  69. package/dist/node/schema.d.ts +49 -0
  70. package/dist/node/schema.d.ts.map +1 -0
  71. package/dist/node/schema.js +18 -0
  72. package/dist/node/schema.js.map +1 -0
  73. package/dist/node/testing/project-connector-test-gateway.d.ts +63 -0
  74. package/dist/node/testing/project-connector-test-gateway.d.ts.map +1 -0
  75. package/dist/node/testing/project-connector-test-gateway.js +370 -0
  76. package/dist/node/testing/project-connector-test-gateway.js.map +1 -0
  77. package/package.json +111 -3
package/LICENSE.md ADDED
@@ -0,0 +1,16 @@
1
+ Copyright 2025 - present "ReJot Nederland B.V.", and individual contributors.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
4
+ associated documentation files (the “Software”), to deal in the Software without restriction,
5
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
6
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
7
+ furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial
10
+ portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
13
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
15
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,286 @@
1
- # Temporary Holding Version
1
+ # @fragno-dev/project-connector-fragment
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A DB-backed Fragno fragment for the hosted OOMOL **Project Connector** API. It connects product
4
+ users to Gmail and other configured OAuth providers, verifies account bindings, reads provider
5
+ profiles, and executes actions using an explicit connected account.
6
+
7
+ Account operations use `oo_proj_...` project keys. Authoritative action contracts use a separate
8
+ server-only catalog credential through the SDK's `Connector.catalog` surface; it is never used to
9
+ execute actions or connect users. Create a project and provider configuration in OOMOL Console
10
+ first; see the [Project Connector guide](https://oomol.com/docs/project-connector/).
11
+
12
+ ## Try the CLI
13
+
14
+ From the repository root, using the same Node version used to install `better-sqlite3`:
15
+
16
+ ```bash
17
+ pnpm --filter @fragno-dev/project-connector-fragment cli -- check \
18
+ --env-file ../../apps/backoffice/.dev.vars
19
+
20
+ pnpm --filter @fragno-dev/project-connector-fragment cli -- connect gmail \
21
+ --env-file ../../apps/backoffice/.dev.vars \
22
+ --user-id wilco --connection-name work --beep
23
+ ```
24
+
25
+ The environment file is relative to the package directory for these `pnpm` commands. With the built
26
+ package, commands can also run from the repository root:
27
+
28
+ ```bash
29
+ node packages/project-connector-fragment/bin/run.js check --env-file apps/backoffice/.dev.vars
30
+ ```
31
+
32
+ After installation, use `fragno-project-connector` instead of the `node .../bin/run.js` prefix.
33
+
34
+ The required server environment variables are:
35
+
36
+ ```dotenv
37
+ OOMOL_CONNECTOR_BASE_URL=https://connector.oomol.com/v1
38
+ OOMOL_PROJECT_API_KEY=oo_proj_...
39
+ ```
40
+
41
+ `OOMOL_CONNECTOR_BASE_URL` is the Connector API root and must end in `/v1`. Environment variables
42
+ override values in `--env-file`. The key never travels through the browser and is not stored in
43
+ SQLite or printed in diagnostics.
44
+
45
+ Action discovery additionally requires `OOMOL_CONNECTOR_CATALOG_API_KEY`, a separate credential with
46
+ catalog access on the same gateway (for hosted OOMOL, a personal `api_...` key). Project credentials
47
+ are never substituted for catalog credentials. Omit it to leave account operations available but
48
+ fail action discovery with `catalog_not_configured` when the selected configuration allows actions.
49
+ A known configuration with an empty allowlist still returns an empty action list without catalog
50
+ access.
51
+
52
+ `connect` opens the authorization link, temporarily listens on `127.0.0.1:3930`, and polls the saved
53
+ request. On success it stores the verified binding and performs a **read-only provider profile
54
+ check**. It does not read Gmail messages or send email. `--beep` requests an audible authorization
55
+ prompt; `--no-open` only prints the link. `--provider-config-id` selects a particular provider
56
+ config instead of asking the gateway to resolve the service.
57
+
58
+ Local state defaults to `~/.fragno/project-connector-fragment`; override it with `--data-dir`. Keep
59
+ `--user-id` and `--data-dir` consistent across commands. Use `--port` for a different callback port
60
+ and `--timeout-ms` to shorten the OAuth wait (maximum ten minutes).
61
+
62
+ Additional commands:
63
+
64
+ ```bash
65
+ fragno-project-connector accounts --user-id wilco --env-file ./connector.env
66
+ fragno-project-connector status <request-id> --user-id wilco --env-file ./connector.env
67
+ fragno-project-connector profile <account-id> --user-id wilco --env-file ./connector.env
68
+
69
+ # Explicit action calls may read or modify provider data. Nothing executes automatically.
70
+ fragno-project-connector execute <account-id> gmail.search_threads \
71
+ --user-id wilco --env-file ./connector.env --input '{"query":"is:unread"}'
72
+ ```
73
+
74
+ All CLI operations exercise the fragment's real HTTP handler and SQLite migrations. The callback
75
+ page is navigation feedback only: even a forged callback account ID cannot create a binding. The
76
+ local CLI chooses its own user identity; do not expose it as an application server.
77
+
78
+ A successful `check` establishes gateway reachability and project-key authentication, not Gmail
79
+ availability. The SaaS API has no health endpoint, so this check expects the authenticated
80
+ `connection_request_not_found` response for a fresh, nonexistent request ID. All provider calls go
81
+ through the official `@oomol-lab/connector` `ProjectConnector` client; action metadata uses its
82
+ separate `Connector.catalog` surface.
83
+
84
+ ## Server integration
85
+
86
+ ```ts
87
+ import { createProjectConnectorFragment } from "@fragno-dev/project-connector-fragment";
88
+
89
+ const callbackUrl = "https://app.example.com/integrations/connected";
90
+ const fragment = createProjectConnectorFragment(
91
+ {
92
+ baseUrl: env.OOMOL_CONNECTOR_BASE_URL,
93
+ apiKey: env.OOMOL_PROJECT_API_KEY,
94
+ catalogApiKey: env.OOMOL_CONNECTOR_CATALOG_API_KEY ?? null,
95
+ // Implement this using your application's authenticated session, not a user-supplied ID.
96
+ getExternalUserId: resolveAuthenticatedUserId,
97
+ allowedReturnUrls: (url) => url.toString() === callbackUrl,
98
+ },
99
+ { databaseAdapter },
100
+ );
101
+ ```
102
+
103
+ `getExternalUserId(headers)` returns the authenticated product user's external ID or `null`. Mount
104
+ and migrate the fragment using your application's usual Fragno integration. The default mount is
105
+ `/api/project-connector-fragment`. Restrict provider/action access with your application's
106
+ authorization policy when needed; the fragment enforces account ownership and action/service
107
+ matching.
108
+
109
+ ## Provider configuration discovery
110
+
111
+ `GET /provider-configs` returns live OAuth configuration metadata for the configured project:
112
+ `projectId` and `providerConfigs`, whose entries contain `id`, `service`, `displayName`,
113
+ `callbackUrl`, `effectiveScopes`, and `proxyAvailable`, without action IDs. Use the
114
+ `useProviderConfigs` client hook to load this catalog, then pass the selected entry's `id` as
115
+ `providerConfigId` when connecting, especially when several configurations use the same service.
116
+
117
+ `GET /provider-configs/:providerConfigId/actions` and the `useProviderActions` client hook retrieve
118
+ `{ projectId, providerConfigId, actions }` for one exact configuration. Each action has `id`,
119
+ `service`, `name`, nullable `description`, and authoritative `inputSchema`/`outputSchema` JSON
120
+ Schemas. An unknown configuration returns `PROVIDER_CONFIG_NOT_FOUND` (404); a known configuration
121
+ with no allowed actions returns an empty `actions` list. Discovery never executes actions.
122
+
123
+ Discovery requires an authenticated product user but is project-scoped, not an account list. It
124
+ neither creates connections nor verifies provider accounts, and does not include API-key or custom
125
+ credential configurations. The server calls `/v1/saas/oauth/provider-configs` with the project key;
126
+ then retrieves the selected service's catalog in one `/v1/actions?service=...` request through
127
+ `Connector.catalog.actions` using only the separate catalog credential. Definitions are indexed by
128
+ unique action ID and selected in the configuration's allowlist order; duplicate allowlist IDs are
129
+ returned once. Only allowed definitions are returned. Their service must match the configuration,
130
+ and both schemas must be present; missing or invalid contracts fail the entire discovery response.
131
+ Catalog presence never expands the configuration's allowlist or bypasses account ownership/execution
132
+ authorization. Credentials and extra upstream fields stay outside the public response. Unsupported
133
+ deployments and upstream failures return `PROJECT_CONNECTOR_ERROR`, rather than an invented,
134
+ partial, or cached catalog.
135
+
136
+ ## Named connections and resumable OAuth
137
+
138
+ A named connection is the exact tuple `{ projectId, providerConfigId, connectionName }` within the
139
+ user identity established by `getExternalUserId`. Use the project/configuration IDs from discovery;
140
+ connection names follow the gateway's alias rule: lowercase letters, digits, underscores, and
141
+ hyphens, starting with a letter or digit. Every request and account has a name.
142
+
143
+ - `GET /connection-requests/by-name?projectId=...&providerConfigId=...&connectionName=...` returns
144
+ the single matching saved OAuth request as `{ request }`, with `request: null` when absent.
145
+ - `GET /accounts/by-name` with the same query returns `{ account }`, with `account: null` when
146
+ absent.
147
+
148
+ Both reads use indexed local state. They do not contact the gateway, refresh consent, execute
149
+ actions, or establish provider health. An OAuth request and its confirmed account have separate
150
+ meanings: a replacement authorization may be pending while the previously confirmed account remains
151
+ available.
152
+
153
+ Named lookup is additive: `POST /connection-requests` still starts a fresh attempt on every call,
154
+ including repeated or concurrent calls with the same name. Earlier request IDs remain usable, and
155
+ confirmed accounts remain addressable by their account IDs. Refreshing a new account does not remove
156
+ other accounts sharing its name. Reauthorization returning the same owned account ID updates that
157
+ binding without duplicating it; an incoming ID belonging to another user cannot replace their
158
+ binding.
159
+
160
+ If either lookup matches more than one record, it returns `CONNECTION_AMBIGUOUS` (409), even when
161
+ only one request is pending. The fragment does not choose the newest record, prefer a status, or
162
+ infer a current attempt. Lookups inspect at most two matching records plus the pagination lookahead;
163
+ no historical reconciliation or current-selection store is introduced. Use an already-known request
164
+ or account ID when a name is ambiguous.
165
+
166
+ After a page reload or server restart, recover the source-owned request instead of keeping a
167
+ separate setup handle:
168
+
169
+ ```ts
170
+ const selector = {
171
+ projectId: "your-project-id",
172
+ providerConfigId: "your-gmail-provider-config-id",
173
+ connectionName: "work",
174
+ };
175
+ const query = new URLSearchParams(selector);
176
+ const response = await fetch(
177
+ `/api/project-connector-fragment/connection-requests/by-name?${query}`,
178
+ );
179
+ if (!response.ok) throw new Error("Could not read the named authorization request");
180
+ const { request: pending } = await response.json();
181
+ if (pending) {
182
+ await connector.refreshConnection().mutate({ path: { requestId: pending.id } });
183
+ }
184
+ ```
185
+
186
+ `useNamedConnectionRequest` and `useNamedAccount` provide the same reads as client stores. Creating
187
+ an OAuth request invalidates named request stores; refreshing invalidates named request, named
188
+ account, and account-list stores. Missing/empty selector fields return `INVALID_SELECTOR` (400).
189
+ User identity is never accepted in the selector; another user's records remain absent.
190
+
191
+ The gateway alias is not an idempotency key. Each start creates its own remote authorization link;
192
+ link creation happens outside the retried local save. A lost gateway response or failed local save
193
+ is not claimed to be recoverable by alias, and this fragment does not introduce remote cleanup
194
+ machinery. Repeating a start is not a way to resume an existing attempt.
195
+
196
+ **Schema migration:** version 4 adds non-unique named lookup indexes; databases keep duplicate names
197
+ without reconciliation or a reset. Version 6 makes `connectionName` non-null on requests and
198
+ accounts. Every start has required a name, so stored rows are expected to have one; the migration
199
+ fails on a database that holds a null name.
200
+
201
+ ### Readiness hook
202
+
203
+ `onConnectionReadinessChanged` is an optional durable hook in the fragment config. It receives
204
+ `{ externalUserId, service, connection, ready }`, where `connection` is the named selector, when a
205
+ write changes whether the name has a confirmed account: `ready: false` when the first request for a
206
+ name starts, and `ready: true` when a refresh confirms the name's first account. A refresh that
207
+ moves an existing account ID to another name also reports the old name `ready: false` when it has no
208
+ other account. Further attempts for a name that already has an account fire nothing. The gateway
209
+ does not notify the fragment of consent or revocation, so readiness changes only when
210
+ `POST /connection-requests/:requestId/refresh` runs.
211
+
212
+ ## Client flow
213
+
214
+ ```ts
215
+ import { createProjectConnectorFragmentClient } from "@fragno-dev/project-connector-fragment/vanilla";
216
+
217
+ const connector = createProjectConnectorFragmentClient();
218
+ const request = await connector.connect().mutate({
219
+ body: {
220
+ providerConfigId: "your-gmail-provider-config-id",
221
+ connectionName: "work",
222
+ returnUri: "https://app.example.com/integrations/connected",
223
+ },
224
+ });
225
+
226
+ // Remember request.id before navigating. Do not trust callback query parameters.
227
+ window.location.assign(request.authorizationUrl);
228
+
229
+ // After returning, or while polling in the initiating UI:
230
+ const confirmed = await connector.refreshConnection().mutate({ path: { requestId: request.id } });
231
+ if (confirmed.state.status === "connected") {
232
+ const profile = await fetch(
233
+ `/api/project-connector-fragment/accounts/${confirmed.state.connectedAccountId}/profile`,
234
+ ).then((response) => response.json());
235
+ }
236
+ ```
237
+
238
+ Use exactly one of `providerConfigId` or `service` when connecting. Explicit provider IDs are
239
+ preferred for projects with multiple configurations for one service. React, Vue, Svelte, and Solid
240
+ entrypoints also export `createProjectConnectorFragmentClient` with their native adapter
241
+ conventions.
242
+
243
+ Client operations: `useProviderConfigs`, `useProviderActions`, `useStatus`, `useAccounts`,
244
+ `useNamedAccount`, `useNamedConnectionRequest`, `useProfile`, `connect`, `refreshConnection`, and
245
+ `executeAction`. Refreshing a connection invalidates account and named-request stores. The account
246
+ list is cursor-paginated (25 items per page); it lists local verified bindings, not live provider
247
+ availability.
248
+
249
+ ## Routes
250
+
251
+ | Method | Path | Purpose |
252
+ | ------ | ------------------------------------------------------------------------------------ | --------------------------------------------------------------- |
253
+ | GET | `/provider-configs` | Overview of this project's available OAuth configurations |
254
+ | GET | `/provider-configs/:providerConfigId/actions` | List allowed action contracts for one exact OAuth configuration |
255
+ | GET | `/status` | Check project-key authentication |
256
+ | GET | `/connection-requests/by-name?projectId=...&providerConfigId=...&connectionName=...` | Read an unambiguous request by exact name |
257
+ | POST | `/connection-requests` | Start a fresh OAuth request |
258
+ | POST | `/connection-requests/:requestId/refresh` | Verify gateway status and bind a completed account |
259
+ | GET | `/accounts?cursor=...` | List this user's locally verified account bindings |
260
+ | GET | `/accounts/by-name?projectId=...&providerConfigId=...&connectionName=...` | Read an unambiguous confirmed account by exact name |
261
+ | GET | `/accounts/:accountId/profile` | Read and verify the provider account profile |
262
+ | POST | `/accounts/:accountId/actions/:actionId` | Execute `{ "input": { ... } }` using the saved selector |
263
+
264
+ A connection is bound only when the authenticated gateway response is `connected` and matches the
265
+ saved request ID, project, provider config, external user, service, and connection name. `failed`
266
+ and `expired` are terminal and never create account bindings. Product users cannot select a
267
+ different user ID in request bodies, read other users' bindings, or execute actions on them.
268
+
269
+ Action output stays opaque; responses preserve `executionId` and `actionId` for troubleshooting.
270
+ Requests have a 30-second timeout. Action POSTs are **not automatically retried**, since retrying a
271
+ write such as `gmail.send_email` can duplicate its side effects. Upstream errors return safe
272
+ connector codes without exposing raw response bodies. Database errors still surface as database
273
+ errors.
274
+
275
+ This first version deliberately excludes provider setup/admin APIs, credential import, account
276
+ disconnect, a personal catalog API, and background synchronization. OAuth tokens are managed by
277
+ Project Connector, not by this fragment.
278
+
279
+ ## Development
280
+
281
+ ```bash
282
+ pnpm exec turbo build types:check test --filter=@fragno-dev/project-connector-fragment --output-logs=errors-only
283
+ ```
284
+
285
+ Scenario tests exercise a real local HTTP gateway, SQLite operations, authenticated routes, client
286
+ store invalidation, cursor pagination, and persistent CLI state. They do not use your real API key.
package/bin/run.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runProjectConnectorCli } from "../dist/cli/cli.js";
3
+
4
+ process.exitCode = await runProjectConnectorCli(process.argv.slice(2));
@@ -0,0 +1,174 @@
1
+ import { a as FragnoClientRequestError, c as InferOr, d as MaybeExtractPathParamsOrWiden, f as QueryParamsHint, i as ReadableAtom, l as ExtractPathParamsOrWiden, o as NonGetHTTPMethod, r as FetcherValue, s as FragnoPublicClientConfig, u as HasPathParams } from "../client-BCzNDSlW.js";
2
+ import { StandardSchemaV1 } from "@standard-schema/spec";
3
+ //#region ../fragno/dist/client/react.d.ts
4
+ //#region src/client/react.d.ts
5
+ type FragnoReactHook<_TMethod extends "GET", TPath extends string, TOutputSchema extends StandardSchemaV1, TErrorCode extends string, TQueryParameters extends string> = (args?: {
6
+ path?: MaybeExtractPathParamsOrWiden<TPath, string | ReadableAtom<string>>;
7
+ query?: QueryParamsHint<TQueryParameters, string | ReadableAtom<string>>;
8
+ }) => FetcherValue<StandardSchemaV1.InferOutput<TOutputSchema>, FragnoClientRequestError<NonNullable<TErrorCode>>> & {
9
+ refetch: () => void;
10
+ };
11
+ type FragnoReactMutator<_TMethod extends NonGetHTTPMethod, TPath extends string, TInputSchema extends StandardSchemaV1 | undefined, TOutputSchema extends StandardSchemaV1 | undefined, TErrorCode extends string, TQueryParameters extends string> = () => {
12
+ mutate: ({ body, path, query }: {
13
+ body?: InferOr<TInputSchema, undefined>;
14
+ path?: HasPathParams<TPath> extends true ? ExtractPathParamsOrWiden<TPath, string | ReadableAtom<string>> : undefined;
15
+ query?: QueryParamsHint<TQueryParameters, string | ReadableAtom<string>>;
16
+ }) => Promise<InferOr<TOutputSchema, undefined>>;
17
+ loading?: boolean | undefined;
18
+ error?: FragnoClientRequestError<NonNullable<TErrorCode>[number]> | undefined;
19
+ data?: InferOr<TOutputSchema, undefined> | undefined;
20
+ };
21
+ //#endregion
22
+ //#region src/client/react.d.ts
23
+ /** Creates the React client for the ProjectConnector fragment. */
24
+ declare function createProjectConnectorFragmentClient(config?: FragnoPublicClientConfig): {
25
+ useProviderConfigs: FragnoReactHook<"GET", "/provider-configs", import("zod").ZodObject<{
26
+ projectId: import("zod").ZodString;
27
+ providerConfigs: import("zod").ZodArray<import("zod").ZodObject<{
28
+ id: import("zod").ZodString;
29
+ service: import("zod").ZodString;
30
+ displayName: import("zod").ZodString;
31
+ callbackUrl: import("zod").ZodURL;
32
+ effectiveScopes: import("zod").ZodArray<import("zod").ZodString>;
33
+ proxyAvailable: import("zod").ZodBoolean;
34
+ }, import("zod/v4/core").$strip>>;
35
+ }, import("zod/v4/core").$strip>, "UNAUTHENTICATED" | "PROJECT_CONNECTOR_ERROR", string>;
36
+ useProviderActions: FragnoReactHook<"GET", "/provider-configs/:providerConfigId/actions", import("zod").ZodObject<{
37
+ projectId: import("zod").ZodString;
38
+ providerConfigId: import("zod").ZodString;
39
+ actions: import("zod").ZodArray<import("zod").ZodObject<{
40
+ id: import("zod").ZodString;
41
+ service: import("zod").ZodString;
42
+ name: import("zod").ZodString;
43
+ description: import("zod").ZodNullable<import("zod").ZodString>;
44
+ inputSchema: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
45
+ outputSchema: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
46
+ }, import("zod/v4/core").$strip>>;
47
+ }, import("zod/v4/core").$strip>, "UNAUTHENTICATED" | "PROJECT_CONNECTOR_ERROR" | "PROVIDER_CONFIG_NOT_FOUND", string>;
48
+ useStatus: FragnoReactHook<"GET", "/status", import("zod").ZodObject<{
49
+ authenticated: import("zod").ZodLiteral<true>;
50
+ }, import("zod/v4/core").$strip>, "UNAUTHENTICATED" | "PROJECT_CONNECTOR_ERROR", string>;
51
+ useAccounts: FragnoReactHook<"GET", "/accounts", import("zod").ZodObject<{
52
+ accounts: import("zod").ZodArray<import("zod").ZodObject<{
53
+ id: import("zod").ZodString;
54
+ projectId: import("zod").ZodString;
55
+ providerConfigId: import("zod").ZodString;
56
+ externalUserId: import("zod").ZodString;
57
+ service: import("zod").ZodString;
58
+ connectionName: import("zod").ZodString;
59
+ }, import("zod/v4/core").$strip>>;
60
+ cursor: import("zod").ZodNullable<import("zod").ZodString>;
61
+ hasNextPage: import("zod").ZodBoolean;
62
+ }, import("zod/v4/core").$strip>, "UNAUTHENTICATED" | "INVALID_CURSOR", "cursor">;
63
+ useNamedAccount: FragnoReactHook<"GET", "/accounts/by-name", import("zod").ZodObject<{
64
+ account: import("zod").ZodNullable<import("zod").ZodObject<{
65
+ id: import("zod").ZodString;
66
+ projectId: import("zod").ZodString;
67
+ providerConfigId: import("zod").ZodString;
68
+ externalUserId: import("zod").ZodString;
69
+ service: import("zod").ZodString;
70
+ connectionName: import("zod").ZodString;
71
+ }, import("zod/v4/core").$strip>>;
72
+ }, import("zod/v4/core").$strict>, "UNAUTHENTICATED" | "INVALID_SELECTOR" | "CONNECTION_AMBIGUOUS", "projectId" | "providerConfigId" | "connectionName">;
73
+ useNamedConnectionRequest: FragnoReactHook<"GET", "/connection-requests/by-name", import("zod").ZodObject<{
74
+ request: import("zod").ZodNullable<import("zod").ZodObject<{
75
+ id: import("zod").ZodString;
76
+ projectId: import("zod").ZodString;
77
+ providerConfigId: import("zod").ZodString;
78
+ externalUserId: import("zod").ZodString;
79
+ service: import("zod").ZodString;
80
+ connectionName: import("zod").ZodString;
81
+ authorizationUrl: import("zod").ZodURL;
82
+ expiresAt: import("zod").ZodString;
83
+ state: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
84
+ status: import("zod").ZodLiteral<"initiated">;
85
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
86
+ status: import("zod").ZodLiteral<"connected">;
87
+ connectedAccountId: import("zod").ZodString;
88
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
89
+ status: import("zod").ZodLiteral<"failed">;
90
+ errorCode: import("zod").ZodNullable<import("zod").ZodString>;
91
+ errorMessage: import("zod").ZodNullable<import("zod").ZodString>;
92
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
93
+ status: import("zod").ZodLiteral<"expired">;
94
+ }, import("zod/v4/core").$strip>], "status">;
95
+ }, import("zod/v4/core").$strip>>;
96
+ }, import("zod/v4/core").$strict>, "UNAUTHENTICATED" | "INVALID_SELECTOR" | "CONNECTION_AMBIGUOUS", "projectId" | "providerConfigId" | "connectionName">;
97
+ useProfile: FragnoReactHook<"GET", "/accounts/:accountId/profile", import("zod").ZodObject<{
98
+ connectedAccountId: import("zod").ZodString;
99
+ externalUserId: import("zod").ZodString;
100
+ service: import("zod").ZodString;
101
+ profile: import("zod").ZodObject<{
102
+ id: import("zod").ZodString;
103
+ kind: import("zod").ZodString;
104
+ username: import("zod").ZodNullable<import("zod").ZodString>;
105
+ displayName: import("zod").ZodNullable<import("zod").ZodString>;
106
+ avatarUrl: import("zod").ZodNullable<import("zod").ZodString>;
107
+ email: import("zod").ZodNullable<import("zod").ZodString>;
108
+ metadata: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
109
+ }, import("zod/v4/core").$strip>;
110
+ fetchedAt: import("zod").ZodNumber;
111
+ }, import("zod/v4/core").$strip>, "UNAUTHENTICATED" | "PROJECT_CONNECTOR_ERROR" | "ACCOUNT_NOT_FOUND", string>;
112
+ connect: FragnoReactMutator<NonGetHTTPMethod, "/connection-requests", import("zod").ZodUnion<readonly [import("zod").ZodObject<{
113
+ service: import("zod").ZodString;
114
+ connectionName: import("zod").ZodString;
115
+ returnUri: import("zod").ZodURL;
116
+ }, import("zod/v4/core").$strict>, import("zod").ZodObject<{
117
+ providerConfigId: import("zod").ZodString;
118
+ connectionName: import("zod").ZodString;
119
+ returnUri: import("zod").ZodURL;
120
+ }, import("zod/v4/core").$strict>]> | undefined, import("zod").ZodObject<{
121
+ id: import("zod").ZodString;
122
+ projectId: import("zod").ZodString;
123
+ providerConfigId: import("zod").ZodString;
124
+ externalUserId: import("zod").ZodString;
125
+ service: import("zod").ZodString;
126
+ connectionName: import("zod").ZodString;
127
+ authorizationUrl: import("zod").ZodURL;
128
+ expiresAt: import("zod").ZodString;
129
+ state: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
130
+ status: import("zod").ZodLiteral<"initiated">;
131
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
132
+ status: import("zod").ZodLiteral<"connected">;
133
+ connectedAccountId: import("zod").ZodString;
134
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
135
+ status: import("zod").ZodLiteral<"failed">;
136
+ errorCode: import("zod").ZodNullable<import("zod").ZodString>;
137
+ errorMessage: import("zod").ZodNullable<import("zod").ZodString>;
138
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
139
+ status: import("zod").ZodLiteral<"expired">;
140
+ }, import("zod/v4/core").$strip>], "status">;
141
+ }, import("zod/v4/core").$strip> | undefined, "UNAUTHENTICATED" | "PROJECT_CONNECTOR_ERROR" | "RETURN_URI_NOT_ALLOWED", string>;
142
+ refreshConnection: FragnoReactMutator<NonGetHTTPMethod, "/connection-requests/:requestId/refresh", import("@standard-schema/spec").StandardSchemaV1<unknown, unknown> | undefined, import("zod").ZodObject<{
143
+ id: import("zod").ZodString;
144
+ projectId: import("zod").ZodString;
145
+ providerConfigId: import("zod").ZodString;
146
+ externalUserId: import("zod").ZodString;
147
+ service: import("zod").ZodString;
148
+ connectionName: import("zod").ZodString;
149
+ authorizationUrl: import("zod").ZodURL;
150
+ expiresAt: import("zod").ZodString;
151
+ state: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
152
+ status: import("zod").ZodLiteral<"initiated">;
153
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
154
+ status: import("zod").ZodLiteral<"connected">;
155
+ connectedAccountId: import("zod").ZodString;
156
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
157
+ status: import("zod").ZodLiteral<"failed">;
158
+ errorCode: import("zod").ZodNullable<import("zod").ZodString>;
159
+ errorMessage: import("zod").ZodNullable<import("zod").ZodString>;
160
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
161
+ status: import("zod").ZodLiteral<"expired">;
162
+ }, import("zod/v4/core").$strip>], "status">;
163
+ }, import("zod/v4/core").$strip> | undefined, "UNAUTHENTICATED" | "PROJECT_CONNECTOR_ERROR" | "REQUEST_NOT_FOUND", string>;
164
+ executeAction: FragnoReactMutator<NonGetHTTPMethod, "/accounts/:accountId/actions/:actionId", import("zod").ZodObject<{
165
+ input: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
166
+ }, import("zod/v4/core").$strict> | undefined, import("zod").ZodObject<{
167
+ executionId: import("zod").ZodString;
168
+ actionId: import("zod").ZodString;
169
+ output: import("zod").ZodUnknown & import("zod").ZodType<{} | null, unknown, import("zod/v4/core").$ZodTypeInternals<{} | null, unknown>>;
170
+ }, import("zod/v4/core").$strip> | undefined, "UNAUTHENTICATED" | "PROJECT_CONNECTOR_ERROR" | "ACCOUNT_NOT_FOUND" | "ACTION_SERVICE_MISMATCH", string>;
171
+ };
172
+ //#endregion
173
+ export { createProjectConnectorFragmentClient };
174
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","names":[],"sources":["../../../../fragno/dist/client/react.d.ts","../../../src/client/react.ts"],"mappings":";;;;KASK,gBAAgB,wBAAwB,sBAAsB,sBAAsB,kBAAkB,2BAA2B,oCAAoC;EACxK,OAAO,8BAA8B,gBAAgB;EACrD,QAAQ,gBAAgB,2BAA2B;MAC/C,aAAa,iBAAiB,YAAY,gBAAgB,yBAAyB,YAAY;EACnG;;KAEG,mBAAmB,iBAAiB,kBAAkB,sBAAsB,qBAAqB,8BAA8B,sBAAsB,8BAA8B,2BAA2B;EACjN,WAAW,MAAM,MAAM;IACrB,OAAO,QAAQ;IACf,OAAO,cAAc,sBAAsB,yBAAyB,gBAAgB;IACpF,QAAQ,gBAAgB,2BAA2B;QAC/C,QAAQ,QAAQ;EACtB;EACA,QAAQ,yBAAyB,YAAY;EAC7C,OAAO,QAAQ;;;;;iBCjBD,qCAAqC,SAAQ;sBAAA"}