@shapio/client 0.2.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,2768 @@
1
+ import { ChangeSummary, ClassifiedChange, DefinitionInput, LocaleDefinition, LockFile, SchemaChange, SchemaDefinition, SyncDecision, ValidationIssue } from "@shapio/schema";
2
+ //#region src/request.d.ts
3
+ /** Fetch's `credentials` mode (spelled out: the DOM lib type is not available to Node consumers). */
4
+ type FetchCredentials = 'omit' | 'same-origin' | 'include';
5
+ type RequestOptions = {
6
+ method?: string;
7
+ body?: unknown;
8
+ signal?: AbortSignal;
9
+ };
10
+ type RequestFn = <T>(path: string, options?: RequestOptions) => Promise<T>;
11
+ //#endregion
12
+ //#region src/admin/contentTypes.d.ts
13
+ /**
14
+ * Admin content API shapes (package E, `apps/api/src/routes/admin/content/**` and
15
+ * `routes/schemas/content.ts`). Entry `data` is keyed by API keys; its shape is the model's, known only at
16
+ * runtime. Dates are ISO-8601 strings.
17
+ */
18
+ /** `modified`: published, and the draft has changed since (or holds autosaved work). */
19
+ type EntryStatus = 'draft' | 'published' | 'modified';
20
+ /** Field values keyed by API key. Admin reads return media fields as asset views; writes take asset IDs. */
21
+ type EntryData = Record<string, unknown>;
22
+ type EntryLocaleState = {
23
+ locale: string;
24
+ /** The draft version: send it back as `expectedVersion` when saving this locale. */
25
+ version: number;
26
+ status: EntryStatus;
27
+ publishedAt: string | null;
28
+ /** The published version's shared (non-localized) fields are older than the draft's (ADR 0004). */
29
+ sharedOutdated: boolean;
30
+ };
31
+ /** One entry's draft in one locale, with every locale's status. */
32
+ type AdminEntry = {
33
+ id: string;
34
+ /** The model's API key. */
35
+ model: string;
36
+ locale: string;
37
+ version: number;
38
+ revisionId: string;
39
+ status: EntryStatus;
40
+ /** Saved without full validation (autosave or duplicate): Save or Publish validates it. */
41
+ autosaved: boolean;
42
+ createdAt: string;
43
+ updatedAt: string;
44
+ publishedAt: string | null;
45
+ data: EntryData;
46
+ /** Locales that have a draft of this entry. */
47
+ locales: EntryLocaleState[];
48
+ /** Other published locales whose live shared values are older than their drafts. */
49
+ sharedOutdatedLocales: string[];
50
+ };
51
+ /** The admin who created an entry (null for entries created by API tokens, app users or imports). */
52
+ type EntryAuthor = {
53
+ id: string;
54
+ name: string;
55
+ };
56
+ /** One locale's status of a list item (localized models). */
57
+ type EntryLocaleStatus = {
58
+ locale: string;
59
+ status: EntryStatus;
60
+ };
61
+ type AdminEntryListItem = {
62
+ id: string;
63
+ locale: string;
64
+ version: number;
65
+ status: EntryStatus;
66
+ autosaved: boolean;
67
+ createdAt: string;
68
+ updatedAt: string;
69
+ data: EntryData;
70
+ author: EntryAuthor | null;
71
+ /** Localized models only: every locale the entry has a version in, with its status. */
72
+ locales?: EntryLocaleStatus[];
73
+ };
74
+ type ContentPagination = {
75
+ page: number;
76
+ pageSize: number;
77
+ total: number;
78
+ pageCount: number;
79
+ };
80
+ type AdminEntryPage = {
81
+ items: AdminEntryListItem[];
82
+ pagination: ContentPagination;
83
+ /** The locale the list was read in. */
84
+ locale: string;
85
+ };
86
+ /** Operators of the content query compiler (`apps/api/src/content/compiler/types.ts`). */
87
+ type ContentFilterOperator = '$eq' | '$ne' | '$in' | '$nin' | '$lt' | '$lte' | '$gt' | '$gte' | '$contains' | '$notContains' | '$containsi' | '$startsWith' | '$endsWith' | '$null' | '$notNull';
88
+ /** A scalar operand; `$in`/`$nin` take a list, `$null`/`$notNull` take `true`. */
89
+ type ContentFilterValue = string | number | boolean | ReadonlyArray<string | number | boolean>;
90
+ /**
91
+ * A filter tree, serialised with brackets: `{ title: { $eq: 'A' } }` → `filters[title][$eq]=A`. Field keys are
92
+ * API keys (or `id`, `createdAt`, `updatedAt`); `$and`/`$or` take lists of trees, `$not` one tree.
93
+ */
94
+ type ContentFilter = {
95
+ [key: string]: Partial<Record<ContentFilterOperator, ContentFilterValue>> | ContentFilterValue | ContentFilter | readonly ContentFilter[];
96
+ };
97
+ type ContentSort = {
98
+ field: string;
99
+ direction: 'asc' | 'desc';
100
+ };
101
+ type ContentListQuery = {
102
+ filters?: ContentFilter;
103
+ sort?: readonly ContentSort[];
104
+ page?: number;
105
+ pageSize?: number;
106
+ /** Free-text search over the model's title field. */
107
+ q?: string;
108
+ locale?: string;
109
+ /** Top-level fields to return (API keys); all readable fields when absent. */
110
+ fields?: readonly string[];
111
+ /** Relation paths to expand, e.g. `author` or `author.company`. */
112
+ populate?: readonly string[];
113
+ /** Admin list only: entries in this status (in the locale the list is read in). */
114
+ status?: EntryStatus;
115
+ /** Admin list only: entries created by this admin user (ID). */
116
+ author?: string;
117
+ };
118
+ type CreateEntryInput = {
119
+ locale?: string;
120
+ data?: EntryData;
121
+ /** Publish the new entry's locale in the same transaction. */
122
+ publish?: boolean;
123
+ };
124
+ type UpdateEntryInput = {
125
+ locale?: string;
126
+ /** The draft version the editor loaded; null creates the entry's version in this locale. */
127
+ expectedVersion: number | null;
128
+ /** Changed fields only: a field set to null is cleared, absent fields are kept. */
129
+ data?: EntryData;
130
+ /** Autosave: moves the draft head only (no revision) and does not enforce `required`. */
131
+ autosave?: boolean;
132
+ };
133
+ /** Publish or unpublish these locales atomically (the request's default locale when omitted). */
134
+ type EntryLocalesInput = {
135
+ locales?: string[];
136
+ };
137
+ type RevisionSummary = {
138
+ id: string;
139
+ locale: string;
140
+ /** Why the revision exists: `create`, `save`, `restore`, `localize`, `publish`... */
141
+ reason: string;
142
+ schemaRevisionId: string;
143
+ authorType: string;
144
+ authorId: string | null;
145
+ parentRevisionId: string | null;
146
+ createdAt: string;
147
+ };
148
+ type RevisionDetail = RevisionSummary & {
149
+ data: EntryData;
150
+ };
151
+ /** One problem with a content value (422 CONTENT_INVALID `details.issues`). */
152
+ type ContentIssue = {
153
+ path: string;
154
+ code: string;
155
+ message: string;
156
+ };
157
+ /** An entry that still points at the one being deleted (409 ENTRY_REFERENCED `details.referrers`). */
158
+ type EntryReferrer = {
159
+ entryId: string;
160
+ modelId: string;
161
+ locale: string;
162
+ state: string;
163
+ };
164
+ /** A custom field editor module the server serves (from the project's `shapio.config` and `extensions/editors`). */
165
+ type EditorManifestItem = {
166
+ /** File name in `extensions/editors/`, e.g. `star-rating.js`. */
167
+ file: string;
168
+ /** Path to import the module from, relative to the server's base URL. */
169
+ path: string;
170
+ /** Content hash: changes whenever the file changes (cache busting). */
171
+ hash: string;
172
+ };
173
+ type EditorManifest = {
174
+ items: EditorManifestItem[];
175
+ };
176
+ //#endregion
177
+ //#region src/deliveryTypes.d.ts
178
+ /**
179
+ * The delivery API (`/api/content/:routeKey`): published content as sites and apps read it. `routeKey` is a
180
+ * collection's plural API ID (`articles`) or a singleton's API ID (`homepage`).
181
+ */
182
+ type DeliveryListQuery = Omit<ContentListQuery, 'status' | 'author'> & {
183
+ /** Read the publication snapshot N (`GET /api/snapshots/current` gives the newest) instead of now. */
184
+ snapshot?: number;
185
+ };
186
+ type DeliveryGetQuery = Pick<DeliveryListQuery, 'locale' | 'fields' | 'populate' | 'snapshot'>;
187
+ type DeliveryMeta = {
188
+ locale: string;
189
+ snapshot: number;
190
+ };
191
+ type DeliveryPagination = {
192
+ page: number;
193
+ pageSize: number;
194
+ total: number;
195
+ pageCount: number;
196
+ };
197
+ type DeliveryList<T = Record<string, unknown>> = {
198
+ data: T[];
199
+ meta: DeliveryMeta & {
200
+ pagination: DeliveryPagination;
201
+ };
202
+ };
203
+ type DeliveryItem<T = Record<string, unknown>> = {
204
+ data: T;
205
+ meta: DeliveryMeta;
206
+ };
207
+ //#endregion
208
+ //#region src/admin/sitesTypes.d.ts
209
+ /** A site: the tenant of content, media, tokens, change sets and snapshots (sites plan §H). */
210
+ type Site = {
211
+ id: string;
212
+ /** Lower case, starts with a letter; fixed once created. Sent as `Shapio-Site` or `?site=`. */
213
+ key: string;
214
+ name: string;
215
+ /** Requests that name no site go to the primary site. Exactly one; it cannot be deleted. */
216
+ isPrimary: boolean;
217
+ version: number;
218
+ createdAt: string;
219
+ updatedAt: string;
220
+ };
221
+ type SiteSummary = Pick<Site, 'id' | 'key' | 'name' | 'isPrimary'>;
222
+ /** A site as webhook payloads and views name it. */
223
+ type SiteRef = Pick<Site, 'id' | 'key'>;
224
+ type CreateSiteInput = {
225
+ key: string;
226
+ name: string;
227
+ };
228
+ /** Only the name changes; `expectedVersion` guards against concurrent edits (409 `VERSION_CONFLICT`). */
229
+ type UpdateSiteInput = {
230
+ expectedVersion: number;
231
+ name: string;
232
+ };
233
+ /**
234
+ * The app roles a site binds: `public` applies to anonymous callers, `authenticated` to every signed-in app
235
+ * user of the site. A new site binds nothing (deny by default).
236
+ */
237
+ type SiteAppRoles = {
238
+ siteId: string;
239
+ public: string[];
240
+ authenticated: string[];
241
+ };
242
+ type SetSiteAppRolesInput = {
243
+ public: string[];
244
+ authenticated: string[];
245
+ };
246
+ //#endregion
247
+ //#region src/admin/usageTypes.d.ts
248
+ /** Field usage from delivery traffic (`GET /api/admin/usage/fields`, apps/api/src/routes/admin/usage). */
249
+ type UsageSelection = 'explicit' | 'implicit';
250
+ type FieldUsageQuery = {
251
+ modelId: string;
252
+ /** Days counted, today included (default 7; capped at USAGE_RETENTION_DAYS). */
253
+ days?: number;
254
+ };
255
+ type FieldPrincipalUsage = {
256
+ /** `token:<id>`, `app_users` or `anonymous`. */
257
+ principalKey: string;
258
+ /** The API token's name (tokens only, while the token exists). */
259
+ tokenName?: string;
260
+ reads: number;
261
+ lastReadAt: string;
262
+ /** `implicit`: every read asked for the whole model (no field selection). */
263
+ selection: UsageSelection;
264
+ };
265
+ type ModelFieldUsage = {
266
+ /** A field ID, or `<relation field ID>.<target field ID>` for a populated relation's field. */
267
+ fieldPath: string;
268
+ /** API keys along the path in the current schema (`author.name`); null when a field no longer exists. */
269
+ apiKeyPath: string | null;
270
+ reads: number;
271
+ lastReadAt: string;
272
+ principals: FieldPrincipalUsage[];
273
+ };
274
+ type PrincipalUsageSummary = {
275
+ principalKey: string;
276
+ tokenName?: string;
277
+ /** Delivery requests over all models in the window. */
278
+ requests: number;
279
+ lastReadAt: string;
280
+ /** The snapshot this principal last pinned with `snapshot`; null when it reads live content. */
281
+ lastSnapshot: number | null;
282
+ };
283
+ type FieldUsageResponse = {
284
+ /** False when USAGE_TRACKING is off (nothing new is counted). */
285
+ tracking: boolean;
286
+ modelId: string;
287
+ days: number;
288
+ /** First day counted (UTC, `YYYY-MM-DD`). */
289
+ since: string;
290
+ fields: ModelFieldUsage[];
291
+ principals: PrincipalUsageSummary[];
292
+ };
293
+ //#endregion
294
+ //#region src/admin/publishingTypes.d.ts
295
+ type Page<T> = {
296
+ items: T[];
297
+ nextCursor: string | null;
298
+ };
299
+ declare const JOB_STATUSES: readonly ["pending", "running", "succeeded", "dead"];
300
+ type JobStatus = (typeof JOB_STATUSES)[number];
301
+ type Job = {
302
+ id: string;
303
+ type: string;
304
+ status: JobStatus;
305
+ attempts: number;
306
+ maxAttempts: number;
307
+ /** When it runs next (pending) or ran last. */
308
+ runAt: string;
309
+ idempotencyKey: string | null;
310
+ lockedBy: string | null;
311
+ lockedUntil: string | null;
312
+ /** Payload and result with secret-looking values replaced by `[redacted]`. */
313
+ payload: unknown;
314
+ result: unknown;
315
+ /** Progress a long job saved (e.g. an import's phase and counts); null when it saved none. */
316
+ progress: unknown;
317
+ lastError: string | null;
318
+ createdAt: string;
319
+ updatedAt: string;
320
+ finishedAt: string | null;
321
+ };
322
+ type JobQuery = {
323
+ status?: JobStatus;
324
+ type?: string;
325
+ cursor?: string;
326
+ limit?: number;
327
+ };
328
+ type JobSummary = {
329
+ counts: Record<JobStatus, number>;
330
+ types: string[];
331
+ };
332
+ declare const PUBLICATION_ACTIONS: readonly ["publish", "unpublish"];
333
+ type PublicationAction = (typeof PUBLICATION_ACTIONS)[number];
334
+ declare const SCHEDULE_STATUSES: readonly ["scheduled", "done", "failed", "cancelled"];
335
+ type ScheduleStatus = (typeof SCHEDULE_STATUSES)[number];
336
+ type ScheduledPublication = {
337
+ id: string;
338
+ entryId: string;
339
+ modelId: string;
340
+ /** Null when the model no longer exists. */
341
+ modelKey: string | null;
342
+ locale: string;
343
+ action: PublicationAction;
344
+ runAt: string;
345
+ status: ScheduleStatus;
346
+ error: string | null;
347
+ /** Publication sequence the change was published at (once done). */
348
+ snapshot: number | null;
349
+ createdBy: string | null;
350
+ createdAt: string;
351
+ executedAt: string | null;
352
+ };
353
+ type ScheduleQuery = {
354
+ status?: ScheduleStatus;
355
+ entryId?: string;
356
+ cursor?: string;
357
+ limit?: number;
358
+ };
359
+ type CreateScheduleInput = {
360
+ modelKey: string;
361
+ entryId: string;
362
+ /** Omit for non-localized models (and for the default locale). */
363
+ locale?: string;
364
+ action: PublicationAction;
365
+ runAt: string;
366
+ };
367
+ type WebhookEventType = {
368
+ type: string;
369
+ group: string;
370
+ };
371
+ type WebhookDeliveryStatus = 'pending' | 'retrying' | 'succeeded' | 'dead';
372
+ type Webhook = {
373
+ id: string;
374
+ name: string;
375
+ url: string;
376
+ /** Event types or `group.*` patterns. */
377
+ events: string[];
378
+ enabled: boolean;
379
+ allowPrivateNetwork: boolean;
380
+ maxAttempts: number;
381
+ /** The site whose events it receives; null for a network-wide webhook (every site's events). */
382
+ site: SiteRef | null;
383
+ lastDelivery: {
384
+ status: WebhookDeliveryStatus;
385
+ at: string;
386
+ } | null;
387
+ createdBy: string | null;
388
+ createdAt: string;
389
+ updatedAt: string;
390
+ version: number;
391
+ };
392
+ type CreateWebhookInput = {
393
+ name: string;
394
+ url: string;
395
+ events: string[];
396
+ enabled?: boolean;
397
+ allowPrivateNetwork?: boolean;
398
+ maxAttempts?: number;
399
+ /** A network-wide webhook (every site's events); otherwise it belongs to the request's site. */
400
+ network?: boolean;
401
+ };
402
+ /** A webhook's site is fixed once created. */
403
+ type UpdateWebhookInput = Partial<Omit<CreateWebhookInput, 'network'>> & {
404
+ expectedVersion: number;
405
+ };
406
+ /** The JSON body every webhook delivery sends (signed; verify it with `verifyWebhookSignature`). */
407
+ type WebhookEventBody = {
408
+ id: string;
409
+ type: string;
410
+ createdAt: string;
411
+ /** The site the event is about; null for events about no site (network-wide). */
412
+ site: SiteRef | null;
413
+ data: unknown;
414
+ };
415
+ /** `secret` is shown once: on creation and after rotation. */
416
+ type WebhookWithSecret = {
417
+ webhook: Webhook;
418
+ secret: string;
419
+ };
420
+ type WebhookAttempt = {
421
+ attempt: number;
422
+ at: string;
423
+ durationMs: number;
424
+ request: {
425
+ method: string;
426
+ url: string;
427
+ headers: Record<string, string>;
428
+ };
429
+ /** Null when no response arrived (refused, timeout, blocked by the network policy). */
430
+ response: {
431
+ status: number;
432
+ headers: Record<string, string>;
433
+ body: string;
434
+ truncated: boolean;
435
+ } | null;
436
+ error: string | null;
437
+ };
438
+ type WebhookDelivery = {
439
+ id: string;
440
+ webhookId: string;
441
+ eventId: string | null;
442
+ eventType: string;
443
+ isTest: boolean;
444
+ status: WebhookDeliveryStatus;
445
+ attempts: number;
446
+ lastResponseStatus: number | null;
447
+ lastError: string | null;
448
+ payload: unknown;
449
+ attemptLog: WebhookAttempt[];
450
+ createdAt: string;
451
+ updatedAt: string;
452
+ deliveredAt: string | null;
453
+ };
454
+ declare const DEPLOYMENT_PROVIDERS: readonly ["generic_webhook", "cloudflare_pages", "vercel", "netlify", "github"];
455
+ type DeploymentProvider = (typeof DEPLOYMENT_PROVIDERS)[number];
456
+ declare const DEPLOYMENT_TRIGGERS: readonly ["publish", "change_set", "schema", "manual"];
457
+ type DeploymentTriggerPolicy = (typeof DEPLOYMENT_TRIGGERS)[number];
458
+ declare const DEPLOYMENT_RUN_STATUSES: readonly ["queued", "triggered", "building", "deployed", "failed", "unknown"];
459
+ type DeploymentRunStatus = (typeof DEPLOYMENT_RUN_STATUSES)[number];
460
+ type DeploymentRunTrigger = 'publish' | 'change_set' | 'schema' | 'manual' | 'retry';
461
+ /**
462
+ * Provider settings (not secret). Generic: `{ url }`. Cloudflare Pages: `{ accountId, projectName }`.
463
+ * GitHub: `{ owner, repo, branch, mode: 'commit' | 'pull_request', directory }`.
464
+ */
465
+ type DeploymentSettings = Record<string, string>;
466
+ /**
467
+ * Secret names per provider. Generic: `signingSecret` (generated when omitted). Cloudflare Pages:
468
+ * `deployHookUrl`, `apiToken`. GitHub: `token`. Values are write-only. A value of `${ENV:VAR_NAME}`
469
+ * makes the server read the secret from that environment variable instead of storing it.
470
+ */
471
+ type DeploymentSecretsInput = Record<string, string>;
472
+ /** Which secrets are set; values never leave the server. `envVar`: read from this environment variable. */
473
+ type DeploymentSecretState = Record<string, {
474
+ set: boolean;
475
+ envVar: string | null;
476
+ }>;
477
+ type DeploymentTimelineEvent = {
478
+ status: DeploymentRunStatus;
479
+ at: string;
480
+ source: 'shapio' | 'callback' | 'provider';
481
+ message: string | null;
482
+ };
483
+ type DeploymentRun = {
484
+ id: string;
485
+ connectionId: string;
486
+ connectionName: string;
487
+ provider: DeploymentProvider;
488
+ status: DeploymentRunStatus;
489
+ trigger: DeploymentRunTrigger;
490
+ /** Publication sequence the run was triggered at (`?snapshot=` on delivery). */
491
+ snapshot: number | null;
492
+ schemaVersion: number | null;
493
+ retryOf: string | null;
494
+ providerRef: string | null;
495
+ logUrl: string | null;
496
+ siteUrl: string | null;
497
+ error: string | null;
498
+ /** False for providers that cannot report completion without callbacks (shown as "completion unknown"). */
499
+ completionReported: boolean;
500
+ timeline: DeploymentTimelineEvent[];
501
+ triggeredAt: string | null;
502
+ finishedAt: string | null;
503
+ createdAt: string;
504
+ updatedAt: string;
505
+ };
506
+ type DeploymentConnection = {
507
+ id: string;
508
+ name: string;
509
+ provider: DeploymentProvider;
510
+ settings: DeploymentSettings;
511
+ secrets: DeploymentSecretState;
512
+ previewUrlTemplate: string | null;
513
+ /** Preview tokens issued for this connection show exactly what this delivery role reads. */
514
+ deliveryRoleId: string | null;
515
+ triggerPolicy: DeploymentTriggerPolicy[];
516
+ debounceSeconds: number;
517
+ allowPrivateNetwork: boolean;
518
+ enabled: boolean;
519
+ /** Where the site posts signed build callbacks (generic webhook connections). */
520
+ callbackUrl: string;
521
+ latestRun: DeploymentRun | null;
522
+ /** The newest deployed run by snapshot: what the site is serving, as far as Shapio knows. */
523
+ currentRun: DeploymentRun | null;
524
+ createdBy: string | null;
525
+ createdAt: string;
526
+ updatedAt: string;
527
+ version: number;
528
+ };
529
+ type CreateDeploymentConnectionInput = {
530
+ name: string;
531
+ provider: DeploymentProvider;
532
+ settings: DeploymentSettings;
533
+ secrets: DeploymentSecretsInput;
534
+ previewUrlTemplate?: string | null;
535
+ triggerPolicy: DeploymentTriggerPolicy[];
536
+ debounceSeconds?: number;
537
+ allowPrivateNetwork?: boolean;
538
+ enabled?: boolean;
539
+ deliveryRoleId?: string | null;
540
+ };
541
+ type UpdateDeploymentConnectionInput = Partial<Omit<CreateDeploymentConnectionInput, 'provider'>> & {
542
+ expectedVersion: number;
543
+ };
544
+ /** `generatedSecrets` holds secrets Shapio generated (the generic signing secret), shown once. */
545
+ type DeploymentConnectionCreated = {
546
+ connection: DeploymentConnection;
547
+ generatedSecrets: Record<string, string>;
548
+ };
549
+ type ConnectionTestResult = {
550
+ ok: boolean;
551
+ checks: Array<{
552
+ name: string;
553
+ ok: boolean;
554
+ message: string;
555
+ }>;
556
+ };
557
+ type DeploymentRunQuery = {
558
+ connectionId?: string;
559
+ cursor?: string;
560
+ limit?: number;
561
+ };
562
+ type PreviewToken = {
563
+ id: string;
564
+ tokenPrefix: string;
565
+ modelId: string;
566
+ modelKey: string | null;
567
+ entryId: string | null;
568
+ locale: string | null;
569
+ connectionId: string | null;
570
+ /** Fields follow this delivery role (within the creator's access); null = the public fields. */
571
+ deliveryRoleId: string | null;
572
+ createdBy: string;
573
+ expiresAt: string;
574
+ revokedAt: string | null;
575
+ lastUsedAt: string | null;
576
+ createdAt: string;
577
+ };
578
+ type CreatePreviewTokenInput = {
579
+ modelKey: string;
580
+ entryId?: string;
581
+ locale?: string;
582
+ /** Default 1 hour, at most 30 days. */
583
+ ttlSeconds?: number;
584
+ connectionId?: string;
585
+ /** Defaults to the connection's delivery role. */
586
+ deliveryRoleId?: string;
587
+ };
588
+ /** `token` is shown once. `url` is rendered from the connection's preview URL template (null without one). */
589
+ type PreviewTokenCreated = {
590
+ token: string;
591
+ previewToken: PreviewToken;
592
+ url: string | null;
593
+ };
594
+ type OpenPreviewInput = {
595
+ modelKey: string;
596
+ entryId: string;
597
+ locale?: string;
598
+ /** Defaults to the first enabled connection with a preview URL template. */
599
+ connectionId?: string;
600
+ };
601
+ /** What the entry form's Preview button opens. `apiUrl` is the preview read endpoint for this entry. */
602
+ type OpenPreviewResult = {
603
+ /** The token's ID (revoke it when the preview closes). */
604
+ id: string;
605
+ url: string | null;
606
+ apiUrl: string;
607
+ token: string;
608
+ expiresAt: string;
609
+ connectionId: string | null;
610
+ };
611
+ /** A connection the site's previews open on (names and origins only). */
612
+ type PreviewTarget = {
613
+ connectionId: string;
614
+ name: string;
615
+ /** null when the preview URL template's origin depends on a variable. */
616
+ origin: string | null;
617
+ /** Whether the admin can show it in its preview frame. */
618
+ framable: boolean;
619
+ };
620
+ //#endregion
621
+ //#region src/admin/schemaTypes.d.ts
622
+ /**
623
+ * Schema registry API shapes (package D), mirroring the TypeBox route schemas in
624
+ * apps/api/src/routes/admin/{models,components,schema,locales}/** and routes/schemas/schemaRegistry.ts.
625
+ */
626
+ /** `/api/admin/models` serves collections and singletons; `/api/admin/components` serves components. */
627
+ type DefinitionCategory = 'model' | 'component';
628
+ type ActiveDefinition = {
629
+ definition: SchemaDefinition;
630
+ /** Per-definition version: send it back as `expectedVersion` when changing the definition. */
631
+ version: number;
632
+ hash: string;
633
+ revisionId: string;
634
+ activatedAt: string;
635
+ };
636
+ /** A list item: the active definition and the change still running for it, if any. */
637
+ type DefinitionListItem = ActiveDefinition & {
638
+ pendingChange: {
639
+ id: string;
640
+ status: SchemaChangeStatus;
641
+ } | null;
642
+ };
643
+ type SchemaChangeStatus = 'pending' | 'running' | 'activated' | 'failed' | 'cancelled';
644
+ /** A planned change whose prerequisites run as jobs before the new revision activates. */
645
+ type SchemaChangeJob = {
646
+ id: string;
647
+ targetType: string;
648
+ targetId: string;
649
+ status: SchemaChangeStatus;
650
+ fromRevisionId: string | null;
651
+ toRevisionId: string | null;
652
+ jobId: string | null;
653
+ /** Why a failed change failed, e.g. `{ reason, invalidCount, sampleEntryIds }`. */
654
+ error: unknown;
655
+ createdAt: string;
656
+ updatedAt: string;
657
+ finishedAt: string | null;
658
+ };
659
+ type DefinitionDetail = ActiveDefinition & {
660
+ pendingChange: SchemaChangeJob | null;
661
+ };
662
+ /** A prerequisite or follow-up step of a plan (see apps/api/src/schema/planner/steps.ts). */
663
+ type PlanStep = {
664
+ kind: string;
665
+ fieldId?: string;
666
+ modelId?: string;
667
+ ownerId?: string;
668
+ } & Record<string, unknown>;
669
+ type ChangePlan = {
670
+ definitionId: string;
671
+ kind: SchemaDefinition['kind'];
672
+ apiKey: string;
673
+ operation: 'create' | 'update' | 'delete';
674
+ fromVersion: number | null;
675
+ changes: ClassifiedChange[];
676
+ summary: ChangeSummary;
677
+ affectedModelIds: string[];
678
+ prerequisites: PlanStep[];
679
+ followUps: PlanStep[];
680
+ issues: ValidationIssue[];
681
+ };
682
+ type PlanStepImpact = {
683
+ key: string;
684
+ kind: string;
685
+ affectedHeads: number;
686
+ invalidHeads?: number;
687
+ };
688
+ type PlanImpact = {
689
+ /** Entry heads (every locale and state) of the affected models. */
690
+ affectedHeads: number;
691
+ steps: PlanStepImpact[];
692
+ };
693
+ type PlanPreview = {
694
+ plan: ChangePlan;
695
+ impact: PlanImpact;
696
+ };
697
+ type ChangeOutcome = {
698
+ status: 'activated' | 'unchanged' | 'pending';
699
+ definitionId: string;
700
+ version?: number | null;
701
+ schemaVersion?: number;
702
+ /** Set when `status` is `pending`: poll `schema.change(changeId)`. */
703
+ changeId?: string;
704
+ toVersion?: number | null;
705
+ };
706
+ /** What the definition endpoints accept: authored input, or a normalized definition (always valid input). */
707
+ type DefinitionPayload = DefinitionInput | SchemaDefinition;
708
+ type Acknowledgement = {
709
+ acknowledgeBreaking?: boolean;
710
+ acknowledgeDestructive?: boolean;
711
+ };
712
+ type CreateDefinitionInput = {
713
+ definition: DefinitionPayload;
714
+ } & Acknowledgement;
715
+ type UpdateDefinitionInput = {
716
+ definition: DefinitionPayload;
717
+ expectedVersion: number;
718
+ } & Acknowledgement;
719
+ type PlanUpdateInput = {
720
+ definition: DefinitionPayload;
721
+ expectedVersion: number;
722
+ };
723
+ type DefinitionRevision = {
724
+ id: string;
725
+ version: number;
726
+ hash: string;
727
+ parentRevisionId: string | null;
728
+ createdByType: string;
729
+ createdById: string | null;
730
+ createdAt: string;
731
+ };
732
+ type SchemaSummaryItem = {
733
+ id: string;
734
+ kind: SchemaDefinition['kind'];
735
+ apiKey: string;
736
+ label: string;
737
+ version: number;
738
+ hash: string;
739
+ };
740
+ type SchemaSummary = {
741
+ schemaVersion: number;
742
+ defaultLocale: string;
743
+ definitions: SchemaSummaryItem[];
744
+ };
745
+ /** The opt-in read-only lock (ADR 0002): when on, only `shapio schema apply` changes the schema. */
746
+ type SchemaSettings = {
747
+ readOnly: boolean;
748
+ readOnlyReason: string | null;
749
+ updatedAt: string;
750
+ };
751
+ type UpdateSchemaSettingsInput = {
752
+ readOnly: boolean;
753
+ readOnlyReason?: string | null;
754
+ };
755
+ type Locale = LocaleDefinition;
756
+ type CreateLocaleInput = {
757
+ code: string;
758
+ label: string;
759
+ fallbacks?: string[];
760
+ };
761
+ type UpdateLocaleInput = {
762
+ label: string;
763
+ fallbacks?: string[];
764
+ };
765
+ type SetDefaultLocaleResult = {
766
+ code: string;
767
+ changed: boolean;
768
+ };
769
+ type DeleteLocaleResult = {
770
+ code: string;
771
+ affectedHeads: number;
772
+ };
773
+ //#endregion
774
+ //#region src/admin/changeSetTypes.d.ts
775
+ /**
776
+ * Change sets and snapshots (developer-face plan §5), mirroring the TypeBox route schemas in
777
+ * apps/api/src/routes/admin/{changeSets,snapshots}/schemas.ts. Dates are ISO-8601 strings.
778
+ */
779
+ declare const CHANGE_SET_STATUSES: readonly ["open", "scheduled", "shipping", "shipped", "failed", "discarded"];
780
+ type ChangeSetStatus = (typeof CHANGE_SET_STATUSES)[number];
781
+ /** While `shipping`: preparing (prerequisite dry runs, index builds) or activating (the final transaction). */
782
+ type ShipPhase = 'preparing' | 'activating';
783
+ type ChangeSetSource = 'manual' | 'release' | 'restore' | 'builder' | 'assist';
784
+ type ChangeSetItemStatus = 'pending' | 'done' | 'failed';
785
+ type SchemaOperation = 'create' | 'update' | 'delete';
786
+ type ChangeSetActor = {
787
+ type: 'admin' | 'token' | 'system';
788
+ id: string | null;
789
+ name: string | null;
790
+ };
791
+ /** Why a ship failed, and the item that stopped it (null when not tied to one item). */
792
+ type ChangeSetError = {
793
+ code: string;
794
+ message: string;
795
+ itemId: string | null;
796
+ details?: unknown;
797
+ };
798
+ type ChangeSetEntryItem = {
799
+ id: string;
800
+ kind: 'entry';
801
+ position: number;
802
+ entryId: string;
803
+ modelId: string;
804
+ modelKey: string | null;
805
+ title: string | null;
806
+ locale: string;
807
+ action: PublicationAction;
808
+ /** Restore items publish this exact revision instead of the current draft. */
809
+ sourceRevisionId: string | null;
810
+ status: ChangeSetItemStatus;
811
+ error: string | null;
812
+ };
813
+ type ChangeSetSchemaItem = {
814
+ id: string;
815
+ kind: 'schema';
816
+ position: number;
817
+ draftId: string;
818
+ definitionId: string;
819
+ category: DefinitionCategory;
820
+ apiKey: string;
821
+ operation: SchemaOperation;
822
+ /** The active version the draft was based on; null for a new definition. */
823
+ baseVersion: number | null;
824
+ draftVersion: number;
825
+ status: ChangeSetItemStatus;
826
+ error: string | null;
827
+ };
828
+ type ChangeSetItem = ChangeSetEntryItem | ChangeSetSchemaItem;
829
+ type ChangeSetSummary = {
830
+ id: string;
831
+ title: string;
832
+ description: string;
833
+ status: ChangeSetStatus;
834
+ shipPhase: ShipPhase | null;
835
+ source: ChangeSetSource;
836
+ restoreOfSnapshot: number | null;
837
+ scheduledFor: string | null;
838
+ /** Connection whose deploy is triggered (pinned to the shipped snapshot) after the set ships. */
839
+ deploymentConnectionId: string | null;
840
+ deploymentRunId: string | null;
841
+ shippedAt: string | null;
842
+ /** The publication snapshot the set went live in. */
843
+ shippedSnapshot: number | null;
844
+ schemaVersionAfter: number | null;
845
+ error: ChangeSetError | null;
846
+ entryItemCount: number;
847
+ schemaItemCount: number;
848
+ createdBy: ChangeSetActor;
849
+ createdAt: string;
850
+ updatedAt: string;
851
+ version: number;
852
+ };
853
+ type ChangeSet = ChangeSetSummary & {
854
+ items: ChangeSetItem[];
855
+ };
856
+ type ChangeSetQuery = {
857
+ /** Comma-separated statuses; default: everything except `discarded`. */
858
+ status?: string;
859
+ cursor?: string;
860
+ limit?: number;
861
+ };
862
+ type CreateChangeSetInput = {
863
+ title: string;
864
+ description?: string;
865
+ /** `builder`: a one-item set the model builder ships at once ("Review & ship now"). Default `manual`. */
866
+ source?: 'manual' | 'builder';
867
+ };
868
+ type UpdateChangeSetInput = {
869
+ title?: string;
870
+ description?: string;
871
+ deploymentConnectionId?: string | null;
872
+ expectedVersion: number;
873
+ };
874
+ type AddChangeSetEntryInput = {
875
+ modelKey: string;
876
+ entryId: string;
877
+ /** Omit for non-localized models (and for the default locale). */
878
+ locale?: string;
879
+ action: PublicationAction;
880
+ };
881
+ type SchemaDraft = {
882
+ id: string;
883
+ changeSetId: string;
884
+ definitionId: string;
885
+ category: DefinitionCategory;
886
+ operation: SchemaOperation;
887
+ baseVersion: number | null;
888
+ /** Null when the draft deletes the definition. */
889
+ definition: SchemaDefinition | null;
890
+ version: number;
891
+ updatedBy: ChangeSetActor;
892
+ createdAt: string;
893
+ updatedAt: string;
894
+ };
895
+ type PutSchemaDraftInput = {
896
+ category: DefinitionCategory;
897
+ /** The whole proposed definition, or null to delete the definition when the set ships. */
898
+ definition: DefinitionPayload | null;
899
+ /** The active version the edit is based on (null: a new definition). */
900
+ baseVersion: number | null;
901
+ /** The draft row version the caller saw; omit when creating the draft. */
902
+ expectedDraftVersion?: number;
903
+ };
904
+ type FieldDiff = {
905
+ fieldId: string;
906
+ apiKey: string;
907
+ label: string;
908
+ before: unknown;
909
+ after: unknown;
910
+ };
911
+ type ReviewIssue = {
912
+ path: string;
913
+ code: string;
914
+ message: string;
915
+ };
916
+ type ReviewEntryItem = {
917
+ itemId: string;
918
+ entryId: string;
919
+ modelId: string;
920
+ modelKey: string | null;
921
+ title: string | null;
922
+ locale: string;
923
+ action: PublicationAction;
924
+ sourceRevisionId: string | null;
925
+ /** Send back in `ship.itemVersions` (strict ship). Null when the item does not publish the draft. */
926
+ draftVersion: number | null;
927
+ liveState: 'unpublished' | 'published' | 'modified' | 'missing';
928
+ fields: FieldDiff[];
929
+ issues: ReviewIssue[];
930
+ };
931
+ type ReviewSchemaItem = {
932
+ itemId: string;
933
+ draftId: string;
934
+ definitionId: string;
935
+ category: DefinitionCategory;
936
+ apiKey: string;
937
+ operation: SchemaOperation;
938
+ baseVersion: number | null;
939
+ activeVersion: number | null;
940
+ /** The active version moved since the draft was based on it: shipping refuses until it is rebased. */
941
+ stale: boolean;
942
+ plan: ChangePlan | null;
943
+ impact: PlanImpact | null;
944
+ issues: ReviewIssue[];
945
+ alsoChangedIn: Array<{
946
+ id: string;
947
+ title: string;
948
+ }>;
949
+ };
950
+ declare const NOT_RESTORABLE_REASONS: readonly ["entry_deleted", "model_missing", "publishing_disabled", "localization_changed", "locale_missing", "invalid", "unique_conflict"];
951
+ type NotRestorableReason = (typeof NOT_RESTORABLE_REASONS)[number];
952
+ type NotRestorable = {
953
+ entryId: string;
954
+ modelId: string;
955
+ modelKey: string | null;
956
+ locale: string;
957
+ reason: NotRestorableReason;
958
+ detail: string;
959
+ };
960
+ type FieldConsumer = {
961
+ /** `token:<id>`, `app_users` or `anonymous`. */
962
+ principalKey: string;
963
+ label: string | null;
964
+ reads: number;
965
+ lastReadAt: string | null;
966
+ /** `implicit`: the reader requested the whole model (no field selection). */
967
+ selection: 'explicit' | 'implicit';
968
+ };
969
+ type FieldConsumers = {
970
+ modelId: string;
971
+ fieldId: string;
972
+ apiKey: string;
973
+ consumers: FieldConsumer[];
974
+ };
975
+ type ChangeSetReview = {
976
+ changeSet: ChangeSet;
977
+ entries: ReviewEntryItem[];
978
+ schema: ReviewSchemaItem[];
979
+ notRestorable: NotRestorable[];
980
+ consumers: FieldConsumers[];
981
+ usageDays: number;
982
+ checks: {
983
+ breaking: boolean;
984
+ destructive: boolean;
985
+ blocking: ReviewIssue[];
986
+ warnings: ReviewIssue[];
987
+ };
988
+ /** Fixed notices, e.g. `NEW_FIELDS_AFTER_SHIP`. */
989
+ notices: string[];
990
+ };
991
+ type ShipChangeSetInput = {
992
+ expectedVersion: number;
993
+ acknowledgeBreaking?: boolean;
994
+ acknowledgeDestructive?: boolean;
995
+ /** Draft versions the review showed; a moved draft makes the ship refuse with 409 CHANGE_SET_STALE. */
996
+ itemVersions?: Array<{
997
+ itemId: string;
998
+ draftVersion: number;
999
+ }>;
1000
+ };
1001
+ type ScheduleChangeSetInput = {
1002
+ at: string;
1003
+ expectedVersion: number;
1004
+ acknowledgeBreaking?: boolean;
1005
+ acknowledgeDestructive?: boolean;
1006
+ };
1007
+ type ChangeSetTimelineEvent = {
1008
+ at: string;
1009
+ kind: string;
1010
+ actor: ChangeSetActor | null;
1011
+ message: string | null;
1012
+ snapshot: number | null;
1013
+ deploymentRunId: string | null;
1014
+ /** `item.changedAfterReview`: the entry whose draft moved between review and a scheduled ship. */
1015
+ item: {
1016
+ entryId: string;
1017
+ locale: string;
1018
+ fromVersion: number;
1019
+ toVersion: number;
1020
+ } | null;
1021
+ };
1022
+ type UnassignedEntry = {
1023
+ entryId: string;
1024
+ modelId: string;
1025
+ modelKey: string | null;
1026
+ title: string | null;
1027
+ locale: string;
1028
+ status: 'draft' | 'modified';
1029
+ updatedAt: string;
1030
+ };
1031
+ declare const SNAPSHOT_SOURCES: readonly ["publish", "unpublish", "delete", "schedule", "change_set", "schema", "conversion", "import", "legacy"];
1032
+ type SnapshotSource = (typeof SNAPSHOT_SOURCES)[number];
1033
+ type Snapshot = {
1034
+ seq: number;
1035
+ schemaVersion: number | null;
1036
+ source: SnapshotSource;
1037
+ changeSetId: string | null;
1038
+ changeSetTitle: string | null;
1039
+ actor: {
1040
+ type: string;
1041
+ id: string | null;
1042
+ };
1043
+ changedEntries: number;
1044
+ deploymentRuns: Array<{
1045
+ id: string;
1046
+ connectionId: string;
1047
+ status: DeploymentRunStatus;
1048
+ }>;
1049
+ createdAt: string;
1050
+ };
1051
+ type SnapshotPage = Page<Snapshot> & {
1052
+ current: number;
1053
+ };
1054
+ type SnapshotQuery = {
1055
+ cursor?: string;
1056
+ limit?: number;
1057
+ };
1058
+ //#endregion
1059
+ //#region src/admin/types.d.ts
1060
+ /**
1061
+ * Admin identity API shapes (package B, build plan §4.B), mirroring the TypeBox route schemas in
1062
+ * apps/api/src/routes/admin/** and routes/schemas/adminIdentity.ts. JSON is camelCase; timestamps are ISO-8601.
1063
+ */
1064
+ type AdminUserStatus = 'active' | 'disabled';
1065
+ /** A role held on one site, or on every site (`siteId` null). */
1066
+ type RoleAssignment = {
1067
+ roleId: string;
1068
+ siteId: string | null;
1069
+ };
1070
+ type AdminUser = {
1071
+ id: string;
1072
+ email: string;
1073
+ name: string;
1074
+ status: AdminUserStatus;
1075
+ /** Where each role applies. */
1076
+ assignments: RoleAssignment[];
1077
+ /** Deprecated: the distinct roles of `assignments`, on any site. */
1078
+ roleIds: string[];
1079
+ lastLoginAt: string | null;
1080
+ createdAt: string;
1081
+ updatedAt: string;
1082
+ };
1083
+ declare const CONTENT_ACTIONS: readonly ["read", "create", "update", "delete", "publish", "schemaManage"];
1084
+ type ContentAction = (typeof CONTENT_ACTIONS)[number];
1085
+ /**
1086
+ * Network actions: about the whole instance. Only roles assigned on every site grant them, so a role held
1087
+ * on one site never reaches the network.
1088
+ */
1089
+ declare const NETWORK_ACTIONS: readonly ["schema.create", "users.manage", "roles.manage", "audit.read", "sites.manage"];
1090
+ type NetworkAction = (typeof NETWORK_ACTIONS)[number];
1091
+ /** Site actions: about one site's library, tokens and publishing. */
1092
+ declare const SITE_ACTIONS: readonly ["tokens.manage", "media.read", "media.write", "media.manage", "publishing.manage", "webhooks.manage", "deployments.manage", "deployments.trigger", "changes.manage", "changes.ship"];
1093
+ type SiteAction = (typeof SITE_ACTIONS)[number];
1094
+ /** Actions not scoped to a model: network actions and site actions. */
1095
+ declare const GLOBAL_ACTIONS: readonly ["schema.create", "users.manage", "roles.manage", "tokens.manage", "audit.read", "sites.manage", "media.read", "media.write", "media.manage", "publishing.manage", "webhooks.manage", "deployments.manage", "deployments.trigger", "changes.manage", "changes.ship"];
1096
+ type GlobalAction = (typeof GLOBAL_ACTIONS)[number];
1097
+ type PermissionAction = ContentAction | GlobalAction;
1098
+ type RoleSummary = {
1099
+ id: string;
1100
+ key: string;
1101
+ name: string;
1102
+ };
1103
+ /** Returned whenever a session starts (setup, login, accepting an invitation). */
1104
+ type SessionStarted = {
1105
+ user: AdminUser;
1106
+ csrfToken: string;
1107
+ };
1108
+ type MeResponse = {
1109
+ user: AdminUser;
1110
+ roles: RoleSummary[];
1111
+ /** The site this response is about: the request's `Shapio-Site`, else the primary site. */
1112
+ site: SiteSummary;
1113
+ /** Every site this admin holds a role on (all of them for a role assigned on every site). */
1114
+ sites: SiteSummary[];
1115
+ /** Network actions (roles assigned on every site only). */
1116
+ networkPermissions: NetworkAction[];
1117
+ /** Site actions on the request's site. */
1118
+ sitePermissions: SiteAction[];
1119
+ /** `networkPermissions` and `sitePermissions` together. */
1120
+ globalPermissions: GlobalAction[];
1121
+ /** Content actions per model ID on the request's site (models without any action are left out). */
1122
+ modelPermissions: Record<string, ContentAction[]>;
1123
+ /** How the server sends email: `console` writes it to the server log (no real delivery is set up). */
1124
+ emailDelivery: EmailDelivery;
1125
+ csrfToken: string;
1126
+ };
1127
+ type EmailDelivery = 'console' | 'smtp';
1128
+ type SetupStatusResponse = {
1129
+ /** No admin exists yet. */
1130
+ required: boolean;
1131
+ /** SETUP_REQUIRE_TOKEN is set: setup also needs the one-time token from the server log. */
1132
+ requiresToken: boolean;
1133
+ };
1134
+ /** `token` is needed only when the server requires it (`requiresToken`); otherwise it is ignored. */
1135
+ type SetupInput = {
1136
+ token?: string;
1137
+ email: string;
1138
+ name: string;
1139
+ password: string;
1140
+ };
1141
+ type LoginInput = {
1142
+ email: string;
1143
+ password: string;
1144
+ };
1145
+ type CsrfResponse = {
1146
+ csrfToken: string;
1147
+ };
1148
+ type UpdateProfileInput = {
1149
+ name: string;
1150
+ };
1151
+ type ChangePasswordInput = {
1152
+ currentPassword: string;
1153
+ newPassword: string;
1154
+ };
1155
+ type PasswordResetRequestInput = {
1156
+ email: string;
1157
+ };
1158
+ type PasswordResetConfirmInput = {
1159
+ token: string;
1160
+ password: string;
1161
+ };
1162
+ type AcceptInvitationInput = {
1163
+ token: string;
1164
+ name: string;
1165
+ password: string;
1166
+ };
1167
+ type InspectInvitationResponse = {
1168
+ email: string;
1169
+ expiresAt: string;
1170
+ };
1171
+ type AdminSession = {
1172
+ id: string;
1173
+ current: boolean;
1174
+ ip: string | null;
1175
+ userAgent: string | null;
1176
+ createdAt: string;
1177
+ lastSeenAt: string;
1178
+ expiresAt: string;
1179
+ };
1180
+ type Invitation = {
1181
+ id: string;
1182
+ email: string;
1183
+ /** The role assignments the invitee gets on accepting. */
1184
+ assignments: RoleAssignment[];
1185
+ /** Deprecated: the distinct roles of `assignments`. */
1186
+ roleIds: string[];
1187
+ invitedBy: string | null;
1188
+ expiresAt: string;
1189
+ createdAt: string;
1190
+ };
1191
+ /** A fresh accept link, shown once; issuing it makes earlier links (emailed or copied) stop working. */
1192
+ type InvitationLink = {
1193
+ acceptUrl: string;
1194
+ expiresAt: string;
1195
+ };
1196
+ /**
1197
+ * Either `assignments` or (deprecated) `roleIds`, meaning those roles on every site; never both. Updating
1198
+ * either replaces every assignment.
1199
+ */
1200
+ type AssignmentsInput = {
1201
+ assignments: RoleAssignment[];
1202
+ roleIds?: never;
1203
+ } | {
1204
+ roleIds: string[];
1205
+ assignments?: never;
1206
+ };
1207
+ type InviteUserInput = {
1208
+ email: string;
1209
+ } & AssignmentsInput;
1210
+ type UpdateAdminUserInput = {
1211
+ name?: string;
1212
+ status?: AdminUserStatus;
1213
+ } & (AssignmentsInput | {
1214
+ assignments?: never;
1215
+ roleIds?: never;
1216
+ });
1217
+ type RoleKind = 'admin' | 'delivery';
1218
+ type RoleCondition = 'ownedByPrincipal';
1219
+ type RolePermission = {
1220
+ action: PermissionAction;
1221
+ /** `null` grants the action on every model (and is required for global actions). */
1222
+ modelId: string | null;
1223
+ condition: RoleCondition | null;
1224
+ /** `null` = every field; otherwise only these stable field IDs. */
1225
+ fieldIds: string[] | null;
1226
+ };
1227
+ type Role = {
1228
+ id: string;
1229
+ key: string;
1230
+ name: string;
1231
+ description: string;
1232
+ kind: RoleKind;
1233
+ isSystem: boolean;
1234
+ /** Optimistic-concurrency version: send it back as `expectedVersion` on update. */
1235
+ version: number;
1236
+ permissions: RolePermission[];
1237
+ createdAt: string;
1238
+ updatedAt: string;
1239
+ };
1240
+ type CreateRoleInput = {
1241
+ key: string;
1242
+ name: string;
1243
+ description?: string;
1244
+ kind?: RoleKind;
1245
+ permissions: RolePermission[];
1246
+ };
1247
+ type UpdateRoleInput = {
1248
+ expectedVersion: number;
1249
+ name?: string;
1250
+ description?: string;
1251
+ permissions?: RolePermission[];
1252
+ };
1253
+ type ApiToken = {
1254
+ id: string;
1255
+ name: string;
1256
+ /** First characters of the token (`shp_` + 6), for telling tokens apart. */
1257
+ tokenPrefix: string;
1258
+ roleId: string;
1259
+ scope: RoleKind;
1260
+ /** The token's site; null for a network admin token (its role applies on every site). */
1261
+ siteId: string | null;
1262
+ createdBy: string | null;
1263
+ expiresAt: string | null;
1264
+ lastUsedAt: string | null;
1265
+ revokedAt: string | null;
1266
+ createdAt: string;
1267
+ };
1268
+ type CreateApiTokenInput = {
1269
+ name: string;
1270
+ roleId: string;
1271
+ expiresAt?: string | null;
1272
+ /**
1273
+ * A network admin token (every site and network actions; needs `users.manage`). Omitted: a network token
1274
+ * when the creator may create one, else a token of the request's site. Delivery tokens are always per site.
1275
+ */
1276
+ network?: boolean;
1277
+ };
1278
+ /** `token` is the plain secret, returned once at creation and never again. */
1279
+ type CreatedApiToken = {
1280
+ token: string;
1281
+ apiToken: ApiToken;
1282
+ };
1283
+ type AuditActorType = 'admin' | 'app_user' | 'token' | 'anonymous' | 'system';
1284
+ type AuditEvent = {
1285
+ id: string;
1286
+ occurredAt: string;
1287
+ actorType: AuditActorType;
1288
+ actorId: string | null;
1289
+ /** The acting admin's (or app user's) display name, when the actor is a known account. */
1290
+ actorName: string | null;
1291
+ actorEmail: string | null;
1292
+ action: string;
1293
+ targetType: string | null;
1294
+ targetId: string | null;
1295
+ outcome: 'success' | 'failure';
1296
+ requestId: string | null;
1297
+ ip: string | null;
1298
+ metadata: unknown;
1299
+ };
1300
+ /** Newest first, cursor-paginated. */
1301
+ type AuditQuery = {
1302
+ cursor?: string;
1303
+ limit?: number;
1304
+ actorType?: AuditActorType;
1305
+ actorId?: string;
1306
+ action?: string;
1307
+ actionPrefix?: string;
1308
+ targetType?: string;
1309
+ targetId?: string;
1310
+ outcome?: 'success' | 'failure';
1311
+ from?: string;
1312
+ to?: string;
1313
+ };
1314
+ type AuditPage = {
1315
+ items: AuditEvent[];
1316
+ nextCursor: string | null;
1317
+ };
1318
+ //#endregion
1319
+ //#region src/admin/appUsersTypes.d.ts
1320
+ type AdminAppUser = {
1321
+ id: string;
1322
+ email: string;
1323
+ name: string;
1324
+ confirmed: boolean;
1325
+ blocked: boolean;
1326
+ /** False for accounts that only sign in with an OAuth provider. */
1327
+ hasPassword: boolean;
1328
+ /** OAuth providers linked to the account (`google`, `github`). */
1329
+ providers: string[];
1330
+ /** Custom app roles; `authenticated` applies to every app user implicitly. */
1331
+ roleIds: string[];
1332
+ lastLoginAt: string | null;
1333
+ createdAt: string;
1334
+ updatedAt: string;
1335
+ };
1336
+ /** Newest first, cursor-paginated; `search` matches email or name. */
1337
+ type AppUserQuery = {
1338
+ search?: string;
1339
+ cursor?: string;
1340
+ limit?: number;
1341
+ };
1342
+ type AppUserPage = {
1343
+ items: AdminAppUser[];
1344
+ nextCursor: string | null;
1345
+ };
1346
+ type UpdateAppUserInput = {
1347
+ blocked?: boolean;
1348
+ roleIds?: string[];
1349
+ };
1350
+ /** What app roles may grant: content actions only. */
1351
+ declare const APP_CONTENT_ACTIONS: readonly ["read", "create", "update", "delete", "publish"];
1352
+ type AppContentAction = (typeof APP_CONTENT_ACTIONS)[number];
1353
+ /** Built-in app role keys: `public` applies to anonymous callers, `authenticated` to every app user. */
1354
+ declare const BUILT_IN_APP_ROLE_KEYS: readonly ["public", "authenticated"];
1355
+ type AppRolePermission = {
1356
+ action: AppContentAction;
1357
+ /** `null` grants the action on every model, including ones created later. */
1358
+ modelId: string | null;
1359
+ condition: RoleCondition | null;
1360
+ /** `null` = every public field; otherwise exactly these stable field IDs (non-public ones included). */
1361
+ fieldIds: string[] | null;
1362
+ };
1363
+ type AppRole = {
1364
+ id: string;
1365
+ key: string;
1366
+ name: string;
1367
+ description: string;
1368
+ isSystem: boolean;
1369
+ version: number;
1370
+ permissions: AppRolePermission[];
1371
+ userCount: number;
1372
+ createdAt: string;
1373
+ updatedAt: string;
1374
+ };
1375
+ type CreateAppRoleInput = {
1376
+ key: string;
1377
+ name: string;
1378
+ description?: string;
1379
+ permissions: AppRolePermission[];
1380
+ };
1381
+ /** Built-in roles accept `permissions` only. */
1382
+ type UpdateAppRoleInput = {
1383
+ expectedVersion: number;
1384
+ name?: string;
1385
+ description?: string;
1386
+ permissions?: AppRolePermission[];
1387
+ };
1388
+ //#endregion
1389
+ //#region src/admin/mediaTypes.d.ts
1390
+ /** Media library types (package G, `apps/api/src/routes/admin/media/schemas.ts`). Dates are ISO-8601 strings. */
1391
+ type MediaVisibility = 'public' | 'private';
1392
+ type MediaAssetStatus = 'processing' | 'ready' | 'failed';
1393
+ type MediaVariantStatus = 'pending' | 'ready' | 'failed';
1394
+ type MediaStorageDriver = 'local' | 's3';
1395
+ type MediaFocalPoint = {
1396
+ x: number;
1397
+ y: number;
1398
+ };
1399
+ type MediaVariant = {
1400
+ name: string;
1401
+ width: number | null;
1402
+ height: number | null;
1403
+ format: string;
1404
+ mimeType: string;
1405
+ sizeBytes: number | null;
1406
+ status: MediaVariantStatus;
1407
+ /** Present once the variant is ready. */
1408
+ url: string | null;
1409
+ };
1410
+ type MediaAsset = {
1411
+ id: string;
1412
+ folderId: string | null;
1413
+ filename: string;
1414
+ mimeType: string;
1415
+ sizeBytes: number;
1416
+ width: number | null;
1417
+ height: number | null;
1418
+ checksumSha256: string | null;
1419
+ alt: string;
1420
+ caption: string;
1421
+ focalPoint: MediaFocalPoint | null;
1422
+ visibility: MediaVisibility;
1423
+ /** `processing` until the checksum, dimensions and variants are done. */
1424
+ status: MediaAssetStatus;
1425
+ processingError: string | null;
1426
+ storageDriver: MediaStorageDriver;
1427
+ /** Stable for public assets; signed and expiring (`urlExpiresAt`) for private ones. */
1428
+ url: string;
1429
+ urlExpiresAt: string | null;
1430
+ variants: MediaVariant[];
1431
+ createdBy: string | null;
1432
+ createdAt: string;
1433
+ updatedAt: string;
1434
+ version: number;
1435
+ };
1436
+ type MediaAssetQuery = {
1437
+ /** A folder ID, or `root` for assets in no folder. Omit for every folder. */
1438
+ folder?: string;
1439
+ /** `image/png` or `image/*`. */
1440
+ mimeType?: string;
1441
+ search?: string;
1442
+ cursor?: string;
1443
+ limit?: number;
1444
+ };
1445
+ type MediaAssetPage = {
1446
+ items: MediaAsset[];
1447
+ nextCursor: string | null;
1448
+ };
1449
+ type UpdateMediaAssetInput = {
1450
+ expectedVersion: number;
1451
+ alt?: string;
1452
+ caption?: string;
1453
+ filename?: string;
1454
+ focalPoint?: MediaFocalPoint | null;
1455
+ folderId?: string | null;
1456
+ /** Needs `media.manage`. */
1457
+ visibility?: MediaVisibility;
1458
+ };
1459
+ type MoveMediaAssetsInput = {
1460
+ assetIds: string[];
1461
+ folderId: string | null;
1462
+ };
1463
+ type MoveMediaAssetsResult = {
1464
+ moved: string[];
1465
+ skipped: string[];
1466
+ };
1467
+ type MediaUsage = {
1468
+ entryId: string;
1469
+ modelId: string;
1470
+ fieldId: string;
1471
+ locale: string;
1472
+ state: 'draft' | 'published';
1473
+ since: string;
1474
+ };
1475
+ type MediaUsagePage = {
1476
+ items: MediaUsage[];
1477
+ total: number;
1478
+ };
1479
+ type MediaFolder = {
1480
+ id: string;
1481
+ parentId: string | null;
1482
+ name: string;
1483
+ assetCount: number;
1484
+ version: number;
1485
+ createdAt: string;
1486
+ updatedAt: string;
1487
+ };
1488
+ type CreateMediaFolderInput = {
1489
+ name: string;
1490
+ parentId?: string | null;
1491
+ };
1492
+ type UpdateMediaFolderInput = {
1493
+ expectedVersion: number;
1494
+ name?: string;
1495
+ parentId?: string | null;
1496
+ };
1497
+ type CreateUploadInput = {
1498
+ filename: string;
1499
+ mimeType: string;
1500
+ sizeBytes: number;
1501
+ folderId?: string | null;
1502
+ visibility?: MediaVisibility;
1503
+ };
1504
+ type ReplaceUploadInput = {
1505
+ filename: string;
1506
+ mimeType: string;
1507
+ sizeBytes: number;
1508
+ };
1509
+ /**
1510
+ * Step 1 of an upload. Send the file as `multipart/form-data` to `upload.url`: every entry of `fields`
1511
+ * first, then the file as `fileField` (see `buildUploadForm`). The same for every storage driver: the URL
1512
+ * is either the bucket (presigned POST) or Shapio's own upload route. Then call `uploads.confirm`.
1513
+ */
1514
+ type UploadGrant = {
1515
+ grantId: string;
1516
+ assetId: string;
1517
+ expiresAt: string;
1518
+ maxSizeBytes: number;
1519
+ upload: {
1520
+ method: 'POST';
1521
+ url: string;
1522
+ fields: Record<string, string>;
1523
+ fileField: 'file';
1524
+ };
1525
+ };
1526
+ //#endregion
1527
+ //#region src/admin/schemaSyncTypes.d.ts
1528
+ /**
1529
+ * Schema sync (`/api/admin/schema/export|apply`, ADR 0002): the pull format `shapio schema pull` writes and
1530
+ * the three-way apply `shapio schema apply` sends. Shared by the CLI and @shapio/mcp.
1531
+ */
1532
+ type SchemaExport = {
1533
+ schemaVersion: number;
1534
+ definitions: Array<{
1535
+ definition: SchemaDefinition;
1536
+ version: number;
1537
+ hash: string;
1538
+ }>;
1539
+ };
1540
+ type SchemaSyncResult = {
1541
+ definitionId: string;
1542
+ apiKey: string;
1543
+ kind: SchemaDefinition['kind'];
1544
+ decision: SyncDecision;
1545
+ changes: SchemaChange[];
1546
+ outcome?: 'activated' | 'pending' | 'skipped';
1547
+ version?: number | null;
1548
+ changeId?: string;
1549
+ plan?: {
1550
+ summary?: {
1551
+ breaking?: boolean;
1552
+ destructive?: boolean;
1553
+ prerequisites?: string[];
1554
+ };
1555
+ };
1556
+ };
1557
+ type SchemaApplyResult = {
1558
+ schemaVersion: number;
1559
+ dryRun: boolean;
1560
+ results: SchemaSyncResult[];
1561
+ };
1562
+ type SchemaApplyInput = {
1563
+ /** Definition files as read (untrusted JSON; the server parses and validates them). */
1564
+ definitions: unknown[];
1565
+ /** The lock file the files came from: the versions the local copy is based on. */
1566
+ base: LockFile;
1567
+ prune: boolean;
1568
+ dryRun: boolean;
1569
+ acknowledgeBreaking: boolean;
1570
+ acknowledgeDestructive: boolean;
1571
+ };
1572
+ //#endregion
1573
+ //#region src/snapshotTypes.d.ts
1574
+ /** Publication snapshots for delivery callers (`/api/snapshots`, apps/api/src/routes/snapshots). */
1575
+ type SnapshotChangeKind = 'published' | 'updated' | 'unpublished';
1576
+ type SnapshotChangesQuery = {
1577
+ from: number;
1578
+ /** Defaults to the current snapshot. */
1579
+ to?: number;
1580
+ /** `nextCursor` of the previous page. */
1581
+ after?: string;
1582
+ /** Entries per page (default 100, at most 500). */
1583
+ limit?: number;
1584
+ };
1585
+ type SnapshotChange = {
1586
+ id: string;
1587
+ modelId: string;
1588
+ /** The model's API ID. */
1589
+ modelKey: string;
1590
+ /** The delivery route key (`/api/content/<routeKey>`). */
1591
+ routeKey: string;
1592
+ /** From the revision live at `to` (at `from` when unpublished); null without a readable title. */
1593
+ title: string | null;
1594
+ /** The cover image's media asset ID, when the model has a readable cover. */
1595
+ coverMediaId: string | null;
1596
+ locales: Array<{
1597
+ locale: string;
1598
+ change: SnapshotChangeKind;
1599
+ /** The revision live at `to`, or at `from` for `unpublished`. */
1600
+ revisionId: string | null;
1601
+ }>;
1602
+ };
1603
+ type SnapshotChangesPage = {
1604
+ from: number;
1605
+ to: number;
1606
+ /** Schema version recorded with each end; when they differ, rebuild the affected models. */
1607
+ schemaVersions: {
1608
+ from: number | null;
1609
+ to: number | null;
1610
+ };
1611
+ items: SnapshotChange[];
1612
+ nextCursor: string | null;
1613
+ };
1614
+ type CurrentSnapshot = {
1615
+ snapshot: number;
1616
+ schemaVersion: number;
1617
+ publishedAt: string | null;
1618
+ };
1619
+ //#endregion
1620
+ //#region src/types.d.ts
1621
+ type HealthResponse = {
1622
+ status: 'ok';
1623
+ };
1624
+ type CheckStatus = 'ok' | 'failing';
1625
+ type ReadyResponse = {
1626
+ status: 'ready';
1627
+ checks: {
1628
+ database: CheckStatus;
1629
+ migrations: CheckStatus;
1630
+ };
1631
+ };
1632
+ type VersionResponse = {
1633
+ name: 'shapio';
1634
+ version: string;
1635
+ node: string;
1636
+ };
1637
+ //#endregion
1638
+ //#region src/client.d.ts
1639
+ type ShapioClientOptions = {
1640
+ /** Base URL of the Shapio server including any BASE_PATH, e.g. `https://cms.example.com/cms`. */
1641
+ baseUrl: string;
1642
+ /** API token sent as a bearer token. */
1643
+ token?: string;
1644
+ /** Defaults to the global fetch; injectable for tests and custom agents. */
1645
+ fetch?: typeof globalThis.fetch;
1646
+ /** Fetch credentials mode. The admin uses `same-origin` so its session cookie is sent. */
1647
+ credentials?: FetchCredentials;
1648
+ /** Extra headers computed per request (the admin's CSRF token). */
1649
+ headers?: () => Readonly<Record<string, string>>;
1650
+ /**
1651
+ * The site key (multi-site instances). Delivery reads send it as `?site=`, every other request as the
1652
+ * `Shapio-Site` header. Leave it out to use the token's site, else the primary site. A site token only
1653
+ * ever reads its own site: naming another one is refused (403 `SITE_MISMATCH`).
1654
+ */
1655
+ site?: string;
1656
+ };
1657
+ declare const createClient: ({ baseUrl, token, fetch, credentials, headers, site }: ShapioClientOptions) => {
1658
+ /**
1659
+ * Any Shapio route, e.g. the delivery API. Delivery paths use the model's route key: a collection's
1660
+ * plural API ID (`request('/api/content/articles')`, `/api/content/articles/<id>`), a singleton's API ID
1661
+ * (`/api/content/homepage`). The admin API (`admin.*`) always uses the singular API ID.
1662
+ */
1663
+ request: RequestFn;
1664
+ system: {
1665
+ health: (signal?: AbortSignal) => Promise<HealthResponse>;
1666
+ ready: (signal?: AbortSignal) => Promise<ReadyResponse>;
1667
+ version: (signal?: AbortSignal) => Promise<VersionResponse>;
1668
+ };
1669
+ /** Published content (the delivery API), typed by the caller. */
1670
+ delivery: {
1671
+ list: <T = Record<string, unknown>>(routeKey: string, query?: DeliveryListQuery) => Promise<DeliveryList<T>>;
1672
+ singleton: <T = Record<string, unknown>>(apiKey: string, query?: DeliveryGetQuery) => Promise<DeliveryItem<T>>;
1673
+ get: <T = Record<string, unknown>>(routeKey: string, id: string, query?: DeliveryGetQuery) => Promise<DeliveryItem<T>>;
1674
+ };
1675
+ admin: {
1676
+ assist: {
1677
+ status: () => Promise<AssistStatus>;
1678
+ altText: (body: AltTextInput) => Promise<AltTextResult>;
1679
+ summarize: (body: SummarizeInput) => Promise<AssistTextResult>;
1680
+ translate: (body: TranslateInput) => Promise<TranslateResult>;
1681
+ rewrite: (body: RewriteInput) => Promise<AssistTextResult>;
1682
+ schemaDraft: (body: SchemaDraftInput) => Promise<SchemaDraftResult>;
1683
+ proposeContentOps: (body: ContentOpsInput) => Promise<{
1684
+ runId: string;
1685
+ }>;
1686
+ contentOpsRun: (runId: string) => Promise<ContentOpsRun>;
1687
+ };
1688
+ sites: {
1689
+ list: () => Promise<Site[]>;
1690
+ get: (id: string) => Promise<Site>;
1691
+ create: (body: CreateSiteInput) => Promise<Site>;
1692
+ update: (id: string, body: UpdateSiteInput) => Promise<Site>;
1693
+ remove: (id: string) => Promise<void>;
1694
+ appRoles: {
1695
+ get: (id: string) => Promise<SiteAppRoles>;
1696
+ set: (id: string, body: SetSiteAppRolesInput) => Promise<SiteAppRoles>;
1697
+ };
1698
+ };
1699
+ usage: {
1700
+ fields: (query: FieldUsageQuery) => Promise<FieldUsageResponse>;
1701
+ };
1702
+ changeSets: {
1703
+ list: (query?: ChangeSetQuery) => Promise<Page<ChangeSetSummary>>;
1704
+ get: (id: string) => Promise<ChangeSet>;
1705
+ create: (body: CreateChangeSetInput) => Promise<ChangeSet>;
1706
+ update: (id: string, body: UpdateChangeSetInput) => Promise<ChangeSet>;
1707
+ discard: (id: string) => Promise<ChangeSet>;
1708
+ addEntry: (id: string, body: AddChangeSetEntryInput) => Promise<ChangeSet>;
1709
+ removeItem: (id: string, itemId: string) => Promise<ChangeSet>;
1710
+ getSchemaDraft: (id: string, definitionId: string) => Promise<SchemaDraft>;
1711
+ putSchemaDraft: (id: string, definitionId: string, body: PutSchemaDraftInput) => Promise<SchemaDraft>;
1712
+ removeSchemaDraft: (id: string, definitionId: string) => Promise<ChangeSet>;
1713
+ review: (id: string) => Promise<ChangeSetReview>;
1714
+ ship: (id: string, body: ShipChangeSetInput) => Promise<ChangeSet>;
1715
+ schedule: (id: string, body: ScheduleChangeSetInput) => Promise<ChangeSet>;
1716
+ unschedule: (id: string) => Promise<ChangeSet>;
1717
+ timeline: (id: string) => Promise<ChangeSetTimelineEvent[]>;
1718
+ unassigned: (query?: {
1719
+ cursor?: string;
1720
+ limit?: number;
1721
+ }) => Promise<Page<UnassignedEntry>>;
1722
+ };
1723
+ snapshots: {
1724
+ list: (query?: SnapshotQuery) => Promise<SnapshotPage>;
1725
+ get: (seq: number) => Promise<Snapshot>;
1726
+ restore: (seq: number) => Promise<ChangeSet>;
1727
+ };
1728
+ appUsers: {
1729
+ list: (query?: AppUserQuery) => Promise<AppUserPage>;
1730
+ get: (id: string) => Promise<AdminAppUser>;
1731
+ update: (id: string, body: UpdateAppUserInput) => Promise<AdminAppUser>;
1732
+ remove: (id: string) => Promise<void>;
1733
+ resendConfirmation: (id: string) => Promise<void>;
1734
+ };
1735
+ appRoles: {
1736
+ list: () => Promise<AppRole[]>;
1737
+ get: (id: string) => Promise<AppRole>;
1738
+ create: (body: CreateAppRoleInput) => Promise<AppRole>;
1739
+ update: (id: string, body: UpdateAppRoleInput) => Promise<AppRole>;
1740
+ remove: (id: string) => Promise<void>;
1741
+ };
1742
+ jobs: {
1743
+ list: (query?: JobQuery) => Promise<Page<Job>>;
1744
+ summary: () => Promise<JobSummary>;
1745
+ get: (id: string) => Promise<Job>;
1746
+ retry: (id: string) => Promise<Job>;
1747
+ };
1748
+ schedules: {
1749
+ list: (query?: ScheduleQuery) => Promise<Page<ScheduledPublication>>;
1750
+ create: (body: CreateScheduleInput) => Promise<ScheduledPublication>;
1751
+ cancel: (id: string) => Promise<void>;
1752
+ };
1753
+ webhooks: {
1754
+ list: () => Promise<Webhook[]>;
1755
+ events: () => Promise<WebhookEventType[]>;
1756
+ get: (id: string) => Promise<Webhook>;
1757
+ create: (body: CreateWebhookInput) => Promise<WebhookWithSecret>;
1758
+ update: (id: string, body: UpdateWebhookInput) => Promise<Webhook>;
1759
+ remove: (id: string) => Promise<void>;
1760
+ rotateSecret: (id: string) => Promise<WebhookWithSecret>;
1761
+ test: (id: string) => Promise<WebhookDelivery>;
1762
+ deliveries: (id: string, query?: {
1763
+ cursor?: string;
1764
+ limit?: number;
1765
+ }) => Promise<Page<WebhookDelivery>>;
1766
+ redeliver: (id: string, deliveryId: string) => Promise<WebhookDelivery>;
1767
+ };
1768
+ deployments: {
1769
+ connections: {
1770
+ list: () => Promise<DeploymentConnection[]>;
1771
+ get: (id: string) => Promise<DeploymentConnection>;
1772
+ create: (body: CreateDeploymentConnectionInput) => Promise<DeploymentConnectionCreated>;
1773
+ update: (id: string, body: UpdateDeploymentConnectionInput) => Promise<DeploymentConnection>;
1774
+ remove: (id: string) => Promise<void>;
1775
+ test: (id: string) => Promise<ConnectionTestResult>;
1776
+ trigger: (id: string) => Promise<DeploymentRun>;
1777
+ };
1778
+ runs: {
1779
+ list: (query?: DeploymentRunQuery) => Promise<Page<DeploymentRun>>;
1780
+ get: (id: string) => Promise<DeploymentRun>;
1781
+ retry: (id: string) => Promise<DeploymentRun>;
1782
+ };
1783
+ };
1784
+ preview: {
1785
+ tokens: {
1786
+ list: (query?: {
1787
+ entryId?: string;
1788
+ }) => Promise<PreviewToken[]>;
1789
+ create: (body: CreatePreviewTokenInput) => Promise<PreviewTokenCreated>;
1790
+ revoke: (id: string) => Promise<void>;
1791
+ };
1792
+ targets: () => Promise<PreviewTarget[]>;
1793
+ open: (body: OpenPreviewInput) => Promise<OpenPreviewResult>;
1794
+ };
1795
+ preflight: {
1796
+ run: (modelKey: string, id: string, body?: PreflightInput) => Promise<PreflightResponse>;
1797
+ };
1798
+ contentHealth: {
1799
+ list: (query?: ContentHealthQuery) => Promise<ContentHealthPage>;
1800
+ summary: () => Promise<ContentHealthSummary>;
1801
+ };
1802
+ presence: {
1803
+ heartbeat: (modelKey: string, id: string, body: PresenceHeartbeatInput) => Promise<EntryPresence>;
1804
+ entry: (modelKey: string, id: string) => Promise<EntryPresence>;
1805
+ model: (modelKey: string) => Promise<ModelPresence>;
1806
+ leave: (modelKey: string, id: string, tabId: string) => Promise<void>;
1807
+ };
1808
+ contentCounts: {
1809
+ list: () => Promise<ContentCounts>;
1810
+ };
1811
+ content: {
1812
+ list: (modelKey: string, query?: ContentListQuery) => Promise<AdminEntryPage>;
1813
+ get: (modelKey: string, id: string, { locale }?: {
1814
+ locale?: string;
1815
+ }) => Promise<AdminEntry>;
1816
+ create: (modelKey: string, body: CreateEntryInput) => Promise<AdminEntry>;
1817
+ update: (modelKey: string, id: string, body: UpdateEntryInput) => Promise<AdminEntry>;
1818
+ remove: (modelKey: string, id: string) => Promise<void>;
1819
+ duplicate: (modelKey: string, id: string) => Promise<AdminEntry>;
1820
+ publish: (modelKey: string, id: string, body?: EntryLocalesInput) => Promise<AdminEntry>;
1821
+ unpublish: (modelKey: string, id: string, body?: EntryLocalesInput) => Promise<AdminEntry>;
1822
+ revisions: (modelKey: string, id: string, { locale }?: {
1823
+ locale?: string;
1824
+ }) => Promise<RevisionSummary[]>;
1825
+ revision: (modelKey: string, id: string, revisionId: string) => Promise<RevisionDetail>;
1826
+ restore: (modelKey: string, id: string, revisionId: string, expectedVersion: number) => Promise<AdminEntry>;
1827
+ };
1828
+ extensions: {
1829
+ editors: () => Promise<EditorManifest>;
1830
+ };
1831
+ media: {
1832
+ folders: {
1833
+ list: () => Promise<MediaFolder[]>;
1834
+ create: (body: CreateMediaFolderInput) => Promise<MediaFolder>;
1835
+ update: (id: string, body: UpdateMediaFolderInput) => Promise<MediaFolder>;
1836
+ remove: (id: string) => Promise<void>;
1837
+ };
1838
+ assets: {
1839
+ list: (query?: MediaAssetQuery) => Promise<MediaAssetPage>;
1840
+ get: (id: string) => Promise<MediaAsset>;
1841
+ update: (id: string, body: UpdateMediaAssetInput) => Promise<MediaAsset>;
1842
+ remove: (id: string, { force }?: {
1843
+ force?: boolean;
1844
+ }) => Promise<void>;
1845
+ move: (body: MoveMediaAssetsInput) => Promise<MoveMediaAssetsResult>;
1846
+ usage: (id: string) => Promise<MediaUsagePage>;
1847
+ replace: (id: string, body: ReplaceUploadInput) => Promise<UploadGrant>;
1848
+ };
1849
+ uploads: {
1850
+ create: (body: CreateUploadInput) => Promise<UploadGrant>;
1851
+ confirm: (grantId: string) => Promise<MediaAsset>;
1852
+ };
1853
+ };
1854
+ models: {
1855
+ list: () => Promise<DefinitionListItem[]>;
1856
+ get: (id: string) => Promise<DefinitionDetail>;
1857
+ create: (body: CreateDefinitionInput) => Promise<ChangeOutcome>;
1858
+ planCreate: (definition: DefinitionPayload) => Promise<PlanPreview>;
1859
+ update: (id: string, body: UpdateDefinitionInput) => Promise<ChangeOutcome>;
1860
+ planUpdate: (id: string, body: PlanUpdateInput) => Promise<PlanPreview>;
1861
+ remove: (id: string, expectedVersion: number) => Promise<ChangeOutcome>;
1862
+ revisions: (id: string) => Promise<DefinitionRevision[]>;
1863
+ changes: (id: string) => Promise<SchemaChangeJob[]>;
1864
+ };
1865
+ components: {
1866
+ list: () => Promise<DefinitionListItem[]>;
1867
+ get: (id: string) => Promise<DefinitionDetail>;
1868
+ create: (body: CreateDefinitionInput) => Promise<ChangeOutcome>;
1869
+ planCreate: (definition: DefinitionPayload) => Promise<PlanPreview>;
1870
+ update: (id: string, body: UpdateDefinitionInput) => Promise<ChangeOutcome>;
1871
+ planUpdate: (id: string, body: PlanUpdateInput) => Promise<PlanPreview>;
1872
+ remove: (id: string, expectedVersion: number) => Promise<ChangeOutcome>;
1873
+ revisions: (id: string) => Promise<DefinitionRevision[]>;
1874
+ changes: (id: string) => Promise<SchemaChangeJob[]>;
1875
+ };
1876
+ schema: {
1877
+ summary: () => Promise<SchemaSummary>;
1878
+ change: (changeId: string) => Promise<SchemaChangeJob>;
1879
+ export: () => Promise<SchemaExport>;
1880
+ apply: (body: SchemaApplyInput) => Promise<SchemaApplyResult>;
1881
+ settings: () => Promise<SchemaSettings>;
1882
+ updateSettings: (body: UpdateSchemaSettingsInput) => Promise<SchemaSettings>;
1883
+ };
1884
+ locales: {
1885
+ list: () => Promise<import("@shapio/schema").LocaleDefinition[]>;
1886
+ create: (body: CreateLocaleInput) => Promise<import("@shapio/schema").LocaleDefinition>;
1887
+ update: (code: string, body: UpdateLocaleInput) => Promise<import("@shapio/schema").LocaleDefinition>;
1888
+ setDefault: (code: string, acknowledgeBreaking: boolean) => Promise<SetDefaultLocaleResult>;
1889
+ remove: (code: string, acknowledgeDestructive: boolean) => Promise<DeleteLocaleResult>;
1890
+ };
1891
+ setup: {
1892
+ status: () => Promise<SetupStatusResponse>;
1893
+ complete: (body: SetupInput) => Promise<SessionStarted>;
1894
+ };
1895
+ auth: {
1896
+ csrf: () => Promise<CsrfResponse>;
1897
+ login: (body: LoginInput) => Promise<SessionStarted>;
1898
+ logout: () => Promise<void>;
1899
+ me: () => Promise<MeResponse>;
1900
+ updateProfile: (body: UpdateProfileInput) => Promise<AdminUser>;
1901
+ changePassword: (body: ChangePasswordInput) => Promise<CsrfResponse>;
1902
+ requestPasswordReset: (body: PasswordResetRequestInput) => Promise<void>;
1903
+ confirmPasswordReset: (body: PasswordResetConfirmInput) => Promise<void>;
1904
+ };
1905
+ sessions: {
1906
+ list: () => Promise<AdminSession[]>;
1907
+ revoke: (id: string) => Promise<void>;
1908
+ };
1909
+ users: {
1910
+ list: () => Promise<AdminUser[]>;
1911
+ get: (id: string) => Promise<AdminUser>;
1912
+ update: (id: string, body: UpdateAdminUserInput) => Promise<AdminUser>;
1913
+ remove: (id: string) => Promise<void>;
1914
+ revokeSessions: (id: string) => Promise<void>;
1915
+ };
1916
+ invitations: {
1917
+ list: () => Promise<Invitation[]>;
1918
+ create: (body: InviteUserInput) => Promise<Invitation>;
1919
+ revoke: (id: string) => Promise<void>;
1920
+ link: (id: string) => Promise<InvitationLink>;
1921
+ inspect: (token: string) => Promise<InspectInvitationResponse>;
1922
+ accept: (body: AcceptInvitationInput) => Promise<SessionStarted>;
1923
+ };
1924
+ roles: {
1925
+ list: () => Promise<Role[]>;
1926
+ get: (id: string) => Promise<Role>;
1927
+ create: (body: CreateRoleInput) => Promise<Role>;
1928
+ update: (id: string, body: UpdateRoleInput) => Promise<Role>;
1929
+ remove: (id: string) => Promise<void>;
1930
+ };
1931
+ tokens: {
1932
+ list: () => Promise<ApiToken[]>;
1933
+ create: (body: CreateApiTokenInput) => Promise<CreatedApiToken>;
1934
+ revoke: (id: string) => Promise<void>;
1935
+ };
1936
+ audit: {
1937
+ list: (query?: AuditQuery) => Promise<AuditPage>;
1938
+ };
1939
+ };
1940
+ /** Publication snapshots and the diff between two (incremental builds). */
1941
+ snapshots: {
1942
+ current: () => Promise<CurrentSnapshot>;
1943
+ changes: (query: SnapshotChangesQuery) => Promise<SnapshotChangesPage>;
1944
+ allChanges: (query: Omit<SnapshotChangesQuery, "after">) => Promise<{
1945
+ from: number;
1946
+ to: number;
1947
+ schemaVersions: {
1948
+ from: number | null;
1949
+ to: number | null;
1950
+ };
1951
+ items: SnapshotChange[];
1952
+ }>;
1953
+ };
1954
+ /** End users of your sites and apps: sign-up, sign-in, tokens, OAuth. */
1955
+ appAuth: {
1956
+ register: (body: AppRegisterInput) => Promise<AppRegisterResult>;
1957
+ login: (body: AppLoginInput) => Promise<AppSession>;
1958
+ refresh: (refreshToken: string) => Promise<AppSession>;
1959
+ logout: (refreshToken: string) => Promise<void>;
1960
+ me: () => Promise<AppUser>;
1961
+ updateMe: (body: {
1962
+ name: string;
1963
+ }) => Promise<AppUser>;
1964
+ changePassword: (body: AppChangePasswordInput) => Promise<AppSession>;
1965
+ deleteMe: (body?: {
1966
+ password?: string;
1967
+ }) => Promise<void>;
1968
+ confirmEmail: (token: string) => Promise<void>;
1969
+ resendConfirmation: (email: string) => Promise<void>;
1970
+ requestPasswordReset: (email: string) => Promise<void>;
1971
+ confirmPasswordReset: (body: {
1972
+ token: string;
1973
+ password: string;
1974
+ }) => Promise<void>;
1975
+ providers: () => Promise<AppOAuthProvider[]>;
1976
+ oauthStartUrl: (provider: AppOAuthProvider, redirectTo: string, codeChallenge: string) => string;
1977
+ exchangeCode: (code: string, codeVerifier: string) => Promise<AppSession>;
1978
+ };
1979
+ };
1980
+ type ShapioClient = ReturnType<typeof createClient>;
1981
+ //#endregion
1982
+ //#region src/errors.d.ts
1983
+ /** The body every Shapio endpoint returns on failure. */
1984
+ type ShapioErrorBody = {
1985
+ error: {
1986
+ code: string;
1987
+ message: string;
1988
+ details?: unknown;
1989
+ };
1990
+ };
1991
+ /** Thrown for any non-2xx response. `code` is Shapio's error code, or `HTTP_<status>` if the body had none. */
1992
+ declare class ShapioApiError extends Error {
1993
+ readonly status: number;
1994
+ readonly code: string;
1995
+ readonly details: unknown;
1996
+ constructor(status: number, body: unknown);
1997
+ }
1998
+ //#endregion
1999
+ //#region src/admin/assistTypes.d.ts
2000
+ /** Editor assists (plan agentic-ecosystem §A0). Agents propose, people ship: nothing here publishes. */
2001
+ type AssistProvider = 'anthropic' | 'openai' | 'openai-compatible';
2002
+ type AssistUsage = {
2003
+ month: string;
2004
+ runs: number;
2005
+ inputTokens: number;
2006
+ outputTokens: number;
2007
+ };
2008
+ /** `usage` only for admins with `changes.manage`; provider and model only while assist is on. */
2009
+ type AssistStatus = {
2010
+ enabled: boolean;
2011
+ provider?: AssistProvider;
2012
+ model?: string;
2013
+ usage?: AssistUsage;
2014
+ };
2015
+ type AltTextInput = {
2016
+ assetId: string;
2017
+ locale?: string;
2018
+ };
2019
+ type AltTextResult = {
2020
+ alt: string;
2021
+ model: string;
2022
+ };
2023
+ /** A model-written text; `truncated` when it was cut to the field's or the request's limit. */
2024
+ type AssistTextResult = {
2025
+ text: string;
2026
+ truncated: boolean;
2027
+ model: string;
2028
+ };
2029
+ type SummarizeInput = {
2030
+ modelKey: string;
2031
+ entryId: string;
2032
+ locale?: string;
2033
+ fieldApiKey: string;
2034
+ };
2035
+ type TranslateInput = {
2036
+ modelKey: string;
2037
+ entryId: string;
2038
+ from: string;
2039
+ to: string;
2040
+ };
2041
+ type AssistIssue = {
2042
+ path: string;
2043
+ code: string;
2044
+ message: string;
2045
+ };
2046
+ /** `data` is in the editor's save format: save it as the `to` locale's draft. */
2047
+ type TranslateResult = {
2048
+ data: Record<string, unknown>;
2049
+ issues: AssistIssue[];
2050
+ model: string;
2051
+ };
2052
+ type RewriteInput = {
2053
+ text: string;
2054
+ instruction: string;
2055
+ maxLength?: number;
2056
+ };
2057
+ type SchemaDraftInput = {
2058
+ description: string;
2059
+ };
2060
+ /** New definitions with new stable IDs, in save order (references first). Nothing is written. */
2061
+ type SchemaDraftResult = {
2062
+ definitions: SchemaDefinition[];
2063
+ model: string;
2064
+ };
2065
+ declare const CONTENT_OPS_RULES: readonly ["altMissing", "localeMissing"];
2066
+ type ContentOpsRule = (typeof CONTENT_OPS_RULES)[number];
2067
+ type ContentOpsInput = {
2068
+ rule: ContentOpsRule;
2069
+ modelKey?: string;
2070
+ fromLocale?: string;
2071
+ };
2072
+ type ContentOpsStatus = 'queued' | 'running' | 'succeeded' | 'failed';
2073
+ /** One library asset's proposed alt text; apply it with the media update at `assetVersion`. */
2074
+ type AltProposal = {
2075
+ assetId: string;
2076
+ filename: string;
2077
+ currentAlt: string | null;
2078
+ proposedAlt: string;
2079
+ assetVersion: number;
2080
+ findingCount: number;
2081
+ };
2082
+ /** A finding the run left alone, and why (an error code or a reason such as `publishesOnSave`). */
2083
+ type ContentOpsSkip = {
2084
+ key: string;
2085
+ entryId?: string;
2086
+ assetId?: string;
2087
+ locale?: string;
2088
+ reason: string;
2089
+ detail?: unknown;
2090
+ };
2091
+ type ContentOpsWritten = {
2092
+ entryId: string;
2093
+ modelKey: string;
2094
+ locale: string;
2095
+ version: number;
2096
+ };
2097
+ type AltMissingResult = {
2098
+ rule: 'altMissing';
2099
+ proposals: AltProposal[];
2100
+ skipped: ContentOpsSkip[];
2101
+ };
2102
+ /** The drafts were written into the change set `changeSetId` (null when nothing was written). */
2103
+ type LocaleMissingResult = {
2104
+ rule: 'localeMissing';
2105
+ changeSetId: string | null;
2106
+ fromLocale: string;
2107
+ written: ContentOpsWritten[];
2108
+ skipped: ContentOpsSkip[];
2109
+ };
2110
+ type ContentOpsResult = AltMissingResult | LocaleMissingResult;
2111
+ type ContentOpsRun = {
2112
+ runId: string;
2113
+ rule: ContentOpsRule;
2114
+ status: ContentOpsStatus;
2115
+ model: string;
2116
+ createdAt: string;
2117
+ finishedAt: string | null;
2118
+ error: {
2119
+ code: string;
2120
+ } | null;
2121
+ /** Once succeeded (null before, or partial progress while running). */
2122
+ result: ContentOpsResult | null;
2123
+ };
2124
+ //#endregion
2125
+ //#region src/admin/editingTypes.d.ts
2126
+ /**
2127
+ * Shapes of the entry document's endpoints (editor experience, E0b): publish pre-flight, content health
2128
+ * findings, presence and per-model counts. Sentences are never sent: the admin builds them from `rule` and
2129
+ * `params` with its translations.
2130
+ */
2131
+ /** Health rules evaluated per entry (`apps/api/src/services/contentHealth.ts`). */
2132
+ declare const HEALTH_RULES: readonly ["requiredEmpty", "altMissing", "localeMissing", "relationMissing", "relationUnpublished", "uniqueConflict", "staleDraft", "unpublishedChanges"];
2133
+ type HealthRule = (typeof HEALTH_RULES)[number];
2134
+ /** Pre-flight adds the publish checks that are not health rules: validator issues and missing media. */
2135
+ type PreflightRule = HealthRule | 'invalid' | 'mediaMissing';
2136
+ type CheckSeverity = 'error' | 'warning';
2137
+ /** Values a sentence needs (field ID, asset ID, locale, counts…). */
2138
+ type CheckParams = Record<string, string | number | null>;
2139
+ type PreflightCheck = {
2140
+ rule: PreflightRule;
2141
+ /** Errors block publishing; warnings are informational. */
2142
+ severity: CheckSeverity;
2143
+ /** JSON pointer (API keys) of the value to fix, e.g. `/body` or `/sections/2/title`. */
2144
+ path?: string;
2145
+ /** The validator's issue code, for `invalid` and `requiredEmpty` errors. */
2146
+ code?: string;
2147
+ params: CheckParams;
2148
+ };
2149
+ type PreflightLocale = {
2150
+ locale: string;
2151
+ /** No error-severity check: publishing this locale is expected to succeed. */
2152
+ ready: boolean;
2153
+ checks: PreflightCheck[];
2154
+ };
2155
+ type PreflightInput = {
2156
+ locales?: string[];
2157
+ };
2158
+ type PreflightResponse = {
2159
+ locales: PreflightLocale[];
2160
+ /** Checks about the entry as a whole, not one locale (e.g. a configured locale not started yet). */
2161
+ entry: PreflightCheck[];
2162
+ };
2163
+ /** A finding of the health engine, open until its rule passes again. */
2164
+ type ContentHealthFinding = {
2165
+ id: string;
2166
+ entryId: string;
2167
+ modelId: string;
2168
+ modelKey: string;
2169
+ /** The entry's title in the finding's locale (or the default locale), when readable. */
2170
+ entryTitle: string | null;
2171
+ /** `*` for a finding about the entry as a whole. */
2172
+ locale: string;
2173
+ rule: HealthRule;
2174
+ /** Distinguishes several findings of one rule on one entry (e.g. two images without alt text). */
2175
+ subject: string;
2176
+ severity: CheckSeverity;
2177
+ path?: string;
2178
+ params: CheckParams;
2179
+ firstSeenAt: string;
2180
+ lastSeenAt: string;
2181
+ };
2182
+ type ContentHealthQuery = {
2183
+ rule?: HealthRule;
2184
+ modelKey?: string;
2185
+ cursor?: string;
2186
+ limit?: number;
2187
+ };
2188
+ type ContentHealthPage = {
2189
+ items: ContentHealthFinding[];
2190
+ nextCursor: string | null;
2191
+ };
2192
+ type ContentHealthSummary = {
2193
+ rules: {
2194
+ rule: HealthRule;
2195
+ count: number;
2196
+ }[];
2197
+ };
2198
+ /** Someone with the entry open. */
2199
+ type PresencePerson = {
2200
+ userId: string;
2201
+ name: string;
2202
+ /** The locale they are editing, when the model is localized. */
2203
+ locale: string | null;
2204
+ /** When this tab started editing. */
2205
+ since: string;
2206
+ /** The caller's own other tab (the calling tab itself is never listed). */
2207
+ you: boolean;
2208
+ };
2209
+ type PresenceHeartbeatInput = {
2210
+ /** A random ID per browser tab, so two tabs of one person are counted apart. */
2211
+ tabId: string;
2212
+ locale?: string | null;
2213
+ };
2214
+ type EntryPresence = {
2215
+ people: PresencePerson[];
2216
+ };
2217
+ type ModelPresence = {
2218
+ entries: {
2219
+ entryId: string;
2220
+ people: PresencePerson[];
2221
+ }[];
2222
+ };
2223
+ type ContentCount = {
2224
+ modelId: string;
2225
+ modelKey: string;
2226
+ total: number;
2227
+ };
2228
+ type ContentCounts = {
2229
+ counts: ContentCount[];
2230
+ };
2231
+ //#endregion
2232
+ //#region src/admin/paths.d.ts
2233
+ /** Every admin route the client calls (packages B, D, F and G, `apps/api/src/routes/admin/**`). */
2234
+ declare const ADMIN_PATHS: {
2235
+ readonly setup: "/api/admin/setup";
2236
+ readonly csrf: "/api/admin/auth/csrf";
2237
+ readonly login: "/api/admin/auth/login";
2238
+ readonly logout: "/api/admin/auth/logout";
2239
+ readonly me: "/api/admin/auth/me";
2240
+ readonly password: "/api/admin/auth/me/password";
2241
+ readonly sessions: "/api/admin/auth/sessions";
2242
+ readonly passwordReset: "/api/admin/auth/password-reset";
2243
+ readonly passwordResetConfirm: "/api/admin/auth/password-reset/confirm";
2244
+ readonly users: "/api/admin/users";
2245
+ readonly invitations: "/api/admin/invitations";
2246
+ readonly inspectInvitation: "/api/admin/invitations/inspect";
2247
+ readonly acceptInvitation: "/api/admin/invitations/accept";
2248
+ readonly roles: "/api/admin/roles";
2249
+ readonly tokens: "/api/admin/tokens";
2250
+ readonly audit: "/api/admin/audit";
2251
+ readonly models: "/api/admin/models";
2252
+ readonly components: "/api/admin/components";
2253
+ readonly schema: "/api/admin/schema";
2254
+ readonly schemaChanges: "/api/admin/schema/changes";
2255
+ readonly schemaExport: "/api/admin/schema/export";
2256
+ readonly schemaApply: "/api/admin/schema/apply";
2257
+ readonly schemaSettings: "/api/admin/schema/settings";
2258
+ readonly locales: "/api/admin/locales";
2259
+ readonly mediaFolders: "/api/admin/media/folders";
2260
+ readonly mediaAssets: "/api/admin/media/assets";
2261
+ readonly mediaUploads: "/api/admin/media/uploads";
2262
+ readonly appUsers: "/api/admin/app-users";
2263
+ readonly appRoles: "/api/admin/app-roles";
2264
+ readonly content: "/api/admin/content";
2265
+ readonly contentCounts: "/api/admin/content-counts";
2266
+ readonly contentHealth: "/api/admin/content-health";
2267
+ readonly presence: "/api/admin/presence";
2268
+ readonly editorManifest: "/api/admin/extensions/editors";
2269
+ readonly jobs: "/api/admin/jobs";
2270
+ readonly schedules: "/api/admin/publishing/schedules";
2271
+ readonly changeSets: "/api/admin/change-sets";
2272
+ readonly snapshots: "/api/admin/snapshots";
2273
+ readonly webhooks: "/api/admin/webhooks";
2274
+ readonly deploymentConnections: "/api/admin/deployments/connections";
2275
+ readonly deploymentRuns: "/api/admin/deployments/runs";
2276
+ readonly preview: "/api/admin/preview";
2277
+ readonly previewTokens: "/api/admin/preview/tokens";
2278
+ };
2279
+ //#endregion
2280
+ //#region src/admin/sites.d.ts
2281
+ declare const SITES_PATHS: {
2282
+ readonly sites: "/api/admin/sites";
2283
+ };
2284
+ /** The admin API header that names the site a site-scoped request is about (default: the primary site). */
2285
+ declare const SITE_HEADER = "shapio-site";
2286
+ //#endregion
2287
+ //#region src/admin/contentQuery.d.ts
2288
+ declare const toContentQueryString: (query?: ContentListQuery) => string;
2289
+ //#endregion
2290
+ //#region src/admin/media.d.ts
2291
+ /** The form for step 2 of an upload: the grant's fields in order, then the file. */
2292
+ declare const buildUploadForm: (grant: UploadGrant, file: Blob, filename: string) => FormData;
2293
+ /**
2294
+ * Where to send a grant's bytes. Shapio's own upload route (local storage) is addressed through the base URL
2295
+ * the caller already talks to, which keeps it reachable when PUBLIC_URL differs from that address (the
2296
+ * admin's dev server, a proxy, a container network). Bucket URLs (presigned POST) are used as given.
2297
+ */
2298
+ declare const resolveUploadUrl: (grant: UploadGrant, apiBaseUrl: string) => string;
2299
+ //#endregion
2300
+ //#region src/admin/assist.d.ts
2301
+ declare const ASSIST_PATHS: {
2302
+ readonly status: "/api/admin/assist/status";
2303
+ readonly altText: "/api/admin/assist/alt-text";
2304
+ readonly summarize: "/api/admin/assist/summarize";
2305
+ readonly translate: "/api/admin/assist/translate";
2306
+ readonly rewrite: "/api/admin/assist/rewrite";
2307
+ readonly schemaDraft: "/api/admin/assist/schema/draft";
2308
+ readonly contentOpsPropose: "/api/admin/assist/content-ops/propose";
2309
+ readonly contentOps: "/api/admin/assist/content-ops";
2310
+ };
2311
+ //#endregion
2312
+ //#region src/admin/index.d.ts
2313
+ /**
2314
+ * Admin endpoints: identity (setup, auth, sessions, users, invitations, roles, tokens, audit) and the schema
2315
+ * registry (models, components, schema, locales), the media library and content.
2316
+ */
2317
+ declare const createAdminApi: (request: RequestFn) => {
2318
+ assist: {
2319
+ status: () => Promise<AssistStatus>;
2320
+ altText: (body: AltTextInput) => Promise<AltTextResult>;
2321
+ summarize: (body: SummarizeInput) => Promise<AssistTextResult>;
2322
+ translate: (body: TranslateInput) => Promise<TranslateResult>;
2323
+ rewrite: (body: RewriteInput) => Promise<AssistTextResult>;
2324
+ schemaDraft: (body: SchemaDraftInput) => Promise<SchemaDraftResult>;
2325
+ proposeContentOps: (body: ContentOpsInput) => Promise<{
2326
+ runId: string;
2327
+ }>;
2328
+ contentOpsRun: (runId: string) => Promise<ContentOpsRun>;
2329
+ };
2330
+ sites: {
2331
+ list: () => Promise<Site[]>;
2332
+ get: (id: string) => Promise<Site>;
2333
+ create: (body: CreateSiteInput) => Promise<Site>;
2334
+ update: (id: string, body: UpdateSiteInput) => Promise<Site>;
2335
+ remove: (id: string) => Promise<void>;
2336
+ appRoles: {
2337
+ get: (id: string) => Promise<SiteAppRoles>;
2338
+ set: (id: string, body: SetSiteAppRolesInput) => Promise<SiteAppRoles>;
2339
+ };
2340
+ };
2341
+ usage: {
2342
+ fields: (query: FieldUsageQuery) => Promise<FieldUsageResponse>;
2343
+ };
2344
+ changeSets: {
2345
+ list: (query?: ChangeSetQuery) => Promise<Page<ChangeSetSummary>>;
2346
+ get: (id: string) => Promise<ChangeSet>;
2347
+ create: (body: CreateChangeSetInput) => Promise<ChangeSet>;
2348
+ update: (id: string, body: UpdateChangeSetInput) => Promise<ChangeSet>;
2349
+ discard: (id: string) => Promise<ChangeSet>;
2350
+ addEntry: (id: string, body: AddChangeSetEntryInput) => Promise<ChangeSet>;
2351
+ removeItem: (id: string, itemId: string) => Promise<ChangeSet>;
2352
+ getSchemaDraft: (id: string, definitionId: string) => Promise<SchemaDraft>;
2353
+ putSchemaDraft: (id: string, definitionId: string, body: PutSchemaDraftInput) => Promise<SchemaDraft>;
2354
+ removeSchemaDraft: (id: string, definitionId: string) => Promise<ChangeSet>;
2355
+ review: (id: string) => Promise<ChangeSetReview>;
2356
+ ship: (id: string, body: ShipChangeSetInput) => Promise<ChangeSet>;
2357
+ schedule: (id: string, body: ScheduleChangeSetInput) => Promise<ChangeSet>;
2358
+ unschedule: (id: string) => Promise<ChangeSet>;
2359
+ timeline: (id: string) => Promise<ChangeSetTimelineEvent[]>;
2360
+ unassigned: (query?: {
2361
+ cursor?: string;
2362
+ limit?: number;
2363
+ }) => Promise<Page<UnassignedEntry>>;
2364
+ };
2365
+ snapshots: {
2366
+ list: (query?: SnapshotQuery) => Promise<SnapshotPage>;
2367
+ get: (seq: number) => Promise<Snapshot>;
2368
+ restore: (seq: number) => Promise<ChangeSet>;
2369
+ };
2370
+ appUsers: {
2371
+ list: (query?: AppUserQuery) => Promise<AppUserPage>;
2372
+ get: (id: string) => Promise<AdminAppUser>;
2373
+ update: (id: string, body: UpdateAppUserInput) => Promise<AdminAppUser>;
2374
+ remove: (id: string) => Promise<void>;
2375
+ resendConfirmation: (id: string) => Promise<void>;
2376
+ };
2377
+ appRoles: {
2378
+ list: () => Promise<AppRole[]>;
2379
+ get: (id: string) => Promise<AppRole>;
2380
+ create: (body: CreateAppRoleInput) => Promise<AppRole>;
2381
+ update: (id: string, body: UpdateAppRoleInput) => Promise<AppRole>;
2382
+ remove: (id: string) => Promise<void>;
2383
+ };
2384
+ jobs: {
2385
+ list: (query?: JobQuery) => Promise<Page<Job>>;
2386
+ summary: () => Promise<JobSummary>;
2387
+ get: (id: string) => Promise<Job>;
2388
+ retry: (id: string) => Promise<Job>;
2389
+ };
2390
+ schedules: {
2391
+ list: (query?: ScheduleQuery) => Promise<Page<ScheduledPublication>>;
2392
+ create: (body: CreateScheduleInput) => Promise<ScheduledPublication>;
2393
+ cancel: (id: string) => Promise<void>;
2394
+ };
2395
+ webhooks: {
2396
+ list: () => Promise<Webhook[]>;
2397
+ events: () => Promise<WebhookEventType[]>;
2398
+ get: (id: string) => Promise<Webhook>;
2399
+ create: (body: CreateWebhookInput) => Promise<WebhookWithSecret>;
2400
+ update: (id: string, body: UpdateWebhookInput) => Promise<Webhook>;
2401
+ remove: (id: string) => Promise<void>;
2402
+ rotateSecret: (id: string) => Promise<WebhookWithSecret>;
2403
+ test: (id: string) => Promise<WebhookDelivery>;
2404
+ deliveries: (id: string, query?: {
2405
+ cursor?: string;
2406
+ limit?: number;
2407
+ }) => Promise<Page<WebhookDelivery>>;
2408
+ redeliver: (id: string, deliveryId: string) => Promise<WebhookDelivery>;
2409
+ };
2410
+ deployments: {
2411
+ connections: {
2412
+ list: () => Promise<DeploymentConnection[]>;
2413
+ get: (id: string) => Promise<DeploymentConnection>;
2414
+ create: (body: CreateDeploymentConnectionInput) => Promise<DeploymentConnectionCreated>;
2415
+ update: (id: string, body: UpdateDeploymentConnectionInput) => Promise<DeploymentConnection>;
2416
+ remove: (id: string) => Promise<void>;
2417
+ test: (id: string) => Promise<ConnectionTestResult>;
2418
+ trigger: (id: string) => Promise<DeploymentRun>;
2419
+ };
2420
+ runs: {
2421
+ list: (query?: DeploymentRunQuery) => Promise<Page<DeploymentRun>>;
2422
+ get: (id: string) => Promise<DeploymentRun>;
2423
+ retry: (id: string) => Promise<DeploymentRun>;
2424
+ };
2425
+ };
2426
+ preview: {
2427
+ tokens: {
2428
+ list: (query?: {
2429
+ entryId?: string;
2430
+ }) => Promise<PreviewToken[]>;
2431
+ create: (body: CreatePreviewTokenInput) => Promise<PreviewTokenCreated>;
2432
+ revoke: (id: string) => Promise<void>;
2433
+ };
2434
+ targets: () => Promise<PreviewTarget[]>;
2435
+ open: (body: OpenPreviewInput) => Promise<OpenPreviewResult>;
2436
+ };
2437
+ preflight: {
2438
+ run: (modelKey: string, id: string, body?: PreflightInput) => Promise<PreflightResponse>;
2439
+ };
2440
+ contentHealth: {
2441
+ list: (query?: ContentHealthQuery) => Promise<ContentHealthPage>;
2442
+ summary: () => Promise<ContentHealthSummary>;
2443
+ };
2444
+ presence: {
2445
+ heartbeat: (modelKey: string, id: string, body: PresenceHeartbeatInput) => Promise<EntryPresence>;
2446
+ entry: (modelKey: string, id: string) => Promise<EntryPresence>;
2447
+ model: (modelKey: string) => Promise<ModelPresence>;
2448
+ leave: (modelKey: string, id: string, tabId: string) => Promise<void>;
2449
+ };
2450
+ contentCounts: {
2451
+ list: () => Promise<ContentCounts>;
2452
+ };
2453
+ content: {
2454
+ list: (modelKey: string, query?: ContentListQuery) => Promise<AdminEntryPage>;
2455
+ get: (modelKey: string, id: string, { locale }?: {
2456
+ locale?: string;
2457
+ }) => Promise<AdminEntry>;
2458
+ create: (modelKey: string, body: CreateEntryInput) => Promise<AdminEntry>;
2459
+ update: (modelKey: string, id: string, body: UpdateEntryInput) => Promise<AdminEntry>;
2460
+ remove: (modelKey: string, id: string) => Promise<void>;
2461
+ duplicate: (modelKey: string, id: string) => Promise<AdminEntry>;
2462
+ publish: (modelKey: string, id: string, body?: EntryLocalesInput) => Promise<AdminEntry>;
2463
+ unpublish: (modelKey: string, id: string, body?: EntryLocalesInput) => Promise<AdminEntry>;
2464
+ revisions: (modelKey: string, id: string, { locale }?: {
2465
+ locale?: string;
2466
+ }) => Promise<RevisionSummary[]>;
2467
+ revision: (modelKey: string, id: string, revisionId: string) => Promise<RevisionDetail>;
2468
+ restore: (modelKey: string, id: string, revisionId: string, expectedVersion: number) => Promise<AdminEntry>;
2469
+ };
2470
+ extensions: {
2471
+ editors: () => Promise<EditorManifest>;
2472
+ };
2473
+ media: {
2474
+ folders: {
2475
+ list: () => Promise<MediaFolder[]>;
2476
+ create: (body: CreateMediaFolderInput) => Promise<MediaFolder>;
2477
+ update: (id: string, body: UpdateMediaFolderInput) => Promise<MediaFolder>;
2478
+ remove: (id: string) => Promise<void>;
2479
+ };
2480
+ assets: {
2481
+ list: (query?: MediaAssetQuery) => Promise<MediaAssetPage>;
2482
+ get: (id: string) => Promise<MediaAsset>;
2483
+ update: (id: string, body: UpdateMediaAssetInput) => Promise<MediaAsset>;
2484
+ remove: (id: string, { force }?: {
2485
+ force?: boolean;
2486
+ }) => Promise<void>;
2487
+ move: (body: MoveMediaAssetsInput) => Promise<MoveMediaAssetsResult>;
2488
+ usage: (id: string) => Promise<MediaUsagePage>;
2489
+ replace: (id: string, body: ReplaceUploadInput) => Promise<UploadGrant>;
2490
+ };
2491
+ uploads: {
2492
+ create: (body: CreateUploadInput) => Promise<UploadGrant>;
2493
+ confirm: (grantId: string) => Promise<MediaAsset>;
2494
+ };
2495
+ };
2496
+ models: {
2497
+ list: () => Promise<DefinitionListItem[]>;
2498
+ get: (id: string) => Promise<DefinitionDetail>;
2499
+ create: (body: CreateDefinitionInput) => Promise<ChangeOutcome>;
2500
+ planCreate: (definition: DefinitionPayload) => Promise<PlanPreview>;
2501
+ update: (id: string, body: UpdateDefinitionInput) => Promise<ChangeOutcome>;
2502
+ planUpdate: (id: string, body: PlanUpdateInput) => Promise<PlanPreview>;
2503
+ remove: (id: string, expectedVersion: number) => Promise<ChangeOutcome>;
2504
+ revisions: (id: string) => Promise<DefinitionRevision[]>;
2505
+ changes: (id: string) => Promise<SchemaChangeJob[]>;
2506
+ };
2507
+ components: {
2508
+ list: () => Promise<DefinitionListItem[]>;
2509
+ get: (id: string) => Promise<DefinitionDetail>;
2510
+ create: (body: CreateDefinitionInput) => Promise<ChangeOutcome>;
2511
+ planCreate: (definition: DefinitionPayload) => Promise<PlanPreview>;
2512
+ update: (id: string, body: UpdateDefinitionInput) => Promise<ChangeOutcome>;
2513
+ planUpdate: (id: string, body: PlanUpdateInput) => Promise<PlanPreview>;
2514
+ remove: (id: string, expectedVersion: number) => Promise<ChangeOutcome>;
2515
+ revisions: (id: string) => Promise<DefinitionRevision[]>;
2516
+ changes: (id: string) => Promise<SchemaChangeJob[]>;
2517
+ };
2518
+ schema: {
2519
+ summary: () => Promise<SchemaSummary>;
2520
+ change: (changeId: string) => Promise<SchemaChangeJob>;
2521
+ export: () => Promise<SchemaExport>;
2522
+ apply: (body: SchemaApplyInput) => Promise<SchemaApplyResult>;
2523
+ settings: () => Promise<SchemaSettings>;
2524
+ updateSettings: (body: UpdateSchemaSettingsInput) => Promise<SchemaSettings>;
2525
+ };
2526
+ locales: {
2527
+ list: () => Promise<import("@shapio/schema").LocaleDefinition[]>;
2528
+ create: (body: CreateLocaleInput) => Promise<import("@shapio/schema").LocaleDefinition>;
2529
+ update: (code: string, body: UpdateLocaleInput) => Promise<import("@shapio/schema").LocaleDefinition>;
2530
+ setDefault: (code: string, acknowledgeBreaking: boolean) => Promise<SetDefaultLocaleResult>;
2531
+ remove: (code: string, acknowledgeDestructive: boolean) => Promise<DeleteLocaleResult>;
2532
+ };
2533
+ setup: {
2534
+ status: () => Promise<SetupStatusResponse>;
2535
+ complete: (body: SetupInput) => Promise<SessionStarted>;
2536
+ };
2537
+ auth: {
2538
+ csrf: () => Promise<CsrfResponse>;
2539
+ login: (body: LoginInput) => Promise<SessionStarted>;
2540
+ logout: () => Promise<void>;
2541
+ me: () => Promise<MeResponse>;
2542
+ updateProfile: (body: UpdateProfileInput) => Promise<AdminUser>;
2543
+ /** The session is rotated: the response carries the new session's CSRF token. */
2544
+ changePassword: (body: ChangePasswordInput) => Promise<CsrfResponse>;
2545
+ requestPasswordReset: (body: PasswordResetRequestInput) => Promise<void>;
2546
+ confirmPasswordReset: (body: PasswordResetConfirmInput) => Promise<void>;
2547
+ };
2548
+ sessions: {
2549
+ list: () => Promise<AdminSession[]>;
2550
+ revoke: (id: string) => Promise<void>;
2551
+ };
2552
+ users: {
2553
+ list: () => Promise<AdminUser[]>;
2554
+ get: (id: string) => Promise<AdminUser>;
2555
+ update: (id: string, body: UpdateAdminUserInput) => Promise<AdminUser>;
2556
+ remove: (id: string) => Promise<void>;
2557
+ revokeSessions: (id: string) => Promise<void>;
2558
+ };
2559
+ invitations: {
2560
+ list: () => Promise<Invitation[]>;
2561
+ create: (body: InviteUserInput) => Promise<Invitation>;
2562
+ revoke: (id: string) => Promise<void>;
2563
+ /** A fresh link to send by hand; any earlier link for this invitation stops working. */
2564
+ link: (id: string) => Promise<InvitationLink>;
2565
+ /** Public: the token travels in the body, never in a URL the server logs. */
2566
+ inspect: (token: string) => Promise<InspectInvitationResponse>;
2567
+ accept: (body: AcceptInvitationInput) => Promise<SessionStarted>;
2568
+ };
2569
+ roles: {
2570
+ list: () => Promise<Role[]>;
2571
+ get: (id: string) => Promise<Role>;
2572
+ create: (body: CreateRoleInput) => Promise<Role>;
2573
+ update: (id: string, body: UpdateRoleInput) => Promise<Role>;
2574
+ remove: (id: string) => Promise<void>;
2575
+ };
2576
+ tokens: {
2577
+ list: () => Promise<ApiToken[]>;
2578
+ create: (body: CreateApiTokenInput) => Promise<CreatedApiToken>;
2579
+ revoke: (id: string) => Promise<void>;
2580
+ };
2581
+ audit: {
2582
+ list: (query?: AuditQuery) => Promise<AuditPage>;
2583
+ };
2584
+ };
2585
+ type AdminApi = ReturnType<typeof createAdminApi>;
2586
+ //#endregion
2587
+ //#region src/delivery.d.ts
2588
+ declare const DELIVERY_PATH = "/api/content";
2589
+ /**
2590
+ * Published content, typed by the caller (`delivery.list<Article>('articles', { locale: 'fr', snapshot })`).
2591
+ * A collection is read with `list` (a page) and `get` (one entry); a singleton with `singleton`.
2592
+ */
2593
+ declare const createDeliveryApi: (request: RequestFn) => {
2594
+ list: <T = Record<string, unknown>>(routeKey: string, query?: DeliveryListQuery) => Promise<DeliveryList<T>>;
2595
+ singleton: <T = Record<string, unknown>>(apiKey: string, query?: DeliveryGetQuery) => Promise<DeliveryItem<T>>;
2596
+ get: <T = Record<string, unknown>>(routeKey: string, id: string, query?: DeliveryGetQuery) => Promise<DeliveryItem<T>>;
2597
+ };
2598
+ type DeliveryApi = ReturnType<typeof createDeliveryApi>;
2599
+ //#endregion
2600
+ //#region src/site.d.ts
2601
+ /** Delivery reads name their site with `?site=`; everything else with the `Shapio-Site` header. */
2602
+ declare const SITE_QUERY_PARAMETER = "site";
2603
+ //#endregion
2604
+ //#region src/webhooks.d.ts
2605
+ /**
2606
+ * Verifying Shapio's signed webhooks and deploy triggers on the receiving side (a site's revalidate route,
2607
+ * a build hook). The scheme is the server's (`apps/api/src/publishing/signature.ts`):
2608
+ * `X-Shapio-Signature: v1=<hex HMAC-SHA256(secret, "<timestamp>.<raw body>")>` with
2609
+ * `X-Shapio-Timestamp: <unix seconds>`; several comma-separated `v1=` values are accepted (secret rotation).
2610
+ * Uses Web Crypto, so it runs in Node, edge runtimes and browsers alike.
2611
+ */
2612
+ declare const WEBHOOK_SIGNATURE_HEADER = "x-shapio-signature";
2613
+ declare const WEBHOOK_TIMESTAMP_HEADER = "x-shapio-timestamp";
2614
+ declare const WEBHOOK_EVENT_HEADER = "x-shapio-event";
2615
+ /** Requests signed further from now than this are rejected (replay protection). */
2616
+ declare const WEBHOOK_TOLERANCE_SECONDS = 300;
2617
+ type WebhookSignatureInput = {
2618
+ /** The webhook's or connection's signing secret. */
2619
+ secret: string;
2620
+ /** The `X-Shapio-Signature` header. */
2621
+ signature: string | null | undefined;
2622
+ /** The `X-Shapio-Timestamp` header. */
2623
+ timestamp: string | null | undefined;
2624
+ /** The raw request body, exactly as received (not re-serialised JSON). */
2625
+ body: string;
2626
+ /** Defaults to the current time. */
2627
+ now?: Date;
2628
+ /** Defaults to WEBHOOK_TOLERANCE_SECONDS. */
2629
+ toleranceSeconds?: number;
2630
+ };
2631
+ type WebhookSignatureCheck = {
2632
+ ok: true;
2633
+ } | {
2634
+ ok: false;
2635
+ reason: string;
2636
+ };
2637
+ /** Checks a Shapio signature; `{ ok: false, reason }` says why it was refused (never throws for bad input). */
2638
+ declare const verifyWebhookSignature: ({ secret, signature, timestamp, body, now, toleranceSeconds }: WebhookSignatureInput) => Promise<WebhookSignatureCheck>;
2639
+ //#endregion
2640
+ //#region src/appAuth/types.d.ts
2641
+ /**
2642
+ * App-user authentication (package I), mirroring apps/api/src/routes/app-auth/schemas.ts. For the sites and
2643
+ * apps built on Shapio: their end users sign up, sign in and manage their accounts here.
2644
+ */
2645
+ type AppUser = {
2646
+ id: string;
2647
+ email: string;
2648
+ name: string;
2649
+ confirmed: boolean;
2650
+ hasPassword: boolean;
2651
+ providers: string[];
2652
+ createdAt: string;
2653
+ lastLoginAt: string | null;
2654
+ };
2655
+ /** Send `accessToken` as `Authorization: Bearer …`; trade `refreshToken` for a new pair before it expires. */
2656
+ type AppSession = {
2657
+ user: AppUser;
2658
+ accessToken: string;
2659
+ tokenType: 'Bearer';
2660
+ /** Access-token lifetime in seconds. */
2661
+ expiresIn: number;
2662
+ /** Single use: each refresh returns the next one. Presenting a used one signs the session out. */
2663
+ refreshToken: string;
2664
+ refreshTokenExpiresAt: string;
2665
+ };
2666
+ type AppRegisterInput = {
2667
+ email: string;
2668
+ password: string;
2669
+ name?: string;
2670
+ };
2671
+ /**
2672
+ * Signed in at once (HTTP 201), or, when the instance requires a confirmed email, `{ confirmationRequired:
2673
+ * true }` (HTTP 202): "check your email". That answer is the same whether or not the address already had an
2674
+ * account, so it never reveals who is registered.
2675
+ */
2676
+ type AppRegisterResult = {
2677
+ confirmationRequired: false;
2678
+ user: AppUser;
2679
+ session: AppSession;
2680
+ } | {
2681
+ confirmationRequired: true;
2682
+ };
2683
+ type AppLoginInput = {
2684
+ email: string;
2685
+ password: string;
2686
+ };
2687
+ type AppChangePasswordInput = {
2688
+ currentPassword?: string;
2689
+ newPassword: string;
2690
+ };
2691
+ type AppOAuthProvider = 'google' | 'github';
2692
+ //#endregion
2693
+ //#region src/appAuth/index.d.ts
2694
+ declare const APP_AUTH_PATHS: {
2695
+ readonly register: "/api/app-auth/register";
2696
+ readonly login: "/api/app-auth/login";
2697
+ readonly refresh: "/api/app-auth/refresh";
2698
+ readonly logout: "/api/app-auth/logout";
2699
+ readonly me: "/api/app-auth/me";
2700
+ readonly password: "/api/app-auth/me/password";
2701
+ readonly confirmEmail: "/api/app-auth/confirm-email";
2702
+ readonly resendConfirmation: "/api/app-auth/confirm-email/resend";
2703
+ readonly passwordReset: "/api/app-auth/password-reset";
2704
+ readonly passwordResetConfirm: "/api/app-auth/password-reset/confirm";
2705
+ readonly providers: "/api/app-auth/providers";
2706
+ readonly oauthExchange: "/api/app-auth/oauth/exchange";
2707
+ };
2708
+ /**
2709
+ * App-user endpoints. Calls that act as the signed-in user need a client created with `token: accessToken`.
2710
+ * `baseUrl` is the client's base URL, used to build the OAuth start link the browser navigates to.
2711
+ */
2712
+ declare const createAppAuthApi: (request: RequestFn, baseUrl: string) => {
2713
+ register: (body: AppRegisterInput) => Promise<AppRegisterResult>;
2714
+ login: (body: AppLoginInput) => Promise<AppSession>;
2715
+ refresh: (refreshToken: string) => Promise<AppSession>;
2716
+ /**
2717
+ * Signs the account out everywhere: this login's refresh tokens are revoked, and every access token the
2718
+ * account holds (on any device) is refused from the next request. Other logins recover with their own
2719
+ * refresh token.
2720
+ */
2721
+ logout: (refreshToken: string) => Promise<void>;
2722
+ /** The signed-in user. Answers 401 once the account logged out anywhere, changed its password or was blocked. */
2723
+ me: () => Promise<AppUser>;
2724
+ updateMe: (body: {
2725
+ name: string;
2726
+ }) => Promise<AppUser>;
2727
+ /** Returns a new session; every other sign-in of the account is revoked. */
2728
+ changePassword: (body: AppChangePasswordInput) => Promise<AppSession>;
2729
+ deleteMe: (body?: {
2730
+ password?: string;
2731
+ }) => Promise<void>;
2732
+ /** The token from the `#token=` fragment of the confirmation link. */
2733
+ confirmEmail: (token: string) => Promise<void>;
2734
+ resendConfirmation: (email: string) => Promise<void>;
2735
+ requestPasswordReset: (email: string) => Promise<void>;
2736
+ confirmPasswordReset: (body: {
2737
+ token: string;
2738
+ password: string;
2739
+ }) => Promise<void>;
2740
+ providers: () => Promise<AppOAuthProvider[]>;
2741
+ /**
2742
+ * Where to send the browser to sign in with a provider. `codeChallenge` comes from `createPkcePair()`;
2743
+ * keep its `codeVerifier` until the browser returns. It comes back to `redirectTo` (an allowed return URL,
2744
+ * by default an origin listed in CORS_ORIGINS) with `?code=` (pass it to `exchangeCode`) or `?error=`.
2745
+ */
2746
+ oauthStartUrl: (provider: AppOAuthProvider, redirectTo: string, codeChallenge: string) => string;
2747
+ /** Trades the one-time code for a session. A wrong verifier spends the code: start the sign-in again. */
2748
+ exchangeCode: (code: string, codeVerifier: string) => Promise<AppSession>;
2749
+ };
2750
+ type AppAuthApi = ReturnType<typeof createAppAuthApi>;
2751
+ //#endregion
2752
+ //#region src/appAuth/pkce.d.ts
2753
+ /**
2754
+ * PKCE (RFC 7636) for the app side of Shapio's OAuth sign-in: the app keeps the verifier (e.g. in
2755
+ * sessionStorage) and sends the S256 challenge with the start link; the one-time code it gets back is only
2756
+ * exchanged together with that verifier. Uses Web Crypto, so it works in browsers and Node alike.
2757
+ */
2758
+ type AppPkcePair = {
2759
+ codeVerifier: string;
2760
+ codeChallenge: string;
2761
+ };
2762
+ /** The S256 challenge of a verifier: base64url(SHA-256(verifier)). */
2763
+ declare const codeChallengeOf: (codeVerifier: string) => Promise<string>;
2764
+ /** A fresh verifier (32 random bytes, 43 characters) and its S256 challenge. */
2765
+ declare const createPkcePair: () => Promise<AppPkcePair>;
2766
+ //#endregion
2767
+ export { AltTextResult as $, UpdateDeploymentConnectionInput as $i, SetupInput as $n, DefinitionRevision as $r, MoveMediaAssetsResult as $t, ADMIN_PATHS as A, ContentFilter as Aa, DeploymentRunTrigger as Ai, CsrfResponse as An, ReviewSchemaItem as Ar, SnapshotChange as At, HEALTH_RULES as B, EntryAuthor as Ba, JobSummary as Bi, NETWORK_ACTIONS as Bn, SnapshotSource as Br, MediaAsset as Bt, AdminApi as C, DeliveryList as Ca, DEPLOYMENT_TRIGGERS as Ci, AuditQuery as Cn, FieldDiff as Cr, ShapioClientOptions as Ct, toContentQueryString as D, AdminEntry as Da, DeploymentRun as Di, CreateApiTokenInput as Dn, PutSchemaDraftInput as Dr, ReadyResponse as Dt, resolveUploadUrl as E, DeliveryPagination as Ea, DeploymentProvider as Ei, ContentAction as En, NotRestorableReason as Er, HealthResponse as Et, ContentHealthFinding as F, ContentPagination as Fa, DeploymentTriggerPolicy as Fi, Invitation as Fn, ShipChangeSetInput as Fr, SchemaApplyResult as Ft, PreflightLocale as G, EntryReferrer as Ga, PreviewTarget as Gi, Role as Gn, ChangeOutcome as Gr, MediaFolder as Gt, ModelPresence as H, EntryLocaleState as Ha, OpenPreviewResult as Hi, PasswordResetConfirmInput as Hn, UpdateChangeSetInput as Hr, MediaAssetQuery as Ht, ContentHealthPage as I, ContentSort as Ia, JOB_STATUSES as Ii, InvitationLink as In, ShipPhase as Ir, SchemaExport as It, PresenceHeartbeatInput as J, RevisionSummary as Ja, PublicationAction as Ji, RoleKind as Jn, CreateLocaleInput as Jr, MediaUsagePage as Jt, PreflightResponse as K, EntryStatus as Ka, PreviewToken as Ki, RoleAssignment as Kn, ChangePlan as Kr, MediaStorageDriver as Kt, ContentHealthQuery as L, CreateEntryInput as La, Job as Li, InviteUserInput as Ln, Snapshot as Lr, SchemaSyncResult as Lt, CheckSeverity as M, ContentFilterValue as Ma, DeploymentSecretsInput as Mi, GLOBAL_ACTIONS as Mn, ScheduleChangeSetInput as Mr, SnapshotChangesPage as Mt, ContentCount as N, ContentIssue as Na, DeploymentSettings as Ni, GlobalAction as Nn, SchemaDraft as Nr, SnapshotChangesQuery as Nt, SITES_PATHS as O, AdminEntryListItem as Oa, DeploymentRunQuery as Oi, CreateRoleInput as On, ReviewEntryItem as Or, VersionResponse as Ot, ContentCounts as P, ContentListQuery as Pa, DeploymentTimelineEvent as Pi, InspectInvitationResponse as Pn, SchemaOperation as Pr, SchemaApplyInput as Pt, AltTextInput as Q, ScheduledPublication as Qi, SessionStarted as Qn, DefinitionPayload as Qr, MoveMediaAssetsInput as Qt, ContentHealthSummary as R, EditorManifest as Ra, JobQuery as Ri, LoginInput as Rn, SnapshotPage as Rr, CreateMediaFolderInput as Rt, DeliveryApi as S, DeliveryItem as Sa, DEPLOYMENT_RUN_STATUSES as Si, AuditPage as Sn, FieldConsumers as Sr, ShapioClient as St, buildUploadForm as T, DeliveryMeta as Ta, DeploymentConnectionCreated as Ti, ChangePasswordInput as Tn, NotRestorable as Tr, CheckStatus as Tt, PreflightCheck as U, EntryLocaleStatus as Ua, PUBLICATION_ACTIONS as Ui, PasswordResetRequestInput as Un, Acknowledgement as Ur, MediaAssetStatus as Ut, HealthRule as V, EntryData as Va, OpenPreviewInput as Vi, NetworkAction as Vn, UnassignedEntry as Vr, MediaAssetPage as Vt, PreflightInput as W, EntryLocalesInput as Wa, Page as Wi, PermissionAction as Wn, ActiveDefinition as Wr, MediaFocalPoint as Wt, AltMissingResult as X, RequestFn as Xa, ScheduleQuery as Xi, RoleSummary as Xn, DefinitionDetail as Xr, MediaVariantStatus as Xt, PresencePerson as Y, UpdateEntryInput as Ya, SCHEDULE_STATUSES as Yi, RolePermission as Yn, DefinitionCategory as Yr, MediaVariant as Yt, AltProposal as Z, RequestOptions as Za, ScheduleStatus as Zi, SITE_ACTIONS as Zn, DefinitionListItem as Zr, MediaVisibility as Zt, WebhookSignatureCheck as _, SiteAppRoles as _a, CreateDeploymentConnectionInput as _i, AdminUser as _n, ChangeSetStatus as _r, SummarizeInput as _t, AppAuthApi as a, WebhookEventBody as aa, PlanStepImpact as ai, AdminAppUser as an, AddChangeSetEntryInput as ar, CONTENT_OPS_RULES as at, SITE_QUERY_PARAMETER as b, UpdateSiteInput as ba, CreateWebhookInput as bi, AuditActorType as bn, CreateChangeSetInput as br, ShapioApiError as bt, AppOAuthProvider as c, FieldPrincipalUsage as ca, SchemaChangeStatus as ci, AppRolePermission as cn, ChangeSetActor as cr, ContentOpsRule as ct, AppSession as d, ModelFieldUsage as da, SchemaSummaryItem as di, BUILT_IN_APP_ROLE_KEYS as dn, ChangeSetItem as dr, ContentOpsStatus as dt, UpdateWebhookInput as ea, DeleteLocaleResult as ei, ReplaceUploadInput as en, SetupStatusResponse as er, AssistIssue as et, AppUser as f, PrincipalUsageSummary as fa, SetDefaultLocaleResult as fi, CreateAppRoleInput as fn, ChangeSetItemStatus as fr, ContentOpsWritten as ft, WEBHOOK_TOLERANCE_SECONDS as g, Site as ga, ConnectionTestResult as gi, AdminSession as gn, ChangeSetSource as gr, SchemaDraftResult as gt, WEBHOOK_TIMESTAMP_HEADER as h, SetSiteAppRolesInput as ha, UpdateSchemaSettingsInput as hi, AcceptInvitationInput as hn, ChangeSetSchemaItem as hr, SchemaDraftInput as ht, APP_AUTH_PATHS as i, WebhookDeliveryStatus as ia, PlanStep as ii, APP_CONTENT_ACTIONS as in, UpdateRoleInput as ir, AssistUsage as it, CheckParams as j, ContentFilterOperator as ja, DeploymentSecretState as ji, EmailDelivery as jn, SNAPSHOT_SOURCES as jr, SnapshotChangeKind as jt, SITE_HEADER as k, AdminEntryPage as ka, DeploymentRunStatus as ki, CreatedApiToken as kn, ReviewIssue as kr, CurrentSnapshot as kt, AppRegisterInput as l, FieldUsageQuery as la, SchemaSettings as li, AppUserPage as ln, ChangeSetEntryItem as lr, ContentOpsRun as lt, WEBHOOK_SIGNATURE_HEADER as m, CreateSiteInput as ma, UpdateLocaleInput as mi, UpdateAppUserInput as mn, ChangeSetReview as mr, RewriteInput as mt, codeChallengeOf as n, WebhookAttempt as na, PlanImpact as ni, UpdateMediaFolderInput as nn, UpdateAdminUserInput as nr, AssistStatus as nt, AppChangePasswordInput as o, WebhookEventType as oa, PlanUpdateInput as oi, AppContentAction as on, CHANGE_SET_STATUSES as or, ContentOpsInput as ot, WEBHOOK_EVENT_HEADER as p, UsageSelection as pa, UpdateDefinitionInput as pi, UpdateAppRoleInput as pn, ChangeSetQuery as pr, LocaleMissingResult as pt, PreflightRule as q, RevisionDetail as qa, PreviewTokenCreated as qi, RoleCondition as qn, CreateDefinitionInput as qr, MediaUsage as qt, createPkcePair as r, WebhookDelivery as ra, PlanPreview as ri, UploadGrant as rn, UpdateProfileInput as rr, AssistTextResult as rt, AppLoginInput as s, WebhookWithSecret as sa, SchemaChangeJob as si, AppRole as sn, ChangeSet as sr, ContentOpsResult as st, AppPkcePair as t, Webhook as ta, Locale as ti, UpdateMediaAssetInput as tn, SiteAction as tr, AssistProvider as tt, AppRegisterResult as u, FieldUsageResponse as ua, SchemaSummary as ui, AppUserQuery as un, ChangeSetError as ur, ContentOpsSkip as ut, WebhookSignatureInput as v, SiteRef as va, CreatePreviewTokenInput as vi, AdminUserStatus as vn, ChangeSetSummary as vr, TranslateInput as vt, ASSIST_PATHS as w, DeliveryListQuery as wa, DeploymentConnection as wi, CONTENT_ACTIONS as wn, NOT_RESTORABLE_REASONS as wr, createClient as wt, DELIVERY_PATH as x, DeliveryGetQuery as xa, DEPLOYMENT_PROVIDERS as xi, AuditEvent as xn, FieldConsumer as xr, ShapioErrorBody as xt, verifyWebhookSignature as y, SiteSummary as ya, CreateScheduleInput as yi, ApiToken as yn, ChangeSetTimelineEvent as yr, TranslateResult as yt, EntryPresence as z, EditorManifestItem as za, JobStatus as zi, MeResponse as zn, SnapshotQuery as zr, CreateUploadInput as zt };
2768
+ //# sourceMappingURL=index-BpSg5A3V.d.ts.map