@fayz-ai/core 0.9.0 → 0.11.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.
Files changed (218) hide show
  1. package/README.md +2 -2
  2. package/dist/access/index.js.map +1 -1
  3. package/dist/chunk-BEGXYHS4.js +566 -0
  4. package/dist/chunk-BEGXYHS4.js.map +1 -0
  5. package/dist/chunk-ED6NBH6U.js +348 -0
  6. package/dist/chunk-ED6NBH6U.js.map +1 -0
  7. package/dist/chunk-EWKX4VUM.js +429 -0
  8. package/dist/chunk-EWKX4VUM.js.map +1 -0
  9. package/dist/chunk-LARZWDHA.js +319 -0
  10. package/dist/chunk-LARZWDHA.js.map +1 -0
  11. package/dist/chunk-OXQGRJZT.js +125 -0
  12. package/dist/chunk-OXQGRJZT.js.map +1 -0
  13. package/dist/chunk-RRYFXUQX.js +1247 -0
  14. package/dist/chunk-RRYFXUQX.js.map +1 -0
  15. package/dist/{chunk-5RJVUC6J.js → chunk-TDI6F6PT.js} +373 -25
  16. package/dist/chunk-TDI6F6PT.js.map +1 -0
  17. package/dist/{chunk-V2MSAUHO.js → chunk-UVKH6RDX.js} +211 -335
  18. package/dist/chunk-UVKH6RDX.js.map +1 -0
  19. package/dist/chunk-V53GR4UT.js +289 -0
  20. package/dist/chunk-V53GR4UT.js.map +1 -0
  21. package/dist/connector-runtime/index.d.ts +15 -0
  22. package/dist/connector-runtime/index.d.ts.map +1 -0
  23. package/dist/connector-runtime/index.js +3 -0
  24. package/dist/connector-runtime/index.js.map +1 -0
  25. package/dist/data/archetype.d.ts.map +1 -1
  26. package/dist/data/backend-env.d.ts +38 -0
  27. package/dist/data/backend-env.d.ts.map +1 -0
  28. package/dist/data/bulk.d.ts +24 -0
  29. package/dist/data/bulk.d.ts.map +1 -1
  30. package/dist/data/cached.d.ts.map +1 -1
  31. package/dist/data/custom-fields.d.ts +5 -0
  32. package/dist/data/custom-fields.d.ts.map +1 -0
  33. package/dist/data/index.d.ts +2 -1
  34. package/dist/data/index.d.ts.map +1 -1
  35. package/dist/data/index.js +3 -1
  36. package/dist/data/mock.d.ts.map +1 -1
  37. package/dist/data/platform-api.d.ts.map +1 -1
  38. package/dist/data/resolve.d.ts.map +1 -1
  39. package/dist/data/supabase.d.ts.map +1 -1
  40. package/dist/data/types.d.ts +8 -0
  41. package/dist/data/types.d.ts.map +1 -1
  42. package/dist/entity/events.d.ts +14 -0
  43. package/dist/entity/events.d.ts.map +1 -0
  44. package/dist/events/envelope.d.ts +31 -0
  45. package/dist/events/envelope.d.ts.map +1 -0
  46. package/dist/events/index.d.ts +4 -0
  47. package/dist/events/index.d.ts.map +1 -1
  48. package/dist/events/log.d.ts +44 -0
  49. package/dist/events/log.d.ts.map +1 -0
  50. package/dist/events/types.d.ts +40 -0
  51. package/dist/events/types.d.ts.map +1 -0
  52. package/dist/fields/store.d.ts +45 -0
  53. package/dist/fields/store.d.ts.map +1 -0
  54. package/dist/i18n/index.d.ts +10 -0
  55. package/dist/i18n/index.d.ts.map +1 -1
  56. package/dist/i18n/index.js +1 -1
  57. package/dist/i18n/shell-translations.en.d.ts.map +1 -1
  58. package/dist/i18n/shell-translations.pt-br.d.ts.map +1 -1
  59. package/dist/index.d.ts +45 -21
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +543 -56
  62. package/dist/index.js.map +1 -1
  63. package/dist/integrations/events.d.ts +7 -0
  64. package/dist/integrations/events.d.ts.map +1 -0
  65. package/dist/integrations/index.d.ts +533 -29
  66. package/dist/integrations/index.d.ts.map +1 -1
  67. package/dist/integrations/index.js +3 -1
  68. package/dist/integrations/permissions.d.ts +132 -0
  69. package/dist/integrations/permissions.d.ts.map +1 -0
  70. package/dist/integrations/request.d.ts +170 -0
  71. package/dist/integrations/request.d.ts.map +1 -0
  72. package/dist/integrations/runtime-token.d.ts +33 -0
  73. package/dist/integrations/runtime-token.d.ts.map +1 -0
  74. package/dist/integrations/runtime.d.ts +398 -0
  75. package/dist/integrations/runtime.d.ts.map +1 -0
  76. package/dist/integrations/settings.d.ts +102 -0
  77. package/dist/integrations/settings.d.ts.map +1 -0
  78. package/dist/integrations/store.d.ts +145 -0
  79. package/dist/integrations/store.d.ts.map +1 -0
  80. package/dist/{address/index.d.ts → lib/address.d.ts} +1 -1
  81. package/dist/{address/index.d.ts.map → lib/address.d.ts.map} +1 -1
  82. package/dist/{phone/index.d.ts → lib/phone.d.ts} +1 -1
  83. package/dist/lib/phone.d.ts.map +1 -0
  84. package/dist/{seo/index.d.ts → lib/seo.d.ts} +18 -1
  85. package/dist/lib/seo.d.ts.map +1 -0
  86. package/dist/{tenant/index.d.ts → lib/tenant.d.ts} +1 -1
  87. package/dist/lib/tenant.d.ts.map +1 -0
  88. package/dist/manifest/index.d.ts +1 -1
  89. package/dist/manifest/index.d.ts.map +1 -1
  90. package/dist/messaging/index.d.ts +3 -0
  91. package/dist/messaging/index.d.ts.map +1 -0
  92. package/dist/messaging/registry.d.ts +35 -0
  93. package/dist/messaging/registry.d.ts.map +1 -0
  94. package/dist/messaging/types.d.ts +67 -0
  95. package/dist/messaging/types.d.ts.map +1 -0
  96. package/dist/plugin/index.js +3 -1
  97. package/dist/plugin/runtime.d.ts +17 -0
  98. package/dist/plugin/runtime.d.ts.map +1 -1
  99. package/dist/registry/block-catalog.d.ts +78 -0
  100. package/dist/registry/block-catalog.d.ts.map +1 -0
  101. package/dist/registry/block-constraints.d.ts +64 -0
  102. package/dist/registry/block-constraints.d.ts.map +1 -0
  103. package/dist/registry/block-schema.d.ts +69 -0
  104. package/dist/registry/block-schema.d.ts.map +1 -0
  105. package/dist/registry/blocks.d.ts +84 -0
  106. package/dist/registry/blocks.d.ts.map +1 -0
  107. package/dist/registry/entities.d.ts +179 -0
  108. package/dist/registry/entities.d.ts.map +1 -0
  109. package/dist/registry/extension-points.d.ts +117 -0
  110. package/dist/registry/extension-points.d.ts.map +1 -0
  111. package/dist/registry/handles.d.ts +41 -0
  112. package/dist/registry/handles.d.ts.map +1 -0
  113. package/dist/registry/index.d.ts +41 -41
  114. package/dist/registry/index.d.ts.map +1 -1
  115. package/dist/registry/loaders.d.ts +55 -0
  116. package/dist/registry/loaders.d.ts.map +1 -0
  117. package/dist/registry/registry-class.d.ts +157 -0
  118. package/dist/registry/registry-class.d.ts.map +1 -0
  119. package/dist/registry/schema-check.d.ts +14 -0
  120. package/dist/registry/schema-check.d.ts.map +1 -0
  121. package/dist/router/index.d.ts +78 -1
  122. package/dist/router/index.d.ts.map +1 -1
  123. package/dist/router/index.js +1 -1
  124. package/dist/{shell-translations.pt-br-2GWRQRRP.js → shell-translations.pt-br-BM5ZFSKJ.js} +72 -3
  125. package/dist/shell-translations.pt-br-BM5ZFSKJ.js.map +1 -0
  126. package/dist/telemetry/errors.d.ts +87 -0
  127. package/dist/telemetry/errors.d.ts.map +1 -0
  128. package/dist/testing/index.js +4 -1
  129. package/dist/{testing/index.d.ts → testing.d.ts} +5 -3
  130. package/dist/testing.d.ts.map +1 -0
  131. package/dist/types/analytics.d.ts +213 -0
  132. package/dist/types/analytics.d.ts.map +1 -0
  133. package/dist/types/crud.d.ts +37 -3
  134. package/dist/types/crud.d.ts.map +1 -1
  135. package/dist/types/plugins.d.ts +138 -1
  136. package/dist/types/plugins.d.ts.map +1 -1
  137. package/package.json +9 -17
  138. package/dist/blocks/index.d.ts +0 -25
  139. package/dist/blocks/index.d.ts.map +0 -1
  140. package/dist/chunk-5RJVUC6J.js.map +0 -1
  141. package/dist/chunk-L4TLMYGC.js +0 -42
  142. package/dist/chunk-L4TLMYGC.js.map +0 -1
  143. package/dist/chunk-V2MSAUHO.js.map +0 -1
  144. package/dist/chunk-X5THHG6T.js +0 -77
  145. package/dist/chunk-X5THHG6T.js.map +0 -1
  146. package/dist/chunk-Y2C2FBQP.js +0 -35
  147. package/dist/chunk-Y2C2FBQP.js.map +0 -1
  148. package/dist/chunk-YH25Y4FW.js +0 -311
  149. package/dist/chunk-YH25Y4FW.js.map +0 -1
  150. package/dist/phone/index.d.ts.map +0 -1
  151. package/dist/seo/index.d.ts.map +0 -1
  152. package/dist/shell-translations.pt-br-2GWRQRRP.js.map +0 -1
  153. package/dist/tenant/index.d.ts.map +0 -1
  154. package/dist/testing/index.d.ts.map +0 -1
  155. package/src/access/denial.ts +0 -33
  156. package/src/access/engine.test.ts +0 -48
  157. package/src/access/engine.ts +0 -136
  158. package/src/access/index.ts +0 -14
  159. package/src/access/limits.ts +0 -18
  160. package/src/address/index.ts +0 -188
  161. package/src/app/render.tsx +0 -69
  162. package/src/blocks/index.tsx +0 -68
  163. package/src/data/archetype.ts +0 -255
  164. package/src/data/bulk.ts +0 -35
  165. package/src/data/cached.ts +0 -55
  166. package/src/data/count.test.ts +0 -152
  167. package/src/data/count.ts +0 -131
  168. package/src/data/filters.test.ts +0 -70
  169. package/src/data/filters.ts +0 -90
  170. package/src/data/index.ts +0 -11
  171. package/src/data/mock.ts +0 -90
  172. package/src/data/platform-api.ts +0 -209
  173. package/src/data/refresh.ts +0 -115
  174. package/src/data/resolve.ts +0 -126
  175. package/src/data/supabase.ts +0 -230
  176. package/src/data/types.ts +0 -50
  177. package/src/entity/index.ts +0 -2
  178. package/src/entity/registry.ts +0 -49
  179. package/src/events/index.tsx +0 -82
  180. package/src/i18n/index.ts +0 -476
  181. package/src/i18n/shell-translations.en.ts +0 -875
  182. package/src/i18n/shell-translations.pt-br.ts +0 -873
  183. package/src/index.ts +0 -217
  184. package/src/integrations/index.ts +0 -237
  185. package/src/lib/cache.ts +0 -118
  186. package/src/lib/csv.ts +0 -54
  187. package/src/lib/format.ts +0 -58
  188. package/src/manifest/app-manifest.schema.json +0 -676
  189. package/src/manifest/index.ts +0 -518
  190. package/src/manifest/serialize.ts +0 -52
  191. package/src/phone/index.ts +0 -85
  192. package/src/plugin/createSafeDataProvider.ts +0 -30
  193. package/src/plugin/index.ts +0 -1
  194. package/src/plugin/runtime.ts +0 -331
  195. package/src/registry/index.ts +0 -163
  196. package/src/router/history.ts +0 -86
  197. package/src/router/index.ts +0 -29
  198. package/src/runtime/index.ts +0 -15
  199. package/src/runtime/oauth.ts +0 -219
  200. package/src/search/engine.ts +0 -559
  201. package/src/search/index.ts +0 -25
  202. package/src/search/text.ts +0 -206
  203. package/src/search/types.ts +0 -75
  204. package/src/seo/index.ts +0 -128
  205. package/src/tenant/index.ts +0 -38
  206. package/src/testing/index.ts +0 -116
  207. package/src/types/auth.ts +0 -41
  208. package/src/types/billing.ts +0 -39
  209. package/src/types/crud.ts +0 -184
  210. package/src/types/entities.ts +0 -142
  211. package/src/types/entitlements.ts +0 -45
  212. package/src/types/i18n.ts +0 -7
  213. package/src/types/index.ts +0 -11
  214. package/src/types/org.ts +0 -137
  215. package/src/types/payment.ts +0 -44
  216. package/src/types/permissions.ts +0 -32
  217. package/src/types/plugins.ts +0 -480
  218. package/src/types/theme.ts +0 -8
@@ -0,0 +1,398 @@
1
+ export type Cursor = {
2
+ kind: 'delta';
3
+ token: string | null;
4
+ restartFrom?: string;
5
+ } | {
6
+ kind: 'window';
7
+ from: string;
8
+ to: string;
9
+ overlapMs: number;
10
+ } | {
11
+ kind: 'period';
12
+ period: string;
13
+ sealed: boolean;
14
+ };
15
+ /** `authoritative` = absence means deleted. `additive` = absence means nothing. */
16
+ export type Completeness = 'authoritative' | 'additive';
17
+ /**
18
+ * What a cursor kind can promise about the records it did NOT return.
19
+ *
20
+ * Only a delta cursor can promise anything: the server counted the changes and
21
+ * named the tombstones. A window is computed by the client against a server
22
+ * with no memory, so the records outside it are not absent — they were never
23
+ * asked for.
24
+ */
25
+ export declare function cursorCompleteness(cursor: Cursor): Completeness;
26
+ /**
27
+ * The header a runtime-data token rides in, on its way to a data plane.
28
+ *
29
+ * It lives beside `redeemConnectorCredential` because the two only make sense
30
+ * together: the function cannot mint a token and must forward the one the
31
+ * request carried, so the caller and the callee have to agree on a spelling.
32
+ * Two connectors that each picked their own would fail at exactly the moment a
33
+ * merchant clicks Sincronizar, and would look like a credential problem.
34
+ *
35
+ * Lower-case: an edge function reads `request.headers.get(...)`, which is
36
+ * case-insensitive, but a CORS `Access-Control-Allow-Headers` list is compared
37
+ * against the lower-cased name the browser sends.
38
+ */
39
+ export declare const CONNECTOR_RUNTIME_TOKEN_HEADER = "x-fayz-runtime-token";
40
+ /** What redemption returns. `secrets` is the credential — it goes to the provider and nowhere else. */
41
+ export interface RedeemedConnectorCredential {
42
+ connectionId: string;
43
+ connectorSlug: string;
44
+ tenantKey: string;
45
+ authKind: string;
46
+ /**
47
+ * For `api-key` and `mtls`, the fields the merchant typed. For `oauth`, a
48
+ * freshly minted access token — `refresh_token` is removed on the platform
49
+ * side, so the field that could mint further tokens has no route out.
50
+ */
51
+ secrets: Record<string, string>;
52
+ /** Present for `oauth`: when the returned access token stops working. */
53
+ expiresAt?: string;
54
+ }
55
+ /** The credential could not be read. Never carries the secret, the token or the body. */
56
+ export declare class ConnectorCredentialUnavailableError extends Error {
57
+ readonly status: number | null;
58
+ constructor(message: string, status?: number | null);
59
+ }
60
+ export interface RedeemConnectorCredentialOptions {
61
+ /** Which connector's credential, e.g. 'appmax'. */
62
+ connectorSlug: string;
63
+ /**
64
+ * The runtime-data token that came in with the request being served.
65
+ *
66
+ * It is what says which tenant this run is for, and the function has no way
67
+ * to mint one — so it is required for anything serving a signed-in operator.
68
+ * The one alternative is {@link tenantKey}; exactly one of the two must be set.
69
+ */
70
+ runtimeToken?: string;
71
+ /**
72
+ * MACHINE mode: name the tenant instead of proving it with a token.
73
+ *
74
+ * For callers a session never reaches — a shopper with no account, a cron job
75
+ * with no user. The redemption secret alone then stands for "not a browser",
76
+ * so the platform bounds this path to `MACHINE_REDEEMABLE_CONNECTORS` and
77
+ * audits every use as `machine`.
78
+ *
79
+ * Consequence worth stating plainly: whoever holds the secret can reach any
80
+ * tenant of that project through this door. That is why it only ever lives in
81
+ * an edge function's environment, never in anything a browser loads.
82
+ */
83
+ tenantKey?: string;
84
+ /** Defaults to `FAYZ_API_URL` from the environment. */
85
+ apiUrl?: string;
86
+ /** Defaults to `FAYZ_PROJECT_ID`. */
87
+ projectId?: string;
88
+ /** Defaults to `CONNECTOR_REDEMPTION_SECRET`. */
89
+ redemptionSecret?: string;
90
+ /** Defaults to the ambient `fetch`. Injected so the call is provable under node:test. */
91
+ fetchImpl?: (input: string, init: Record<string, unknown>) => Promise<{
92
+ ok: boolean;
93
+ status: number;
94
+ text(): Promise<string>;
95
+ }>;
96
+ /** Defaults to `Deno.env.get`, falling back to `process.env`. */
97
+ env?: (name: string) => string | undefined;
98
+ }
99
+ /**
100
+ * The header a data-plane call carries its runtime token in.
101
+ *
102
+ * A header and not the body: `Authorization` already belongs to the platform
103
+ * the function is deployed on (Supabase checks the caller's JWT there), and a
104
+ * token in a body is a token in whatever logs that body.
105
+ *
106
+ * It is declared ONCE, above, in the module that loads under Deno, because both
107
+ * halves have to name it and only one of them can import the other's: the
108
+ * browser side gets it through `@fayz-ai/core` and the function side through
109
+ * `@fayz-ai/core/connector-runtime`. Written down once, or the second caller
110
+ * spells it differently and neither is wrong at review time — which is exactly
111
+ * what two branches did here, each adding its own `const` with the same value.
112
+ */
113
+ /** The three names `provisionConnectorRuntimeEnv` puts into a project's functions. */
114
+ export declare const CONNECTOR_REDEMPTION_ENV_KEYS: readonly ["FAYZ_API_URL", "FAYZ_PROJECT_ID", "CONNECTOR_REDEMPTION_SECRET"];
115
+ /** The host a redemption was addressed to. Never the path — it carries the ids. */
116
+ export declare function redemptionHost(url: string): string;
117
+ /**
118
+ * What a failed redemption should say. Exported so it can be graded — the value
119
+ * is entirely in what it names.
120
+ *
121
+ * `door` is `'session'` for an operator's token, or the tenant key a machine
122
+ * call named. Both are safe to print; neither the secret nor the token is.
123
+ */
124
+ export declare function redemptionFailure(connectorSlug: string, status: number, url: string, door: 'session' | string, said?: string): string;
125
+ /**
126
+ * Read a tenant's connector credential from the platform, server-side.
127
+ *
128
+ * Everything that could leak is deliberately absent from what this can throw:
129
+ * the response body is never quoted, because the only route that returns a
130
+ * credential is this one and an error message is the easiest place for it to
131
+ * end up.
132
+ */
133
+ export declare function redeemConnectorCredential(options: RedeemConnectorCredentialOptions): Promise<RedeemedConnectorCredential>;
134
+ /**
135
+ * A provider answered with a status the caller could not use. `body` is carried
136
+ * because some providers put the real reason there and only there — Google
137
+ * signals quota exhaustion as 403 with `rateLimitExceeded` in the payload, and a
138
+ * classifier that only sees the status cannot tell it from a permission denial.
139
+ */
140
+ export declare class ConnectorHttpError extends Error {
141
+ readonly status: number;
142
+ readonly retryAfterMs: number | null;
143
+ readonly body: string | null;
144
+ readonly details: unknown;
145
+ constructor(status: number, message: string, options?: {
146
+ retryAfterMs?: number | null;
147
+ body?: string | null;
148
+ details?: unknown;
149
+ });
150
+ }
151
+ /**
152
+ * RFC 7231 `Retry-After`: either delta-seconds or an HTTP-date. Returns
153
+ * milliseconds, or null when the header is absent or unparseable.
154
+ */
155
+ export declare function parseRetryAfter(value: string | null | undefined, now?: number): number | null;
156
+ export interface BackoffOptions {
157
+ baseDelayMs?: number;
158
+ maxDelayMs?: number;
159
+ random?: () => number;
160
+ }
161
+ /** Exponential backoff with ±25% jitter, capped. Attempt is 1-based. */
162
+ export declare function backoffDelay(attempt: number, options?: BackoffOptions): number;
163
+ export type Verdict =
164
+ /** Hand the response back to the caller — success, or a client error it must see. */
165
+ {
166
+ action: 'return';
167
+ }
168
+ /** Wait, then repeat the same request. */
169
+ | {
170
+ action: 'retry';
171
+ delayMs: number;
172
+ }
173
+ /** The credential is stale: renew it, then repeat the request once. */
174
+ | {
175
+ action: 'reauth';
176
+ }
177
+ /** The cursor is gone: discard it and restart the run from scratch. */
178
+ | {
179
+ action: 'reset-cursor';
180
+ }
181
+ /** Nothing left to try. */
182
+ | {
183
+ action: 'fail';
184
+ reason: string;
185
+ };
186
+ /** What `classify` is shown about one attempt. */
187
+ export interface AttemptOutcome {
188
+ /** null when the transport itself failed and there is no response. */
189
+ status: number | null;
190
+ headers?: {
191
+ get(name: string): string | null;
192
+ } | null;
193
+ /** Response body, when the caller peeked at it. See {@link ClassifyOptions.needsBody}. */
194
+ body?: string | null;
195
+ error?: unknown;
196
+ /** 1-based. */
197
+ attempt: number;
198
+ maxAttempts: number;
199
+ }
200
+ export interface ClassifyOptions extends BackoffOptions {
201
+ now?: () => number;
202
+ /** Statuses to retry beyond the defaults (408, 425, 429, 5xx). */
203
+ retryableStatuses?: number[];
204
+ /** Statuses meaning "the cursor is stale, start over". Google: 410. */
205
+ resetCursorStatuses?: number[];
206
+ /** Statuses meaning "renew the credential and repeat". Default: 401. */
207
+ reauthStatuses?: number[];
208
+ /** Where this provider states its wait. Default: `Retry-After` (RFC 7231). */
209
+ readRetryAfter?(headers: {
210
+ get(name: string): string | null;
211
+ } | null | undefined, now: number): number | null;
212
+ /**
213
+ * Whether a 403 is quota exhaustion rather than a permission denial.
214
+ *
215
+ * This is the defect the extraction fixes. `isRetryableGoogleStatus` returned
216
+ * false for 403 — and 403 with `rateLimitExceeded` in the body is exactly how
217
+ * the Google Calendar API reports the quota being blown, the single most
218
+ * characteristic failure of the provider it was written for.
219
+ */
220
+ isQuotaBody?(body: string | null | undefined, status: number): boolean;
221
+ /** Statuses whose body `classify` needs. Default: [403], for the case above. */
222
+ needsBody?: number[];
223
+ }
224
+ /** Statuses whose body must be read before `classify` can decide. */
225
+ export declare function statusNeedsBody(status: number | null, options?: ClassifyOptions): boolean;
226
+ /** The one retry policy. See {@link Verdict}. */
227
+ export declare function classify(outcome: AttemptOutcome, options?: ClassifyOptions): Verdict;
228
+ /** The slice of `Response` this module touches. Keeps the module runtime-free. */
229
+ export interface MinimalResponse {
230
+ status: number;
231
+ headers: {
232
+ get(name: string): string | null;
233
+ };
234
+ clone?(): {
235
+ text(): Promise<string>;
236
+ };
237
+ text?(): Promise<string>;
238
+ }
239
+ export interface FetchWithRetryOptions extends ClassifyOptions {
240
+ maxAttempts?: number;
241
+ sleep?: (ms: number) => Promise<void>;
242
+ onRetry?(info: {
243
+ attempt: number;
244
+ delayMs: number;
245
+ status: number | null;
246
+ error: unknown;
247
+ }): void;
248
+ /**
249
+ * Renew the credential and return the init for the repeat. Called at most
250
+ * once per request — a refresh loop against a provider that rate-limits its
251
+ * own token endpoint is how an IP gets blocked for an hour.
252
+ */
253
+ onReauth?(): Promise<Record<string, unknown> | void> | Record<string, unknown> | void;
254
+ }
255
+ type FetchLike = (input: unknown, init?: unknown) => Promise<MinimalResponse>;
256
+ /**
257
+ * One request, retried according to {@link classify}. Returns the last response;
258
+ * it never converts a status into an exception, because which 4xx is fatal is
259
+ * the caller's domain question, not the transport's.
260
+ */
261
+ export declare function fetchWithRetry(fetchImpl: FetchLike, input: unknown, init: unknown, options?: FetchWithRetryOptions): Promise<MinimalResponse>;
262
+ /**
263
+ * Whether something dated expires within the lead time — a watch channel, an
264
+ * OAuth access token, a refresh token that rotates. Renewing with slack is a
265
+ * requirement and not a nicety for a provider like Bling, whose token endpoint
266
+ * blocks the IP for an hour after 20 calls in a minute: the only safe refresh
267
+ * is the one made days early, never the one made in a loop at the deadline.
268
+ */
269
+ export declare function isExpiring(expiresAt: string | number | Date | null | undefined, options?: {
270
+ now?: number;
271
+ leadMs?: number;
272
+ }): boolean;
273
+ export interface PageResult<TItem, TRequest> {
274
+ items?: TItem[];
275
+ /** The request for the next page, or null/undefined when this was the last. */
276
+ next?: TRequest | null;
277
+ }
278
+ export interface PaginateOptions<TItem, TRequest> {
279
+ /** The request for page one. */
280
+ first: TRequest;
281
+ fetchPage(request: TRequest): Promise<PageResult<TItem, TRequest>>;
282
+ /** Hard stop, so a provider that always returns a next token cannot spin. */
283
+ maxPages?: number;
284
+ /**
285
+ * Where to restart when a page fails with a `reset-cursor` verdict. Absent =
286
+ * the reset is not available and the error propagates.
287
+ */
288
+ resetTo?(request: TRequest): TRequest | null;
289
+ /** Classify a thrown page error. Defaults to reading `error.status`. */
290
+ classifyError?(error: unknown): Verdict;
291
+ onCursorReset?(): void;
292
+ }
293
+ export interface PaginateResult<TItem> {
294
+ items: TItem[];
295
+ pages: number;
296
+ /** Whether the run restarted after the provider rejected the cursor. */
297
+ cursorReset: boolean;
298
+ }
299
+ /**
300
+ * Walk every page. The contract is that `items` is complete when this returns —
301
+ * a caller that stops at the first page is the FAY-1377 bug, and no connector
302
+ * should have to re-derive the loop to avoid it.
303
+ */
304
+ export declare function paginate<TItem, TRequest>(options: PaginateOptions<TItem, TRequest>): Promise<PaginateResult<TItem>>;
305
+ export interface RateLimitBudget {
306
+ /** Sustained requests per second the provider allows for one account. */
307
+ perSecond?: number;
308
+ /** Requests per rolling day for one account, summed across every module. */
309
+ perDay?: number;
310
+ }
311
+ export interface RateLimiterOptions {
312
+ now?: () => number;
313
+ sleep?: (ms: number) => Promise<void>;
314
+ /** Calls already spent today, read from the run history on resume. */
315
+ spentToday?: number;
316
+ }
317
+ export declare class RateLimitExceededError extends Error {
318
+ readonly kind = "daily-budget";
319
+ constructor(perDay: number);
320
+ }
321
+ export interface RateLimiter {
322
+ /** Wait until one call fits inside the budget. Throws when the day is spent. */
323
+ take(): Promise<void>;
324
+ /** Calls taken since the limiter was created, plus what it resumed with. */
325
+ readonly spent: number;
326
+ /** Whether another call fits today at all. */
327
+ readonly exhausted: boolean;
328
+ }
329
+ /**
330
+ * A token bucket over the declared budget. The clock is injected, so "3000 SKUs
331
+ * enter without blowing 3 req/s" is a proof and not an impression.
332
+ */
333
+ export declare function createRateLimiter(budget: RateLimitBudget, options?: RateLimiterOptions): RateLimiter;
334
+ /**
335
+ * Split a range into slices no longer than `maxSpanMs`.
336
+ *
337
+ * Bling answers a date filter wider than one year with a 400, so the window is
338
+ * always sliced. Generic because the constraint is not Bling's alone — a
339
+ * provider that caps a range is the normal case, and a connector that discovers
340
+ * the cap in production discovers it as a failed backfill.
341
+ */
342
+ export declare function sliceWindow(from: string, to: string, maxSpanMs: number): Array<{
343
+ from: string;
344
+ to: string;
345
+ }>;
346
+ /**
347
+ * The next window to ask for, overlapping the one just finished.
348
+ *
349
+ * The overlap is not belt-and-braces: a provider that stamps `updatedAt` at
350
+ * second precision, or writes it a moment before the row is visible, drops
351
+ * whatever landed on the boundary. Re-reading it costs an idempotent upsert.
352
+ */
353
+ export declare function advanceWindow(cursor: Extract<Cursor, {
354
+ kind: 'window';
355
+ }>, now?: number): Extract<Cursor, {
356
+ kind: 'window';
357
+ }>;
358
+ /** Serialise a cursor for `plg_sync_runs.cursor`, which is one text column. */
359
+ export declare function serializeCursor(cursor: Cursor | null | undefined): string | null;
360
+ export interface MirrorRecord {
361
+ /** The local row's id. */
362
+ id: string;
363
+ /** The provider's id it is linked to. */
364
+ externalId: string;
365
+ }
366
+ export interface ReconcileInput {
367
+ completeness: Completeness;
368
+ /** Provider ids this run actually saw. */
369
+ observed: Iterable<string>;
370
+ /** Local rows currently linked to this stream. */
371
+ linked: Iterable<MirrorRecord>;
372
+ /** Provider ids the provider explicitly reported as gone. Always honoured. */
373
+ tombstones?: Iterable<string>;
374
+ }
375
+ export interface ReconcileResult {
376
+ /** Local ids to cancel. */
377
+ cancel: string[];
378
+ /** Local ids absent from this run that must NOT be touched. */
379
+ keptOutOfRange: string[];
380
+ reason: 'absence-is-deletion' | 'absence-means-nothing';
381
+ }
382
+ /**
383
+ * Decide what a run's silence means.
384
+ *
385
+ * Under `authoritative` the provider counted the changes and named the
386
+ * tombstones, so a linked row that did not appear was deleted. Under `additive`
387
+ * the run only ever asked about part of the world — a window, a statement
388
+ * period — and a row that did not appear was simply not asked about. Cancelling
389
+ * it is silent data loss, and it is the failure this whole cursor design exists
390
+ * to make impossible.
391
+ *
392
+ * Explicit tombstones are obeyed under both: a provider that bothers to say
393
+ * "this one is gone" is authoritative about that one record regardless of how
394
+ * the run was scoped.
395
+ */
396
+ export declare function reconcileMirror(input: ReconcileInput): ReconcileResult;
397
+ export {};
398
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/integrations/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * How a setting is asked for.
3
+ *
4
+ * Closed, and short on purpose: each member is a control someone has to build,
5
+ * localize and test. It grew to exactly what the two real cases needed — a
6
+ * multi-select for payment methods, a constrained text for a postcode — and the
7
+ * next one is added by whoever has the next real case.
8
+ */
9
+ export type ConnectorSettingType =
10
+ /** One line, optionally shaped by `pattern` (a postcode, a CNPJ). */
11
+ 'text'
12
+ /** Exactly one of `options`. */
13
+ | 'select'
14
+ /** Any number of `options`; persisted as a `string[]`. */
15
+ | 'multi-select'
16
+ /** On/off; persisted as a boolean. */
17
+ | 'toggle';
18
+ /** One choice of a `select` / `multi-select`. */
19
+ export interface ConnectorSettingOption {
20
+ value: string;
21
+ label: string;
22
+ }
23
+ /** A value a setting can hold. Never a secret — see the module header. */
24
+ export type ConnectorSettingValue = string | string[] | boolean;
25
+ /**
26
+ * One operational setting a connector exposes once it is connected.
27
+ *
28
+ * The declaration is what kills the free-text box: "pix, boleto, credit_card"
29
+ * typed into an input is three chances to misspell a value the storefront then
30
+ * silently does not offer. A `multi-select` over declared options cannot be
31
+ * misspelled, and it is the same declaration the store validates writes against.
32
+ */
33
+ export interface ConnectorSetting {
34
+ /** Key inside `plg_connections.settings`. Must not collide with a credential field. */
35
+ key: string;
36
+ label: string;
37
+ /** The sentence under the label — the same affordance every settings row has. */
38
+ description?: string;
39
+ type: ConnectorSettingType;
40
+ /** Required for `select` and `multi-select`, meaningless elsewhere. */
41
+ options?: ConnectorSettingOption[];
42
+ /** `text` only. */
43
+ placeholder?: string;
44
+ /**
45
+ * `text` only: the shape the value must have, as a RegExp source anchored by
46
+ * the renderer. A postcode is eight digits or it is not a postcode, and
47
+ * finding that out at the first quote is finding it out from a buyer.
48
+ */
49
+ pattern?: string;
50
+ /** What the reader is told when `pattern` refuses. Required whenever `pattern` is set. */
51
+ patternHint?: string;
52
+ /**
53
+ * The connector cannot do its job until this is chosen — and is still
54
+ * connectable without it. See the module header.
55
+ */
56
+ requiredToOperate?: boolean;
57
+ /** Offered when the connection has no value yet. Never written on its own. */
58
+ defaultValue?: ConnectorSettingValue;
59
+ }
60
+ /**
61
+ * A setting counts as chosen when it holds something.
62
+ *
63
+ * `''` and `[]` are not values: an empty multi-select is a merchant who accepts
64
+ * no payment method, which is indistinguishable from one who has not decided,
65
+ * and treating it as decided is what would let a store go live accepting
66
+ * nothing. `false` IS a value — a toggle turned off was answered.
67
+ */
68
+ export declare function isSettingSet(value: unknown): boolean;
69
+ /** The declared settings of a connector, or none. */
70
+ export declare function connectorSettings(def: {
71
+ settings?: ConnectorSetting[];
72
+ }): ConnectorSetting[];
73
+ /**
74
+ * Which required-to-operate settings this connection has not got.
75
+ *
76
+ * Keys, never values — the answer is rendered as copy and persisted into
77
+ * `status_detail`, and neither is a place for what the tenant typed.
78
+ */
79
+ export declare function missingRequiredSettings(settings: ConnectorSetting[] | undefined, values: Record<string, unknown> | undefined | null): string[];
80
+ /** What {@link settingsStatus} contributes to a `ConnectorStatus`. */
81
+ export interface SettingsReadiness {
82
+ /** Connected, and unable to work until something is chosen. */
83
+ needsSetup: boolean;
84
+ /** The keys that are missing. Present only when `needsSetup`. */
85
+ missingSettings?: string[];
86
+ }
87
+ /**
88
+ * The setup half of a connector's status, derived from the row the list already
89
+ * read.
90
+ *
91
+ * Derived and not merely read back from `status`, because the declaration is the
92
+ * truth: a connector that gains a required setting in a new version must report
93
+ * "falta configurar" on connections saved before that version existed, and no
94
+ * write happened to those rows to say so.
95
+ */
96
+ export declare function settingsStatus(settings: ConnectorSetting[] | undefined, connection: {
97
+ active?: boolean;
98
+ settings?: Record<string, unknown>;
99
+ } | null | undefined): SettingsReadiness;
100
+ /** `status_detail` for a connection waiting on configuration. Keys only. */
101
+ export declare function setupStatusDetail(missing: string[]): string;
102
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/integrations/settings.ts"],"names":[],"mappings":"AA6BA;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB;AAC9B,qEAAqE;AACnE,MAAM;AACR,gCAAgC;GAC9B,QAAQ;AACV,0DAA0D;GACxD,cAAc;AAChB,sCAAsC;GACpC,QAAQ,CAAA;AAEZ,iDAAiD;AACjD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,0EAA0E;AAC1E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAA;AAE/D;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uFAAuF;IACvF,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,oBAAoB,CAAA;IAC1B,uEAAuE;IACvE,OAAO,CAAC,EAAE,sBAAsB,EAAE,CAAA;IAClC,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,8EAA8E;IAC9E,YAAY,CAAC,EAAE,qBAAqB,CAAA;CACrC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKpD;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAA;CAAE,GAAG,gBAAgB,EAAE,CAE5F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,SAAS,EACxC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GACjD,MAAM,EAAE,CAIV;AAED,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,UAAU,EAAE,OAAO,CAAA;IACnB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,gBAAgB,EAAE,GAAG,SAAS,EACxC,UAAU,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GACtF,iBAAiB,CAInB;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAE3D"}
@@ -0,0 +1,145 @@
1
+ import type { ConnectionConfig, ConnectorField, ConnectorStatus, SyncRun } from './index';
2
+ import { type ConnectorSetting, type ConnectorSettingValue } from './settings';
3
+ /**
4
+ * The one data layer every connector shares. A connector declares a
5
+ * ConnectorDefinition and writes no SQL: `plg_connections` and `plg_sync_runs`
6
+ * (migration 029) are read and written from here.
7
+ *
8
+ * `recordRun` is deliberately absent. A run is a server-side write — the table
9
+ * carries no INSERT grant for `authenticated`, because a history the
10
+ * application can write is not a history.
11
+ *
12
+ * Opt-in, not mandatory: a connector whose truth lives entirely at the provider
13
+ * (Stripe Connect) stores nothing here rather than keeping a second source of
14
+ * truth that derives from the first.
15
+ */
16
+ export declare const CONNECTIONS_TABLE = "plg_connections";
17
+ export declare const SYNC_RUNS_TABLE = "plg_sync_runs";
18
+ /** A settings key that is not declared, or is a credential. */
19
+ export declare class ConnectionSettingsError extends Error {
20
+ constructor(message: string);
21
+ }
22
+ export interface ConnectionStoreOptions {
23
+ /** The connector's declared fields — the allow-list `save()` checks against. */
24
+ fields?: ConnectorField[];
25
+ /**
26
+ * The connector's declared operational settings. Their keys are allowed, and
27
+ * the required-to-operate ones decide whether a saved connection reads as
28
+ * `connected` or as `pending` — see {@link createConnectionStore}.
29
+ */
30
+ settings?: ConnectorSetting[];
31
+ /** Non-credential keys the connector writes itself (a chosen calendar, an import mode). */
32
+ settingsKeys?: string[];
33
+ /** Which account at the provider. `''` (default) is the single-account case. */
34
+ instanceKey?: string;
35
+ /** Tenant override; defaults to the active tenant. */
36
+ tenantId?: string;
37
+ /** Supabase client override; defaults to the globally registered one. */
38
+ client?: unknown;
39
+ }
40
+ /** The mutable half of a connection. `status` is absent on purpose: it is observed server-side. */
41
+ export interface ConnectionSaveInput {
42
+ settings?: Record<string, unknown>;
43
+ displayName?: string | null;
44
+ active?: boolean;
45
+ providerAccountKey?: string | null;
46
+ }
47
+ export interface ConnectionStore {
48
+ readonly connectorId: string;
49
+ readonly instanceKey: string;
50
+ get(): Promise<ConnectionConfig | null>;
51
+ save(input?: ConnectionSaveInput): Promise<ConnectionConfig>;
52
+ disconnect(): Promise<void>;
53
+ listRuns(options?: {
54
+ limit?: number;
55
+ }): Promise<SyncRun[]>;
56
+ }
57
+ /**
58
+ * The keys a connector is allowed to put in `settings`: its declared
59
+ * non-credential fields, plus anything it named in `settingsKeys`.
60
+ *
61
+ * Rejecting is the point. Without it, "settings never holds a credential" is a
62
+ * comment in a migration — three connectors already broke that comment. With
63
+ * it, a `type: 'password'` field arriving as a settings key is an error with a
64
+ * name, and the doctor has a rule it can run.
65
+ */
66
+ export declare function assertSettingsAllowed(settings: Record<string, unknown>, options: Pick<ConnectionStoreOptions, 'fields' | 'settings' | 'settingsKeys'>, connectorId?: string): void;
67
+ /**
68
+ * The connection store for one connector, on one account.
69
+ *
70
+ * @param connectorId Stable connector id, e.g. 'google-calendar'.
71
+ */
72
+ export declare function createConnectionStore(connectorId: string, options?: ConnectionStoreOptions): ConnectionStore;
73
+ /** Map key for {@link listConnections}. A connection is (connector, account). */
74
+ export declare function connectionKey(connectorId: string, instanceKey?: string): string;
75
+ export interface ListConnectionsOptions {
76
+ /** Tenant override; defaults to the active tenant. */
77
+ tenantId?: string;
78
+ /** Supabase client override; defaults to the globally registered one. */
79
+ client?: unknown;
80
+ }
81
+ /**
82
+ * Every named connector's row in ONE read.
83
+ *
84
+ * The connectors screen used to cost one `plg_connections` GET per connector,
85
+ * because each connector asked for its own row through its own store — N round
86
+ * trips to fill one list. They all share the table, so `connector_id=in.(…)`
87
+ * answers all of them at once.
88
+ *
89
+ * The tenant is part of the QUERY, never of a cache key alone: a caller that
90
+ * holds this map across a tenant switch is holding the wrong tenant's rows, so
91
+ * the map is deliberately returned, not stored.
92
+ */
93
+ export declare function listConnections(connectorIds: readonly string[], options?: ListConnectionsOptions): Promise<Map<string, ConnectionConfig>>;
94
+ /** What {@link connectionStatus} contributes to a ConnectorDefinition. */
95
+ export interface ConnectionBackedStatus {
96
+ instanceKey: string;
97
+ statusFromConnection: (connection: ConnectionConfig | null) => ConnectorStatus;
98
+ getStatus: () => Promise<ConnectorStatus>;
99
+ }
100
+ /**
101
+ * Wire a connector's status badge to its `plg_connections` row.
102
+ *
103
+ * One `derive` answers both doors: `getStatus()` for a screen showing this
104
+ * connector alone, and `statusFromConnection` for a screen showing a list — the
105
+ * list hands it a row it already read in a batch, so N connectors cost one
106
+ * request instead of N. Spread the result into the definition.
107
+ *
108
+ * A connector whose truth lives at the provider (Stripe Connect) writes its own
109
+ * `getStatus` and declares no `statusFromConnection`; the list then reads it
110
+ * one-by-one, which is correct because there is no shared row to batch.
111
+ */
112
+ /** What {@link connectionSettings} contributes to a ConnectorDefinition. */
113
+ export interface ConnectionSettingsIO {
114
+ getSettings: () => Promise<Record<string, unknown>>;
115
+ saveSettings: (values: Record<string, ConnectorSettingValue>) => Promise<void>;
116
+ }
117
+ /**
118
+ * Wire a connector's settings form to its `plg_connections.settings` jsonb.
119
+ *
120
+ * Spread into the definition, the same way {@link connectionStatus} is. Every
121
+ * store-backed connector would otherwise write the same four lines, and the one
122
+ * that wrote them slightly differently would be the one that replaced the jsonb
123
+ * instead of merging into it.
124
+ */
125
+ export declare function connectionSettings(store: ConnectionStore): ConnectionSettingsIO;
126
+ /** What {@link connectionRuns} contributes to a ConnectorDefinition. */
127
+ export interface ConnectionRunsIO {
128
+ listRuns: (options?: {
129
+ limit?: number;
130
+ }) => Promise<SyncRun[]>;
131
+ }
132
+ /**
133
+ * Wire a connector's history to its `plg_sync_runs` rows.
134
+ *
135
+ * Spread into the definition, like {@link connectionStatus} and
136
+ * {@link connectionSettings}. Swallowing is the point: a history is never the
137
+ * reason a connector's screen fails to render, and "no rows" and "unreadable"
138
+ * are the same answer to somebody asking what has happened.
139
+ */
140
+ export declare function connectionRuns(store: ConnectionStore | (() => ConnectionStore)): ConnectionRunsIO;
141
+ export declare function connectionStatus(connectorId: string, derive: (connection: ConnectionConfig | null) => ConnectorStatus, options?: {
142
+ instanceKey?: string;
143
+ store?: () => ConnectionStore;
144
+ }): ConnectionBackedStatus;
145
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/integrations/store.ts"],"names":[],"mappings":"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"}