@fluid-app/sites 0.0.0-stage → 0.1.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.
@@ -0,0 +1,394 @@
1
+ //#region src/api.d.ts
2
+ /** `fluid.api`. */
3
+ interface SitesApi {
4
+ /**
5
+ * Call the Fluid API: `"/orders"` calls `/_fluid/api/v2026-10/orders` on
6
+ * the site's own origin.
7
+ *
8
+ * path - The Member API path, starting with `/`; it may carry a query.
9
+ * init - The request's options, as for `fetch`.
10
+ *
11
+ * Returns the response, whatever its status.
12
+ * Throws TypeError when the path is not a path under the API, such as an
13
+ * absolute URL or one that climbs out with `..`.
14
+ */
15
+ fetch(path: string, init?: RequestInit): Promise<Response>;
16
+ /**
17
+ * `GET` a Fluid API path and parse its JSON.
18
+ *
19
+ * path - The Member API path, starting with `/`.
20
+ * query - Query parameters to add to the path.
21
+ *
22
+ * Returns the parsed body.
23
+ * Throws TypeError for a path as `fetch` refuses it, and FluidRequestError
24
+ * when the API answers with a status that is not 2xx.
25
+ */
26
+ get<T>(path: string, query?: Record<string, string>): Promise<T>;
27
+ }
28
+ /** The path every `fluid.api` call goes under, `/_fluid/api/v2026-10`. */
29
+ declare const API_PATH_PREFIX: string;
30
+ //#endregion
31
+ //#region ../sites-contracts/src/schema.d.ts
32
+ /**
33
+ * Contracts section 7: `SchemaV1`, a site's `db/schema.json`.
34
+ *
35
+ * The gateway reads the schema to check every request, and drivers translate
36
+ * it into their own storage.
37
+ */
38
+ /** Any JSON value. */
39
+ type JsonValue = string | number | boolean | null | JsonValue[] | {
40
+ [key: string]: JsonValue;
41
+ };
42
+ /** `[a-z][a-z0-9_]{0,62}`; not a system column; not starting with "_" or "pg_". */
43
+ type Name = string;
44
+ //#endregion
45
+ //#region ../sites-contracts/src/query.d.ts
46
+ type Row = Record<Name, Value>;
47
+ type Value = string | number | boolean | null | JsonValue;
48
+ /** The answer to a `DbRequestV1`, whatever the HTTP status. */
49
+ interface DbResponseV1 {
50
+ data: Row[] | null;
51
+ count?: number;
52
+ error: DbError | null;
53
+ }
54
+ type DbErrorCode = "validation" | "rule_denied" | "quota_exceeded" | "unique_violation" | "timeout" | "unavailable" | "no_database";
55
+ interface DbError {
56
+ code: DbErrorCode;
57
+ message: string;
58
+ details?: JsonValue;
59
+ }
60
+ //#endregion
61
+ //#region ../sites-contracts/src/access.d.ts
62
+ /** How a viewer relates to a site. `other_company` is V2; phase 014 adds "editor". */
63
+ type ViewerRelation = "owner" | "admin" | "member" | "other_company";
64
+ /** The person a request is made for. */
65
+ interface Viewer {
66
+ userId: string;
67
+ name: string;
68
+ avatarUrl: string | null;
69
+ /** The viewer's member in the site's company, or null. */
70
+ memberId: string | null;
71
+ relation: ViewerRelation;
72
+ }
73
+ //#endregion
74
+ //#region ../sites-contracts/src/sdk.d.ts
75
+ /** The answer to `GET /_fluid/me`. */
76
+ interface Me {
77
+ viewer: (Viewer & {
78
+ fields: Record<string, unknown>;
79
+ }) | null;
80
+ /** Null unless the decision is allow (section 1). */
81
+ site: {
82
+ id: string;
83
+ handle: string;
84
+ name: string;
85
+ visibility: "public" | "private";
86
+ companyName: string;
87
+ } | null;
88
+ scopes: string[];
89
+ /** The visit's FairShare credit: the sharer's, else the owner's, else "home"; null unless the decision is allow. */
90
+ credit: string | null;
91
+ /** The company's primary storefront origin, such as "https://yoli.com". */
92
+ storefrontUrl: string;
93
+ /** V1: the storefront origins that may frame the site and send it a port. */
94
+ shellOrigins: string[];
95
+ }
96
+ /** A thenable: awaiting it sends one `DbRequestV1` and resolves `{ data, error, count }`. */
97
+ interface QueryBuilder extends PromiseLike<DbResponseV1> {
98
+ /** "a,b" or "*". */
99
+ select(columns?: string, opts?: {
100
+ count?: "exact";
101
+ }): QueryBuilder;
102
+ insert(rows: Row | Row[]): QueryBuilder;
103
+ update(set: Row): QueryBuilder;
104
+ delete(): QueryBuilder;
105
+ eq(column: string, value: Value): QueryBuilder;
106
+ neq(column: string, value: Value): QueryBuilder;
107
+ gt(column: string, value: Value): QueryBuilder;
108
+ gte(column: string, value: Value): QueryBuilder;
109
+ lt(column: string, value: Value): QueryBuilder;
110
+ lte(column: string, value: Value): QueryBuilder;
111
+ in(column: string, values: Value[]): QueryBuilder;
112
+ is(column: string, value: null): QueryBuilder;
113
+ like(column: string, pattern: string): QueryBuilder;
114
+ ilike(column: string, pattern: string): QueryBuilder;
115
+ not(column: string, op: string, value: Value): QueryBuilder;
116
+ /** "a.eq.1,b.gt.2". */
117
+ or(filters: string): QueryBuilder;
118
+ match(values: Row): QueryBuilder;
119
+ order(column: string, opts?: {
120
+ ascending?: boolean;
121
+ nullsFirst?: boolean;
122
+ }): QueryBuilder;
123
+ limit(count: number): QueryBuilder;
124
+ range(from: number, to: number): QueryBuilder;
125
+ single(): PromiseLike<{
126
+ data: Row | null;
127
+ error: DbError | null;
128
+ }>;
129
+ maybeSingle(): PromiseLike<{
130
+ data: Row | null;
131
+ error: DbError | null;
132
+ }>;
133
+ }
134
+ /** The error a Supabase method this SDK leaves out throws, naming the method. */
135
+ declare const NOT_SUPPORTED: "not_supported";
136
+ //#endregion
137
+ //#region src/auth.d.ts
138
+ /** `fluid.auth`. */
139
+ interface SitesAuth {
140
+ /**
141
+ * Read `GET /_fluid/me` on the site's own origin: the viewer, the site,
142
+ * the scopes, the visit's credit and the shell origins. It waits for the
143
+ * first shell token, or three seconds, then asks as a guest.
144
+ *
145
+ * Returns the answer.
146
+ * Throws FluidRequestError when `/_fluid/me` answers with a status that is
147
+ * not 2xx, such as 404 `not_found`.
148
+ */
149
+ me(): Promise<Me>;
150
+ /**
151
+ * Ask the shell to send the visitor to the storefront's sign-in, and back.
152
+ * The shell does it only when a click is behind it. With no shell, it does
153
+ * nothing and logs a warning.
154
+ *
155
+ * opts - `returnTo`, the frame path to come back to; the address bar's path when left out.
156
+ *
157
+ * Returns nothing.
158
+ */
159
+ signIn(opts?: {
160
+ returnTo?: string;
161
+ }): void;
162
+ /**
163
+ * Ask the shell to open the Passport, which holds the sign-out. With no
164
+ * shell, it does nothing and logs a warning. V1 ignores `everywhere`.
165
+ *
166
+ * opts - `everywhere`, for V2.
167
+ *
168
+ * Returns a promise that resolves once the message is posted.
169
+ */
170
+ signOut(opts?: {
171
+ everywhere?: boolean;
172
+ }): Promise<void>;
173
+ }
174
+ //#endregion
175
+ //#region src/cart.d.ts
176
+ /**
177
+ * How long a cart call waits for its `cart_result` before it rejects. The
178
+ * shell answers once FairShare's own call settles, which waits up to three
179
+ * seconds for FairShare to start and then for the storefront's API; thirty
180
+ * seconds is well past both, and a shell that never answers (one without the
181
+ * relay, or a port replaced mid-call) does not leave the call pending forever.
182
+ */
183
+ declare const CART_RESULT_TIMEOUT_MS = 30000;
184
+ /** `fluid.cart`. Every argument is FairShare's own, passed through unchanged. */
185
+ interface SitesCart {
186
+ /**
187
+ * Add to the cart: FairShare's `addCartItems`.
188
+ *
189
+ * args - `addCartItems`'s arguments, such as `[{ variant_id: 501, quantity: 1 }]`.
190
+ *
191
+ * Returns a promise of what `addCartItems` resolved, usually the cart.
192
+ * Rejects with an Error when there is no shell, the shell reports a failure,
193
+ * or no answer comes within thirty seconds.
194
+ */
195
+ add(...args: unknown[]): Promise<unknown>;
196
+ /**
197
+ * Change quantities: FairShare's `updateCartItems`.
198
+ *
199
+ * args - `updateCartItems`'s arguments.
200
+ *
201
+ * Returns a promise of what `updateCartItems` resolved.
202
+ * Rejects as `add` does.
203
+ */
204
+ update(...args: unknown[]): Promise<unknown>;
205
+ /**
206
+ * Remove a line: FairShare's `removeCartItemById`.
207
+ *
208
+ * args - `removeCartItemById`'s arguments, such as the cart item id.
209
+ *
210
+ * Returns a promise of what `removeCartItemById` resolved.
211
+ * Rejects as `add` does.
212
+ */
213
+ remove(...args: unknown[]): Promise<unknown>;
214
+ /**
215
+ * Read the current cart.
216
+ *
217
+ * Returns a promise of the cart.
218
+ * Rejects as `add` does.
219
+ */
220
+ get(): Promise<unknown>;
221
+ /**
222
+ * Open the cart drawer in the shell. A failure is logged, never thrown.
223
+ *
224
+ * Returns nothing.
225
+ */
226
+ open(): void;
227
+ /**
228
+ * Close the cart drawer in the shell. A failure is logged, never thrown.
229
+ *
230
+ * Returns nothing.
231
+ */
232
+ close(): void;
233
+ /**
234
+ * Open checkout. It navigates the shell, not the frame. A failure is
235
+ * logged, never thrown.
236
+ *
237
+ * Returns nothing.
238
+ */
239
+ checkout(): void;
240
+ /**
241
+ * Listen for each change to the cart the shell reports.
242
+ *
243
+ * listener - Called with the cart as FairShare's `onCartChange` gave it.
244
+ *
245
+ * Returns a function that stops the listener.
246
+ */
247
+ onChange(listener: (cart: unknown) => void): () => void;
248
+ }
249
+ //#endregion
250
+ //#region src/db/builder.d.ts
251
+ /** `fluid.db`. */
252
+ interface SitesDb {
253
+ /**
254
+ * Start a query on one of the site's tables.
255
+ *
256
+ * table - The table's name in the site's schema.
257
+ *
258
+ * Returns a builder; awaiting it sends one request.
259
+ */
260
+ from(table: string): QueryBuilder;
261
+ }
262
+ /** What `single()` and `maybeSingle()` resolve. */
263
+ interface SingleResponse {
264
+ data: Row | null;
265
+ error: DbError | null;
266
+ }
267
+ //#endregion
268
+ //#region src/fn.d.ts
269
+ /** `fluid.fn`. */
270
+ interface SitesFn {
271
+ /**
272
+ * Call one of the site's server functions: `"rsvp"` calls
273
+ * `/_fluid/fn/rsvp` on the site's own origin, as the viewer.
274
+ *
275
+ * name - The function's name, such as `rsvp`.
276
+ * init - The request's options, as for `fetch`.
277
+ *
278
+ * Returns the response, whatever its status; in V1, 404
279
+ * `fn_not_available`.
280
+ * Throws TypeError when the name is not a function name, so a call never
281
+ * leaves `/_fluid/fn/`.
282
+ */
283
+ fetch(name: string, init?: RequestInit): Promise<Response>;
284
+ }
285
+ //#endregion
286
+ //#region src/shell/go.d.ts
287
+ /** A site router's listener for `go`: the frame path and the fragment, or null. */
288
+ type GoListener = (path: string, hash: string | null) => void;
289
+ //#endregion
290
+ //#region src/shell/history.d.ts
291
+ /** `fluid.history`: how a single-page app follows Back and Forward. */
292
+ interface SitesHistory {
293
+ /**
294
+ * Let the site's router follow Back, Forward and the shell's re-syncs.
295
+ * While a listener is registered, the SDK calls it instead of reloading
296
+ * the frame with `location.replace`. The listener moves the router to the
297
+ * path, with `pushState` or `replaceState`; neither adds an entry.
298
+ *
299
+ * listener - Called with the frame path, such as "/events/42?tab=2", and
300
+ * the fragment, such as "#agenda", or null.
301
+ *
302
+ * Examples
303
+ *
304
+ * fluid.history.onGo((path, hash) => router.navigate(path + (hash ?? "")));
305
+ *
306
+ * Returns a function that removes the listener.
307
+ */
308
+ onGo(listener: GoListener): () => void;
309
+ }
310
+ //#endregion
311
+ //#region src/storefront.d.ts
312
+ /** `fluid.storefront`. */
313
+ interface SitesStorefront {
314
+ /**
315
+ * Build the storefront address of a path, carrying the visit's credit:
316
+ * the credit from the shell, else `/_fluid/me`'s. It waits for the first
317
+ * shell token, or three seconds, as every `/_fluid/*` call does.
318
+ *
319
+ * path - A storefront path, such as `/shop` or `/products/tea?size=2`.
320
+ *
321
+ * Examples
322
+ *
323
+ * await fluid.storefront.url("/shop")
324
+ * # => "https://yoli.com/janedoe/shop"
325
+ *
326
+ * Returns the absolute address; with no credit, or `home`, the path has no
327
+ * credit prefix.
328
+ * Throws TypeError when the path leaves the storefront, such as
329
+ * `https://other.test/shop`.
330
+ * Throws Error when `/_fluid/me` gives no storefront address.
331
+ */
332
+ url(path: string): Promise<string>;
333
+ }
334
+ //#endregion
335
+ //#region src/errors.d.ts
336
+ /**
337
+ * The error the SDK throws when `/_fluid/*` answers with a status that is not
338
+ * 2xx, such as 401 `sign_in_required` or 403 `scope_not_granted`.
339
+ */
340
+ declare class FluidRequestError extends Error {
341
+ /** The HTTP status. */
342
+ readonly status: number;
343
+ /** The body's `error` code, such as `scope_not_granted`, or null when there is none. */
344
+ readonly code: string | null;
345
+ /** The parsed JSON body, or null when the body is not JSON. */
346
+ readonly body: unknown;
347
+ constructor(status: number, code: string | null, body: unknown);
348
+ /**
349
+ * Read a failed response into an error.
350
+ *
351
+ * response - A response whose status is not 2xx.
352
+ *
353
+ * Returns the error, carrying the body's `error` code when there is one.
354
+ */
355
+ static fromResponse(response: Response): Promise<FluidRequestError>;
356
+ }
357
+ /**
358
+ * The error a Supabase method that `fluid.db` leaves out throws, such as
359
+ * `upsert`, `rpc` or a join, so the caller learns at once which one it was
360
+ * (contracts section 11).
361
+ */
362
+ declare class NotSupportedError extends Error {
363
+ /** Always `not_supported`. */
364
+ readonly code: typeof NOT_SUPPORTED;
365
+ /** The method or feature that is not supported, such as `upsert`. */
366
+ readonly method: string;
367
+ constructor(method: string);
368
+ }
369
+ //#endregion
370
+ //#region src/index.d.ts
371
+ /**
372
+ * The SDK: `fluid.auth`, `fluid.api`, `fluid.db`, `fluid.fn`, `fluid.cart`,
373
+ * `fluid.history` and `fluid.storefront`.
374
+ */
375
+ interface Fluid {
376
+ /** Who is here. */
377
+ auth: SitesAuth;
378
+ /** The Fluid API, as the viewer, within the site's grants. */
379
+ api: SitesApi;
380
+ /** The site's database, Supabase-style. */
381
+ db: SitesDb;
382
+ /** The site's own server functions; in V1 each answers 404 `fn_not_available`. */
383
+ fn: SitesFn;
384
+ /** The storefront's cart: FairShare in the shell, with FairShare's own arguments. */
385
+ cart: SitesCart;
386
+ /** Back and Forward for a single-page app's router, in a V1 frame. */
387
+ history: SitesHistory;
388
+ /** Storefront addresses that carry the visit's FairShare credit. */
389
+ storefront: SitesStorefront;
390
+ }
391
+ /** The SDK, also at `window.fluid`. */
392
+ declare const fluid: Fluid;
393
+ //#endregion
394
+ export { API_PATH_PREFIX, CART_RESULT_TIMEOUT_MS, type DbError, type DbResponseV1, Fluid, FluidRequestError, type GoListener, type Me, NotSupportedError, type QueryBuilder, type Row, type SingleResponse, type SitesApi, type SitesAuth, type SitesCart, type SitesDb, type SitesFn, type SitesHistory, type SitesStorefront, type Value, fluid };