@shapio/client 0.4.1 → 0.5.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.
@@ -1,5 +1,50 @@
1
1
  import { DEFAULT_SEO_KEYS, ResolveSeoContext, SEO_COMPONENT_ID, SEO_FIELD_IDS, SeoDefaults, SeoKeys, SeoLocaleDefaults, SeoLocaleDefaults as SeoLocaleDefaults$1, applyTitleTemplate, resolveSeo, seoDefaultsForLocale } from "@shapio/schema/seo";
2
2
  import { ChangeSummary, ClassifiedChange, DefinitionInput, ExportedDefinition, LocaleDefinition, LockFile, SchemaChange, SchemaDefinition, SyncDecision, ValidationIssue } from "@shapio/schema";
3
+ //#region src/nextCache.d.ts
4
+ /**
5
+ * Next.js data-cache support for delivery reads. Under Next (`process.env.NEXT_RUNTIME` is set) or when the
6
+ * client is given a `next` option, every delivery read passes `next: { tags }` to `fetch`, so a site can
7
+ * refresh exactly what changed with `revalidateTag`. The cache mode is only set when asked for, except that a
8
+ * read pinned to a publication snapshot is immutable and always `force-cache`. Elsewhere nothing is added.
9
+ */
10
+ /** Next's `fetch` cache modes the client passes through. */
11
+ type NextCacheMode = 'force-cache' | 'no-store';
12
+ type NextCacheOptions = {
13
+ /** Next's `fetch` `cache` option. Unset: Next's own default, except pinned snapshot reads (`force-cache`). */
14
+ cache?: NextCacheMode;
15
+ /** Seconds a cached response stays fresh (`next.revalidate`); `false` keeps it until a tag is revalidated. */
16
+ revalidate?: number | false;
17
+ };
18
+ /** The last argument of every delivery read: overrides the client's `next` option; `false` adds nothing. */
19
+ type DeliveryReadOptions = {
20
+ next?: NextCacheOptions | false;
21
+ };
22
+ /** What a delivery read adds to its `fetch` init. */
23
+ type NextFetchInit = {
24
+ cache?: NextCacheMode;
25
+ next?: {
26
+ tags: string[];
27
+ revalidate?: number | false;
28
+ };
29
+ };
30
+ /**
31
+ * The cache tags delivery reads carry (`revalidateTag(shapioTags.entry('articles', id), { expire: 0 })`).
32
+ * Models are named by their route key: a collection's plural API ID, a singleton's API ID.
33
+ */
34
+ declare const shapioTags: {
35
+ /** Every delivery read of the site; `shapio:site` when the client names no site. */
36
+ readonly site: (siteKey?: string) => string;
37
+ /** Every read of one model (lists, singletons and its entries). */
38
+ readonly model: (routeKey: string) => string;
39
+ /** Reads of one entry by its ID. */
40
+ readonly entry: (routeKey: string, entryId: string) => string;
41
+ };
42
+ /** What every delivery read needs to tag itself: the client's site and `next` option. */
43
+ type DeliveryCacheContext = {
44
+ site: string | undefined;
45
+ next: NextCacheOptions | false | undefined;
46
+ };
47
+ //#endregion
3
48
  //#region src/request.d.ts
4
49
  /** Fetch's `credentials` mode (spelled out: the DOM lib type is not available to Node consumers). */
5
50
  type FetchCredentials = 'omit' | 'same-origin' | 'include';
@@ -7,7 +52,7 @@ type RequestOptions = {
7
52
  method?: string;
8
53
  body?: unknown;
9
54
  signal?: AbortSignal;
10
- };
55
+ } & NextFetchInit;
11
56
  type RequestFn = <T>(path: string, options?: RequestOptions) => Promise<T>;
12
57
  //#endregion
13
58
  //#region src/admin/contentTypes.d.ts
@@ -1791,8 +1836,15 @@ type ShapioClientOptions = {
1791
1836
  * ever reads its own site: naming another one is refused (403 `SITE_MISMATCH`).
1792
1837
  */
1793
1838
  site?: string;
1839
+ /**
1840
+ * Next.js data-cache options for delivery reads (`delivery.*`, `site.get`), e.g. `{ cache: 'force-cache' }`.
1841
+ * Under Next the reads are tagged for `revalidateTag` whether or not this is set; the cache mode is only
1842
+ * passed when asked for, and reads pinned to a snapshot are always `force-cache`. Set it outside Next to send
1843
+ * the same fetch options; `false` sends none. A read's own `next` option overrides this one.
1844
+ */
1845
+ next?: NextCacheOptions | false;
1794
1846
  };
1795
- declare const createClient: ({ baseUrl, token, fetch, credentials, headers, site }: ShapioClientOptions) => {
1847
+ declare const createClient: ({ baseUrl, token, fetch, credentials, headers, site, next }: ShapioClientOptions) => {
1796
1848
  /**
1797
1849
  * Any Shapio route, e.g. the delivery API. Delivery paths use the model's route key: a collection's
1798
1850
  * plural API ID (`request('/api/content/articles')`, `/api/content/articles/<id>`), a singleton's API ID
@@ -1806,13 +1858,13 @@ declare const createClient: ({ baseUrl, token, fetch, credentials, headers, site
1806
1858
  };
1807
1859
  /** Published content (the delivery API), typed by the caller. */
1808
1860
  delivery: {
1809
- list: <T = Record<string, unknown>>(routeKey: string, query?: DeliveryListQuery) => Promise<DeliveryList<T>>;
1810
- singleton: <T = Record<string, unknown>>(apiKey: string, query?: DeliveryGetQuery) => Promise<DeliveryItem<T>>;
1811
- get: <T = Record<string, unknown>>(routeKey: string, id: string, query?: DeliveryGetQuery) => Promise<DeliveryItem<T>>;
1861
+ list: <T = Record<string, unknown>>(routeKey: string, query?: DeliveryListQuery, options?: DeliveryReadOptions) => Promise<DeliveryList<T>>;
1862
+ singleton: <T = Record<string, unknown>>(apiKey: string, query?: DeliveryGetQuery, options?: DeliveryReadOptions) => Promise<DeliveryItem<T>>;
1863
+ get: <T = Record<string, unknown>>(routeKey: string, id: string, query?: DeliveryGetQuery, options?: DeliveryReadOptions) => Promise<DeliveryItem<T>>;
1812
1864
  };
1813
1865
  /** The site as delivery sees it: key, name and SEO defaults (`GET /api/site`). */
1814
1866
  site: {
1815
- get: () => Promise<DeliverySite>;
1867
+ get: ({ next }?: DeliveryReadOptions) => Promise<DeliverySite>;
1816
1868
  };
1817
1869
  admin: {
1818
1870
  assist: {
@@ -2749,24 +2801,69 @@ type AdminApi = ReturnType<typeof createAdminApi>;
2749
2801
  declare const DELIVERY_PATH = "/api/content";
2750
2802
  /**
2751
2803
  * Published content, typed by the caller (`delivery.list<Article>('articles', { locale: 'fr', snapshot })`).
2752
- * A collection is read with `list` (a page) and `get` (one entry); a singleton with `singleton`.
2804
+ * A collection is read with `list` (a page) and `get` (one entry); a singleton with `singleton`. Each read
2805
+ * takes Next.js cache options last and is tagged for `revalidateTag` (nextCache.ts): lists and singletons with
2806
+ * the site and model tags, `get` with the entry's tag too.
2753
2807
  */
2754
- declare const createDeliveryApi: (request: RequestFn) => {
2755
- list: <T = Record<string, unknown>>(routeKey: string, query?: DeliveryListQuery) => Promise<DeliveryList<T>>;
2756
- singleton: <T = Record<string, unknown>>(apiKey: string, query?: DeliveryGetQuery) => Promise<DeliveryItem<T>>;
2757
- get: <T = Record<string, unknown>>(routeKey: string, id: string, query?: DeliveryGetQuery) => Promise<DeliveryItem<T>>;
2808
+ declare const createDeliveryApi: (request: RequestFn, cacheContext: DeliveryCacheContext) => {
2809
+ list: <T = Record<string, unknown>>(routeKey: string, query?: DeliveryListQuery, options?: DeliveryReadOptions) => Promise<DeliveryList<T>>;
2810
+ singleton: <T = Record<string, unknown>>(apiKey: string, query?: DeliveryGetQuery, options?: DeliveryReadOptions) => Promise<DeliveryItem<T>>;
2811
+ get: <T = Record<string, unknown>>(routeKey: string, id: string, query?: DeliveryGetQuery, options?: DeliveryReadOptions) => Promise<DeliveryItem<T>>;
2758
2812
  };
2759
2813
  type DeliveryApi = ReturnType<typeof createDeliveryApi>;
2760
2814
  //#endregion
2815
+ //#region src/deliveryClient.d.ts
2816
+ type DeliveryClientOptions = {
2817
+ /** The site key the reads are tagged with (`shapioTags.site`); the transport names the site itself. */
2818
+ site?: string;
2819
+ /** Next.js data-cache options, as `createClient`'s `next` option. */
2820
+ next?: NextCacheOptions | false;
2821
+ };
2822
+ /**
2823
+ * The read side of the client over any transport: published content (`delivery`), the site (`site`) and
2824
+ * publication snapshots (`snapshots`). `createClient` builds it over HTTP; `@shapio/local` over the delivery
2825
+ * API running in the same process. The transport receives exactly the paths the HTTP client sends.
2826
+ */
2827
+ declare const createDeliveryClient: (request: RequestFn, { site, next }?: DeliveryClientOptions) => {
2828
+ /** Published content (the delivery API), typed by the caller. */
2829
+ delivery: {
2830
+ list: <T = Record<string, unknown>>(routeKey: string, query?: DeliveryListQuery, options?: DeliveryReadOptions) => Promise<DeliveryList<T>>;
2831
+ singleton: <T = Record<string, unknown>>(apiKey: string, query?: DeliveryGetQuery, options?: DeliveryReadOptions) => Promise<DeliveryItem<T>>;
2832
+ get: <T = Record<string, unknown>>(routeKey: string, id: string, query?: DeliveryGetQuery, options?: DeliveryReadOptions) => Promise<DeliveryItem<T>>;
2833
+ };
2834
+ /** The site as delivery sees it: key, name and SEO defaults (`GET /api/site`). */
2835
+ site: {
2836
+ get: ({ next }?: DeliveryReadOptions) => Promise<DeliverySite>;
2837
+ };
2838
+ /** Publication snapshots and the diff between two (incremental builds). */
2839
+ snapshots: {
2840
+ current: () => Promise<CurrentSnapshot>;
2841
+ changes: (query: SnapshotChangesQuery) => Promise<SnapshotChangesPage>;
2842
+ allChanges: (query: Omit<SnapshotChangesQuery, "after">) => Promise<{
2843
+ from: number;
2844
+ to: number;
2845
+ schemaVersions: {
2846
+ from: number | null;
2847
+ to: number | null;
2848
+ };
2849
+ items: SnapshotChange[];
2850
+ }>;
2851
+ };
2852
+ };
2853
+ type ShapioDeliveryClient = ReturnType<typeof createDeliveryClient>;
2854
+ //#endregion
2761
2855
  //#region src/site.d.ts
2762
2856
  /** Delivery reads name their site with `?site=`; everything else with the `Shapio-Site` header. */
2763
2857
  declare const SITE_QUERY_PARAMETER = "site";
2764
2858
  //#endregion
2765
2859
  //#region src/siteDelivery.d.ts
2766
2860
  declare const DELIVERY_SITE_PATH = "/api/site";
2767
- /** The request's site as delivery sees it (key, name, SEO defaults), with the client's token and site. */
2768
- declare const createSiteApi: (request: RequestFn) => {
2769
- get: () => Promise<DeliverySite>;
2861
+ /**
2862
+ * The request's site as delivery sees it (key, name, SEO defaults), with the client's token and site. Under
2863
+ * Next.js the read carries the site tag (nextCache.ts).
2864
+ */
2865
+ declare const createSiteApi: (request: RequestFn, cacheContext: DeliveryCacheContext) => {
2866
+ get: ({ next }?: DeliveryReadOptions) => Promise<DeliverySite>;
2770
2867
  };
2771
2868
  type SiteApi = ReturnType<typeof createSiteApi>;
2772
2869
  //#endregion
@@ -2933,5 +3030,5 @@ declare const codeChallengeOf: (codeVerifier: string) => Promise<string>;
2933
3030
  /** A fresh verifier (32 random bytes, 43 characters) and its S256 challenge. */
2934
3031
  declare const createPkcePair: () => Promise<AppPkcePair>;
2935
3032
  //#endregion
2936
- export { HealthRule as $, ContentFilterValue as $a, JobQuery as $i, NetworkAction as $n, UnassignedEntry as $r, MediaAssetPage as $t, DELIVERY_SITE_PATH as A, SetSiteAppRolesInput as Aa, UpdateSchemaSettingsInput as Ai, AdminUserStatus as An, ChangeSetSummary as Ar, TranslateInput as At, SITES_PATHS as B, DeliveryGetQuery as Ba, DeploymentConnectionCreated as Bi, CreateRoleInput as Bn, ReviewEntryItem as Br, VersionResponse as Bt, WEBHOOK_EVENT_HEADER as C, FieldPrincipalUsage as Ca, SchemaChangeStatus as Ci, BUILT_IN_APP_ROLE_KEYS as Cn, ChangeSetItem as Cr, ContentOpsStatus as Ct, WebhookSignatureCheck as D, PrincipalUsageSummary as Da, SetDefaultLocaleResult as Di, AcceptInvitationInput as Dn, ChangeSetSchemaItem as Dr, SchemaDraftInput as Dt, WEBHOOK_TOLERANCE_SECONDS as E, ModelFieldUsage as Ea, SchemaSummaryItem as Ei, UpdateAppUserInput as En, ChangeSetReview as Er, RewriteInput as Et, AdminApi as F, UpdateSiteInput as Fa, CreateWebhookInput as Fi, AuditQuery as Fn, FieldDiff as Fr, ShapioClientOptions as Ft, ContentCount as G, DeliveryPagination as Ga, DeploymentRunTrigger as Gi, GlobalAction as Gn, SchemaDraft as Gr, SnapshotChangesQuery as Gt, ADMIN_PATHS as H, DeliveryList as Ha, DeploymentRun as Hi, CsrfResponse as Hn, ReviewSchemaItem as Hr, SnapshotChange as Ht, ASSIST_PATHS as I, DeliveryAsset as Ia, DEPLOYMENT_PROVIDERS as Ii, CONTENT_ACTIONS as In, NOT_RESTORABLE_REASONS as Ir, createClient as It, ContentHealthPage as J, AdminEntry as Ja, DeploymentSettings as Ji, InvitationLink as Jn, ShipPhase as Jr, SchemaExport as Jt, ContentCounts as K, RichTextMode as Ka, DeploymentSecretState as Ki, InspectInvitationResponse as Kn, SchemaOperation as Kr, SchemaApplyInput as Kt, buildUploadForm as L, DeliverySite as La, DEPLOYMENT_RUN_STATUSES as Li, ChangePasswordInput as Ln, NotRestorable as Lr, CheckStatus as Lt, SITE_QUERY_PARAMETER as M, SiteAppRoles as Ma, CreateDeploymentConnectionInput as Mi, AuditActorType as Mn, CreateChangeSetInput as Mr, ShapioApiError as Mt, DELIVERY_PATH as N, SiteRef as Na, CreatePreviewTokenInput as Ni, AuditEvent as Nn, FieldConsumer as Nr, ShapioErrorBody as Nt, WebhookSignatureInput as O, UsageSelection as Oa, UpdateDefinitionInput as Oi, AdminSession as On, ChangeSetSource as Or, SchemaDraftResult as Ot, DeliveryApi as P, SiteSummary as Pa, CreateScheduleInput as Pi, AuditPage as Pn, FieldConsumers as Pr, ShapioClient as Pt, HEALTH_RULES as Q, ContentFilterOperator as Qa, Job as Qi, NETWORK_ACTIONS as Qn, SnapshotSource as Qr, MediaAsset as Qt, resolveUploadUrl as R, SeoFields as Ra, DEPLOYMENT_TRIGGERS as Ri, ContentAction as Rn, NotRestorableReason as Rr, HealthResponse as Rt, AppUser as S, WebhookWithSecret as Sa, SchemaChangeJob as Si, AppUserQuery as Sn, ChangeSetError as Sr, ContentOpsSkip as St, WEBHOOK_TIMESTAMP_HEADER as T, FieldUsageResponse as Ta, SchemaSummary as Ti, UpdateAppRoleInput as Tn, ChangeSetQuery as Tr, LocaleMissingResult as Tt, CheckParams as U, DeliveryListQuery as Ua, DeploymentRunQuery as Ui, EmailDelivery as Un, SNAPSHOT_SOURCES as Ur, SnapshotChangeKind as Ut, SITE_HEADER as V, DeliveryItem as Va, DeploymentProvider as Vi, CreatedApiToken as Vn, ReviewIssue as Vr, CurrentSnapshot as Vt, CheckSeverity as W, DeliveryMeta as Wa, DeploymentRunStatus as Wi, GLOBAL_ACTIONS as Wn, ScheduleChangeSetInput as Wr, SnapshotChangesPage as Wt, ContentHealthSummary as X, AdminEntryPage as Xa, DeploymentTriggerPolicy as Xi, LoginInput as Xn, SnapshotPage as Xr, CreateMediaFolderInput as Xt, ContentHealthQuery as Y, AdminEntryListItem as Ya, DeploymentTimelineEvent as Yi, InviteUserInput as Yn, Snapshot as Yr, SchemaSyncResult as Yt, EntryPresence as Z, ContentFilter as Za, JOB_STATUSES as Zi, MeResponse as Zn, SnapshotQuery as Zr, CreateUploadInput as Zt, AppLoginInput as _, WebhookAttempt as _a, PlanImpact as _i, AdminAppUser as _n, RevisionSummary as _o, AddChangeSetEntryInput as _r, CONTENT_OPS_RULES as _t, SeoDefaults as a, Page as aa, ChangeScopeInput as ai, MediaUsage as an, EditorManifest as ao, RoleCondition as ar, PreflightRule as at, AppRegisterResult as b, WebhookEventBody as ba, PlanStepImpact as bi, AppRolePermission as bn, RequestOptions as bo, ChangeSetActor as br, ContentOpsRule as bt, applyTitleTemplate as c, PreviewTokenCreated as ca, CreateLocaleInput as ci, MediaVariantStatus as cn, EntryData as co, RoleSummary as cr, AltMissingResult as ct, AppPkcePair as d, ScheduleQuery as da, DefinitionListItem as di, MoveMediaAssetsResult as dn, EntryLocalesInput as do, SetupInput as dr, AltTextResult as dt, JobStatus as ea, UpdateChangeSetInput as ei, MediaAssetQuery as en, ContentIssue as eo, PasswordResetConfirmInput as er, ModelPresence as et, codeChallengeOf as f, ScheduleStatus as fa, DefinitionPayload as fi, ReplaceUploadInput as fn, EntryReferrer as fo, SetupStatusResponse as fr, AssistIssue as ft, AppChangePasswordInput as g, Webhook as ga, Locale as gi, APP_CONTENT_ACTIONS as gn, RevisionDetail as go, UpdateRoleInput as gr, AssistUsage as gt, AppAuthApi as h, UpdateWebhookInput as ha, DeleteLocaleResult as hi, UploadGrant as hn, ExtensionThemeList as ho, UpdateProfileInput as hr, AssistTextResult as ht, SEO_FIELD_IDS as i, PUBLICATION_ACTIONS as ia, ChangePlan as ii, MediaStorageDriver as in, CreateEntryInput as io, RoleAssignment as ir, PreflightResponse as it, SiteApi as j, Site as ja, ConnectionTestResult as ji, ApiToken as jn, ChangeSetTimelineEvent as jr, TranslateResult as jt, verifyWebhookSignature as k, CreateSiteInput as ka, UpdateLocaleInput as ki, AdminUser as kn, ChangeSetStatus as kr, SummarizeInput as kt, resolveSeo as l, PublicationAction as la, DefinitionCategory as li, MediaVisibility as ln, EntryLocaleState as lo, SITE_ACTIONS as lr, AltProposal as lt, APP_AUTH_PATHS as m, UpdateDeploymentConnectionInput as ma, DefinitionScope as mi, UpdateMediaFolderInput as mn, ExtensionTheme as mo, UpdateAdminUserInput as mr, AssistStatus as mt, ResolveSeoContext as n, OpenPreviewInput as na, ActiveDefinition as ni, MediaFocalPoint as nn, ContentPagination as no, PermissionAction as nr, PreflightInput as nt, SeoKeys as o, PreviewTarget as oa, ChangeScopeOutcome as oi, MediaUsagePage as on, EditorManifestItem as oo, RoleKind as or, PresenceHeartbeatInput as ot, createPkcePair as p, ScheduledPublication as pa, DefinitionRevision as pi, UpdateMediaAssetInput as pn, EntryStatus as po, SiteAction as pr, AssistProvider as pt, ContentHealthFinding as q, SeoMode as qa, DeploymentSecretsInput as qi, Invitation as qn, ShipChangeSetInput as qr, SchemaApplyResult as qt, SEO_COMPONENT_ID as r, OpenPreviewResult as ra, ChangeOutcome as ri, MediaFolder as rn, ContentSort as ro, Role as rr, PreflightLocale as rt, SeoLocaleDefaults$1 as s, PreviewToken as sa, CreateDefinitionInput as si, MediaVariant as sn, EntryAuthor as so, RolePermission as sr, PresencePerson as st, DEFAULT_SEO_KEYS as t, JobSummary as ta, Acknowledgement as ti, MediaAssetStatus as tn, ContentListQuery as to, PasswordResetRequestInput as tr, PreflightCheck as tt, seoDefaultsForLocale as u, SCHEDULE_STATUSES as ua, DefinitionDetail as ui, MoveMediaAssetsInput as un, EntryLocaleStatus as uo, SessionStarted as ur, AltTextInput as ut, AppOAuthProvider as v, WebhookDelivery as va, PlanPreview as vi, AppContentAction as vn, UpdateEntryInput as vo, CHANGE_SET_STATUSES as vr, ContentOpsInput as vt, WEBHOOK_SIGNATURE_HEADER as w, FieldUsageQuery as wa, SchemaSettings as wi, CreateAppRoleInput as wn, ChangeSetItemStatus as wr, ContentOpsWritten as wt, AppSession as x, WebhookEventType as xa, PlanUpdateInput as xi, AppUserPage as xn, ChangeSetEntryItem as xr, ContentOpsRun as xt, AppRegisterInput as y, WebhookDeliveryStatus as ya, PlanStep as yi, AppRole as yn, RequestFn as yo, ChangeSet as yr, ContentOpsResult as yt, toContentQueryString as z, SeoResolved as za, DeploymentConnection as zi, CreateApiTokenInput as zn, PutSchemaDraftInput as zr, ReadyResponse as zt };
2937
- //# sourceMappingURL=index-D-BBgz21.d.ts.map
3033
+ export { ContentHealthSummary as $, AdminEntryPage as $a, DeploymentTriggerPolicy as $i, LoginInput as $n, SnapshotPage as $r, CreateMediaFolderInput as $t, DELIVERY_SITE_PATH as A, PrincipalUsageSummary as Aa, SetDefaultLocaleResult as Ai, AcceptInvitationInput as An, ChangeSetSchemaItem as Ar, SchemaDraftInput as At, buildUploadForm as B, DeliverySite as Ba, DEPLOYMENT_RUN_STATUSES as Bi, ChangePasswordInput as Bn, NotRestorable as Br, CheckStatus as Bt, WEBHOOK_EVENT_HEADER as C, WebhookEventBody as Ca, PlanStepImpact as Ci, AppRolePermission as Cn, RequestOptions as Co, ChangeSetActor as Cr, ContentOpsRule as Ct, WebhookSignatureCheck as D, FieldUsageQuery as Da, SchemaSettings as Di, CreateAppRoleInput as Dn, shapioTags as Do, ChangeSetItemStatus as Dr, ContentOpsWritten as Dt, WEBHOOK_TOLERANCE_SECONDS as E, FieldPrincipalUsage as Ea, SchemaChangeStatus as Ei, BUILT_IN_APP_ROLE_KEYS as En, NextCacheOptions as Eo, ChangeSetItem as Er, ContentOpsStatus as Et, createDeliveryClient as F, SiteAppRoles as Fa, CreateDeploymentConnectionInput as Fi, AuditActorType as Fn, CreateChangeSetInput as Fr, ShapioApiError as Ft, ADMIN_PATHS as G, DeliveryList as Ga, DeploymentRun as Gi, CsrfResponse as Gn, ReviewSchemaItem as Gr, SnapshotChange as Gt, toContentQueryString as H, SeoResolved as Ha, DeploymentConnection as Hi, CreateApiTokenInput as Hn, PutSchemaDraftInput as Hr, ReadyResponse as Ht, DELIVERY_PATH as I, SiteRef as Ia, CreatePreviewTokenInput as Ii, AuditEvent as In, FieldConsumer as Ir, ShapioErrorBody as It, ContentCount as J, DeliveryPagination as Ja, DeploymentRunTrigger as Ji, GlobalAction as Jn, SchemaDraft as Jr, SnapshotChangesQuery as Jt, CheckParams as K, DeliveryListQuery as Ka, DeploymentRunQuery as Ki, EmailDelivery as Kn, SNAPSHOT_SOURCES as Kr, SnapshotChangeKind as Kt, DeliveryApi as L, SiteSummary as La, CreateScheduleInput as Li, AuditPage as Ln, FieldConsumers as Lr, ShapioClient as Lt, SITE_QUERY_PARAMETER as M, CreateSiteInput as Ma, UpdateLocaleInput as Mi, AdminUser as Mn, ChangeSetStatus as Mr, SummarizeInput as Mt, DeliveryClientOptions as N, SetSiteAppRolesInput as Na, UpdateSchemaSettingsInput as Ni, AdminUserStatus as Nn, ChangeSetSummary as Nr, TranslateInput as Nt, WebhookSignatureInput as O, FieldUsageResponse as Oa, SchemaSummary as Oi, UpdateAppRoleInput as On, ChangeSetQuery as Or, LocaleMissingResult as Ot, ShapioDeliveryClient as P, Site as Pa, ConnectionTestResult as Pi, ApiToken as Pn, ChangeSetTimelineEvent as Pr, TranslateResult as Pt, ContentHealthQuery as Q, AdminEntryListItem as Qa, DeploymentTimelineEvent as Qi, InviteUserInput as Qn, Snapshot as Qr, SchemaSyncResult as Qt, AdminApi as R, UpdateSiteInput as Ra, CreateWebhookInput as Ri, AuditQuery as Rn, FieldDiff as Rr, ShapioClientOptions as Rt, AppUser as S, WebhookDeliveryStatus as Sa, PlanStep as Si, AppRole as Sn, RequestFn as So, ChangeSet as Sr, ContentOpsResult as St, WEBHOOK_TIMESTAMP_HEADER as T, WebhookWithSecret as Ta, SchemaChangeJob as Ti, AppUserQuery as Tn, NextCacheMode as To, ChangeSetError as Tr, ContentOpsSkip as Tt, SITES_PATHS as U, DeliveryGetQuery as Ua, DeploymentConnectionCreated as Ui, CreateRoleInput as Un, ReviewEntryItem as Ur, VersionResponse as Ut, resolveUploadUrl as V, SeoFields as Va, DEPLOYMENT_TRIGGERS as Vi, ContentAction as Vn, NotRestorableReason as Vr, HealthResponse as Vt, SITE_HEADER as W, DeliveryItem as Wa, DeploymentProvider as Wi, CreatedApiToken as Wn, ReviewIssue as Wr, CurrentSnapshot as Wt, ContentHealthFinding as X, SeoMode as Xa, DeploymentSecretsInput as Xi, Invitation as Xn, ShipChangeSetInput as Xr, SchemaApplyResult as Xt, ContentCounts as Y, RichTextMode as Ya, DeploymentSecretState as Yi, InspectInvitationResponse as Yn, SchemaOperation as Yr, SchemaApplyInput as Yt, ContentHealthPage as Z, AdminEntry as Za, DeploymentSettings as Zi, InvitationLink as Zn, ShipPhase as Zr, SchemaExport as Zt, AppLoginInput as _, UpdateDeploymentConnectionInput as _a, DefinitionScope as _i, UpdateMediaFolderInput as _n, ExtensionTheme as _o, UpdateAdminUserInput as _r, AssistStatus as _t, SeoDefaults as a, OpenPreviewInput as aa, ActiveDefinition as ai, MediaFocalPoint as an, ContentPagination as ao, PermissionAction as ar, PreflightInput as at, AppRegisterResult as b, WebhookAttempt as ba, PlanImpact as bi, AdminAppUser as bn, RevisionSummary as bo, AddChangeSetEntryInput as br, CONTENT_OPS_RULES as bt, applyTitleTemplate as c, Page as ca, ChangeScopeInput as ci, MediaUsage as cn, EditorManifest as co, RoleCondition as cr, PreflightRule as ct, AppPkcePair as d, PreviewTokenCreated as da, CreateLocaleInput as di, MediaVariantStatus as dn, EntryData as do, RoleSummary as dr, AltMissingResult as dt, JOB_STATUSES as ea, SnapshotQuery as ei, CreateUploadInput as en, ContentFilter as eo, MeResponse as er, EntryPresence as et, codeChallengeOf as f, PublicationAction as fa, DefinitionCategory as fi, MediaVisibility as fn, EntryLocaleState as fo, SITE_ACTIONS as fr, AltProposal as ft, AppChangePasswordInput as g, ScheduledPublication as ga, DefinitionRevision as gi, UpdateMediaAssetInput as gn, EntryStatus as go, SiteAction as gr, AssistProvider as gt, AppAuthApi as h, ScheduleStatus as ha, DefinitionPayload as hi, ReplaceUploadInput as hn, EntryReferrer as ho, SetupStatusResponse as hr, AssistIssue as ht, SEO_FIELD_IDS as i, JobSummary as ia, Acknowledgement as ii, MediaAssetStatus as in, ContentListQuery as io, PasswordResetRequestInput as ir, PreflightCheck as it, SiteApi as j, UsageSelection as ja, UpdateDefinitionInput as ji, AdminSession as jn, ChangeSetSource as jr, SchemaDraftResult as jt, verifyWebhookSignature as k, ModelFieldUsage as ka, SchemaSummaryItem as ki, UpdateAppUserInput as kn, ChangeSetReview as kr, RewriteInput as kt, resolveSeo as l, PreviewTarget as la, ChangeScopeOutcome as li, MediaUsagePage as ln, EditorManifestItem as lo, RoleKind as lr, PresenceHeartbeatInput as lt, APP_AUTH_PATHS as m, ScheduleQuery as ma, DefinitionListItem as mi, MoveMediaAssetsResult as mn, EntryLocalesInput as mo, SetupInput as mr, AltTextResult as mt, ResolveSeoContext as n, JobQuery as na, UnassignedEntry as ni, MediaAssetPage as nn, ContentFilterValue as no, NetworkAction as nr, HealthRule as nt, SeoKeys as o, OpenPreviewResult as oa, ChangeOutcome as oi, MediaFolder as on, ContentSort as oo, Role as or, PreflightLocale as ot, createPkcePair as p, SCHEDULE_STATUSES as pa, DefinitionDetail as pi, MoveMediaAssetsInput as pn, EntryLocaleStatus as po, SessionStarted as pr, AltTextInput as pt, CheckSeverity as q, DeliveryMeta as qa, DeploymentRunStatus as qi, GLOBAL_ACTIONS as qn, ScheduleChangeSetInput as qr, SnapshotChangesPage as qt, SEO_COMPONENT_ID as r, JobStatus as ra, UpdateChangeSetInput as ri, MediaAssetQuery as rn, ContentIssue as ro, PasswordResetConfirmInput as rr, ModelPresence as rt, SeoLocaleDefaults$1 as s, PUBLICATION_ACTIONS as sa, ChangePlan as si, MediaStorageDriver as sn, CreateEntryInput as so, RoleAssignment as sr, PreflightResponse as st, DEFAULT_SEO_KEYS as t, Job as ta, SnapshotSource as ti, MediaAsset as tn, ContentFilterOperator as to, NETWORK_ACTIONS as tr, HEALTH_RULES as tt, seoDefaultsForLocale as u, PreviewToken as ua, CreateDefinitionInput as ui, MediaVariant as un, EntryAuthor as uo, RolePermission as ur, PresencePerson as ut, AppOAuthProvider as v, UpdateWebhookInput as va, DeleteLocaleResult as vi, UploadGrant as vn, ExtensionThemeList as vo, UpdateProfileInput as vr, AssistTextResult as vt, WEBHOOK_SIGNATURE_HEADER as w, WebhookEventType as wa, PlanUpdateInput as wi, AppUserPage as wn, DeliveryReadOptions as wo, ChangeSetEntryItem as wr, ContentOpsRun as wt, AppSession as x, WebhookDelivery as xa, PlanPreview as xi, AppContentAction as xn, UpdateEntryInput as xo, CHANGE_SET_STATUSES as xr, ContentOpsInput as xt, AppRegisterInput as y, Webhook as ya, Locale as yi, APP_CONTENT_ACTIONS as yn, RevisionDetail as yo, UpdateRoleInput as yr, AssistUsage as yt, ASSIST_PATHS as z, DeliveryAsset as za, DEPLOYMENT_PROVIDERS as zi, CONTENT_ACTIONS as zn, NOT_RESTORABLE_REASONS as zr, createClient as zt };
3034
+ //# sourceMappingURL=index-C48tjTFc.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as HealthRule, $a as ContentFilterValue, $i as JobQuery, $n as NetworkAction, $r as UnassignedEntry, $t as MediaAssetPage, A as DELIVERY_SITE_PATH, Aa as SetSiteAppRolesInput, Ai as UpdateSchemaSettingsInput, An as AdminUserStatus, Ar as ChangeSetSummary, At as TranslateInput, B as SITES_PATHS, Ba as DeliveryGetQuery, Bi as DeploymentConnectionCreated, Bn as CreateRoleInput, Br as ReviewEntryItem, Bt as VersionResponse, C as WEBHOOK_EVENT_HEADER, Ca as FieldPrincipalUsage, Ci as SchemaChangeStatus, Cn as BUILT_IN_APP_ROLE_KEYS, Cr as ChangeSetItem, Ct as ContentOpsStatus, D as WebhookSignatureCheck, Da as PrincipalUsageSummary, Di as SetDefaultLocaleResult, Dn as AcceptInvitationInput, Dr as ChangeSetSchemaItem, Dt as SchemaDraftInput, E as WEBHOOK_TOLERANCE_SECONDS, Ea as ModelFieldUsage, Ei as SchemaSummaryItem, En as UpdateAppUserInput, Er as ChangeSetReview, Et as RewriteInput, F as AdminApi, Fa as UpdateSiteInput, Fi as CreateWebhookInput, Fn as AuditQuery, Fr as FieldDiff, Ft as ShapioClientOptions, G as ContentCount, Ga as DeliveryPagination, Gi as DeploymentRunTrigger, Gn as GlobalAction, Gr as SchemaDraft, Gt as SnapshotChangesQuery, H as ADMIN_PATHS, Ha as DeliveryList, Hi as DeploymentRun, Hn as CsrfResponse, Hr as ReviewSchemaItem, Ht as SnapshotChange, I as ASSIST_PATHS, Ia as DeliveryAsset, Ii as DEPLOYMENT_PROVIDERS, In as CONTENT_ACTIONS, Ir as NOT_RESTORABLE_REASONS, It as createClient, J as ContentHealthPage, Ja as AdminEntry, Ji as DeploymentSettings, Jn as InvitationLink, Jr as ShipPhase, Jt as SchemaExport, K as ContentCounts, Ka as RichTextMode, Ki as DeploymentSecretState, Kn as InspectInvitationResponse, Kr as SchemaOperation, Kt as SchemaApplyInput, L as buildUploadForm, La as DeliverySite, Li as DEPLOYMENT_RUN_STATUSES, Ln as ChangePasswordInput, Lr as NotRestorable, Lt as CheckStatus, M as SITE_QUERY_PARAMETER, Ma as SiteAppRoles, Mi as CreateDeploymentConnectionInput, Mn as AuditActorType, Mr as CreateChangeSetInput, Mt as ShapioApiError, N as DELIVERY_PATH, Na as SiteRef, Ni as CreatePreviewTokenInput, Nn as AuditEvent, Nr as FieldConsumer, Nt as ShapioErrorBody, O as WebhookSignatureInput, Oa as UsageSelection, Oi as UpdateDefinitionInput, On as AdminSession, Or as ChangeSetSource, Ot as SchemaDraftResult, P as DeliveryApi, Pa as SiteSummary, Pi as CreateScheduleInput, Pn as AuditPage, Pr as FieldConsumers, Pt as ShapioClient, Q as HEALTH_RULES, Qa as ContentFilterOperator, Qi as Job, Qn as NETWORK_ACTIONS, Qr as SnapshotSource, Qt as MediaAsset, R as resolveUploadUrl, Ra as SeoFields, Ri as DEPLOYMENT_TRIGGERS, Rn as ContentAction, Rr as NotRestorableReason, Rt as HealthResponse, S as AppUser, Sa as WebhookWithSecret, Si as SchemaChangeJob, Sn as AppUserQuery, Sr as ChangeSetError, St as ContentOpsSkip, T as WEBHOOK_TIMESTAMP_HEADER, Ta as FieldUsageResponse, Ti as SchemaSummary, Tn as UpdateAppRoleInput, Tr as ChangeSetQuery, Tt as LocaleMissingResult, U as CheckParams, Ua as DeliveryListQuery, Ui as DeploymentRunQuery, Un as EmailDelivery, Ur as SNAPSHOT_SOURCES, Ut as SnapshotChangeKind, V as SITE_HEADER, Va as DeliveryItem, Vi as DeploymentProvider, Vn as CreatedApiToken, Vr as ReviewIssue, Vt as CurrentSnapshot, W as CheckSeverity, Wa as DeliveryMeta, Wi as DeploymentRunStatus, Wn as GLOBAL_ACTIONS, Wr as ScheduleChangeSetInput, Wt as SnapshotChangesPage, X as ContentHealthSummary, Xa as AdminEntryPage, Xi as DeploymentTriggerPolicy, Xn as LoginInput, Xr as SnapshotPage, Xt as CreateMediaFolderInput, Y as ContentHealthQuery, Ya as AdminEntryListItem, Yi as DeploymentTimelineEvent, Yn as InviteUserInput, Yr as Snapshot, Yt as SchemaSyncResult, Z as EntryPresence, Za as ContentFilter, Zi as JOB_STATUSES, Zn as MeResponse, Zr as SnapshotQuery, Zt as CreateUploadInput, _ as AppLoginInput, _a as WebhookAttempt, _i as PlanImpact, _n as AdminAppUser, _o as RevisionSummary, _r as AddChangeSetEntryInput, _t as CONTENT_OPS_RULES, a as SeoDefaults, aa as Page, ai as ChangeScopeInput, an as MediaUsage, ao as EditorManifest, ar as RoleCondition, at as PreflightRule, b as AppRegisterResult, ba as WebhookEventBody, bi as PlanStepImpact, bn as AppRolePermission, bo as RequestOptions, br as ChangeSetActor, bt as ContentOpsRule, c as applyTitleTemplate, ca as PreviewTokenCreated, ci as CreateLocaleInput, cn as MediaVariantStatus, co as EntryData, cr as RoleSummary, ct as AltMissingResult, d as AppPkcePair, da as ScheduleQuery, di as DefinitionListItem, dn as MoveMediaAssetsResult, do as EntryLocalesInput, dr as SetupInput, dt as AltTextResult, ea as JobStatus, ei as UpdateChangeSetInput, en as MediaAssetQuery, eo as ContentIssue, er as PasswordResetConfirmInput, et as ModelPresence, f as codeChallengeOf, fa as ScheduleStatus, fi as DefinitionPayload, fn as ReplaceUploadInput, fo as EntryReferrer, fr as SetupStatusResponse, ft as AssistIssue, g as AppChangePasswordInput, ga as Webhook, gi as Locale, gn as APP_CONTENT_ACTIONS, go as RevisionDetail, gr as UpdateRoleInput, gt as AssistUsage, h as AppAuthApi, ha as UpdateWebhookInput, hi as DeleteLocaleResult, hn as UploadGrant, ho as ExtensionThemeList, hr as UpdateProfileInput, ht as AssistTextResult, i as SEO_FIELD_IDS, ia as PUBLICATION_ACTIONS, ii as ChangePlan, in as MediaStorageDriver, io as CreateEntryInput, ir as RoleAssignment, it as PreflightResponse, j as SiteApi, ja as Site, ji as ConnectionTestResult, jn as ApiToken, jr as ChangeSetTimelineEvent, jt as TranslateResult, k as verifyWebhookSignature, ka as CreateSiteInput, ki as UpdateLocaleInput, kn as AdminUser, kr as ChangeSetStatus, kt as SummarizeInput, l as resolveSeo, la as PublicationAction, li as DefinitionCategory, ln as MediaVisibility, lo as EntryLocaleState, lr as SITE_ACTIONS, lt as AltProposal, m as APP_AUTH_PATHS, ma as UpdateDeploymentConnectionInput, mi as DefinitionScope, mn as UpdateMediaFolderInput, mo as ExtensionTheme, mr as UpdateAdminUserInput, mt as AssistStatus, n as ResolveSeoContext, na as OpenPreviewInput, ni as ActiveDefinition, nn as MediaFocalPoint, no as ContentPagination, nr as PermissionAction, nt as PreflightInput, o as SeoKeys, oa as PreviewTarget, oi as ChangeScopeOutcome, on as MediaUsagePage, oo as EditorManifestItem, or as RoleKind, ot as PresenceHeartbeatInput, p as createPkcePair, pa as ScheduledPublication, pi as DefinitionRevision, pn as UpdateMediaAssetInput, po as EntryStatus, pr as SiteAction, pt as AssistProvider, q as ContentHealthFinding, qa as SeoMode, qi as DeploymentSecretsInput, qn as Invitation, qr as ShipChangeSetInput, qt as SchemaApplyResult, r as SEO_COMPONENT_ID, ra as OpenPreviewResult, ri as ChangeOutcome, rn as MediaFolder, ro as ContentSort, rr as Role, rt as PreflightLocale, s as SeoLocaleDefaults, sa as PreviewToken, si as CreateDefinitionInput, sn as MediaVariant, so as EntryAuthor, sr as RolePermission, st as PresencePerson, t as DEFAULT_SEO_KEYS, ta as JobSummary, ti as Acknowledgement, tn as MediaAssetStatus, to as ContentListQuery, tr as PasswordResetRequestInput, tt as PreflightCheck, u as seoDefaultsForLocale, ua as SCHEDULE_STATUSES, ui as DefinitionDetail, un as MoveMediaAssetsInput, uo as EntryLocaleStatus, ur as SessionStarted, ut as AltTextInput, v as AppOAuthProvider, va as WebhookDelivery, vi as PlanPreview, vn as AppContentAction, vo as UpdateEntryInput, vr as CHANGE_SET_STATUSES, vt as ContentOpsInput, w as WEBHOOK_SIGNATURE_HEADER, wa as FieldUsageQuery, wi as SchemaSettings, wn as CreateAppRoleInput, wr as ChangeSetItemStatus, wt as ContentOpsWritten, x as AppSession, xa as WebhookEventType, xi as PlanUpdateInput, xn as AppUserPage, xr as ChangeSetEntryItem, xt as ContentOpsRun, y as AppRegisterInput, ya as WebhookDeliveryStatus, yi as PlanStep, yn as AppRole, yo as RequestFn, yr as ChangeSet, yt as ContentOpsResult, z as toContentQueryString, za as SeoResolved, zi as DeploymentConnection, zn as CreateApiTokenInput, zr as PutSchemaDraftInput, zt as ReadyResponse } from "./index-D-BBgz21.js";
2
- export { ADMIN_PATHS, APP_AUTH_PATHS, APP_CONTENT_ACTIONS, ASSIST_PATHS, type AcceptInvitationInput, type Acknowledgement, type ActiveDefinition, type AddChangeSetEntryInput, type AdminApi, type AdminAppUser, type AdminEntry, type AdminEntryListItem, type AdminEntryPage, type AdminSession, type AdminUser, type AdminUserStatus, type AltMissingResult, type AltProposal, type AltTextInput, type AltTextResult, type ApiToken, type AppAuthApi, type AppChangePasswordInput, type AppContentAction, type AppLoginInput, type AppOAuthProvider, type AppPkcePair, type AppRegisterInput, type AppRegisterResult, type AppRole, type AppRolePermission, type AppSession, type AppUser, type AppUserPage, type AppUserQuery, type AssistIssue, type AssistProvider, type AssistStatus, type AssistTextResult, type AssistUsage, type AuditActorType, type AuditEvent, type AuditPage, type AuditQuery, BUILT_IN_APP_ROLE_KEYS, CHANGE_SET_STATUSES, CONTENT_ACTIONS, CONTENT_OPS_RULES, type ChangeOutcome, type ChangePasswordInput, type ChangePlan, type ChangeScopeInput, type ChangeScopeOutcome, type ChangeSet, type ChangeSetActor, type ChangeSetEntryItem, type ChangeSetError, type ChangeSetItem, type ChangeSetItemStatus, type ChangeSetQuery, type ChangeSetReview, type ChangeSetSchemaItem, type ChangeSetSource, type ChangeSetStatus, type ChangeSetSummary, type ChangeSetTimelineEvent, type CheckParams, type CheckSeverity, type CheckStatus, type ConnectionTestResult, type ContentAction, type ContentCount, type ContentCounts, type ContentFilter, type ContentFilterOperator, type ContentFilterValue, type ContentHealthFinding, type ContentHealthPage, type ContentHealthQuery, type ContentHealthSummary, type ContentIssue, type ContentListQuery, type ContentOpsInput, type ContentOpsResult, type ContentOpsRule, type ContentOpsRun, type ContentOpsSkip, type ContentOpsStatus, type ContentOpsWritten, type ContentPagination, type ContentSort, type CreateApiTokenInput, type CreateAppRoleInput, type CreateChangeSetInput, type CreateDefinitionInput, type CreateDeploymentConnectionInput, type CreateEntryInput, type CreateLocaleInput, type CreateMediaFolderInput, type CreatePreviewTokenInput, type CreateRoleInput, type CreateScheduleInput, type CreateSiteInput, type CreateUploadInput, type CreateWebhookInput, type CreatedApiToken, type CsrfResponse, type CurrentSnapshot, DEFAULT_SEO_KEYS, DELIVERY_PATH, DELIVERY_SITE_PATH, DEPLOYMENT_PROVIDERS, DEPLOYMENT_RUN_STATUSES, DEPLOYMENT_TRIGGERS, type DefinitionCategory, type DefinitionDetail, type DefinitionListItem, type DefinitionPayload, type DefinitionRevision, type DefinitionScope, type DeleteLocaleResult, type DeliveryApi, type DeliveryAsset, type DeliveryGetQuery, type DeliveryItem, type DeliveryList, type DeliveryListQuery, type DeliveryMeta, type DeliveryPagination, type DeliverySite, type DeploymentConnection, type DeploymentConnectionCreated, type DeploymentProvider, type DeploymentRun, type DeploymentRunQuery, type DeploymentRunStatus, type DeploymentRunTrigger, type DeploymentSecretState, type DeploymentSecretsInput, type DeploymentSettings, type DeploymentTimelineEvent, type DeploymentTriggerPolicy, type EditorManifest, type EditorManifestItem, type EmailDelivery, type EntryAuthor, type EntryData, type EntryLocaleState, type EntryLocaleStatus, type EntryLocalesInput, type EntryPresence, type EntryReferrer, type EntryStatus, type ExtensionTheme, type ExtensionThemeList, type FieldConsumer, type FieldConsumers, type FieldDiff, type FieldPrincipalUsage, type FieldUsageQuery, type FieldUsageResponse, GLOBAL_ACTIONS, type GlobalAction, HEALTH_RULES, type HealthResponse, type HealthRule, type InspectInvitationResponse, type Invitation, type InvitationLink, type InviteUserInput, JOB_STATUSES, type Job, type JobQuery, type JobStatus, type JobSummary, type Locale, type LocaleMissingResult, type LoginInput, type MeResponse, type MediaAsset, type MediaAssetPage, type MediaAssetQuery, type MediaAssetStatus, type MediaFocalPoint, type MediaFolder, type MediaStorageDriver, type MediaUsage, type MediaUsagePage, type MediaVariant, type MediaVariantStatus, type MediaVisibility, type ModelFieldUsage, type ModelPresence, type MoveMediaAssetsInput, type MoveMediaAssetsResult, NETWORK_ACTIONS, NOT_RESTORABLE_REASONS, type NetworkAction, type NotRestorable, type NotRestorableReason, type OpenPreviewInput, type OpenPreviewResult, PUBLICATION_ACTIONS, type Page, type PasswordResetConfirmInput, type PasswordResetRequestInput, type PermissionAction, type PlanImpact, type PlanPreview, type PlanStep, type PlanStepImpact, type PlanUpdateInput, type PreflightCheck, type PreflightInput, type PreflightLocale, type PreflightResponse, type PreflightRule, type PresenceHeartbeatInput, type PresencePerson, type PreviewTarget, type PreviewToken, type PreviewTokenCreated, type PrincipalUsageSummary, type PublicationAction, type PutSchemaDraftInput, type ReadyResponse, type ReplaceUploadInput, type RequestFn, type RequestOptions, type ResolveSeoContext, type ReviewEntryItem, type ReviewIssue, type ReviewSchemaItem, type RevisionDetail, type RevisionSummary, type RewriteInput, type RichTextMode, type Role, type RoleAssignment, type RoleCondition, type RoleKind, type RolePermission, type RoleSummary, SCHEDULE_STATUSES, SEO_COMPONENT_ID, SEO_FIELD_IDS, SITES_PATHS, SITE_ACTIONS, SITE_HEADER, SITE_QUERY_PARAMETER, SNAPSHOT_SOURCES, type ScheduleChangeSetInput, type ScheduleQuery, type ScheduleStatus, type ScheduledPublication, type SchemaApplyInput, type SchemaApplyResult, type SchemaChangeJob, type SchemaChangeStatus, type SchemaDraft, type SchemaDraftInput, type SchemaDraftResult, type SchemaExport, type SchemaOperation, type SchemaSettings, type SchemaSummary, type SchemaSummaryItem, type SchemaSyncResult, type SeoDefaults, type SeoFields, type SeoKeys, type SeoLocaleDefaults, type SeoMode, type SeoResolved, type SessionStarted, type SetDefaultLocaleResult, type SetSiteAppRolesInput, type SetupInput, type SetupStatusResponse, ShapioApiError, type ShapioClient, type ShapioClientOptions, type ShapioErrorBody, type ShipChangeSetInput, type ShipPhase, type Site, type SiteAction, type SiteApi, type SiteAppRoles, type SiteRef, type SiteSummary, type Snapshot, type SnapshotChange, type SnapshotChangeKind, type SnapshotChangesPage, type SnapshotChangesQuery, type SnapshotPage, type SnapshotQuery, type SnapshotSource, type SummarizeInput, type TranslateInput, type TranslateResult, type UnassignedEntry, type UpdateAdminUserInput, type UpdateAppRoleInput, type UpdateAppUserInput, type UpdateChangeSetInput, type UpdateDefinitionInput, type UpdateDeploymentConnectionInput, type UpdateEntryInput, type UpdateLocaleInput, type UpdateMediaAssetInput, type UpdateMediaFolderInput, type UpdateProfileInput, type UpdateRoleInput, type UpdateSchemaSettingsInput, type UpdateSiteInput, type UpdateWebhookInput, type UploadGrant, type UsageSelection, type VersionResponse, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, WEBHOOK_TOLERANCE_SECONDS, type Webhook, type WebhookAttempt, type WebhookDelivery, type WebhookDeliveryStatus, type WebhookEventBody, type WebhookEventType, type WebhookSignatureCheck, type WebhookSignatureInput, type WebhookWithSecret, applyTitleTemplate, buildUploadForm, codeChallengeOf, createClient, createPkcePair, resolveSeo, resolveUploadUrl, seoDefaultsForLocale, toContentQueryString, verifyWebhookSignature };
1
+ import { $ as ContentHealthSummary, $a as AdminEntryPage, $i as DeploymentTriggerPolicy, $n as LoginInput, $r as SnapshotPage, $t as CreateMediaFolderInput, A as DELIVERY_SITE_PATH, Aa as PrincipalUsageSummary, Ai as SetDefaultLocaleResult, An as AcceptInvitationInput, Ar as ChangeSetSchemaItem, At as SchemaDraftInput, B as buildUploadForm, Ba as DeliverySite, Bi as DEPLOYMENT_RUN_STATUSES, Bn as ChangePasswordInput, Br as NotRestorable, Bt as CheckStatus, C as WEBHOOK_EVENT_HEADER, Ca as WebhookEventBody, Ci as PlanStepImpact, Cn as AppRolePermission, Co as RequestOptions, Cr as ChangeSetActor, Ct as ContentOpsRule, D as WebhookSignatureCheck, Da as FieldUsageQuery, Di as SchemaSettings, Dn as CreateAppRoleInput, Do as shapioTags, Dr as ChangeSetItemStatus, Dt as ContentOpsWritten, E as WEBHOOK_TOLERANCE_SECONDS, Ea as FieldPrincipalUsage, Ei as SchemaChangeStatus, En as BUILT_IN_APP_ROLE_KEYS, Eo as NextCacheOptions, Er as ChangeSetItem, Et as ContentOpsStatus, F as createDeliveryClient, Fa as SiteAppRoles, Fi as CreateDeploymentConnectionInput, Fn as AuditActorType, Fr as CreateChangeSetInput, Ft as ShapioApiError, G as ADMIN_PATHS, Ga as DeliveryList, Gi as DeploymentRun, Gn as CsrfResponse, Gr as ReviewSchemaItem, Gt as SnapshotChange, H as toContentQueryString, Ha as SeoResolved, Hi as DeploymentConnection, Hn as CreateApiTokenInput, Hr as PutSchemaDraftInput, Ht as ReadyResponse, I as DELIVERY_PATH, Ia as SiteRef, Ii as CreatePreviewTokenInput, In as AuditEvent, Ir as FieldConsumer, It as ShapioErrorBody, J as ContentCount, Ja as DeliveryPagination, Ji as DeploymentRunTrigger, Jn as GlobalAction, Jr as SchemaDraft, Jt as SnapshotChangesQuery, K as CheckParams, Ka as DeliveryListQuery, Ki as DeploymentRunQuery, Kn as EmailDelivery, Kr as SNAPSHOT_SOURCES, Kt as SnapshotChangeKind, L as DeliveryApi, La as SiteSummary, Li as CreateScheduleInput, Ln as AuditPage, Lr as FieldConsumers, Lt as ShapioClient, M as SITE_QUERY_PARAMETER, Ma as CreateSiteInput, Mi as UpdateLocaleInput, Mn as AdminUser, Mr as ChangeSetStatus, Mt as SummarizeInput, N as DeliveryClientOptions, Na as SetSiteAppRolesInput, Ni as UpdateSchemaSettingsInput, Nn as AdminUserStatus, Nr as ChangeSetSummary, Nt as TranslateInput, O as WebhookSignatureInput, Oa as FieldUsageResponse, Oi as SchemaSummary, On as UpdateAppRoleInput, Or as ChangeSetQuery, Ot as LocaleMissingResult, P as ShapioDeliveryClient, Pa as Site, Pi as ConnectionTestResult, Pn as ApiToken, Pr as ChangeSetTimelineEvent, Pt as TranslateResult, Q as ContentHealthQuery, Qa as AdminEntryListItem, Qi as DeploymentTimelineEvent, Qn as InviteUserInput, Qr as Snapshot, Qt as SchemaSyncResult, R as AdminApi, Ra as UpdateSiteInput, Ri as CreateWebhookInput, Rn as AuditQuery, Rr as FieldDiff, Rt as ShapioClientOptions, S as AppUser, Sa as WebhookDeliveryStatus, Si as PlanStep, Sn as AppRole, So as RequestFn, Sr as ChangeSet, St as ContentOpsResult, T as WEBHOOK_TIMESTAMP_HEADER, Ta as WebhookWithSecret, Ti as SchemaChangeJob, Tn as AppUserQuery, To as NextCacheMode, Tr as ChangeSetError, Tt as ContentOpsSkip, U as SITES_PATHS, Ua as DeliveryGetQuery, Ui as DeploymentConnectionCreated, Un as CreateRoleInput, Ur as ReviewEntryItem, Ut as VersionResponse, V as resolveUploadUrl, Va as SeoFields, Vi as DEPLOYMENT_TRIGGERS, Vn as ContentAction, Vr as NotRestorableReason, Vt as HealthResponse, W as SITE_HEADER, Wa as DeliveryItem, Wi as DeploymentProvider, Wn as CreatedApiToken, Wr as ReviewIssue, Wt as CurrentSnapshot, X as ContentHealthFinding, Xa as SeoMode, Xi as DeploymentSecretsInput, Xn as Invitation, Xr as ShipChangeSetInput, Xt as SchemaApplyResult, Y as ContentCounts, Ya as RichTextMode, Yi as DeploymentSecretState, Yn as InspectInvitationResponse, Yr as SchemaOperation, Yt as SchemaApplyInput, Z as ContentHealthPage, Za as AdminEntry, Zi as DeploymentSettings, Zn as InvitationLink, Zr as ShipPhase, Zt as SchemaExport, _ as AppLoginInput, _a as UpdateDeploymentConnectionInput, _i as DefinitionScope, _n as UpdateMediaFolderInput, _o as ExtensionTheme, _r as UpdateAdminUserInput, _t as AssistStatus, a as SeoDefaults, aa as OpenPreviewInput, ai as ActiveDefinition, an as MediaFocalPoint, ao as ContentPagination, ar as PermissionAction, at as PreflightInput, b as AppRegisterResult, ba as WebhookAttempt, bi as PlanImpact, bn as AdminAppUser, bo as RevisionSummary, br as AddChangeSetEntryInput, bt as CONTENT_OPS_RULES, c as applyTitleTemplate, ca as Page, ci as ChangeScopeInput, cn as MediaUsage, co as EditorManifest, cr as RoleCondition, ct as PreflightRule, d as AppPkcePair, da as PreviewTokenCreated, di as CreateLocaleInput, dn as MediaVariantStatus, do as EntryData, dr as RoleSummary, dt as AltMissingResult, ea as JOB_STATUSES, ei as SnapshotQuery, en as CreateUploadInput, eo as ContentFilter, er as MeResponse, et as EntryPresence, f as codeChallengeOf, fa as PublicationAction, fi as DefinitionCategory, fn as MediaVisibility, fo as EntryLocaleState, fr as SITE_ACTIONS, ft as AltProposal, g as AppChangePasswordInput, ga as ScheduledPublication, gi as DefinitionRevision, gn as UpdateMediaAssetInput, go as EntryStatus, gr as SiteAction, gt as AssistProvider, h as AppAuthApi, ha as ScheduleStatus, hi as DefinitionPayload, hn as ReplaceUploadInput, ho as EntryReferrer, hr as SetupStatusResponse, ht as AssistIssue, i as SEO_FIELD_IDS, ia as JobSummary, ii as Acknowledgement, in as MediaAssetStatus, io as ContentListQuery, ir as PasswordResetRequestInput, it as PreflightCheck, j as SiteApi, ja as UsageSelection, ji as UpdateDefinitionInput, jn as AdminSession, jr as ChangeSetSource, jt as SchemaDraftResult, k as verifyWebhookSignature, ka as ModelFieldUsage, ki as SchemaSummaryItem, kn as UpdateAppUserInput, kr as ChangeSetReview, kt as RewriteInput, l as resolveSeo, la as PreviewTarget, li as ChangeScopeOutcome, ln as MediaUsagePage, lo as EditorManifestItem, lr as RoleKind, lt as PresenceHeartbeatInput, m as APP_AUTH_PATHS, ma as ScheduleQuery, mi as DefinitionListItem, mn as MoveMediaAssetsResult, mo as EntryLocalesInput, mr as SetupInput, mt as AltTextResult, n as ResolveSeoContext, na as JobQuery, ni as UnassignedEntry, nn as MediaAssetPage, no as ContentFilterValue, nr as NetworkAction, nt as HealthRule, o as SeoKeys, oa as OpenPreviewResult, oi as ChangeOutcome, on as MediaFolder, oo as ContentSort, or as Role, ot as PreflightLocale, p as createPkcePair, pa as SCHEDULE_STATUSES, pi as DefinitionDetail, pn as MoveMediaAssetsInput, po as EntryLocaleStatus, pr as SessionStarted, pt as AltTextInput, q as CheckSeverity, qa as DeliveryMeta, qi as DeploymentRunStatus, qn as GLOBAL_ACTIONS, qr as ScheduleChangeSetInput, qt as SnapshotChangesPage, r as SEO_COMPONENT_ID, ra as JobStatus, ri as UpdateChangeSetInput, rn as MediaAssetQuery, ro as ContentIssue, rr as PasswordResetConfirmInput, rt as ModelPresence, s as SeoLocaleDefaults, sa as PUBLICATION_ACTIONS, si as ChangePlan, sn as MediaStorageDriver, so as CreateEntryInput, sr as RoleAssignment, st as PreflightResponse, t as DEFAULT_SEO_KEYS, ta as Job, ti as SnapshotSource, tn as MediaAsset, to as ContentFilterOperator, tr as NETWORK_ACTIONS, tt as HEALTH_RULES, u as seoDefaultsForLocale, ua as PreviewToken, ui as CreateDefinitionInput, un as MediaVariant, uo as EntryAuthor, ur as RolePermission, ut as PresencePerson, v as AppOAuthProvider, va as UpdateWebhookInput, vi as DeleteLocaleResult, vn as UploadGrant, vo as ExtensionThemeList, vr as UpdateProfileInput, vt as AssistTextResult, w as WEBHOOK_SIGNATURE_HEADER, wa as WebhookEventType, wi as PlanUpdateInput, wn as AppUserPage, wo as DeliveryReadOptions, wr as ChangeSetEntryItem, wt as ContentOpsRun, x as AppSession, xa as WebhookDelivery, xi as PlanPreview, xn as AppContentAction, xo as UpdateEntryInput, xr as CHANGE_SET_STATUSES, xt as ContentOpsInput, y as AppRegisterInput, ya as Webhook, yi as Locale, yn as APP_CONTENT_ACTIONS, yo as RevisionDetail, yr as UpdateRoleInput, yt as AssistUsage, z as ASSIST_PATHS, za as DeliveryAsset, zi as DEPLOYMENT_PROVIDERS, zn as CONTENT_ACTIONS, zr as NOT_RESTORABLE_REASONS, zt as createClient } from "./index-C48tjTFc.js";
2
+ export { ADMIN_PATHS, APP_AUTH_PATHS, APP_CONTENT_ACTIONS, ASSIST_PATHS, type AcceptInvitationInput, type Acknowledgement, type ActiveDefinition, type AddChangeSetEntryInput, type AdminApi, type AdminAppUser, type AdminEntry, type AdminEntryListItem, type AdminEntryPage, type AdminSession, type AdminUser, type AdminUserStatus, type AltMissingResult, type AltProposal, type AltTextInput, type AltTextResult, type ApiToken, type AppAuthApi, type AppChangePasswordInput, type AppContentAction, type AppLoginInput, type AppOAuthProvider, type AppPkcePair, type AppRegisterInput, type AppRegisterResult, type AppRole, type AppRolePermission, type AppSession, type AppUser, type AppUserPage, type AppUserQuery, type AssistIssue, type AssistProvider, type AssistStatus, type AssistTextResult, type AssistUsage, type AuditActorType, type AuditEvent, type AuditPage, type AuditQuery, BUILT_IN_APP_ROLE_KEYS, CHANGE_SET_STATUSES, CONTENT_ACTIONS, CONTENT_OPS_RULES, type ChangeOutcome, type ChangePasswordInput, type ChangePlan, type ChangeScopeInput, type ChangeScopeOutcome, type ChangeSet, type ChangeSetActor, type ChangeSetEntryItem, type ChangeSetError, type ChangeSetItem, type ChangeSetItemStatus, type ChangeSetQuery, type ChangeSetReview, type ChangeSetSchemaItem, type ChangeSetSource, type ChangeSetStatus, type ChangeSetSummary, type ChangeSetTimelineEvent, type CheckParams, type CheckSeverity, type CheckStatus, type ConnectionTestResult, type ContentAction, type ContentCount, type ContentCounts, type ContentFilter, type ContentFilterOperator, type ContentFilterValue, type ContentHealthFinding, type ContentHealthPage, type ContentHealthQuery, type ContentHealthSummary, type ContentIssue, type ContentListQuery, type ContentOpsInput, type ContentOpsResult, type ContentOpsRule, type ContentOpsRun, type ContentOpsSkip, type ContentOpsStatus, type ContentOpsWritten, type ContentPagination, type ContentSort, type CreateApiTokenInput, type CreateAppRoleInput, type CreateChangeSetInput, type CreateDefinitionInput, type CreateDeploymentConnectionInput, type CreateEntryInput, type CreateLocaleInput, type CreateMediaFolderInput, type CreatePreviewTokenInput, type CreateRoleInput, type CreateScheduleInput, type CreateSiteInput, type CreateUploadInput, type CreateWebhookInput, type CreatedApiToken, type CsrfResponse, type CurrentSnapshot, DEFAULT_SEO_KEYS, DELIVERY_PATH, DELIVERY_SITE_PATH, DEPLOYMENT_PROVIDERS, DEPLOYMENT_RUN_STATUSES, DEPLOYMENT_TRIGGERS, type DefinitionCategory, type DefinitionDetail, type DefinitionListItem, type DefinitionPayload, type DefinitionRevision, type DefinitionScope, type DeleteLocaleResult, type DeliveryApi, type DeliveryAsset, type DeliveryClientOptions, type DeliveryGetQuery, type DeliveryItem, type DeliveryList, type DeliveryListQuery, type DeliveryMeta, type DeliveryPagination, type DeliveryReadOptions, type DeliverySite, type DeploymentConnection, type DeploymentConnectionCreated, type DeploymentProvider, type DeploymentRun, type DeploymentRunQuery, type DeploymentRunStatus, type DeploymentRunTrigger, type DeploymentSecretState, type DeploymentSecretsInput, type DeploymentSettings, type DeploymentTimelineEvent, type DeploymentTriggerPolicy, type EditorManifest, type EditorManifestItem, type EmailDelivery, type EntryAuthor, type EntryData, type EntryLocaleState, type EntryLocaleStatus, type EntryLocalesInput, type EntryPresence, type EntryReferrer, type EntryStatus, type ExtensionTheme, type ExtensionThemeList, type FieldConsumer, type FieldConsumers, type FieldDiff, type FieldPrincipalUsage, type FieldUsageQuery, type FieldUsageResponse, GLOBAL_ACTIONS, type GlobalAction, HEALTH_RULES, type HealthResponse, type HealthRule, type InspectInvitationResponse, type Invitation, type InvitationLink, type InviteUserInput, JOB_STATUSES, type Job, type JobQuery, type JobStatus, type JobSummary, type Locale, type LocaleMissingResult, type LoginInput, type MeResponse, type MediaAsset, type MediaAssetPage, type MediaAssetQuery, type MediaAssetStatus, type MediaFocalPoint, type MediaFolder, type MediaStorageDriver, type MediaUsage, type MediaUsagePage, type MediaVariant, type MediaVariantStatus, type MediaVisibility, type ModelFieldUsage, type ModelPresence, type MoveMediaAssetsInput, type MoveMediaAssetsResult, NETWORK_ACTIONS, NOT_RESTORABLE_REASONS, type NetworkAction, type NextCacheMode, type NextCacheOptions, type NotRestorable, type NotRestorableReason, type OpenPreviewInput, type OpenPreviewResult, PUBLICATION_ACTIONS, type Page, type PasswordResetConfirmInput, type PasswordResetRequestInput, type PermissionAction, type PlanImpact, type PlanPreview, type PlanStep, type PlanStepImpact, type PlanUpdateInput, type PreflightCheck, type PreflightInput, type PreflightLocale, type PreflightResponse, type PreflightRule, type PresenceHeartbeatInput, type PresencePerson, type PreviewTarget, type PreviewToken, type PreviewTokenCreated, type PrincipalUsageSummary, type PublicationAction, type PutSchemaDraftInput, type ReadyResponse, type ReplaceUploadInput, type RequestFn, type RequestOptions, type ResolveSeoContext, type ReviewEntryItem, type ReviewIssue, type ReviewSchemaItem, type RevisionDetail, type RevisionSummary, type RewriteInput, type RichTextMode, type Role, type RoleAssignment, type RoleCondition, type RoleKind, type RolePermission, type RoleSummary, SCHEDULE_STATUSES, SEO_COMPONENT_ID, SEO_FIELD_IDS, SITES_PATHS, SITE_ACTIONS, SITE_HEADER, SITE_QUERY_PARAMETER, SNAPSHOT_SOURCES, type ScheduleChangeSetInput, type ScheduleQuery, type ScheduleStatus, type ScheduledPublication, type SchemaApplyInput, type SchemaApplyResult, type SchemaChangeJob, type SchemaChangeStatus, type SchemaDraft, type SchemaDraftInput, type SchemaDraftResult, type SchemaExport, type SchemaOperation, type SchemaSettings, type SchemaSummary, type SchemaSummaryItem, type SchemaSyncResult, type SeoDefaults, type SeoFields, type SeoKeys, type SeoLocaleDefaults, type SeoMode, type SeoResolved, type SessionStarted, type SetDefaultLocaleResult, type SetSiteAppRolesInput, type SetupInput, type SetupStatusResponse, ShapioApiError, type ShapioClient, type ShapioClientOptions, type ShapioDeliveryClient, type ShapioErrorBody, type ShipChangeSetInput, type ShipPhase, type Site, type SiteAction, type SiteApi, type SiteAppRoles, type SiteRef, type SiteSummary, type Snapshot, type SnapshotChange, type SnapshotChangeKind, type SnapshotChangesPage, type SnapshotChangesQuery, type SnapshotPage, type SnapshotQuery, type SnapshotSource, type SummarizeInput, type TranslateInput, type TranslateResult, type UnassignedEntry, type UpdateAdminUserInput, type UpdateAppRoleInput, type UpdateAppUserInput, type UpdateChangeSetInput, type UpdateDefinitionInput, type UpdateDeploymentConnectionInput, type UpdateEntryInput, type UpdateLocaleInput, type UpdateMediaAssetInput, type UpdateMediaFolderInput, type UpdateProfileInput, type UpdateRoleInput, type UpdateSchemaSettingsInput, type UpdateSiteInput, type UpdateWebhookInput, type UploadGrant, type UsageSelection, type VersionResponse, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, WEBHOOK_TOLERANCE_SECONDS, type Webhook, type WebhookAttempt, type WebhookDelivery, type WebhookDeliveryStatus, type WebhookEventBody, type WebhookEventType, type WebhookSignatureCheck, type WebhookSignatureInput, type WebhookWithSecret, applyTitleTemplate, buildUploadForm, codeChallengeOf, createClient, createDeliveryClient, createPkcePair, resolveSeo, resolveUploadUrl, seoDefaultsForLocale, shapioTags, toContentQueryString, verifyWebhookSignature };
package/dist/index.js CHANGED
@@ -799,6 +799,51 @@ const createAppAuthApi = (request, baseUrl) => ({
799
799
  })
800
800
  });
801
801
  //#endregion
802
+ //#region src/nextCache.ts
803
+ const TAG_PREFIX = "shapio";
804
+ /**
805
+ * The cache tags delivery reads carry (`revalidateTag(shapioTags.entry('articles', id), { expire: 0 })`).
806
+ * Models are named by their route key: a collection's plural API ID, a singleton's API ID.
807
+ */
808
+ const shapioTags = {
809
+ /** Every delivery read of the site; `shapio:site` when the client names no site. */
810
+ site: (siteKey) => siteKey === void 0 ? `${TAG_PREFIX}:site` : `${TAG_PREFIX}:site:${siteKey}`,
811
+ /** Every read of one model (lists, singletons and its entries). */
812
+ model: (routeKey) => `${TAG_PREFIX}:${routeKey}`,
813
+ /** Reads of one entry by its ID. */
814
+ entry: (routeKey, entryId) => `${TAG_PREFIX}:${routeKey}:${entryId}`
815
+ };
816
+ /** Spelled out so bundlers that inline `process.env.NEXT_RUNTIME` see it; guarded for browsers. */
817
+ const isNextRuntime = () => {
818
+ try {
819
+ return typeof process !== "undefined" && Boolean(process.env.NEXT_RUNTIME);
820
+ } catch {
821
+ return false;
822
+ }
823
+ };
824
+ /** The `cache` and `next` fetch options of one delivery read; empty outside Next unless asked for. */
825
+ const nextFetchInit = ({ client, read, tags, pinned }) => {
826
+ if (read === false || read === void 0 && client === false) return {};
827
+ const configured = client === false ? read : read === void 0 ? client : {
828
+ ...client,
829
+ ...read
830
+ };
831
+ if (configured === void 0 && !isNextRuntime()) return {};
832
+ if (pinned && read?.cache === void 0) return {
833
+ cache: "force-cache",
834
+ next: { tags }
835
+ };
836
+ const cache = configured?.cache;
837
+ const revalidate = configured?.revalidate;
838
+ return {
839
+ ...cache === void 0 ? {} : { cache },
840
+ next: {
841
+ tags,
842
+ ...revalidate === void 0 ? {} : { revalidate }
843
+ }
844
+ };
845
+ };
846
+ //#endregion
802
847
  //#region src/delivery.ts
803
848
  const DELIVERY_PATH = "/api/content";
804
849
  const routePath = (routeKey) => `${DELIVERY_PATH}/${encodeURIComponent(routeKey)}`;
@@ -815,18 +860,41 @@ const deliveryQueryString = ({ snapshot, richText, seo, ...query }) => {
815
860
  };
816
861
  /**
817
862
  * Published content, typed by the caller (`delivery.list<Article>('articles', { locale: 'fr', snapshot })`).
818
- * A collection is read with `list` (a page) and `get` (one entry); a singleton with `singleton`.
863
+ * A collection is read with `list` (a page) and `get` (one entry); a singleton with `singleton`. Each read
864
+ * takes Next.js cache options last and is tagged for `revalidateTag` (nextCache.ts): lists and singletons with
865
+ * the site and model tags, `get` with the entry's tag too.
819
866
  */
820
- const createDeliveryApi = (request) => ({
821
- list: (routeKey, query = {}) => request(`${routePath(routeKey)}${deliveryQueryString(query)}`),
822
- singleton: (apiKey, query = {}) => request(`${routePath(apiKey)}${deliveryQueryString(query)}`),
823
- get: (routeKey, id, query = {}) => request(`${routePath(routeKey)}/${encodeURIComponent(id)}${deliveryQueryString(query)}`)
824
- });
867
+ const createDeliveryApi = (request, cacheContext) => {
868
+ const fetchInit = (tags, query, { next }) => nextFetchInit({
869
+ client: cacheContext.next,
870
+ read: next,
871
+ tags,
872
+ pinned: query.snapshot !== void 0
873
+ });
874
+ const siteTag = shapioTags.site(cacheContext.site);
875
+ return {
876
+ list: (routeKey, query = {}, options = {}) => request(`${routePath(routeKey)}${deliveryQueryString(query)}`, fetchInit([siteTag, shapioTags.model(routeKey)], query, options)),
877
+ singleton: (apiKey, query = {}, options = {}) => request(`${routePath(apiKey)}${deliveryQueryString(query)}`, fetchInit([siteTag, shapioTags.model(apiKey)], query, options)),
878
+ get: (routeKey, id, query = {}, options = {}) => request(`${routePath(routeKey)}/${encodeURIComponent(id)}${deliveryQueryString(query)}`, fetchInit([
879
+ siteTag,
880
+ shapioTags.model(routeKey),
881
+ shapioTags.entry(routeKey, id)
882
+ ], query, options))
883
+ };
884
+ };
825
885
  //#endregion
826
886
  //#region src/siteDelivery.ts
827
887
  const DELIVERY_SITE_PATH = "/api/site";
828
- /** The request's site as delivery sees it (key, name, SEO defaults), with the client's token and site. */
829
- const createSiteApi = (request) => ({ get: () => request(DELIVERY_SITE_PATH) });
888
+ /**
889
+ * The request's site as delivery sees it (key, name, SEO defaults), with the client's token and site. Under
890
+ * Next.js the read carries the site tag (nextCache.ts).
891
+ */
892
+ const createSiteApi = (request, cacheContext) => ({ get: ({ next } = {}) => request(DELIVERY_SITE_PATH, nextFetchInit({
893
+ client: cacheContext.next,
894
+ read: next,
895
+ tags: [shapioTags.site(cacheContext.site)],
896
+ pinned: false
897
+ })) });
830
898
  //#endregion
831
899
  //#region src/snapshots.ts
832
900
  const SNAPSHOT_PATHS = {
@@ -862,6 +930,27 @@ const createSnapshotsApi = (request) => {
862
930
  };
863
931
  };
864
932
  //#endregion
933
+ //#region src/deliveryClient.ts
934
+ /**
935
+ * The read side of the client over any transport: published content (`delivery`), the site (`site`) and
936
+ * publication snapshots (`snapshots`). `createClient` builds it over HTTP; `@shapio/local` over the delivery
937
+ * API running in the same process. The transport receives exactly the paths the HTTP client sends.
938
+ */
939
+ const createDeliveryClient = (request, { site, next } = {}) => {
940
+ const cacheContext = {
941
+ site,
942
+ next
943
+ };
944
+ return {
945
+ /** Published content (the delivery API), typed by the caller. */
946
+ delivery: createDeliveryApi(request, cacheContext),
947
+ /** The site as delivery sees it: key, name and SEO defaults (`GET /api/site`). */
948
+ site: createSiteApi(request, cacheContext),
949
+ /** Publication snapshots and the diff between two (incremental builds). */
950
+ snapshots: createSnapshotsApi(request)
951
+ };
952
+ };
953
+ //#endregion
865
954
  //#region src/site.ts
866
955
  /** Delivery reads name their site with `?site=`; everything else with the `Shapio-Site` header. */
867
956
  const SITE_QUERY_PARAMETER = "site";
@@ -913,7 +1002,7 @@ const parseBody = async (response) => {
913
1002
  /** Builds the JSON request function every endpoint group uses. Non-2xx responses throw ShapioApiError. */
914
1003
  const createRequest = ({ baseUrl, token, fetch, credentials, headers, site }) => {
915
1004
  const origin = baseUrl.replace(/\/+$/, "");
916
- return async (requestPath, { method = "GET", body, signal } = {}) => {
1005
+ return async (requestPath, { method = "GET", body, signal, cache, next } = {}) => {
917
1006
  const { path, headers: siteHeaders } = applySite(site, method, requestPath);
918
1007
  const requestHeaders = {
919
1008
  accept: "application/json",
@@ -922,13 +1011,16 @@ const createRequest = ({ baseUrl, token, fetch, credentials, headers, site }) =>
922
1011
  };
923
1012
  if (token) requestHeaders.authorization = `Bearer ${token}`;
924
1013
  if (body !== void 0) requestHeaders["content-type"] = "application/json";
925
- const response = await fetch(`${origin}${path}`, {
1014
+ const init = {
926
1015
  method,
927
1016
  headers: requestHeaders,
928
1017
  ...body !== void 0 ? { body: JSON.stringify(body) } : {},
929
1018
  ...signal ? { signal } : {},
930
- ...credentials ? { credentials } : {}
931
- });
1019
+ ...credentials ? { credentials } : {},
1020
+ ...cache ? { cache } : {},
1021
+ ...next ? { next } : {}
1022
+ };
1023
+ const response = await fetch(`${origin}${path}`, init);
932
1024
  const parsed = await parseBody(response);
933
1025
  if (!response.ok) throw new ShapioApiError(response.status, parsed);
934
1026
  return parsed;
@@ -936,7 +1028,7 @@ const createRequest = ({ baseUrl, token, fetch, credentials, headers, site }) =>
936
1028
  };
937
1029
  //#endregion
938
1030
  //#region src/client.ts
939
- const createClient = ({ baseUrl, token, fetch = globalThis.fetch, credentials, headers, site }) => {
1031
+ const createClient = ({ baseUrl, token, fetch = globalThis.fetch, credentials, headers, site, next }) => {
940
1032
  const request = createRequest({
941
1033
  baseUrl,
942
1034
  token,
@@ -945,6 +1037,10 @@ const createClient = ({ baseUrl, token, fetch = globalThis.fetch, credentials, h
945
1037
  headers,
946
1038
  site
947
1039
  });
1040
+ const reads = createDeliveryClient(request, {
1041
+ site,
1042
+ next
1043
+ });
948
1044
  return {
949
1045
  /**
950
1046
  * Any Shapio route, e.g. the delivery API. Delivery paths use the model's route key: a collection's
@@ -958,12 +1054,12 @@ const createClient = ({ baseUrl, token, fetch = globalThis.fetch, credentials, h
958
1054
  version: (signal) => request("/api/version", signal ? { signal } : {})
959
1055
  },
960
1056
  /** Published content (the delivery API), typed by the caller. */
961
- delivery: createDeliveryApi(request),
1057
+ delivery: reads.delivery,
962
1058
  /** The site as delivery sees it: key, name and SEO defaults (`GET /api/site`). */
963
- site: createSiteApi(request),
1059
+ site: reads.site,
964
1060
  admin: createAdminApi(request),
965
1061
  /** Publication snapshots and the diff between two (incremental builds). */
966
- snapshots: createSnapshotsApi(request),
1062
+ snapshots: reads.snapshots,
967
1063
  /** End users of your sites and apps: sign-up, sign-in, tokens, OAuth. */
968
1064
  appAuth: createAppAuthApi(request, baseUrl)
969
1065
  };
@@ -1030,6 +1126,6 @@ const createPkcePair = async () => {
1030
1126
  };
1031
1127
  };
1032
1128
  //#endregion
1033
- export { ADMIN_PATHS, APP_AUTH_PATHS, APP_CONTENT_ACTIONS, ASSIST_PATHS, BUILT_IN_APP_ROLE_KEYS, CHANGE_SET_STATUSES, CONTENT_ACTIONS, CONTENT_OPS_RULES, DEFAULT_SEO_KEYS, DELIVERY_PATH, DELIVERY_SITE_PATH, DEPLOYMENT_PROVIDERS, DEPLOYMENT_RUN_STATUSES, DEPLOYMENT_TRIGGERS, GLOBAL_ACTIONS, HEALTH_RULES, JOB_STATUSES, NETWORK_ACTIONS, NOT_RESTORABLE_REASONS, PUBLICATION_ACTIONS, SCHEDULE_STATUSES, SEO_COMPONENT_ID, SEO_FIELD_IDS, SITES_PATHS, SITE_ACTIONS, SITE_HEADER, SITE_QUERY_PARAMETER, SNAPSHOT_SOURCES, ShapioApiError, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, WEBHOOK_TOLERANCE_SECONDS, applyTitleTemplate, buildUploadForm, codeChallengeOf, createClient, createPkcePair, resolveSeo, resolveUploadUrl, seoDefaultsForLocale, toContentQueryString, verifyWebhookSignature };
1129
+ export { ADMIN_PATHS, APP_AUTH_PATHS, APP_CONTENT_ACTIONS, ASSIST_PATHS, BUILT_IN_APP_ROLE_KEYS, CHANGE_SET_STATUSES, CONTENT_ACTIONS, CONTENT_OPS_RULES, DEFAULT_SEO_KEYS, DELIVERY_PATH, DELIVERY_SITE_PATH, DEPLOYMENT_PROVIDERS, DEPLOYMENT_RUN_STATUSES, DEPLOYMENT_TRIGGERS, GLOBAL_ACTIONS, HEALTH_RULES, JOB_STATUSES, NETWORK_ACTIONS, NOT_RESTORABLE_REASONS, PUBLICATION_ACTIONS, SCHEDULE_STATUSES, SEO_COMPONENT_ID, SEO_FIELD_IDS, SITES_PATHS, SITE_ACTIONS, SITE_HEADER, SITE_QUERY_PARAMETER, SNAPSHOT_SOURCES, ShapioApiError, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, WEBHOOK_TOLERANCE_SECONDS, applyTitleTemplate, buildUploadForm, codeChallengeOf, createClient, createDeliveryClient, createPkcePair, resolveSeo, resolveUploadUrl, seoDefaultsForLocale, shapioTags, toContentQueryString, verifyWebhookSignature };
1034
1130
 
1035
1131
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["entryPath"],"sources":["../src/admin/appUsers.ts","../src/admin/assist.ts","../src/admin/changeSets.ts","../src/admin/contentQuery.ts","../src/admin/content.ts","../src/admin/editing.ts","../src/admin/publishing.ts","../src/admin/schema.ts","../src/admin/sites.ts","../src/admin/usage.ts","../src/admin/types.ts","../src/admin/publishingTypes.ts","../src/admin/appUsersTypes.ts","../src/admin/changeSetTypes.ts","../src/admin/editingTypes.ts","../src/admin/assistTypes.ts","../src/admin/index.ts","../src/appAuth/index.ts","../src/delivery.ts","../src/siteDelivery.ts","../src/snapshots.ts","../src/site.ts","../src/request.ts","../src/client.ts","../src/webhooks.ts","../src/appAuth/pkce.ts"],"sourcesContent":["import type { RequestFn } from '../request.js';\nimport type {\n AdminAppUser,\n AppRole,\n AppUserPage,\n AppUserQuery,\n CreateAppRoleInput,\n UpdateAppRoleInput,\n UpdateAppUserInput,\n} from './appUsersTypes.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { toQueryString } from './query.js';\n\n/** App users (Users → App users) and app roles (Settings → Roles → App roles). */\nexport const createAppUsersApi = (request: RequestFn) => ({\n appUsers: {\n list: (query: AppUserQuery = {}) =>\n request<AppUserPage>(`${ADMIN_PATHS.appUsers}${toQueryString(query)}`),\n get: (id: string) => request<AdminAppUser>(withId(ADMIN_PATHS.appUsers, id)),\n /** Block/unblock and replace custom roles. Blocking takes effect on the user's next request. */\n update: (id: string, body: UpdateAppUserInput) =>\n request<AdminAppUser>(withId(ADMIN_PATHS.appUsers, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.appUsers, id), { method: 'DELETE' }),\n /** 409 NOT_CONFIGURED without APP_AUTH_CONFIRM_EMAIL_URL; 409 ALREADY_CONFIRMED. */\n resendConfirmation: (id: string) =>\n request<void>(`${withId(ADMIN_PATHS.appUsers, id)}/resend-confirmation`, { method: 'POST' }),\n },\n appRoles: {\n list: () => request<AppRole[]>(ADMIN_PATHS.appRoles),\n get: (id: string) => request<AppRole>(withId(ADMIN_PATHS.appRoles, id)),\n create: (body: CreateAppRoleInput) => request<AppRole>(ADMIN_PATHS.appRoles, { method: 'POST', body }),\n /** 409 VERSION_CONFLICT when `expectedVersion` is stale. */\n update: (id: string, body: UpdateAppRoleInput) =>\n request<AppRole>(withId(ADMIN_PATHS.appRoles, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.appRoles, id), { method: 'DELETE' }),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport type {\n AltTextInput,\n AltTextResult,\n AssistStatus,\n AssistTextResult,\n ContentOpsInput,\n ContentOpsRun,\n RewriteInput,\n SchemaDraftInput,\n SchemaDraftResult,\n SummarizeInput,\n TranslateInput,\n TranslateResult,\n} from './assistTypes.js';\nimport { withId } from './paths.js';\n\nexport const ASSIST_PATHS = {\n status: '/api/admin/assist/status',\n altText: '/api/admin/assist/alt-text',\n summarize: '/api/admin/assist/summarize',\n translate: '/api/admin/assist/translate',\n rewrite: '/api/admin/assist/rewrite',\n schemaDraft: '/api/admin/assist/schema/draft',\n contentOpsPropose: '/api/admin/assist/content-ops/propose',\n contentOps: '/api/admin/assist/content-ops',\n} as const;\n\n/** Editor assists with the instance's own model provider (documentation/assist.md). */\nexport const createAssistApi = (request: RequestFn) => ({\n assist: {\n status: () => request<AssistStatus>(ASSIST_PATHS.status),\n altText: (body: AltTextInput) => request<AltTextResult>(ASSIST_PATHS.altText, { method: 'POST', body }),\n summarize: (body: SummarizeInput) =>\n request<AssistTextResult>(ASSIST_PATHS.summarize, { method: 'POST', body }),\n translate: (body: TranslateInput) =>\n request<TranslateResult>(ASSIST_PATHS.translate, { method: 'POST', body }),\n rewrite: (body: RewriteInput) =>\n request<AssistTextResult>(ASSIST_PATHS.rewrite, { method: 'POST', body }),\n schemaDraft: (body: SchemaDraftInput) =>\n request<SchemaDraftResult>(ASSIST_PATHS.schemaDraft, { method: 'POST', body }),\n /** Starts a background run (202); poll it with `contentOpsRun`. */\n proposeContentOps: (body: ContentOpsInput) =>\n request<{ runId: string }>(ASSIST_PATHS.contentOpsPropose, { method: 'POST', body }),\n contentOpsRun: (runId: string) => request<ContentOpsRun>(withId(ASSIST_PATHS.contentOps, runId)),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport type {\n AddChangeSetEntryInput,\n ChangeSet,\n ChangeSetQuery,\n ChangeSetReview,\n ChangeSetSummary,\n ChangeSetTimelineEvent,\n CreateChangeSetInput,\n PutSchemaDraftInput,\n ScheduleChangeSetInput,\n SchemaDraft,\n ShipChangeSetInput,\n Snapshot,\n SnapshotPage,\n SnapshotQuery,\n UnassignedEntry,\n UpdateChangeSetInput,\n} from './changeSetTypes.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport type { Page } from './publishingTypes.js';\nimport { toQueryString } from './query.js';\n\nconst setPath = (id: string) => withId(ADMIN_PATHS.changeSets, id);\nconst draftPath = (id: string, definitionId: string) =>\n `${setPath(id)}/schema/${encodeURIComponent(definitionId)}`;\n\n/** Change sets (schema + content shipped as one snapshot) and the snapshot ledger. */\nexport const createChangeSetsApi = (request: RequestFn) => ({\n changeSets: {\n list: (query: ChangeSetQuery = {}) =>\n request<Page<ChangeSetSummary>>(`${ADMIN_PATHS.changeSets}${toQueryString(query)}`),\n get: (id: string) => request<ChangeSet>(setPath(id)),\n create: (body: CreateChangeSetInput) =>\n request<ChangeSet>(ADMIN_PATHS.changeSets, { method: 'POST', body }),\n update: (id: string, body: UpdateChangeSetInput) =>\n request<ChangeSet>(setPath(id), { method: 'PATCH', body }),\n /** Keeps the set as history (`discarded`) and deletes its schema drafts. */\n discard: (id: string) => request<ChangeSet>(`${setPath(id)}/discard`, { method: 'POST' }),\n addEntry: (id: string, body: AddChangeSetEntryInput) =>\n request<ChangeSet>(`${setPath(id)}/items`, { method: 'POST', body }),\n removeItem: (id: string, itemId: string) =>\n request<ChangeSet>(`${setPath(id)}/items/${encodeURIComponent(itemId)}`, { method: 'DELETE' }),\n getSchemaDraft: (id: string, definitionId: string) => request<SchemaDraft>(draftPath(id, definitionId)),\n putSchemaDraft: (id: string, definitionId: string, body: PutSchemaDraftInput) =>\n request<SchemaDraft>(draftPath(id, definitionId), { method: 'PUT', body }),\n removeSchemaDraft: (id: string, definitionId: string) =>\n request<ChangeSet>(draftPath(id, definitionId), { method: 'DELETE' }),\n review: (id: string) => request<ChangeSetReview>(`${setPath(id)}/review`),\n /**\n * Resolves with the set: `shipped` (or `failed`) when it shipped inline, `shipping` (HTTP 202) when\n * prerequisites run in the background. Poll `get` until it leaves `shipping`.\n */\n ship: (id: string, body: ShipChangeSetInput) =>\n request<ChangeSet>(`${setPath(id)}/ship`, { method: 'POST', body }),\n schedule: (id: string, body: ScheduleChangeSetInput) =>\n request<ChangeSet>(`${setPath(id)}/schedule`, { method: 'POST', body }),\n unschedule: (id: string) => request<ChangeSet>(`${setPath(id)}/unschedule`, { method: 'POST' }),\n timeline: async (id: string) =>\n (await request<{ items: ChangeSetTimelineEvent[] }>(`${setPath(id)}/timeline`)).items,\n unassigned: (query: { cursor?: string; limit?: number } = {}) =>\n request<Page<UnassignedEntry>>(`${ADMIN_PATHS.changeSets}/unassigned${toQueryString(query)}`),\n },\n snapshots: {\n list: (query: SnapshotQuery = {}) =>\n request<SnapshotPage>(`${ADMIN_PATHS.snapshots}${toQueryString(query)}`),\n get: (seq: number) => request<Snapshot>(`${ADMIN_PATHS.snapshots}/${seq}`),\n /** Creates an open restore change set (reviewable); nothing goes live until it ships. */\n restore: (seq: number) =>\n request<ChangeSet>(`${ADMIN_PATHS.snapshots}/${seq}/restore`, { method: 'POST' }),\n },\n});\n","import type { ContentFilter, ContentListQuery } from './contentTypes.js';\n\n/**\n * Serialises a content list query into the bracket querystring the content compiler parses\n * (`filters[title][$eq]=A&sort=title:asc&page=2`). Lists repeat the key (`filters[id][$in]=a&filters[id][$in]=b`).\n */\nconst appendFilter = (params: URLSearchParams, prefix: string, value: unknown) => {\n if (value === undefined || value === null) {\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((item: unknown, index) => {\n if (typeof item === 'object' && item !== null) {\n appendFilter(params, `${prefix}[${index}]`, item);\n } else {\n params.append(prefix, String(item));\n }\n });\n return;\n }\n if (typeof value === 'object') {\n for (const [key, child] of Object.entries(value as ContentFilter)) {\n appendFilter(params, `${prefix}[${key}]`, child);\n }\n return;\n }\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n params.append(prefix, String(value));\n }\n};\n\nexport const toContentQueryString = (query: ContentListQuery = {}): string => {\n const params = new URLSearchParams();\n if (query.filters) {\n appendFilter(params, 'filters', query.filters);\n }\n for (const term of query.sort ?? []) {\n params.append('sort', `${term.field}:${term.direction}`);\n }\n if (query.page !== undefined) {\n params.set('page', String(query.page));\n }\n if (query.pageSize !== undefined) {\n params.set('pageSize', String(query.pageSize));\n }\n if (query.q) {\n params.set('q', query.q);\n }\n if (query.locale) {\n params.set('locale', query.locale);\n }\n for (const field of query.fields ?? []) {\n params.append('fields', field);\n }\n for (const path of query.populate ?? []) {\n params.append('populate', path);\n }\n if (query.status) {\n params.set('status', query.status);\n }\n if (query.author) {\n params.set('author', query.author);\n }\n const serialised = params.toString();\n return serialised ? `?${serialised}` : '';\n};\n","import type { RequestFn } from '../request.js';\nimport { toContentQueryString } from './contentQuery.js';\nimport type {\n AdminEntry,\n AdminEntryPage,\n ContentListQuery,\n CreateEntryInput,\n EditorManifest,\n EntryLocalesInput,\n ExtensionThemeList,\n RevisionDetail,\n RevisionSummary,\n UpdateEntryInput,\n} from './contentTypes.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { toQueryString } from './query.js';\n\nconst modelPath = (modelKey: string) => withId(ADMIN_PATHS.content, modelKey);\nconst entryPath = (modelKey: string, id: string) => withId(modelPath(modelKey), id);\nconst revisionsPath = (modelKey: string, id: string) => `${entryPath(modelKey, id)}/revisions`;\n\n/**\n * Content of any model through the generic admin routes (`/api/admin/content/:modelKey`, where `modelKey`\n * is the model's singular API ID for collections too; only the delivery API uses the plural). Drafts are read\n * and written here; publishing is per locale. Writes carry the draft `version` the editor saw and fail with\n * 409 CONTENT_VERSION_CONFLICT (or SCHEMA_CHANGED) when it moved.\n */\nexport const createContentApi = (request: RequestFn) => ({\n content: {\n list: (modelKey: string, query: ContentListQuery = {}) =>\n request<AdminEntryPage>(`${modelPath(modelKey)}${toContentQueryString(query)}`),\n get: (modelKey: string, id: string, { locale }: { locale?: string } = {}) =>\n request<AdminEntry>(`${entryPath(modelKey, id)}${toQueryString({ locale })}`),\n /** Fully validated (`required` included); 422 CONTENT_INVALID with `details.issues`. */\n create: (modelKey: string, body: CreateEntryInput) =>\n request<AdminEntry>(modelPath(modelKey), { method: 'POST', body }),\n /** Saves a patch of one locale's draft; `autosave` skips `required` and creates no revision. */\n update: (modelKey: string, id: string, body: UpdateEntryInput) =>\n request<AdminEntry>(entryPath(modelKey, id), { method: 'PUT', body }),\n /** 409 ENTRY_REFERENCED with `details.referrers` while other entries point at it. */\n remove: (modelKey: string, id: string) => request<void>(entryPath(modelKey, id), { method: 'DELETE' }),\n duplicate: (modelKey: string, id: string) =>\n request<AdminEntry>(`${entryPath(modelKey, id)}/duplicate`, { method: 'POST' }),\n publish: (modelKey: string, id: string, body: EntryLocalesInput = {}) =>\n request<AdminEntry>(`${entryPath(modelKey, id)}/publish`, { method: 'POST', body }),\n unpublish: (modelKey: string, id: string, body: EntryLocalesInput = {}) =>\n request<AdminEntry>(`${entryPath(modelKey, id)}/unpublish`, { method: 'POST', body }),\n revisions: async (modelKey: string, id: string, { locale }: { locale?: string } = {}) =>\n (\n await request<{ items: RevisionSummary[] }>(\n `${revisionsPath(modelKey, id)}${toQueryString({ locale })}`,\n )\n ).items,\n revision: (modelKey: string, id: string, revisionId: string) =>\n request<RevisionDetail>(withId(revisionsPath(modelKey, id), revisionId)),\n /** Brings an older revision back as the new draft of its locale (a new revision). */\n restore: (modelKey: string, id: string, revisionId: string, expectedVersion: number) =>\n request<AdminEntry>(`${withId(revisionsPath(modelKey, id), revisionId)}/restore`, {\n method: 'POST',\n body: { expectedVersion },\n }),\n },\n extensions: {\n /** Custom field editors the project installed (`shapio.config` + `extensions/editors/*.js`). */\n editors: () => request<EditorManifest>(ADMIN_PATHS.editorManifest),\n /** Admin colour themes the project declares (`shapio.config` `themes`). Public: no session needed. */\n themes: () => request<ExtensionThemeList>(ADMIN_PATHS.extensionThemes),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport type {\n ContentCounts,\n ContentHealthPage,\n ContentHealthQuery,\n ContentHealthSummary,\n EntryPresence,\n ModelPresence,\n PresenceHeartbeatInput,\n PreflightInput,\n PreflightResponse,\n} from './editingTypes.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { toQueryString } from './query.js';\n\nconst entryPath = (base: string, modelKey: string, id: string) => withId(withId(base, modelKey), id);\n\n/** The entry document's endpoints: pre-flight, content health (the Inbox), presence and counts. */\nexport const createEditingApi = (request: RequestFn) => ({\n preflight: {\n /** What publishing these locales would run into, without publishing (no hooks, no locks). */\n run: (modelKey: string, id: string, body: PreflightInput = {}) =>\n request<PreflightResponse>(`${entryPath(ADMIN_PATHS.content, modelKey, id)}/preflight`, {\n method: 'POST',\n body,\n }),\n },\n contentHealth: {\n list: (query: ContentHealthQuery = {}) =>\n request<ContentHealthPage>(`${ADMIN_PATHS.contentHealth}${toQueryString(query)}`),\n summary: () => request<ContentHealthSummary>(`${ADMIN_PATHS.contentHealth}/summary`),\n },\n presence: {\n /** Heartbeat (every 15s while the document is visible); returns who else has the entry open. */\n heartbeat: (modelKey: string, id: string, body: PresenceHeartbeatInput) =>\n request<EntryPresence>(entryPath(ADMIN_PATHS.presence, modelKey, id), { method: 'PUT', body }),\n entry: (modelKey: string, id: string) =>\n request<EntryPresence>(entryPath(ADMIN_PATHS.presence, modelKey, id)),\n /** Everyone editing an entry of the model (list rows). */\n model: (modelKey: string) => request<ModelPresence>(withId(ADMIN_PATHS.presence, modelKey)),\n leave: (modelKey: string, id: string, tabId: string) =>\n request<void>(`${entryPath(ADMIN_PATHS.presence, modelKey, id)}${toQueryString({ tabId })}`, {\n method: 'DELETE',\n }),\n },\n contentCounts: {\n list: () => request<ContentCounts>(ADMIN_PATHS.contentCounts),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport type {\n ConnectionTestResult,\n CreateDeploymentConnectionInput,\n CreatePreviewTokenInput,\n CreateScheduleInput,\n CreateWebhookInput,\n DeploymentConnection,\n DeploymentConnectionCreated,\n DeploymentRun,\n DeploymentRunQuery,\n Job,\n JobQuery,\n JobSummary,\n OpenPreviewInput,\n OpenPreviewResult,\n PreviewTarget,\n Page,\n PreviewToken,\n PreviewTokenCreated,\n ScheduledPublication,\n ScheduleQuery,\n UpdateDeploymentConnectionInput,\n UpdateWebhookInput,\n Webhook,\n WebhookDelivery,\n WebhookEventType,\n WebhookWithSecret,\n} from './publishingTypes.js';\nimport { toQueryString } from './query.js';\n\n/** Jobs, scheduled publications, webhooks, deployment connections and runs, preview (package H). */\nexport const createPublishingApi = (request: RequestFn) => ({\n jobs: {\n list: (query: JobQuery = {}) => request<Page<Job>>(`${ADMIN_PATHS.jobs}${toQueryString(query)}`),\n summary: () => request<JobSummary>(`${ADMIN_PATHS.jobs}/summary`),\n get: (id: string) => request<Job>(withId(ADMIN_PATHS.jobs, id)),\n /** Dead jobs only: runs again from attempt 1. 409 JOB_NOT_RETRYABLE otherwise. */\n retry: (id: string) => request<Job>(`${withId(ADMIN_PATHS.jobs, id)}/retry`, { method: 'POST' }),\n },\n schedules: {\n list: (query: ScheduleQuery = {}) =>\n request<Page<ScheduledPublication>>(`${ADMIN_PATHS.schedules}${toQueryString(query)}`),\n create: (body: CreateScheduleInput) =>\n request<ScheduledPublication>(ADMIN_PATHS.schedules, { method: 'POST', body }),\n cancel: (id: string) => request<void>(withId(ADMIN_PATHS.schedules, id), { method: 'DELETE' }),\n },\n webhooks: {\n list: () => request<Webhook[]>(ADMIN_PATHS.webhooks),\n events: async () =>\n (await request<{ items: WebhookEventType[] }>(`${ADMIN_PATHS.webhooks}/events`)).items,\n get: (id: string) => request<Webhook>(withId(ADMIN_PATHS.webhooks, id)),\n create: (body: CreateWebhookInput) =>\n request<WebhookWithSecret>(ADMIN_PATHS.webhooks, { method: 'POST', body }),\n update: (id: string, body: UpdateWebhookInput) =>\n request<Webhook>(withId(ADMIN_PATHS.webhooks, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.webhooks, id), { method: 'DELETE' }),\n rotateSecret: (id: string) =>\n request<WebhookWithSecret>(`${withId(ADMIN_PATHS.webhooks, id)}/rotate-secret`, { method: 'POST' }),\n /** Queues a `webhook.test` delivery; poll the delivery log for its outcome. */\n test: (id: string) =>\n request<WebhookDelivery>(`${withId(ADMIN_PATHS.webhooks, id)}/test`, { method: 'POST' }),\n deliveries: (id: string, query: { cursor?: string; limit?: number } = {}) =>\n request<Page<WebhookDelivery>>(`${withId(ADMIN_PATHS.webhooks, id)}/deliveries${toQueryString(query)}`),\n /** Sends the same payload again as a new delivery. */\n redeliver: (id: string, deliveryId: string) =>\n request<WebhookDelivery>(\n `${withId(ADMIN_PATHS.webhooks, id)}/deliveries/${encodeURIComponent(deliveryId)}/redeliver`,\n { method: 'POST' },\n ),\n },\n deployments: {\n connections: {\n list: () => request<DeploymentConnection[]>(ADMIN_PATHS.deploymentConnections),\n get: (id: string) => request<DeploymentConnection>(withId(ADMIN_PATHS.deploymentConnections, id)),\n create: (body: CreateDeploymentConnectionInput) =>\n request<DeploymentConnectionCreated>(ADMIN_PATHS.deploymentConnections, { method: 'POST', body }),\n update: (id: string, body: UpdateDeploymentConnectionInput) =>\n request<DeploymentConnection>(withId(ADMIN_PATHS.deploymentConnections, id), {\n method: 'PATCH',\n body,\n }),\n remove: (id: string) =>\n request<void>(withId(ADMIN_PATHS.deploymentConnections, id), { method: 'DELETE' }),\n test: (id: string) =>\n request<ConnectionTestResult>(`${withId(ADMIN_PATHS.deploymentConnections, id)}/test`, {\n method: 'POST',\n }),\n /** A manual run at the current publication snapshot. */\n trigger: (id: string) =>\n request<DeploymentRun>(`${withId(ADMIN_PATHS.deploymentConnections, id)}/runs`, { method: 'POST' }),\n },\n runs: {\n list: (query: DeploymentRunQuery = {}) =>\n request<Page<DeploymentRun>>(`${ADMIN_PATHS.deploymentRuns}${toQueryString(query)}`),\n get: (id: string) => request<DeploymentRun>(withId(ADMIN_PATHS.deploymentRuns, id)),\n /** A new run (linked by `retryOf`) at the current snapshot. */\n retry: (id: string) =>\n request<DeploymentRun>(`${withId(ADMIN_PATHS.deploymentRuns, id)}/retry`, { method: 'POST' }),\n },\n },\n preview: {\n tokens: {\n list: (query: { entryId?: string } = {}) =>\n request<PreviewToken[]>(`${ADMIN_PATHS.previewTokens}${toQueryString(query)}`),\n create: (body: CreatePreviewTokenInput) =>\n request<PreviewTokenCreated>(ADMIN_PATHS.previewTokens, { method: 'POST', body }),\n revoke: (id: string) => request<void>(withId(ADMIN_PATHS.previewTokens, id), { method: 'DELETE' }),\n },\n /** The site's connections with a preview URL (the entry form's Preview pane). */\n targets: () => request<PreviewTarget[]>(`${ADMIN_PATHS.preview}/targets`),\n /** The entry form's Preview action: a short-lived entry token and the rendered preview URL. */\n open: (body: OpenPreviewInput) =>\n request<OpenPreviewResult>(`${ADMIN_PATHS.preview}/open`, { method: 'POST', body }),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { toQueryString } from './query.js';\nimport type { SchemaApplyInput, SchemaApplyResult, SchemaExport } from './schemaSyncTypes.js';\nimport type {\n ChangeOutcome,\n ChangeScopeInput,\n ChangeScopeOutcome,\n CreateDefinitionInput,\n CreateLocaleInput,\n DefinitionCategory,\n DefinitionPayload,\n DefinitionDetail,\n DefinitionScope,\n DefinitionListItem,\n DefinitionRevision,\n DeleteLocaleResult,\n Locale,\n PlanPreview,\n PlanUpdateInput,\n SchemaChangeJob,\n SchemaSettings,\n SchemaSummary,\n SetDefaultLocaleResult,\n UpdateDefinitionInput,\n UpdateLocaleInput,\n UpdateSchemaSettingsInput,\n} from './schemaTypes.js';\n\nconst DEFINITION_PATHS = {\n model: ADMIN_PATHS.models,\n component: ADMIN_PATHS.components,\n} as const satisfies Record<DefinitionCategory, string>;\n\n/** Models (collections and singletons) and components share one set of endpoints under their own base. */\nexport const createDefinitionApi = (request: RequestFn, category: DefinitionCategory) => {\n const base = DEFINITION_PATHS[category];\n return {\n /** The site's view (shared definitions and its own); `{ scope: 'network' }` lists the shared ones. */\n list: async (options: { scope?: DefinitionScope } = {}) =>\n (await request<{ items: DefinitionListItem[] }>(`${base}${toQueryString(options)}`)).items,\n get: (id: string) => request<DefinitionDetail>(withId(base, id)),\n /** Creates and activates a definition (`pending` when prerequisites must run first). */\n create: (body: CreateDefinitionInput) => request<ChangeOutcome>(base, { method: 'POST', body }),\n /** Plan preview of a create: classification and impact, nothing written. */\n planCreate: (definition: DefinitionPayload, scope?: DefinitionScope) =>\n request<PlanPreview>(`${base}/plan`, {\n method: 'POST',\n body: scope ? { definition, scope } : { definition },\n }),\n /** Shares a definition with all sites, or keeps it on one (needs schema.create on every site). */\n changeScope: (id: string, body: ChangeScopeInput) =>\n request<ChangeScopeOutcome>(`${withId(base, id)}/scope`, { method: 'PUT', body }),\n /** Changes a definition; 409 SCHEMA_VERSION_CONFLICT when `expectedVersion` is stale. */\n update: (id: string, body: UpdateDefinitionInput) =>\n request<ChangeOutcome>(withId(base, id), { method: 'PUT', body }),\n planUpdate: (id: string, body: PlanUpdateInput) =>\n request<PlanPreview>(`${withId(base, id)}/plan`, { method: 'POST', body }),\n /** Soft delete: entries are kept and reappear if the definition is applied again. */\n remove: (id: string, expectedVersion: number) =>\n request<ChangeOutcome>(`${withId(base, id)}${toQueryString({ expectedVersion })}`, {\n method: 'DELETE',\n }),\n revisions: async (id: string) =>\n (await request<{ items: DefinitionRevision[] }>(`${withId(base, id)}/revisions`)).items,\n changes: async (id: string) =>\n (await request<{ items: SchemaChangeJob[] }>(`${withId(base, id)}/changes`)).items,\n };\n};\n\n/** Schema-wide endpoints: the version summary, planned-change status, the read-only lock, locales. */\nexport const createSchemaApi = (request: RequestFn) => ({\n models: createDefinitionApi(request, 'model'),\n components: createDefinitionApi(request, 'component'),\n schema: {\n /** The global schema version and every visible definition's version (cheap; poll it for changes). */\n summary: () => request<SchemaSummary>(ADMIN_PATHS.schema),\n change: (changeId: string) => request<SchemaChangeJob>(withId(ADMIN_PATHS.schemaChanges, changeId)),\n /** Every definition in the pull format, with the schema version they come from (`shapio schema pull`). */\n export: (options: { scope?: DefinitionScope } = {}) =>\n request<SchemaExport>(`${ADMIN_PATHS.schemaExport}${toQueryString(options)}`),\n /** Applies definition files live through the change planner; refuses when the base moved (409). */\n apply: (body: SchemaApplyInput) =>\n request<SchemaApplyResult>(ADMIN_PATHS.schemaApply, { method: 'POST', body }),\n settings: () => request<SchemaSettings>(ADMIN_PATHS.schemaSettings),\n updateSettings: (body: UpdateSchemaSettingsInput) =>\n request<SchemaSettings>(ADMIN_PATHS.schemaSettings, { method: 'PUT', body }),\n },\n locales: {\n list: async () => (await request<{ items: Locale[] }>(ADMIN_PATHS.locales)).items,\n create: (body: CreateLocaleInput) => request<Locale>(ADMIN_PATHS.locales, { method: 'POST', body }),\n update: (code: string, body: UpdateLocaleInput) =>\n request<Locale>(withId(ADMIN_PATHS.locales, code), { method: 'PUT', body }),\n /** A contract change: without `acknowledgeBreaking` the server answers 409 SCHEMA_CHANGE_NOT_ACKNOWLEDGED. */\n setDefault: (code: string, acknowledgeBreaking: boolean) =>\n request<SetDefaultLocaleResult>(`${withId(ADMIN_PATHS.locales, code)}/default`, {\n method: 'POST',\n body: { acknowledgeBreaking },\n }),\n /**\n * Deletes a locale and purges its content. When content exists and `acknowledgeDestructive` is false,\n * the server answers 409 SCHEMA_CHANGE_NOT_ACKNOWLEDGED with `details.plan.impact.affectedHeads`.\n */\n remove: (code: string, acknowledgeDestructive: boolean) =>\n request<DeleteLocaleResult>(\n `${withId(ADMIN_PATHS.locales, code)}${toQueryString({ acknowledgeDestructive: acknowledgeDestructive || undefined })}`,\n { method: 'DELETE' },\n ),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport type {\n CreateSiteInput,\n SetSiteAppRolesInput,\n Site,\n SiteAppRoles,\n UpdateSiteInput,\n} from './sitesTypes.js';\n\nexport const SITES_PATHS = { sites: '/api/admin/sites' } as const;\n\n/** The admin API header that names the site a site-scoped request is about (default: the primary site). */\nexport const SITE_HEADER = 'shapio-site';\n\nconst sitePath = (id: string) => `${SITES_PATHS.sites}/${encodeURIComponent(id)}`;\n\n/** Sites (network routes): listing shows the sites the caller holds a role on; changes need `sites.manage`. */\nexport const createSitesApi = (request: RequestFn) => ({\n sites: {\n list: () => request<Site[]>(SITES_PATHS.sites),\n get: (id: string) => request<Site>(sitePath(id)),\n create: (body: CreateSiteInput) => request<Site>(SITES_PATHS.sites, { method: 'POST', body }),\n update: (id: string, body: UpdateSiteInput) => request<Site>(sitePath(id), { method: 'PATCH', body }),\n /** Only an empty site (409 `SITE_NOT_EMPTY`); never the primary site (409 `SITE_IS_PRIMARY`). */\n remove: (id: string) => request<void>(sitePath(id), { method: 'DELETE' }),\n /** The app roles bound to the site's anonymous callers (`public`) and signed-in app users (`authenticated`). */\n appRoles: {\n get: (id: string) => request<SiteAppRoles>(`${sitePath(id)}/app-roles`),\n /** Replaces both bindings (`roles.manage`). */\n set: (id: string, body: SetSiteAppRolesInput) =>\n request<SiteAppRoles>(`${sitePath(id)}/app-roles`, { method: 'PUT', body }),\n },\n },\n});\n","import type { RequestFn } from '../request.js';\nimport { toQueryString } from './query.js';\nimport type { FieldUsageQuery, FieldUsageResponse } from './usageTypes.js';\n\nexport const USAGE_PATHS = { fields: '/api/admin/usage/fields' } as const;\n\n/** Who reads which fields (needs `tokens.manage`). */\nexport const createUsageApi = (request: RequestFn) => ({\n usage: {\n fields: (query: FieldUsageQuery) =>\n request<FieldUsageResponse>(`${USAGE_PATHS.fields}${toQueryString(query)}`),\n },\n});\n","import type { SiteSummary } from './sitesTypes.js';\n/**\n * Admin identity API shapes (package B, build plan §4.B), mirroring the TypeBox route schemas in\n * apps/api/src/routes/admin/** and routes/schemas/adminIdentity.ts. JSON is camelCase; timestamps are ISO-8601.\n */\n\nexport type AdminUserStatus = 'active' | 'disabled';\n\n/** A role held on one site, or on every site (`siteId` null). */\nexport type RoleAssignment = { roleId: string; siteId: string | null };\n\nexport type AdminUser = {\n id: string;\n email: string;\n name: string;\n status: AdminUserStatus;\n /** Where each role applies. */\n assignments: RoleAssignment[];\n /** Deprecated: the distinct roles of `assignments`, on any site. */\n roleIds: string[];\n lastLoginAt: string | null;\n createdAt: string;\n updatedAt: string;\n};\n\nexport const CONTENT_ACTIONS = ['read', 'create', 'update', 'delete', 'publish', 'schemaManage'] as const;\nexport type ContentAction = (typeof CONTENT_ACTIONS)[number];\n\n/**\n * Network actions: about the whole instance. Only roles assigned on every site grant them, so a role held\n * on one site never reaches the network.\n */\nexport const NETWORK_ACTIONS = [\n 'schema.create',\n 'users.manage',\n 'roles.manage',\n 'audit.read',\n 'sites.manage',\n] as const;\nexport type NetworkAction = (typeof NETWORK_ACTIONS)[number];\n\n/** Site actions: about one site's library, tokens and publishing. */\nexport const SITE_ACTIONS = [\n 'tokens.manage',\n 'media.read',\n 'media.write',\n 'media.manage',\n 'publishing.manage',\n 'webhooks.manage',\n 'deployments.manage',\n 'deployments.trigger',\n 'changes.manage',\n 'changes.ship',\n] as const;\nexport type SiteAction = (typeof SITE_ACTIONS)[number];\n\n/** Actions not scoped to a model: network actions and site actions. */\nexport const GLOBAL_ACTIONS = [\n 'schema.create',\n 'users.manage',\n 'roles.manage',\n 'tokens.manage',\n 'audit.read',\n 'sites.manage',\n 'media.read',\n 'media.write',\n 'media.manage',\n 'publishing.manage',\n 'webhooks.manage',\n 'deployments.manage',\n 'deployments.trigger',\n 'changes.manage',\n 'changes.ship',\n 'site.settings',\n] as const;\nexport type GlobalAction = (typeof GLOBAL_ACTIONS)[number];\n\nexport type PermissionAction = ContentAction | GlobalAction;\n\nexport type RoleSummary = { id: string; key: string; name: string };\n\n/** Returned whenever a session starts (setup, login, accepting an invitation). */\nexport type SessionStarted = { user: AdminUser; csrfToken: string };\n\nexport type MeResponse = {\n user: AdminUser;\n roles: RoleSummary[];\n /** The site this response is about: the request's `Shapio-Site`, else the primary site. */\n site: SiteSummary;\n /** Every site this admin holds a role on (all of them for a role assigned on every site). */\n sites: SiteSummary[];\n /** Sites on this instance (whether or not the admin holds a role on them); scope is shown only above 1. */\n siteCount: number;\n /** Network actions (roles assigned on every site only). */\n networkPermissions: NetworkAction[];\n /**\n * Site actions on the request's site, plus `schema.create` when a role on the site grants it for the\n * site's own definitions (`networkPermissions` lists it when shared definitions may be created too).\n */\n sitePermissions: Array<SiteAction | 'schema.create'>;\n /** `networkPermissions` and `sitePermissions` together. */\n globalPermissions: GlobalAction[];\n /** Content actions per model ID on the request's site (models without any action are left out). */\n modelPermissions: Record<string, ContentAction[]>;\n /** How the server sends email: `console` writes it to the server log (no real delivery is set up). */\n emailDelivery: EmailDelivery;\n csrfToken: string;\n};\n\nexport type EmailDelivery = 'console' | 'smtp';\n\nexport type SetupStatusResponse = {\n /** No admin exists yet. */\n required: boolean;\n /** SETUP_REQUIRE_TOKEN is set: setup also needs the one-time token from the server log. */\n requiresToken: boolean;\n};\n\n/** `token` is needed only when the server requires it (`requiresToken`); otherwise it is ignored. */\nexport type SetupInput = { token?: string; email: string; name: string; password: string };\n\nexport type LoginInput = { email: string; password: string };\n\nexport type CsrfResponse = { csrfToken: string };\n\nexport type UpdateProfileInput = { name: string };\n\nexport type ChangePasswordInput = { currentPassword: string; newPassword: string };\n\nexport type PasswordResetRequestInput = { email: string };\n\nexport type PasswordResetConfirmInput = { token: string; password: string };\n\nexport type AcceptInvitationInput = { token: string; name: string; password: string };\n\nexport type InspectInvitationResponse = { email: string; expiresAt: string };\n\nexport type AdminSession = {\n id: string;\n current: boolean;\n ip: string | null;\n userAgent: string | null;\n createdAt: string;\n lastSeenAt: string;\n expiresAt: string;\n};\n\nexport type Invitation = {\n id: string;\n email: string;\n /** The role assignments the invitee gets on accepting. */\n assignments: RoleAssignment[];\n /** Deprecated: the distinct roles of `assignments`. */\n roleIds: string[];\n invitedBy: string | null;\n expiresAt: string;\n createdAt: string;\n};\n\n/** A fresh accept link, shown once; issuing it makes earlier links (emailed or copied) stop working. */\nexport type InvitationLink = { acceptUrl: string; expiresAt: string };\n\n/**\n * Either `assignments` or (deprecated) `roleIds`, meaning those roles on every site; never both. Updating\n * either replaces every assignment.\n */\ntype AssignmentsInput =\n { assignments: RoleAssignment[]; roleIds?: never } | { roleIds: string[]; assignments?: never };\n\nexport type InviteUserInput = { email: string } & AssignmentsInput;\n\nexport type UpdateAdminUserInput = { name?: string; status?: AdminUserStatus } & (\n AssignmentsInput | { assignments?: never; roleIds?: never }\n);\n\nexport type RoleKind = 'admin' | 'delivery';\n\nexport type RoleCondition = 'ownedByPrincipal';\n\nexport type RolePermission = {\n action: PermissionAction;\n /** `null` grants the action on every model (and is required for global actions). */\n modelId: string | null;\n condition: RoleCondition | null;\n /** `null` = every field; otherwise only these stable field IDs. */\n fieldIds: string[] | null;\n};\n\nexport type Role = {\n id: string;\n key: string;\n name: string;\n description: string;\n kind: RoleKind;\n isSystem: boolean;\n /** Optimistic-concurrency version: send it back as `expectedVersion` on update. */\n version: number;\n permissions: RolePermission[];\n createdAt: string;\n updatedAt: string;\n};\n\nexport type CreateRoleInput = {\n key: string;\n name: string;\n description?: string;\n kind?: RoleKind;\n permissions: RolePermission[];\n};\n\nexport type UpdateRoleInput = {\n expectedVersion: number;\n name?: string;\n description?: string;\n permissions?: RolePermission[];\n};\n\nexport type ApiToken = {\n id: string;\n name: string;\n /** First characters of the token (`shp_` + 6), for telling tokens apart. */\n tokenPrefix: string;\n roleId: string;\n scope: RoleKind;\n /** The token's site; null for a network admin token (its role applies on every site). */\n siteId: string | null;\n createdBy: string | null;\n expiresAt: string | null;\n lastUsedAt: string | null;\n revokedAt: string | null;\n createdAt: string;\n};\n\nexport type CreateApiTokenInput = {\n name: string;\n roleId: string;\n expiresAt?: string | null;\n /**\n * A network admin token (every site and network actions; needs `users.manage`). Omitted: a network token\n * when the creator may create one, else a token of the request's site. Delivery tokens are always per site.\n */\n network?: boolean;\n};\n\n/** `token` is the plain secret, returned once at creation and never again. */\nexport type CreatedApiToken = { token: string; apiToken: ApiToken };\n\nexport type AuditActorType = 'admin' | 'app_user' | 'token' | 'anonymous' | 'system';\n\nexport type AuditEvent = {\n id: string;\n occurredAt: string;\n actorType: AuditActorType;\n actorId: string | null;\n /** The acting admin's (or app user's) display name, when the actor is a known account. */\n actorName: string | null;\n actorEmail: string | null;\n action: string;\n targetType: string | null;\n targetId: string | null;\n outcome: 'success' | 'failure';\n requestId: string | null;\n ip: string | null;\n metadata: unknown;\n};\n\n/** Newest first, cursor-paginated. */\nexport type AuditQuery = {\n cursor?: string;\n limit?: number;\n actorType?: AuditActorType;\n actorId?: string;\n action?: string;\n actionPrefix?: string;\n targetType?: string;\n targetId?: string;\n outcome?: 'success' | 'failure';\n from?: string;\n to?: string;\n};\n\nexport type AuditPage = { items: AuditEvent[]; nextCursor: string | null };\n","/**\n * Publishing types (package H, `apps/api/src/routes/admin/{jobs,publishing,webhooks,deployments,preview}`).\n * Dates are ISO-8601 strings.\n */\nimport type { SiteRef } from './sitesTypes.js';\n\nexport type Page<T> = { items: T[]; nextCursor: string | null };\n\n// Jobs ---------------------------------------------------------------------------------------------\n\nexport const JOB_STATUSES = ['pending', 'running', 'succeeded', 'dead'] as const;\nexport type JobStatus = (typeof JOB_STATUSES)[number];\n\nexport type Job = {\n id: string;\n type: string;\n status: JobStatus;\n attempts: number;\n maxAttempts: number;\n /** When it runs next (pending) or ran last. */\n runAt: string;\n idempotencyKey: string | null;\n lockedBy: string | null;\n lockedUntil: string | null;\n /** Payload and result with secret-looking values replaced by `[redacted]`. */\n payload: unknown;\n result: unknown;\n /** Progress a long job saved (e.g. an import's phase and counts); null when it saved none. */\n progress: unknown;\n lastError: string | null;\n createdAt: string;\n updatedAt: string;\n finishedAt: string | null;\n};\n\nexport type JobQuery = { status?: JobStatus; type?: string; cursor?: string; limit?: number };\n\nexport type JobSummary = { counts: Record<JobStatus, number>; types: string[] };\n\n// Scheduled publications ---------------------------------------------------------------------------\n\nexport const PUBLICATION_ACTIONS = ['publish', 'unpublish'] as const;\nexport type PublicationAction = (typeof PUBLICATION_ACTIONS)[number];\n\nexport const SCHEDULE_STATUSES = ['scheduled', 'done', 'failed', 'cancelled'] as const;\nexport type ScheduleStatus = (typeof SCHEDULE_STATUSES)[number];\n\nexport type ScheduledPublication = {\n id: string;\n entryId: string;\n modelId: string;\n /** Null when the model no longer exists. */\n modelKey: string | null;\n locale: string;\n action: PublicationAction;\n runAt: string;\n status: ScheduleStatus;\n error: string | null;\n /** Publication sequence the change was published at (once done). */\n snapshot: number | null;\n createdBy: string | null;\n createdAt: string;\n executedAt: string | null;\n};\n\nexport type ScheduleQuery = { status?: ScheduleStatus; entryId?: string; cursor?: string; limit?: number };\n\nexport type CreateScheduleInput = {\n modelKey: string;\n entryId: string;\n /** Omit for non-localized models (and for the default locale). */\n locale?: string;\n action: PublicationAction;\n runAt: string;\n};\n\n// Webhooks -----------------------------------------------------------------------------------------\n\nexport type WebhookEventType = { type: string; group: string };\n\nexport type WebhookDeliveryStatus = 'pending' | 'retrying' | 'succeeded' | 'dead';\n\nexport type Webhook = {\n id: string;\n name: string;\n url: string;\n /** Event types or `group.*` patterns. */\n events: string[];\n enabled: boolean;\n allowPrivateNetwork: boolean;\n maxAttempts: number;\n /** The site whose events it receives; null for a network-wide webhook (every site's events). */\n site: SiteRef | null;\n lastDelivery: { status: WebhookDeliveryStatus; at: string } | null;\n createdBy: string | null;\n createdAt: string;\n updatedAt: string;\n version: number;\n};\n\nexport type CreateWebhookInput = {\n name: string;\n url: string;\n events: string[];\n enabled?: boolean;\n allowPrivateNetwork?: boolean;\n maxAttempts?: number;\n /** A network-wide webhook (every site's events); otherwise it belongs to the request's site. */\n network?: boolean;\n};\n\n/** A webhook's site is fixed once created. */\nexport type UpdateWebhookInput = Partial<Omit<CreateWebhookInput, 'network'>> & { expectedVersion: number };\n\n/** The JSON body every webhook delivery sends (signed; verify it with `verifyWebhookSignature`). */\nexport type WebhookEventBody = {\n id: string;\n type: string;\n createdAt: string;\n /** The site the event is about; null for events about no site (network-wide). */\n site: SiteRef | null;\n data: unknown;\n};\n\n/** `secret` is shown once: on creation and after rotation. */\nexport type WebhookWithSecret = { webhook: Webhook; secret: string };\n\nexport type WebhookAttempt = {\n attempt: number;\n at: string;\n durationMs: number;\n request: { method: string; url: string; headers: Record<string, string> };\n /** Null when no response arrived (refused, timeout, blocked by the network policy). */\n response: { status: number; headers: Record<string, string>; body: string; truncated: boolean } | null;\n error: string | null;\n};\n\nexport type WebhookDelivery = {\n id: string;\n webhookId: string;\n eventId: string | null;\n eventType: string;\n isTest: boolean;\n status: WebhookDeliveryStatus;\n attempts: number;\n lastResponseStatus: number | null;\n lastError: string | null;\n payload: unknown;\n attemptLog: WebhookAttempt[];\n createdAt: string;\n updatedAt: string;\n deliveredAt: string | null;\n};\n\n// Deployments --------------------------------------------------------------------------------------\n\nexport const DEPLOYMENT_PROVIDERS = [\n 'generic_webhook',\n 'cloudflare_pages',\n 'vercel',\n 'netlify',\n 'github',\n] as const;\nexport type DeploymentProvider = (typeof DEPLOYMENT_PROVIDERS)[number];\n\nexport const DEPLOYMENT_TRIGGERS = ['publish', 'change_set', 'schema', 'manual'] as const;\nexport type DeploymentTriggerPolicy = (typeof DEPLOYMENT_TRIGGERS)[number];\n\nexport const DEPLOYMENT_RUN_STATUSES = [\n 'queued',\n 'triggered',\n 'building',\n 'deployed',\n 'failed',\n 'unknown',\n] as const;\nexport type DeploymentRunStatus = (typeof DEPLOYMENT_RUN_STATUSES)[number];\n\nexport type DeploymentRunTrigger = 'publish' | 'change_set' | 'schema' | 'manual' | 'retry';\n\n/**\n * Provider settings (not secret). Generic: `{ url }`. Cloudflare Pages: `{ accountId, projectName }`.\n * GitHub: `{ owner, repo, branch, mode: 'commit' | 'pull_request', directory }`.\n */\nexport type DeploymentSettings = Record<string, string>;\n\n/**\n * Secret names per provider. Generic: `signingSecret` (generated when omitted). Cloudflare Pages:\n * `deployHookUrl`, `apiToken`. GitHub: `token`. Values are write-only. A value of `${ENV:VAR_NAME}`\n * makes the server read the secret from that environment variable instead of storing it.\n */\nexport type DeploymentSecretsInput = Record<string, string>;\n\n/** Which secrets are set; values never leave the server. `envVar`: read from this environment variable. */\nexport type DeploymentSecretState = Record<string, { set: boolean; envVar: string | null }>;\n\nexport type DeploymentTimelineEvent = {\n status: DeploymentRunStatus;\n at: string;\n source: 'shapio' | 'callback' | 'provider';\n message: string | null;\n};\n\nexport type DeploymentRun = {\n id: string;\n connectionId: string;\n connectionName: string;\n provider: DeploymentProvider;\n status: DeploymentRunStatus;\n trigger: DeploymentRunTrigger;\n /** Publication sequence the run was triggered at (`?snapshot=` on delivery). */\n snapshot: number | null;\n schemaVersion: number | null;\n retryOf: string | null;\n providerRef: string | null;\n logUrl: string | null;\n siteUrl: string | null;\n error: string | null;\n /** False for providers that cannot report completion without callbacks (shown as \"completion unknown\"). */\n completionReported: boolean;\n timeline: DeploymentTimelineEvent[];\n triggeredAt: string | null;\n finishedAt: string | null;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type DeploymentConnection = {\n id: string;\n name: string;\n provider: DeploymentProvider;\n settings: DeploymentSettings;\n secrets: DeploymentSecretState;\n previewUrlTemplate: string | null;\n /** Preview tokens issued for this connection show exactly what this delivery role reads. */\n deliveryRoleId: string | null;\n triggerPolicy: DeploymentTriggerPolicy[];\n debounceSeconds: number;\n allowPrivateNetwork: boolean;\n enabled: boolean;\n /** Where the site posts signed build callbacks (generic webhook connections). */\n callbackUrl: string;\n latestRun: DeploymentRun | null;\n /** The newest deployed run by snapshot: what the site is serving, as far as Shapio knows. */\n currentRun: DeploymentRun | null;\n createdBy: string | null;\n createdAt: string;\n updatedAt: string;\n version: number;\n};\n\nexport type CreateDeploymentConnectionInput = {\n name: string;\n provider: DeploymentProvider;\n settings: DeploymentSettings;\n secrets: DeploymentSecretsInput;\n previewUrlTemplate?: string | null;\n triggerPolicy: DeploymentTriggerPolicy[];\n debounceSeconds?: number;\n allowPrivateNetwork?: boolean;\n enabled?: boolean;\n deliveryRoleId?: string | null;\n};\n\nexport type UpdateDeploymentConnectionInput = Partial<Omit<CreateDeploymentConnectionInput, 'provider'>> & {\n expectedVersion: number;\n};\n\n/** `generatedSecrets` holds secrets Shapio generated (the generic signing secret), shown once. */\nexport type DeploymentConnectionCreated = {\n connection: DeploymentConnection;\n generatedSecrets: Record<string, string>;\n};\n\nexport type ConnectionTestResult = {\n ok: boolean;\n checks: Array<{ name: string; ok: boolean; message: string }>;\n};\n\nexport type DeploymentRunQuery = { connectionId?: string; cursor?: string; limit?: number };\n\n// Preview ------------------------------------------------------------------------------------------\n\nexport type PreviewToken = {\n id: string;\n tokenPrefix: string;\n modelId: string;\n modelKey: string | null;\n entryId: string | null;\n locale: string | null;\n connectionId: string | null;\n /** Fields follow this delivery role (within the creator's access); null = the public fields. */\n deliveryRoleId: string | null;\n createdBy: string;\n expiresAt: string;\n revokedAt: string | null;\n lastUsedAt: string | null;\n createdAt: string;\n};\n\nexport type CreatePreviewTokenInput = {\n modelKey: string;\n entryId?: string;\n locale?: string;\n /** Default 1 hour, at most 30 days. */\n ttlSeconds?: number;\n connectionId?: string;\n /** Defaults to the connection's delivery role. */\n deliveryRoleId?: string;\n};\n\n/** `token` is shown once. `url` is rendered from the connection's preview URL template (null without one). */\nexport type PreviewTokenCreated = { token: string; previewToken: PreviewToken; url: string | null };\n\nexport type OpenPreviewInput = {\n modelKey: string;\n entryId: string;\n locale?: string;\n /** Defaults to the first enabled connection with a preview URL template. */\n connectionId?: string;\n};\n\n/** What the entry form's Preview button opens. `apiUrl` is the preview read endpoint for this entry. */\nexport type OpenPreviewResult = {\n /** The token's ID (revoke it when the preview closes). */\n id: string;\n url: string | null;\n apiUrl: string;\n token: string;\n expiresAt: string;\n connectionId: string | null;\n};\n\n/** A connection the site's previews open on (names and origins only). */\nexport type PreviewTarget = {\n connectionId: string;\n name: string;\n /** null when the preview URL template's origin depends on a variable. */\n origin: string | null;\n /** Whether the admin can show it in its preview frame. */\n framable: boolean;\n};\n","/**\n * App users and app roles as administrators manage them (package I), mirroring the TypeBox route schemas in\n * apps/api/src/routes/admin/{appUsers,appRoles}. JSON is camelCase; timestamps are ISO-8601.\n */\nimport type { RoleCondition } from './types.js';\n\nexport type AdminAppUser = {\n id: string;\n email: string;\n name: string;\n confirmed: boolean;\n blocked: boolean;\n /** False for accounts that only sign in with an OAuth provider. */\n hasPassword: boolean;\n /** OAuth providers linked to the account (`google`, `github`). */\n providers: string[];\n /** Custom app roles; `authenticated` applies to every app user implicitly. */\n roleIds: string[];\n lastLoginAt: string | null;\n createdAt: string;\n updatedAt: string;\n};\n\n/** Newest first, cursor-paginated; `search` matches email or name. */\nexport type AppUserQuery = { search?: string; cursor?: string; limit?: number };\n\nexport type AppUserPage = { items: AdminAppUser[]; nextCursor: string | null };\n\nexport type UpdateAppUserInput = { blocked?: boolean; roleIds?: string[] };\n\n/** What app roles may grant: content actions only. */\nexport const APP_CONTENT_ACTIONS = ['read', 'create', 'update', 'delete', 'publish'] as const;\nexport type AppContentAction = (typeof APP_CONTENT_ACTIONS)[number];\n\n/** Built-in app role keys: `public` applies to anonymous callers, `authenticated` to every app user. */\nexport const BUILT_IN_APP_ROLE_KEYS = ['public', 'authenticated'] as const;\n\nexport type AppRolePermission = {\n action: AppContentAction;\n /** `null` grants the action on every model, including ones created later. */\n modelId: string | null;\n condition: RoleCondition | null;\n /** `null` = every public field; otherwise exactly these stable field IDs (non-public ones included). */\n fieldIds: string[] | null;\n};\n\nexport type AppRole = {\n id: string;\n key: string;\n name: string;\n description: string;\n isSystem: boolean;\n version: number;\n permissions: AppRolePermission[];\n userCount: number;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type CreateAppRoleInput = {\n key: string;\n name: string;\n description?: string;\n permissions: AppRolePermission[];\n};\n\n/** Built-in roles accept `permissions` only. */\nexport type UpdateAppRoleInput = {\n expectedVersion: number;\n name?: string;\n description?: string;\n permissions?: AppRolePermission[];\n};\n","import type { SchemaDefinition } from '@shapio/schema';\nimport type { DeploymentRunStatus, Page, PublicationAction } from './publishingTypes.js';\nimport type { ChangePlan, DefinitionCategory, DefinitionPayload, PlanImpact } from './schemaTypes.js';\nimport type { SiteRef } from './sitesTypes.js';\n\n/**\n * Change sets and snapshots (developer-face plan §5), mirroring the TypeBox route schemas in\n * apps/api/src/routes/admin/{changeSets,snapshots}/schemas.ts. Dates are ISO-8601 strings.\n */\n\nexport const CHANGE_SET_STATUSES = [\n 'open',\n 'scheduled',\n 'shipping',\n 'shipped',\n 'failed',\n 'discarded',\n] as const;\nexport type ChangeSetStatus = (typeof CHANGE_SET_STATUSES)[number];\n/** While `shipping`: preparing (prerequisite dry runs, index builds) or activating (the final transaction). */\nexport type ShipPhase = 'preparing' | 'activating';\nexport type ChangeSetSource = 'manual' | 'release' | 'restore' | 'builder' | 'assist';\nexport type ChangeSetItemStatus = 'pending' | 'done' | 'failed';\nexport type SchemaOperation = 'create' | 'update' | 'delete';\n\nexport type ChangeSetActor = { type: 'admin' | 'token' | 'system'; id: string | null; name: string | null };\n\n/** Why a ship failed, and the item that stopped it (null when not tied to one item). */\nexport type ChangeSetError = { code: string; message: string; itemId: string | null; details?: unknown };\n\nexport type ChangeSetEntryItem = {\n id: string;\n kind: 'entry';\n position: number;\n entryId: string;\n modelId: string;\n modelKey: string | null;\n title: string | null;\n locale: string;\n action: PublicationAction;\n /** Restore items publish this exact revision instead of the current draft. */\n sourceRevisionId: string | null;\n status: ChangeSetItemStatus;\n error: string | null;\n};\n\nexport type ChangeSetSchemaItem = {\n id: string;\n kind: 'schema';\n position: number;\n draftId: string;\n definitionId: string;\n category: DefinitionCategory;\n apiKey: string;\n operation: SchemaOperation;\n /** The active version the draft was based on; null for a new definition. */\n baseVersion: number | null;\n draftVersion: number;\n status: ChangeSetItemStatus;\n error: string | null;\n};\n\nexport type ChangeSetItem = ChangeSetEntryItem | ChangeSetSchemaItem;\n\nexport type ChangeSetSummary = {\n id: string;\n title: string;\n description: string;\n status: ChangeSetStatus;\n shipPhase: ShipPhase | null;\n source: ChangeSetSource;\n restoreOfSnapshot: number | null;\n scheduledFor: string | null;\n /** Connection whose deploy is triggered (pinned to the shipped snapshot) after the set ships. */\n deploymentConnectionId: string | null;\n deploymentRunId: string | null;\n shippedAt: string | null;\n /** The publication snapshot the set went live in. */\n shippedSnapshot: number | null;\n schemaVersionAfter: number | null;\n error: ChangeSetError | null;\n entryItemCount: number;\n schemaItemCount: number;\n createdBy: ChangeSetActor;\n createdAt: string;\n updatedAt: string;\n version: number;\n};\n\nexport type ChangeSet = ChangeSetSummary & { items: ChangeSetItem[] };\n\nexport type ChangeSetQuery = {\n /** Comma-separated statuses; default: everything except `discarded`. */\n status?: string;\n cursor?: string;\n limit?: number;\n};\n\nexport type CreateChangeSetInput = {\n title: string;\n description?: string;\n /** `builder`: a one-item set the model builder ships at once (\"Review & ship now\"). Default `manual`. */\n source?: 'manual' | 'builder';\n};\nexport type UpdateChangeSetInput = {\n title?: string;\n description?: string;\n deploymentConnectionId?: string | null;\n expectedVersion: number;\n};\nexport type AddChangeSetEntryInput = {\n modelKey: string;\n entryId: string;\n /** Omit for non-localized models (and for the default locale). */\n locale?: string;\n action: PublicationAction;\n};\n\nexport type SchemaDraft = {\n id: string;\n changeSetId: string;\n definitionId: string;\n category: DefinitionCategory;\n operation: SchemaOperation;\n baseVersion: number | null;\n /** Null when the draft deletes the definition. */\n definition: SchemaDefinition | null;\n /** A new definition the draft creates shared with all sites (otherwise it belongs to the set's site). */\n shared: boolean;\n version: number;\n updatedBy: ChangeSetActor;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type PutSchemaDraftInput = {\n category: DefinitionCategory;\n /** The whole proposed definition, or null to delete the definition when the set ships. */\n definition: DefinitionPayload | null;\n /** The active version the edit is based on (null: a new definition). */\n baseVersion: number | null;\n /** For a new definition: create it shared with all sites (default false: the set's site). */\n shared?: boolean;\n /** The draft row version the caller saw; omit when creating the draft. */\n expectedDraftVersion?: number;\n};\n\nexport type FieldDiff = { fieldId: string; apiKey: string; label: string; before: unknown; after: unknown };\nexport type ReviewIssue = { path: string; code: string; message: string };\n\nexport type ReviewEntryItem = {\n itemId: string;\n entryId: string;\n modelId: string;\n modelKey: string | null;\n title: string | null;\n locale: string;\n action: PublicationAction;\n sourceRevisionId: string | null;\n /** Send back in `ship.itemVersions` (strict ship). Null when the item does not publish the draft. */\n draftVersion: number | null;\n liveState: 'unpublished' | 'published' | 'modified' | 'missing';\n fields: FieldDiff[];\n issues: ReviewIssue[];\n};\n\nexport type ReviewSchemaItem = {\n itemId: string;\n draftId: string;\n definitionId: string;\n category: DefinitionCategory;\n apiKey: string;\n operation: SchemaOperation;\n baseVersion: number | null;\n activeVersion: number | null;\n /** The active version moved since the draft was based on it: shipping refuses until it is rebased. */\n stale: boolean;\n plan: ChangePlan | null;\n impact: PlanImpact | null;\n /** Entries of the affected models per site (a shared definition converts every site's content). */\n affectedEntriesBySite: Array<{ site: SiteRef; entries: number }>;\n issues: ReviewIssue[];\n alsoChangedIn: Array<{ id: string; title: string }>;\n};\n\nexport const NOT_RESTORABLE_REASONS = [\n 'entry_deleted',\n 'model_missing',\n 'publishing_disabled',\n 'localization_changed',\n 'locale_missing',\n 'invalid',\n 'unique_conflict',\n] as const;\nexport type NotRestorableReason = (typeof NOT_RESTORABLE_REASONS)[number];\n\nexport type NotRestorable = {\n entryId: string;\n modelId: string;\n modelKey: string | null;\n locale: string;\n reason: NotRestorableReason;\n detail: string;\n};\n\nexport type FieldConsumer = {\n /** The site the reads were made on. */\n site: SiteRef;\n /** `token:<id>`, `app_users` or `anonymous`. */\n principalKey: string;\n label: string | null;\n reads: number;\n lastReadAt: string | null;\n /** `implicit`: the reader requested the whole model (no field selection). */\n selection: 'explicit' | 'implicit';\n};\n\nexport type FieldConsumers = {\n modelId: string;\n fieldId: string;\n apiKey: string;\n consumers: FieldConsumer[];\n /**\n * Readers on other sites, as totals, when the viewer holds no role on every site; null when the viewer\n * sees every site's readers in `consumers`.\n */\n otherSites: { consumers: number; reads: number } | null;\n};\n\nexport type ChangeSetReview = {\n changeSet: ChangeSet;\n entries: ReviewEntryItem[];\n schema: ReviewSchemaItem[];\n notRestorable: NotRestorable[];\n consumers: FieldConsumers[];\n usageDays: number;\n checks: { breaking: boolean; destructive: boolean; blocking: ReviewIssue[]; warnings: ReviewIssue[] };\n /** Fixed notices, e.g. `NEW_FIELDS_AFTER_SHIP`. */\n notices: string[];\n};\n\nexport type ShipChangeSetInput = {\n expectedVersion: number;\n acknowledgeBreaking?: boolean;\n acknowledgeDestructive?: boolean;\n /** Draft versions the review showed; a moved draft makes the ship refuse with 409 CHANGE_SET_STALE. */\n itemVersions?: Array<{ itemId: string; draftVersion: number }>;\n};\n\nexport type ScheduleChangeSetInput = {\n at: string;\n expectedVersion: number;\n acknowledgeBreaking?: boolean;\n acknowledgeDestructive?: boolean;\n};\n\nexport type ChangeSetTimelineEvent = {\n at: string;\n kind: string;\n actor: ChangeSetActor | null;\n message: string | null;\n snapshot: number | null;\n deploymentRunId: string | null;\n /** `item.changedAfterReview`: the entry whose draft moved between review and a scheduled ship. */\n item: { entryId: string; locale: string; fromVersion: number; toVersion: number } | null;\n};\n\nexport type UnassignedEntry = {\n entryId: string;\n modelId: string;\n modelKey: string | null;\n title: string | null;\n locale: string;\n status: 'draft' | 'modified';\n updatedAt: string;\n};\n\n// Snapshots ----------------------------------------------------------------------------------------\n\nexport const SNAPSHOT_SOURCES = [\n 'publish',\n 'unpublish',\n 'delete',\n 'schedule',\n 'change_set',\n 'schema',\n 'conversion',\n 'import',\n 'legacy',\n] as const;\nexport type SnapshotSource = (typeof SNAPSHOT_SOURCES)[number];\n\nexport type Snapshot = {\n seq: number;\n schemaVersion: number | null;\n source: SnapshotSource;\n changeSetId: string | null;\n changeSetTitle: string | null;\n actor: { type: string; id: string | null };\n changedEntries: number;\n deploymentRuns: Array<{ id: string; connectionId: string; status: DeploymentRunStatus }>;\n createdAt: string;\n};\n\nexport type SnapshotPage = Page<Snapshot> & { current: number };\nexport type SnapshotQuery = { cursor?: string; limit?: number };\n","/**\n * Shapes of the entry document's endpoints (editor experience, E0b): publish pre-flight, content health\n * findings, presence and per-model counts. Sentences are never sent: the admin builds them from `rule` and\n * `params` with its translations.\n */\n\n/** Health rules evaluated per entry (`apps/api/src/services/contentHealth.ts`). */\nexport const HEALTH_RULES = [\n 'requiredEmpty',\n 'altMissing',\n 'localeMissing',\n 'relationMissing',\n 'relationUnpublished',\n 'uniqueConflict',\n 'staleDraft',\n 'unpublishedChanges',\n] as const;\nexport type HealthRule = (typeof HEALTH_RULES)[number];\n\n/** Pre-flight adds the publish checks that are not health rules: validator issues and missing media. */\nexport type PreflightRule = HealthRule | 'invalid' | 'mediaMissing';\n\nexport type CheckSeverity = 'error' | 'warning';\n\n/** Values a sentence needs (field ID, asset ID, locale, counts…). */\nexport type CheckParams = Record<string, string | number | null>;\n\nexport type PreflightCheck = {\n rule: PreflightRule;\n /** Errors block publishing; warnings are informational. */\n severity: CheckSeverity;\n /** JSON pointer (API keys) of the value to fix, e.g. `/body` or `/sections/2/title`. */\n path?: string;\n /** The validator's issue code, for `invalid` and `requiredEmpty` errors. */\n code?: string;\n params: CheckParams;\n};\n\nexport type PreflightLocale = {\n locale: string;\n /** No error-severity check: publishing this locale is expected to succeed. */\n ready: boolean;\n checks: PreflightCheck[];\n};\n\nexport type PreflightInput = { locales?: string[] };\n\nexport type PreflightResponse = {\n locales: PreflightLocale[];\n /** Checks about the entry as a whole, not one locale (e.g. a configured locale not started yet). */\n entry: PreflightCheck[];\n};\n\n/** A finding of the health engine, open until its rule passes again. */\nexport type ContentHealthFinding = {\n id: string;\n entryId: string;\n modelId: string;\n modelKey: string;\n /** The entry's title in the finding's locale (or the default locale), when readable. */\n entryTitle: string | null;\n /** `*` for a finding about the entry as a whole. */\n locale: string;\n rule: HealthRule;\n /** Distinguishes several findings of one rule on one entry (e.g. two images without alt text). */\n subject: string;\n severity: CheckSeverity;\n path?: string;\n params: CheckParams;\n firstSeenAt: string;\n lastSeenAt: string;\n};\n\nexport type ContentHealthQuery = { rule?: HealthRule; modelKey?: string; cursor?: string; limit?: number };\n\nexport type ContentHealthPage = { items: ContentHealthFinding[]; nextCursor: string | null };\n\nexport type ContentHealthSummary = { rules: { rule: HealthRule; count: number }[] };\n\n/** Someone with the entry open. */\nexport type PresencePerson = {\n userId: string;\n name: string;\n /** The locale they are editing, when the model is localized. */\n locale: string | null;\n /** When this tab started editing. */\n since: string;\n /** The caller's own other tab (the calling tab itself is never listed). */\n you: boolean;\n};\n\nexport type PresenceHeartbeatInput = {\n /** A random ID per browser tab, so two tabs of one person are counted apart. */\n tabId: string;\n locale?: string | null;\n};\n\nexport type EntryPresence = { people: PresencePerson[] };\n\nexport type ModelPresence = { entries: { entryId: string; people: PresencePerson[] }[] };\n\nexport type ContentCount = { modelId: string; modelKey: string; total: number };\n\nexport type ContentCounts = { counts: ContentCount[] };\n","import type { SchemaDefinition } from '@shapio/schema';\n\n/** Editor assists (plan agentic-ecosystem §A0). Agents propose, people ship: nothing here publishes. */\nexport type AssistProvider = 'anthropic' | 'openai' | 'openai-compatible';\n\nexport type AssistUsage = { month: string; runs: number; inputTokens: number; outputTokens: number };\n\n/** `usage` only for admins with `changes.manage`; provider and model only while assist is on. */\nexport type AssistStatus = {\n enabled: boolean;\n provider?: AssistProvider;\n model?: string;\n usage?: AssistUsage;\n};\n\nexport type AltTextInput = { assetId: string; locale?: string };\nexport type AltTextResult = { alt: string; model: string };\n\n/** A model-written text; `truncated` when it was cut to the field's or the request's limit. */\nexport type AssistTextResult = { text: string; truncated: boolean; model: string };\n\nexport type SummarizeInput = { modelKey: string; entryId: string; locale?: string; fieldApiKey: string };\n\nexport type TranslateInput = { modelKey: string; entryId: string; from: string; to: string };\nexport type AssistIssue = { path: string; code: string; message: string };\n/** `data` is in the editor's save format: save it as the `to` locale's draft. */\nexport type TranslateResult = { data: Record<string, unknown>; issues: AssistIssue[]; model: string };\n\nexport type RewriteInput = { text: string; instruction: string; maxLength?: number };\n\nexport type SchemaDraftInput = { description: string };\n/** New definitions with new stable IDs, in save order (references first). Nothing is written. */\nexport type SchemaDraftResult = { definitions: SchemaDefinition[]; model: string };\n\nexport const CONTENT_OPS_RULES = ['altMissing', 'localeMissing'] as const;\nexport type ContentOpsRule = (typeof CONTENT_OPS_RULES)[number];\nexport type ContentOpsInput = { rule: ContentOpsRule; modelKey?: string; fromLocale?: string };\nexport type ContentOpsStatus = 'queued' | 'running' | 'succeeded' | 'failed';\n\n/** One library asset's proposed alt text; apply it with the media update at `assetVersion`. */\nexport type AltProposal = {\n assetId: string;\n filename: string;\n currentAlt: string | null;\n proposedAlt: string;\n assetVersion: number;\n findingCount: number;\n};\n\n/** A finding the run left alone, and why (an error code or a reason such as `publishesOnSave`). */\nexport type ContentOpsSkip = {\n key: string;\n entryId?: string;\n assetId?: string;\n locale?: string;\n reason: string;\n detail?: unknown;\n};\nexport type ContentOpsWritten = { entryId: string; modelKey: string; locale: string; version: number };\n\nexport type AltMissingResult = { rule: 'altMissing'; proposals: AltProposal[]; skipped: ContentOpsSkip[] };\n/** The drafts were written into the change set `changeSetId` (null when nothing was written). */\nexport type LocaleMissingResult = {\n rule: 'localeMissing';\n changeSetId: string | null;\n fromLocale: string;\n written: ContentOpsWritten[];\n skipped: ContentOpsSkip[];\n};\nexport type ContentOpsResult = AltMissingResult | LocaleMissingResult;\n\nexport type ContentOpsRun = {\n runId: string;\n rule: ContentOpsRule;\n status: ContentOpsStatus;\n model: string;\n createdAt: string;\n finishedAt: string | null;\n error: { code: string } | null;\n /** Once succeeded (null before, or partial progress while running). */\n result: ContentOpsResult | null;\n};\n","import type { RequestFn } from '../request.js';\nimport { createAppUsersApi } from './appUsers.js';\nimport { createAssistApi } from './assist.js';\nimport { createChangeSetsApi } from './changeSets.js';\nimport { createContentApi } from './content.js';\nimport { createEditingApi } from './editing.js';\nimport { createMediaApi } from './media.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { createPublishingApi } from './publishing.js';\nimport { toQueryString } from './query.js';\nimport { createSchemaApi } from './schema.js';\nimport { createSitesApi } from './sites.js';\nimport type {\n AcceptInvitationInput,\n AdminSession,\n AdminUser,\n ApiToken,\n AuditPage,\n AuditQuery,\n ChangePasswordInput,\n CreateApiTokenInput,\n CreatedApiToken,\n CreateRoleInput,\n CsrfResponse,\n InspectInvitationResponse,\n Invitation,\n InvitationLink,\n InviteUserInput,\n LoginInput,\n MeResponse,\n PasswordResetConfirmInput,\n PasswordResetRequestInput,\n Role,\n SessionStarted,\n SetupInput,\n SetupStatusResponse,\n UpdateAdminUserInput,\n UpdateProfileInput,\n UpdateRoleInput,\n} from './types.js';\nimport { createUsageApi } from './usage.js';\n\n/**\n * Admin endpoints: identity (setup, auth, sessions, users, invitations, roles, tokens, audit) and the schema\n * registry (models, components, schema, locales), the media library and content.\n */\nexport const createAdminApi = (request: RequestFn) => ({\n setup: {\n status: () => request<SetupStatusResponse>(ADMIN_PATHS.setup),\n complete: (body: SetupInput) => request<SessionStarted>(ADMIN_PATHS.setup, { method: 'POST', body }),\n },\n auth: {\n csrf: () => request<CsrfResponse>(ADMIN_PATHS.csrf),\n login: (body: LoginInput) => request<SessionStarted>(ADMIN_PATHS.login, { method: 'POST', body }),\n logout: () => request<void>(ADMIN_PATHS.logout, { method: 'POST' }),\n me: () => request<MeResponse>(ADMIN_PATHS.me),\n updateProfile: (body: UpdateProfileInput) =>\n request<AdminUser>(ADMIN_PATHS.me, { method: 'PATCH', body }),\n /** The session is rotated: the response carries the new session's CSRF token. */\n changePassword: (body: ChangePasswordInput) =>\n request<CsrfResponse>(ADMIN_PATHS.password, { method: 'POST', body }),\n requestPasswordReset: (body: PasswordResetRequestInput) =>\n request<void>(ADMIN_PATHS.passwordReset, { method: 'POST', body }),\n confirmPasswordReset: (body: PasswordResetConfirmInput) =>\n request<void>(ADMIN_PATHS.passwordResetConfirm, { method: 'POST', body }),\n },\n sessions: {\n list: () => request<AdminSession[]>(ADMIN_PATHS.sessions),\n revoke: (id: string) => request<void>(withId(ADMIN_PATHS.sessions, id), { method: 'DELETE' }),\n },\n users: {\n list: () => request<AdminUser[]>(ADMIN_PATHS.users),\n get: (id: string) => request<AdminUser>(withId(ADMIN_PATHS.users, id)),\n update: (id: string, body: UpdateAdminUserInput) =>\n request<AdminUser>(withId(ADMIN_PATHS.users, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.users, id), { method: 'DELETE' }),\n revokeSessions: (id: string) =>\n request<void>(`${withId(ADMIN_PATHS.users, id)}/sessions`, { method: 'DELETE' }),\n },\n invitations: {\n list: () => request<Invitation[]>(ADMIN_PATHS.invitations),\n create: (body: InviteUserInput) => request<Invitation>(ADMIN_PATHS.invitations, { method: 'POST', body }),\n revoke: (id: string) => request<void>(withId(ADMIN_PATHS.invitations, id), { method: 'DELETE' }),\n /** A fresh link to send by hand; any earlier link for this invitation stops working. */\n link: (id: string) =>\n request<InvitationLink>(`${withId(ADMIN_PATHS.invitations, id)}/link`, { method: 'POST' }),\n /** Public: the token travels in the body, never in a URL the server logs. */\n inspect: (token: string) =>\n request<InspectInvitationResponse>(ADMIN_PATHS.inspectInvitation, { method: 'POST', body: { token } }),\n accept: (body: AcceptInvitationInput) =>\n request<SessionStarted>(ADMIN_PATHS.acceptInvitation, { method: 'POST', body }),\n },\n roles: {\n list: () => request<Role[]>(ADMIN_PATHS.roles),\n get: (id: string) => request<Role>(withId(ADMIN_PATHS.roles, id)),\n create: (body: CreateRoleInput) => request<Role>(ADMIN_PATHS.roles, { method: 'POST', body }),\n update: (id: string, body: UpdateRoleInput) =>\n request<Role>(withId(ADMIN_PATHS.roles, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.roles, id), { method: 'DELETE' }),\n },\n tokens: {\n list: () => request<ApiToken[]>(ADMIN_PATHS.tokens),\n create: (body: CreateApiTokenInput) =>\n request<CreatedApiToken>(ADMIN_PATHS.tokens, { method: 'POST', body }),\n revoke: (id: string) => request<void>(withId(ADMIN_PATHS.tokens, id), { method: 'DELETE' }),\n },\n audit: {\n list: (query: AuditQuery = {}) => request<AuditPage>(`${ADMIN_PATHS.audit}${toQueryString(query)}`),\n },\n ...createSchemaApi(request),\n ...createMediaApi(request),\n ...createContentApi(request),\n ...createEditingApi(request),\n ...createPublishingApi(request),\n ...createAppUsersApi(request),\n ...createChangeSetsApi(request),\n ...createUsageApi(request),\n ...createSitesApi(request),\n ...createAssistApi(request),\n});\n\nexport type AdminApi = ReturnType<typeof createAdminApi>;\nexport { ADMIN_PATHS } from './paths.js';\nexport * from './types.js';\nexport * from './schemaTypes.js';\nexport * from './schemaSyncTypes.js';\nexport * from './mediaTypes.js';\nexport * from './contentTypes.js';\nexport * from './publishingTypes.js';\nexport * from './appUsersTypes.js';\nexport * from './changeSetTypes.js';\nexport * from './usageTypes.js';\nexport * from './sitesTypes.js';\nexport { SITE_HEADER, SITES_PATHS } from './sites.js';\nexport { toContentQueryString } from './contentQuery.js';\nexport { buildUploadForm, resolveUploadUrl } from './media.js';\nexport { HEALTH_RULES } from './editingTypes.js';\nexport { ASSIST_PATHS } from './assist.js';\nexport { CONTENT_OPS_RULES } from './assistTypes.js';\n","import type { RequestFn } from '../request.js';\nimport type {\n AppChangePasswordInput,\n AppLoginInput,\n AppOAuthProvider,\n AppRegisterInput,\n AppRegisterResult,\n AppSession,\n AppUser,\n} from './types.js';\n\nexport const APP_AUTH_PATHS = {\n register: '/api/app-auth/register',\n login: '/api/app-auth/login',\n refresh: '/api/app-auth/refresh',\n logout: '/api/app-auth/logout',\n me: '/api/app-auth/me',\n password: '/api/app-auth/me/password',\n confirmEmail: '/api/app-auth/confirm-email',\n resendConfirmation: '/api/app-auth/confirm-email/resend',\n passwordReset: '/api/app-auth/password-reset',\n passwordResetConfirm: '/api/app-auth/password-reset/confirm',\n providers: '/api/app-auth/providers',\n oauthExchange: '/api/app-auth/oauth/exchange',\n} as const;\n\n/**\n * App-user endpoints. Calls that act as the signed-in user need a client created with `token: accessToken`.\n * `baseUrl` is the client's base URL, used to build the OAuth start link the browser navigates to.\n */\nexport const createAppAuthApi = (request: RequestFn, baseUrl: string) => ({\n register: (body: AppRegisterInput) =>\n request<AppRegisterResult>(APP_AUTH_PATHS.register, { method: 'POST', body }),\n login: (body: AppLoginInput) => request<AppSession>(APP_AUTH_PATHS.login, { method: 'POST', body }),\n refresh: (refreshToken: string) =>\n request<AppSession>(APP_AUTH_PATHS.refresh, { method: 'POST', body: { refreshToken } }),\n /**\n * Signs the account out everywhere: this login's refresh tokens are revoked, and every access token the\n * account holds (on any device) is refused from the next request. Other logins recover with their own\n * refresh token.\n */\n logout: (refreshToken: string) =>\n request<void>(APP_AUTH_PATHS.logout, { method: 'POST', body: { refreshToken } }),\n /** The signed-in user. Answers 401 once the account logged out anywhere, changed its password or was blocked. */\n me: () => request<AppUser>(APP_AUTH_PATHS.me),\n updateMe: (body: { name: string }) => request<AppUser>(APP_AUTH_PATHS.me, { method: 'PATCH', body }),\n /** Returns a new session; every other sign-in of the account is revoked. */\n changePassword: (body: AppChangePasswordInput) =>\n request<AppSession>(APP_AUTH_PATHS.password, { method: 'POST', body }),\n deleteMe: (body: { password?: string } = {}) =>\n request<void>(APP_AUTH_PATHS.me, { method: 'DELETE', body }),\n /** The token from the `#token=` fragment of the confirmation link. */\n confirmEmail: (token: string) =>\n request<void>(APP_AUTH_PATHS.confirmEmail, { method: 'POST', body: { token } }),\n resendConfirmation: (email: string) =>\n request<void>(APP_AUTH_PATHS.resendConfirmation, { method: 'POST', body: { email } }),\n requestPasswordReset: (email: string) =>\n request<void>(APP_AUTH_PATHS.passwordReset, { method: 'POST', body: { email } }),\n confirmPasswordReset: (body: { token: string; password: string }) =>\n request<void>(APP_AUTH_PATHS.passwordResetConfirm, { method: 'POST', body }),\n providers: async () =>\n (await request<{ providers: AppOAuthProvider[] }>(APP_AUTH_PATHS.providers)).providers,\n /**\n * Where to send the browser to sign in with a provider. `codeChallenge` comes from `createPkcePair()`;\n * keep its `codeVerifier` until the browser returns. It comes back to `redirectTo` (an allowed return URL,\n * by default an origin listed in CORS_ORIGINS) with `?code=` (pass it to `exchangeCode`) or `?error=`.\n */\n oauthStartUrl: (provider: AppOAuthProvider, redirectTo: string, codeChallenge: string) =>\n `${baseUrl.replace(/\\/+$/, '')}/api/app-auth/oauth/${provider}/start?redirectTo=${encodeURIComponent(redirectTo)}&codeChallenge=${encodeURIComponent(codeChallenge)}`,\n /** Trades the one-time code for a session. A wrong verifier spends the code: start the sign-in again. */\n exchangeCode: (code: string, codeVerifier: string) =>\n request<AppSession>(APP_AUTH_PATHS.oauthExchange, { method: 'POST', body: { code, codeVerifier } }),\n});\n\nexport type AppAuthApi = ReturnType<typeof createAppAuthApi>;\n","import { toContentQueryString } from './admin/contentQuery.js';\nimport type { DeliveryGetQuery, DeliveryItem, DeliveryList, DeliveryListQuery } from './deliveryTypes.js';\nimport type { RequestFn } from './request.js';\n\nexport const DELIVERY_PATH = '/api/content';\n\nconst routePath = (routeKey: string) => `${DELIVERY_PATH}/${encodeURIComponent(routeKey)}`;\n\n/** The content query string plus `snapshot`, `richText` and `seo`, which only delivery reads take. */\nconst deliveryQueryString = ({ snapshot, richText, seo, ...query }: DeliveryListQuery): string => {\n const extra = [\n ...(snapshot === undefined ? [] : [`snapshot=${encodeURIComponent(String(snapshot))}`]),\n ...(richText === undefined ? [] : [`richText=${encodeURIComponent(richText)}`]),\n ...(seo === undefined ? [] : [`seo=${encodeURIComponent(seo)}`]),\n ];\n const base = toContentQueryString(query);\n if (extra.length === 0) {\n return base;\n }\n return base ? `${base}&${extra.join('&')}` : `?${extra.join('&')}`;\n};\n\n/**\n * Published content, typed by the caller (`delivery.list<Article>('articles', { locale: 'fr', snapshot })`).\n * A collection is read with `list` (a page) and `get` (one entry); a singleton with `singleton`.\n */\nexport const createDeliveryApi = (request: RequestFn) => ({\n list: <T = Record<string, unknown>>(routeKey: string, query: DeliveryListQuery = {}) =>\n request<DeliveryList<T>>(`${routePath(routeKey)}${deliveryQueryString(query)}`),\n singleton: <T = Record<string, unknown>>(apiKey: string, query: DeliveryGetQuery = {}) =>\n request<DeliveryItem<T>>(`${routePath(apiKey)}${deliveryQueryString(query)}`),\n get: <T = Record<string, unknown>>(routeKey: string, id: string, query: DeliveryGetQuery = {}) =>\n request<DeliveryItem<T>>(`${routePath(routeKey)}/${encodeURIComponent(id)}${deliveryQueryString(query)}`),\n});\n\nexport type DeliveryApi = ReturnType<typeof createDeliveryApi>;\n","import type { RequestFn } from './request.js';\nimport type { DeliverySite } from './seoTypes.js';\n\nexport const DELIVERY_SITE_PATH = '/api/site';\n\n/** The request's site as delivery sees it (key, name, SEO defaults), with the client's token and site. */\nexport const createSiteApi = (request: RequestFn) => ({\n get: () => request<DeliverySite>(DELIVERY_SITE_PATH),\n});\n\nexport type SiteApi = ReturnType<typeof createSiteApi>;\n","import { toQueryString } from './admin/query.js';\nimport type { RequestFn } from './request.js';\nimport type {\n CurrentSnapshot,\n SnapshotChange,\n SnapshotChangesPage,\n SnapshotChangesQuery,\n} from './snapshotTypes.js';\n\nexport const SNAPSHOT_PATHS = {\n current: '/api/snapshots/current',\n changes: '/api/snapshots/changes',\n} as const;\n\n/** Snapshots and the diff between two of them, for incremental site builds (delivery credentials). */\nexport const createSnapshotsApi = (request: RequestFn) => {\n const changes = (query: SnapshotChangesQuery) =>\n request<SnapshotChangesPage>(`${SNAPSHOT_PATHS.changes}${toQueryString(query)}`);\n return {\n current: () => request<CurrentSnapshot>(SNAPSHOT_PATHS.current),\n changes,\n /** Every change between `from` and `to`, following `nextCursor` until the last page. */\n allChanges: async (query: Omit<SnapshotChangesQuery, 'after'>) => {\n const items: SnapshotChange[] = [];\n let page = await changes(query);\n items.push(...page.items);\n while (page.nextCursor !== null) {\n page = await changes({ ...query, to: page.to, after: page.nextCursor });\n items.push(...page.items);\n }\n return { from: page.from, to: page.to, schemaVersions: page.schemaVersions, items };\n },\n };\n};\n","import { SITE_HEADER } from './admin/sites.js';\nimport { DELIVERY_PATH } from './delivery.js';\nimport { DELIVERY_SITE_PATH } from './siteDelivery.js';\nimport { SNAPSHOT_PATHS } from './snapshots.js';\n\n/** Delivery reads name their site with `?site=`; everything else with the `Shapio-Site` header. */\nexport const SITE_QUERY_PARAMETER = 'site';\n\n/** Delivery reads (content, snapshots, the site): a GET there carries the site in its URL. */\nconst DELIVERY_READ_PREFIXES = [\n `${DELIVERY_PATH}/`,\n `${DELIVERY_PATH}?`,\n '/api/snapshots/',\n `${DELIVERY_SITE_PATH}?`,\n] as const;\n\nconst isDeliveryRead = (method: string, path: string) =>\n method === 'GET' &&\n (path === DELIVERY_PATH ||\n path === DELIVERY_SITE_PATH ||\n Object.values(SNAPSHOT_PATHS).some((snapshotPath) => path === snapshotPath) ||\n DELIVERY_READ_PREFIXES.some((prefix) => path.startsWith(prefix)));\n\nconst namesSite = (path: string) => {\n const index = path.indexOf('?');\n return index !== -1 && new URLSearchParams(path.slice(index + 1)).has(SITE_QUERY_PARAMETER);\n};\n\n/**\n * Where a request names the client's site (sites plan §H). Delivery GETs put it in the query string: a\n * simple cross-origin GET needs no CORS preflight, and URL-keyed CDN caches keep sites apart. Every other\n * request sends the `Shapio-Site` header. A path that already names a site is left as it is.\n */\nexport const applySite = (\n site: string | undefined,\n method: string,\n path: string,\n): { path: string; headers: Record<string, string> } => {\n if (site === undefined || namesSite(path)) {\n return { path, headers: {} };\n }\n if (isDeliveryRead(method, path)) {\n const parameter = `${SITE_QUERY_PARAMETER}=${encodeURIComponent(site)}`;\n return { path: `${path}${path.includes('?') ? '&' : '?'}${parameter}`, headers: {} };\n }\n return { path, headers: { [SITE_HEADER]: site } };\n};\n","import { ShapioApiError } from './errors.js';\nimport { applySite } from './site.js';\n\n/** Fetch's `credentials` mode (spelled out: the DOM lib type is not available to Node consumers). */\nexport type FetchCredentials = 'omit' | 'same-origin' | 'include';\n\nexport type RequestOptions = { method?: string; body?: unknown; signal?: AbortSignal };\n\nexport type RequestFn = <T>(path: string, options?: RequestOptions) => Promise<T>;\n\nexport type RequestConfig = {\n baseUrl: string;\n token: string | undefined;\n fetch: typeof globalThis.fetch;\n credentials: FetchCredentials | undefined;\n headers: (() => Readonly<Record<string, string>>) | undefined;\n /** The site key every request names (see site.ts); undefined: the credential's site, else the primary. */\n site: string | undefined;\n};\n\nconst parseBody = async (response: Response): Promise<unknown> => {\n const text = await response.text();\n if (text.length === 0) {\n return undefined;\n }\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n};\n\n/** Builds the JSON request function every endpoint group uses. Non-2xx responses throw ShapioApiError. */\nexport const createRequest = ({\n baseUrl,\n token,\n fetch,\n credentials,\n headers,\n site,\n}: RequestConfig): RequestFn => {\n const origin = baseUrl.replace(/\\/+$/, '');\n return async <T>(\n requestPath: string,\n { method = 'GET', body, signal }: RequestOptions = {},\n ): Promise<T> => {\n const { path, headers: siteHeaders } = applySite(site, method, requestPath);\n const requestHeaders: Record<string, string> = {\n accept: 'application/json',\n ...siteHeaders,\n ...headers?.(),\n };\n if (token) {\n requestHeaders.authorization = `Bearer ${token}`;\n }\n if (body !== undefined) {\n requestHeaders['content-type'] = 'application/json';\n }\n const response = await fetch(`${origin}${path}`, {\n method,\n headers: requestHeaders,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n ...(signal ? { signal } : {}),\n ...(credentials ? { credentials } : {}),\n });\n const parsed = await parseBody(response);\n if (!response.ok) {\n throw new ShapioApiError(response.status, parsed);\n }\n return parsed as T;\n };\n};\n","import { createAdminApi } from './admin/index.js';\nimport { createAppAuthApi } from './appAuth/index.js';\nimport { createDeliveryApi } from './delivery.js';\nimport { createRequest, type FetchCredentials } from './request.js';\nimport { createSiteApi } from './siteDelivery.js';\nimport { createSnapshotsApi } from './snapshots.js';\nimport type { HealthResponse, ReadyResponse, VersionResponse } from './types.js';\n\nexport type ShapioClientOptions = {\n /** Base URL of the Shapio server including any BASE_PATH, e.g. `https://cms.example.com/cms`. */\n baseUrl: string;\n /** API token sent as a bearer token. */\n token?: string;\n /** Defaults to the global fetch; injectable for tests and custom agents. */\n fetch?: typeof globalThis.fetch;\n /** Fetch credentials mode. The admin uses `same-origin` so its session cookie is sent. */\n credentials?: FetchCredentials;\n /** Extra headers computed per request (the admin's CSRF token). */\n headers?: () => Readonly<Record<string, string>>;\n /**\n * The site key (multi-site instances). Delivery reads send it as `?site=`, every other request as the\n * `Shapio-Site` header. Leave it out to use the token's site, else the primary site. A site token only\n * ever reads its own site: naming another one is refused (403 `SITE_MISMATCH`).\n */\n site?: string;\n};\n\nexport const createClient = ({\n baseUrl,\n token,\n fetch = globalThis.fetch,\n credentials,\n headers,\n site,\n}: ShapioClientOptions) => {\n const request = createRequest({ baseUrl, token, fetch, credentials, headers, site });\n\n return {\n /**\n * Any Shapio route, e.g. the delivery API. Delivery paths use the model's route key: a collection's\n * plural API ID (`request('/api/content/articles')`, `/api/content/articles/<id>`), a singleton's API ID\n * (`/api/content/homepage`). The admin API (`admin.*`) always uses the singular API ID.\n */\n request,\n system: {\n health: (signal?: AbortSignal) => request<HealthResponse>('/api/health', signal ? { signal } : {}),\n ready: (signal?: AbortSignal) => request<ReadyResponse>('/api/ready', signal ? { signal } : {}),\n version: (signal?: AbortSignal) => request<VersionResponse>('/api/version', signal ? { signal } : {}),\n },\n /** Published content (the delivery API), typed by the caller. */\n delivery: createDeliveryApi(request),\n /** The site as delivery sees it: key, name and SEO defaults (`GET /api/site`). */\n site: createSiteApi(request),\n admin: createAdminApi(request),\n /** Publication snapshots and the diff between two (incremental builds). */\n snapshots: createSnapshotsApi(request),\n /** End users of your sites and apps: sign-up, sign-in, tokens, OAuth. */\n appAuth: createAppAuthApi(request, baseUrl),\n };\n};\n\nexport type ShapioClient = ReturnType<typeof createClient>;\n","/**\n * Verifying Shapio's signed webhooks and deploy triggers on the receiving side (a site's revalidate route,\n * a build hook). The scheme is the server's (`apps/api/src/publishing/signature.ts`):\n * `X-Shapio-Signature: v1=<hex HMAC-SHA256(secret, \"<timestamp>.<raw body>\")>` with\n * `X-Shapio-Timestamp: <unix seconds>`; several comma-separated `v1=` values are accepted (secret rotation).\n * Uses Web Crypto, so it runs in Node, edge runtimes and browsers alike.\n */\nexport const WEBHOOK_SIGNATURE_HEADER = 'x-shapio-signature';\nexport const WEBHOOK_TIMESTAMP_HEADER = 'x-shapio-timestamp';\nexport const WEBHOOK_EVENT_HEADER = 'x-shapio-event';\n/** Requests signed further from now than this are rejected (replay protection). */\nexport const WEBHOOK_TOLERANCE_SECONDS = 300;\n\nconst SIGNATURE_VERSION = 'v1';\n\nexport type WebhookSignatureInput = {\n /** The webhook's or connection's signing secret. */\n secret: string;\n /** The `X-Shapio-Signature` header. */\n signature: string | null | undefined;\n /** The `X-Shapio-Timestamp` header. */\n timestamp: string | null | undefined;\n /** The raw request body, exactly as received (not re-serialised JSON). */\n body: string;\n /** Defaults to the current time. */\n now?: Date;\n /** Defaults to WEBHOOK_TOLERANCE_SECONDS. */\n toleranceSeconds?: number;\n};\n\nexport type WebhookSignatureCheck = { ok: true } | { ok: false; reason: string };\n\nconst toHex = (bytes: ArrayBuffer) =>\n Array.from(new Uint8Array(bytes), (byte) => byte.toString(16).padStart(2, '0')).join('');\n\n/** Compares two strings without returning early on the first difference. */\nconst constantTimeEqual = (a: string, b: string) => {\n let difference = a.length ^ b.length;\n for (let index = 0; index < Math.max(a.length, b.length); index += 1) {\n difference |= (a.charCodeAt(index) || 0) ^ (b.charCodeAt(index) || 0);\n }\n return difference === 0;\n};\n\nconst expectedSignature = async (secret: string, timestamp: number, body: string) => {\n const encoder = new TextEncoder();\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const mac = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(`${timestamp}.${body}`));\n return `${SIGNATURE_VERSION}=${toHex(mac)}`;\n};\n\n/** Checks a Shapio signature; `{ ok: false, reason }` says why it was refused (never throws for bad input). */\nexport const verifyWebhookSignature = async ({\n secret,\n signature,\n timestamp,\n body,\n now = new Date(),\n toleranceSeconds = WEBHOOK_TOLERANCE_SECONDS,\n}: WebhookSignatureInput): Promise<WebhookSignatureCheck> => {\n if (!signature || !timestamp || !/^\\d{1,12}$/.test(timestamp)) {\n return { ok: false, reason: 'missing signature or timestamp' };\n }\n const seconds = Number(timestamp);\n if (Math.abs(now.getTime() / 1000 - seconds) > toleranceSeconds) {\n return { ok: false, reason: 'timestamp outside the allowed window' };\n }\n const expected = await expectedSignature(secret, seconds, body);\n const matches = signature\n .split(',')\n .map((candidate) => candidate.trim())\n .some((candidate) => constantTimeEqual(candidate, expected));\n return matches ? { ok: true } : { ok: false, reason: 'signature mismatch' };\n};\n","/**\n * PKCE (RFC 7636) for the app side of Shapio's OAuth sign-in: the app keeps the verifier (e.g. in\n * sessionStorage) and sends the S256 challenge with the start link; the one-time code it gets back is only\n * exchanged together with that verifier. Uses Web Crypto, so it works in browsers and Node alike.\n */\nexport type AppPkcePair = { codeVerifier: string; codeChallenge: string };\n\nconst toBase64Url = (bytes: Uint8Array): string =>\n btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n\n/** The S256 challenge of a verifier: base64url(SHA-256(verifier)). */\nexport const codeChallengeOf = async (codeVerifier: string): Promise<string> =>\n toBase64Url(\n new Uint8Array(await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier))),\n );\n\n/** A fresh verifier (32 random bytes, 43 characters) and its S256 challenge. */\nexport const createPkcePair = async (): Promise<AppPkcePair> => {\n const codeVerifier = toBase64Url(globalThis.crypto.getRandomValues(new Uint8Array(32)));\n return { codeVerifier, codeChallenge: await codeChallengeOf(codeVerifier) };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["entryPath"],"sources":["../src/admin/appUsers.ts","../src/admin/assist.ts","../src/admin/changeSets.ts","../src/admin/contentQuery.ts","../src/admin/content.ts","../src/admin/editing.ts","../src/admin/publishing.ts","../src/admin/schema.ts","../src/admin/sites.ts","../src/admin/usage.ts","../src/admin/types.ts","../src/admin/publishingTypes.ts","../src/admin/appUsersTypes.ts","../src/admin/changeSetTypes.ts","../src/admin/editingTypes.ts","../src/admin/assistTypes.ts","../src/admin/index.ts","../src/appAuth/index.ts","../src/nextCache.ts","../src/delivery.ts","../src/siteDelivery.ts","../src/snapshots.ts","../src/deliveryClient.ts","../src/site.ts","../src/request.ts","../src/client.ts","../src/webhooks.ts","../src/appAuth/pkce.ts"],"sourcesContent":["import type { RequestFn } from '../request.js';\nimport type {\n AdminAppUser,\n AppRole,\n AppUserPage,\n AppUserQuery,\n CreateAppRoleInput,\n UpdateAppRoleInput,\n UpdateAppUserInput,\n} from './appUsersTypes.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { toQueryString } from './query.js';\n\n/** App users (Users → App users) and app roles (Settings → Roles → App roles). */\nexport const createAppUsersApi = (request: RequestFn) => ({\n appUsers: {\n list: (query: AppUserQuery = {}) =>\n request<AppUserPage>(`${ADMIN_PATHS.appUsers}${toQueryString(query)}`),\n get: (id: string) => request<AdminAppUser>(withId(ADMIN_PATHS.appUsers, id)),\n /** Block/unblock and replace custom roles. Blocking takes effect on the user's next request. */\n update: (id: string, body: UpdateAppUserInput) =>\n request<AdminAppUser>(withId(ADMIN_PATHS.appUsers, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.appUsers, id), { method: 'DELETE' }),\n /** 409 NOT_CONFIGURED without APP_AUTH_CONFIRM_EMAIL_URL; 409 ALREADY_CONFIRMED. */\n resendConfirmation: (id: string) =>\n request<void>(`${withId(ADMIN_PATHS.appUsers, id)}/resend-confirmation`, { method: 'POST' }),\n },\n appRoles: {\n list: () => request<AppRole[]>(ADMIN_PATHS.appRoles),\n get: (id: string) => request<AppRole>(withId(ADMIN_PATHS.appRoles, id)),\n create: (body: CreateAppRoleInput) => request<AppRole>(ADMIN_PATHS.appRoles, { method: 'POST', body }),\n /** 409 VERSION_CONFLICT when `expectedVersion` is stale. */\n update: (id: string, body: UpdateAppRoleInput) =>\n request<AppRole>(withId(ADMIN_PATHS.appRoles, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.appRoles, id), { method: 'DELETE' }),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport type {\n AltTextInput,\n AltTextResult,\n AssistStatus,\n AssistTextResult,\n ContentOpsInput,\n ContentOpsRun,\n RewriteInput,\n SchemaDraftInput,\n SchemaDraftResult,\n SummarizeInput,\n TranslateInput,\n TranslateResult,\n} from './assistTypes.js';\nimport { withId } from './paths.js';\n\nexport const ASSIST_PATHS = {\n status: '/api/admin/assist/status',\n altText: '/api/admin/assist/alt-text',\n summarize: '/api/admin/assist/summarize',\n translate: '/api/admin/assist/translate',\n rewrite: '/api/admin/assist/rewrite',\n schemaDraft: '/api/admin/assist/schema/draft',\n contentOpsPropose: '/api/admin/assist/content-ops/propose',\n contentOps: '/api/admin/assist/content-ops',\n} as const;\n\n/** Editor assists with the instance's own model provider (documentation/assist.md). */\nexport const createAssistApi = (request: RequestFn) => ({\n assist: {\n status: () => request<AssistStatus>(ASSIST_PATHS.status),\n altText: (body: AltTextInput) => request<AltTextResult>(ASSIST_PATHS.altText, { method: 'POST', body }),\n summarize: (body: SummarizeInput) =>\n request<AssistTextResult>(ASSIST_PATHS.summarize, { method: 'POST', body }),\n translate: (body: TranslateInput) =>\n request<TranslateResult>(ASSIST_PATHS.translate, { method: 'POST', body }),\n rewrite: (body: RewriteInput) =>\n request<AssistTextResult>(ASSIST_PATHS.rewrite, { method: 'POST', body }),\n schemaDraft: (body: SchemaDraftInput) =>\n request<SchemaDraftResult>(ASSIST_PATHS.schemaDraft, { method: 'POST', body }),\n /** Starts a background run (202); poll it with `contentOpsRun`. */\n proposeContentOps: (body: ContentOpsInput) =>\n request<{ runId: string }>(ASSIST_PATHS.contentOpsPropose, { method: 'POST', body }),\n contentOpsRun: (runId: string) => request<ContentOpsRun>(withId(ASSIST_PATHS.contentOps, runId)),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport type {\n AddChangeSetEntryInput,\n ChangeSet,\n ChangeSetQuery,\n ChangeSetReview,\n ChangeSetSummary,\n ChangeSetTimelineEvent,\n CreateChangeSetInput,\n PutSchemaDraftInput,\n ScheduleChangeSetInput,\n SchemaDraft,\n ShipChangeSetInput,\n Snapshot,\n SnapshotPage,\n SnapshotQuery,\n UnassignedEntry,\n UpdateChangeSetInput,\n} from './changeSetTypes.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport type { Page } from './publishingTypes.js';\nimport { toQueryString } from './query.js';\n\nconst setPath = (id: string) => withId(ADMIN_PATHS.changeSets, id);\nconst draftPath = (id: string, definitionId: string) =>\n `${setPath(id)}/schema/${encodeURIComponent(definitionId)}`;\n\n/** Change sets (schema + content shipped as one snapshot) and the snapshot ledger. */\nexport const createChangeSetsApi = (request: RequestFn) => ({\n changeSets: {\n list: (query: ChangeSetQuery = {}) =>\n request<Page<ChangeSetSummary>>(`${ADMIN_PATHS.changeSets}${toQueryString(query)}`),\n get: (id: string) => request<ChangeSet>(setPath(id)),\n create: (body: CreateChangeSetInput) =>\n request<ChangeSet>(ADMIN_PATHS.changeSets, { method: 'POST', body }),\n update: (id: string, body: UpdateChangeSetInput) =>\n request<ChangeSet>(setPath(id), { method: 'PATCH', body }),\n /** Keeps the set as history (`discarded`) and deletes its schema drafts. */\n discard: (id: string) => request<ChangeSet>(`${setPath(id)}/discard`, { method: 'POST' }),\n addEntry: (id: string, body: AddChangeSetEntryInput) =>\n request<ChangeSet>(`${setPath(id)}/items`, { method: 'POST', body }),\n removeItem: (id: string, itemId: string) =>\n request<ChangeSet>(`${setPath(id)}/items/${encodeURIComponent(itemId)}`, { method: 'DELETE' }),\n getSchemaDraft: (id: string, definitionId: string) => request<SchemaDraft>(draftPath(id, definitionId)),\n putSchemaDraft: (id: string, definitionId: string, body: PutSchemaDraftInput) =>\n request<SchemaDraft>(draftPath(id, definitionId), { method: 'PUT', body }),\n removeSchemaDraft: (id: string, definitionId: string) =>\n request<ChangeSet>(draftPath(id, definitionId), { method: 'DELETE' }),\n review: (id: string) => request<ChangeSetReview>(`${setPath(id)}/review`),\n /**\n * Resolves with the set: `shipped` (or `failed`) when it shipped inline, `shipping` (HTTP 202) when\n * prerequisites run in the background. Poll `get` until it leaves `shipping`.\n */\n ship: (id: string, body: ShipChangeSetInput) =>\n request<ChangeSet>(`${setPath(id)}/ship`, { method: 'POST', body }),\n schedule: (id: string, body: ScheduleChangeSetInput) =>\n request<ChangeSet>(`${setPath(id)}/schedule`, { method: 'POST', body }),\n unschedule: (id: string) => request<ChangeSet>(`${setPath(id)}/unschedule`, { method: 'POST' }),\n timeline: async (id: string) =>\n (await request<{ items: ChangeSetTimelineEvent[] }>(`${setPath(id)}/timeline`)).items,\n unassigned: (query: { cursor?: string; limit?: number } = {}) =>\n request<Page<UnassignedEntry>>(`${ADMIN_PATHS.changeSets}/unassigned${toQueryString(query)}`),\n },\n snapshots: {\n list: (query: SnapshotQuery = {}) =>\n request<SnapshotPage>(`${ADMIN_PATHS.snapshots}${toQueryString(query)}`),\n get: (seq: number) => request<Snapshot>(`${ADMIN_PATHS.snapshots}/${seq}`),\n /** Creates an open restore change set (reviewable); nothing goes live until it ships. */\n restore: (seq: number) =>\n request<ChangeSet>(`${ADMIN_PATHS.snapshots}/${seq}/restore`, { method: 'POST' }),\n },\n});\n","import type { ContentFilter, ContentListQuery } from './contentTypes.js';\n\n/**\n * Serialises a content list query into the bracket querystring the content compiler parses\n * (`filters[title][$eq]=A&sort=title:asc&page=2`). Lists repeat the key (`filters[id][$in]=a&filters[id][$in]=b`).\n */\nconst appendFilter = (params: URLSearchParams, prefix: string, value: unknown) => {\n if (value === undefined || value === null) {\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((item: unknown, index) => {\n if (typeof item === 'object' && item !== null) {\n appendFilter(params, `${prefix}[${index}]`, item);\n } else {\n params.append(prefix, String(item));\n }\n });\n return;\n }\n if (typeof value === 'object') {\n for (const [key, child] of Object.entries(value as ContentFilter)) {\n appendFilter(params, `${prefix}[${key}]`, child);\n }\n return;\n }\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n params.append(prefix, String(value));\n }\n};\n\nexport const toContentQueryString = (query: ContentListQuery = {}): string => {\n const params = new URLSearchParams();\n if (query.filters) {\n appendFilter(params, 'filters', query.filters);\n }\n for (const term of query.sort ?? []) {\n params.append('sort', `${term.field}:${term.direction}`);\n }\n if (query.page !== undefined) {\n params.set('page', String(query.page));\n }\n if (query.pageSize !== undefined) {\n params.set('pageSize', String(query.pageSize));\n }\n if (query.q) {\n params.set('q', query.q);\n }\n if (query.locale) {\n params.set('locale', query.locale);\n }\n for (const field of query.fields ?? []) {\n params.append('fields', field);\n }\n for (const path of query.populate ?? []) {\n params.append('populate', path);\n }\n if (query.status) {\n params.set('status', query.status);\n }\n if (query.author) {\n params.set('author', query.author);\n }\n const serialised = params.toString();\n return serialised ? `?${serialised}` : '';\n};\n","import type { RequestFn } from '../request.js';\nimport { toContentQueryString } from './contentQuery.js';\nimport type {\n AdminEntry,\n AdminEntryPage,\n ContentListQuery,\n CreateEntryInput,\n EditorManifest,\n EntryLocalesInput,\n ExtensionThemeList,\n RevisionDetail,\n RevisionSummary,\n UpdateEntryInput,\n} from './contentTypes.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { toQueryString } from './query.js';\n\nconst modelPath = (modelKey: string) => withId(ADMIN_PATHS.content, modelKey);\nconst entryPath = (modelKey: string, id: string) => withId(modelPath(modelKey), id);\nconst revisionsPath = (modelKey: string, id: string) => `${entryPath(modelKey, id)}/revisions`;\n\n/**\n * Content of any model through the generic admin routes (`/api/admin/content/:modelKey`, where `modelKey`\n * is the model's singular API ID for collections too; only the delivery API uses the plural). Drafts are read\n * and written here; publishing is per locale. Writes carry the draft `version` the editor saw and fail with\n * 409 CONTENT_VERSION_CONFLICT (or SCHEMA_CHANGED) when it moved.\n */\nexport const createContentApi = (request: RequestFn) => ({\n content: {\n list: (modelKey: string, query: ContentListQuery = {}) =>\n request<AdminEntryPage>(`${modelPath(modelKey)}${toContentQueryString(query)}`),\n get: (modelKey: string, id: string, { locale }: { locale?: string } = {}) =>\n request<AdminEntry>(`${entryPath(modelKey, id)}${toQueryString({ locale })}`),\n /** Fully validated (`required` included); 422 CONTENT_INVALID with `details.issues`. */\n create: (modelKey: string, body: CreateEntryInput) =>\n request<AdminEntry>(modelPath(modelKey), { method: 'POST', body }),\n /** Saves a patch of one locale's draft; `autosave` skips `required` and creates no revision. */\n update: (modelKey: string, id: string, body: UpdateEntryInput) =>\n request<AdminEntry>(entryPath(modelKey, id), { method: 'PUT', body }),\n /** 409 ENTRY_REFERENCED with `details.referrers` while other entries point at it. */\n remove: (modelKey: string, id: string) => request<void>(entryPath(modelKey, id), { method: 'DELETE' }),\n duplicate: (modelKey: string, id: string) =>\n request<AdminEntry>(`${entryPath(modelKey, id)}/duplicate`, { method: 'POST' }),\n publish: (modelKey: string, id: string, body: EntryLocalesInput = {}) =>\n request<AdminEntry>(`${entryPath(modelKey, id)}/publish`, { method: 'POST', body }),\n unpublish: (modelKey: string, id: string, body: EntryLocalesInput = {}) =>\n request<AdminEntry>(`${entryPath(modelKey, id)}/unpublish`, { method: 'POST', body }),\n revisions: async (modelKey: string, id: string, { locale }: { locale?: string } = {}) =>\n (\n await request<{ items: RevisionSummary[] }>(\n `${revisionsPath(modelKey, id)}${toQueryString({ locale })}`,\n )\n ).items,\n revision: (modelKey: string, id: string, revisionId: string) =>\n request<RevisionDetail>(withId(revisionsPath(modelKey, id), revisionId)),\n /** Brings an older revision back as the new draft of its locale (a new revision). */\n restore: (modelKey: string, id: string, revisionId: string, expectedVersion: number) =>\n request<AdminEntry>(`${withId(revisionsPath(modelKey, id), revisionId)}/restore`, {\n method: 'POST',\n body: { expectedVersion },\n }),\n },\n extensions: {\n /** Custom field editors the project installed (`shapio.config` + `extensions/editors/*.js`). */\n editors: () => request<EditorManifest>(ADMIN_PATHS.editorManifest),\n /** Admin colour themes the project declares (`shapio.config` `themes`). Public: no session needed. */\n themes: () => request<ExtensionThemeList>(ADMIN_PATHS.extensionThemes),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport type {\n ContentCounts,\n ContentHealthPage,\n ContentHealthQuery,\n ContentHealthSummary,\n EntryPresence,\n ModelPresence,\n PresenceHeartbeatInput,\n PreflightInput,\n PreflightResponse,\n} from './editingTypes.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { toQueryString } from './query.js';\n\nconst entryPath = (base: string, modelKey: string, id: string) => withId(withId(base, modelKey), id);\n\n/** The entry document's endpoints: pre-flight, content health (the Inbox), presence and counts. */\nexport const createEditingApi = (request: RequestFn) => ({\n preflight: {\n /** What publishing these locales would run into, without publishing (no hooks, no locks). */\n run: (modelKey: string, id: string, body: PreflightInput = {}) =>\n request<PreflightResponse>(`${entryPath(ADMIN_PATHS.content, modelKey, id)}/preflight`, {\n method: 'POST',\n body,\n }),\n },\n contentHealth: {\n list: (query: ContentHealthQuery = {}) =>\n request<ContentHealthPage>(`${ADMIN_PATHS.contentHealth}${toQueryString(query)}`),\n summary: () => request<ContentHealthSummary>(`${ADMIN_PATHS.contentHealth}/summary`),\n },\n presence: {\n /** Heartbeat (every 15s while the document is visible); returns who else has the entry open. */\n heartbeat: (modelKey: string, id: string, body: PresenceHeartbeatInput) =>\n request<EntryPresence>(entryPath(ADMIN_PATHS.presence, modelKey, id), { method: 'PUT', body }),\n entry: (modelKey: string, id: string) =>\n request<EntryPresence>(entryPath(ADMIN_PATHS.presence, modelKey, id)),\n /** Everyone editing an entry of the model (list rows). */\n model: (modelKey: string) => request<ModelPresence>(withId(ADMIN_PATHS.presence, modelKey)),\n leave: (modelKey: string, id: string, tabId: string) =>\n request<void>(`${entryPath(ADMIN_PATHS.presence, modelKey, id)}${toQueryString({ tabId })}`, {\n method: 'DELETE',\n }),\n },\n contentCounts: {\n list: () => request<ContentCounts>(ADMIN_PATHS.contentCounts),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport type {\n ConnectionTestResult,\n CreateDeploymentConnectionInput,\n CreatePreviewTokenInput,\n CreateScheduleInput,\n CreateWebhookInput,\n DeploymentConnection,\n DeploymentConnectionCreated,\n DeploymentRun,\n DeploymentRunQuery,\n Job,\n JobQuery,\n JobSummary,\n OpenPreviewInput,\n OpenPreviewResult,\n PreviewTarget,\n Page,\n PreviewToken,\n PreviewTokenCreated,\n ScheduledPublication,\n ScheduleQuery,\n UpdateDeploymentConnectionInput,\n UpdateWebhookInput,\n Webhook,\n WebhookDelivery,\n WebhookEventType,\n WebhookWithSecret,\n} from './publishingTypes.js';\nimport { toQueryString } from './query.js';\n\n/** Jobs, scheduled publications, webhooks, deployment connections and runs, preview (package H). */\nexport const createPublishingApi = (request: RequestFn) => ({\n jobs: {\n list: (query: JobQuery = {}) => request<Page<Job>>(`${ADMIN_PATHS.jobs}${toQueryString(query)}`),\n summary: () => request<JobSummary>(`${ADMIN_PATHS.jobs}/summary`),\n get: (id: string) => request<Job>(withId(ADMIN_PATHS.jobs, id)),\n /** Dead jobs only: runs again from attempt 1. 409 JOB_NOT_RETRYABLE otherwise. */\n retry: (id: string) => request<Job>(`${withId(ADMIN_PATHS.jobs, id)}/retry`, { method: 'POST' }),\n },\n schedules: {\n list: (query: ScheduleQuery = {}) =>\n request<Page<ScheduledPublication>>(`${ADMIN_PATHS.schedules}${toQueryString(query)}`),\n create: (body: CreateScheduleInput) =>\n request<ScheduledPublication>(ADMIN_PATHS.schedules, { method: 'POST', body }),\n cancel: (id: string) => request<void>(withId(ADMIN_PATHS.schedules, id), { method: 'DELETE' }),\n },\n webhooks: {\n list: () => request<Webhook[]>(ADMIN_PATHS.webhooks),\n events: async () =>\n (await request<{ items: WebhookEventType[] }>(`${ADMIN_PATHS.webhooks}/events`)).items,\n get: (id: string) => request<Webhook>(withId(ADMIN_PATHS.webhooks, id)),\n create: (body: CreateWebhookInput) =>\n request<WebhookWithSecret>(ADMIN_PATHS.webhooks, { method: 'POST', body }),\n update: (id: string, body: UpdateWebhookInput) =>\n request<Webhook>(withId(ADMIN_PATHS.webhooks, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.webhooks, id), { method: 'DELETE' }),\n rotateSecret: (id: string) =>\n request<WebhookWithSecret>(`${withId(ADMIN_PATHS.webhooks, id)}/rotate-secret`, { method: 'POST' }),\n /** Queues a `webhook.test` delivery; poll the delivery log for its outcome. */\n test: (id: string) =>\n request<WebhookDelivery>(`${withId(ADMIN_PATHS.webhooks, id)}/test`, { method: 'POST' }),\n deliveries: (id: string, query: { cursor?: string; limit?: number } = {}) =>\n request<Page<WebhookDelivery>>(`${withId(ADMIN_PATHS.webhooks, id)}/deliveries${toQueryString(query)}`),\n /** Sends the same payload again as a new delivery. */\n redeliver: (id: string, deliveryId: string) =>\n request<WebhookDelivery>(\n `${withId(ADMIN_PATHS.webhooks, id)}/deliveries/${encodeURIComponent(deliveryId)}/redeliver`,\n { method: 'POST' },\n ),\n },\n deployments: {\n connections: {\n list: () => request<DeploymentConnection[]>(ADMIN_PATHS.deploymentConnections),\n get: (id: string) => request<DeploymentConnection>(withId(ADMIN_PATHS.deploymentConnections, id)),\n create: (body: CreateDeploymentConnectionInput) =>\n request<DeploymentConnectionCreated>(ADMIN_PATHS.deploymentConnections, { method: 'POST', body }),\n update: (id: string, body: UpdateDeploymentConnectionInput) =>\n request<DeploymentConnection>(withId(ADMIN_PATHS.deploymentConnections, id), {\n method: 'PATCH',\n body,\n }),\n remove: (id: string) =>\n request<void>(withId(ADMIN_PATHS.deploymentConnections, id), { method: 'DELETE' }),\n test: (id: string) =>\n request<ConnectionTestResult>(`${withId(ADMIN_PATHS.deploymentConnections, id)}/test`, {\n method: 'POST',\n }),\n /** A manual run at the current publication snapshot. */\n trigger: (id: string) =>\n request<DeploymentRun>(`${withId(ADMIN_PATHS.deploymentConnections, id)}/runs`, { method: 'POST' }),\n },\n runs: {\n list: (query: DeploymentRunQuery = {}) =>\n request<Page<DeploymentRun>>(`${ADMIN_PATHS.deploymentRuns}${toQueryString(query)}`),\n get: (id: string) => request<DeploymentRun>(withId(ADMIN_PATHS.deploymentRuns, id)),\n /** A new run (linked by `retryOf`) at the current snapshot. */\n retry: (id: string) =>\n request<DeploymentRun>(`${withId(ADMIN_PATHS.deploymentRuns, id)}/retry`, { method: 'POST' }),\n },\n },\n preview: {\n tokens: {\n list: (query: { entryId?: string } = {}) =>\n request<PreviewToken[]>(`${ADMIN_PATHS.previewTokens}${toQueryString(query)}`),\n create: (body: CreatePreviewTokenInput) =>\n request<PreviewTokenCreated>(ADMIN_PATHS.previewTokens, { method: 'POST', body }),\n revoke: (id: string) => request<void>(withId(ADMIN_PATHS.previewTokens, id), { method: 'DELETE' }),\n },\n /** The site's connections with a preview URL (the entry form's Preview pane). */\n targets: () => request<PreviewTarget[]>(`${ADMIN_PATHS.preview}/targets`),\n /** The entry form's Preview action: a short-lived entry token and the rendered preview URL. */\n open: (body: OpenPreviewInput) =>\n request<OpenPreviewResult>(`${ADMIN_PATHS.preview}/open`, { method: 'POST', body }),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { toQueryString } from './query.js';\nimport type { SchemaApplyInput, SchemaApplyResult, SchemaExport } from './schemaSyncTypes.js';\nimport type {\n ChangeOutcome,\n ChangeScopeInput,\n ChangeScopeOutcome,\n CreateDefinitionInput,\n CreateLocaleInput,\n DefinitionCategory,\n DefinitionPayload,\n DefinitionDetail,\n DefinitionScope,\n DefinitionListItem,\n DefinitionRevision,\n DeleteLocaleResult,\n Locale,\n PlanPreview,\n PlanUpdateInput,\n SchemaChangeJob,\n SchemaSettings,\n SchemaSummary,\n SetDefaultLocaleResult,\n UpdateDefinitionInput,\n UpdateLocaleInput,\n UpdateSchemaSettingsInput,\n} from './schemaTypes.js';\n\nconst DEFINITION_PATHS = {\n model: ADMIN_PATHS.models,\n component: ADMIN_PATHS.components,\n} as const satisfies Record<DefinitionCategory, string>;\n\n/** Models (collections and singletons) and components share one set of endpoints under their own base. */\nexport const createDefinitionApi = (request: RequestFn, category: DefinitionCategory) => {\n const base = DEFINITION_PATHS[category];\n return {\n /** The site's view (shared definitions and its own); `{ scope: 'network' }` lists the shared ones. */\n list: async (options: { scope?: DefinitionScope } = {}) =>\n (await request<{ items: DefinitionListItem[] }>(`${base}${toQueryString(options)}`)).items,\n get: (id: string) => request<DefinitionDetail>(withId(base, id)),\n /** Creates and activates a definition (`pending` when prerequisites must run first). */\n create: (body: CreateDefinitionInput) => request<ChangeOutcome>(base, { method: 'POST', body }),\n /** Plan preview of a create: classification and impact, nothing written. */\n planCreate: (definition: DefinitionPayload, scope?: DefinitionScope) =>\n request<PlanPreview>(`${base}/plan`, {\n method: 'POST',\n body: scope ? { definition, scope } : { definition },\n }),\n /** Shares a definition with all sites, or keeps it on one (needs schema.create on every site). */\n changeScope: (id: string, body: ChangeScopeInput) =>\n request<ChangeScopeOutcome>(`${withId(base, id)}/scope`, { method: 'PUT', body }),\n /** Changes a definition; 409 SCHEMA_VERSION_CONFLICT when `expectedVersion` is stale. */\n update: (id: string, body: UpdateDefinitionInput) =>\n request<ChangeOutcome>(withId(base, id), { method: 'PUT', body }),\n planUpdate: (id: string, body: PlanUpdateInput) =>\n request<PlanPreview>(`${withId(base, id)}/plan`, { method: 'POST', body }),\n /** Soft delete: entries are kept and reappear if the definition is applied again. */\n remove: (id: string, expectedVersion: number) =>\n request<ChangeOutcome>(`${withId(base, id)}${toQueryString({ expectedVersion })}`, {\n method: 'DELETE',\n }),\n revisions: async (id: string) =>\n (await request<{ items: DefinitionRevision[] }>(`${withId(base, id)}/revisions`)).items,\n changes: async (id: string) =>\n (await request<{ items: SchemaChangeJob[] }>(`${withId(base, id)}/changes`)).items,\n };\n};\n\n/** Schema-wide endpoints: the version summary, planned-change status, the read-only lock, locales. */\nexport const createSchemaApi = (request: RequestFn) => ({\n models: createDefinitionApi(request, 'model'),\n components: createDefinitionApi(request, 'component'),\n schema: {\n /** The global schema version and every visible definition's version (cheap; poll it for changes). */\n summary: () => request<SchemaSummary>(ADMIN_PATHS.schema),\n change: (changeId: string) => request<SchemaChangeJob>(withId(ADMIN_PATHS.schemaChanges, changeId)),\n /** Every definition in the pull format, with the schema version they come from (`shapio schema pull`). */\n export: (options: { scope?: DefinitionScope } = {}) =>\n request<SchemaExport>(`${ADMIN_PATHS.schemaExport}${toQueryString(options)}`),\n /** Applies definition files live through the change planner; refuses when the base moved (409). */\n apply: (body: SchemaApplyInput) =>\n request<SchemaApplyResult>(ADMIN_PATHS.schemaApply, { method: 'POST', body }),\n settings: () => request<SchemaSettings>(ADMIN_PATHS.schemaSettings),\n updateSettings: (body: UpdateSchemaSettingsInput) =>\n request<SchemaSettings>(ADMIN_PATHS.schemaSettings, { method: 'PUT', body }),\n },\n locales: {\n list: async () => (await request<{ items: Locale[] }>(ADMIN_PATHS.locales)).items,\n create: (body: CreateLocaleInput) => request<Locale>(ADMIN_PATHS.locales, { method: 'POST', body }),\n update: (code: string, body: UpdateLocaleInput) =>\n request<Locale>(withId(ADMIN_PATHS.locales, code), { method: 'PUT', body }),\n /** A contract change: without `acknowledgeBreaking` the server answers 409 SCHEMA_CHANGE_NOT_ACKNOWLEDGED. */\n setDefault: (code: string, acknowledgeBreaking: boolean) =>\n request<SetDefaultLocaleResult>(`${withId(ADMIN_PATHS.locales, code)}/default`, {\n method: 'POST',\n body: { acknowledgeBreaking },\n }),\n /**\n * Deletes a locale and purges its content. When content exists and `acknowledgeDestructive` is false,\n * the server answers 409 SCHEMA_CHANGE_NOT_ACKNOWLEDGED with `details.plan.impact.affectedHeads`.\n */\n remove: (code: string, acknowledgeDestructive: boolean) =>\n request<DeleteLocaleResult>(\n `${withId(ADMIN_PATHS.locales, code)}${toQueryString({ acknowledgeDestructive: acknowledgeDestructive || undefined })}`,\n { method: 'DELETE' },\n ),\n },\n});\n","import type { RequestFn } from '../request.js';\nimport type {\n CreateSiteInput,\n SetSiteAppRolesInput,\n Site,\n SiteAppRoles,\n UpdateSiteInput,\n} from './sitesTypes.js';\n\nexport const SITES_PATHS = { sites: '/api/admin/sites' } as const;\n\n/** The admin API header that names the site a site-scoped request is about (default: the primary site). */\nexport const SITE_HEADER = 'shapio-site';\n\nconst sitePath = (id: string) => `${SITES_PATHS.sites}/${encodeURIComponent(id)}`;\n\n/** Sites (network routes): listing shows the sites the caller holds a role on; changes need `sites.manage`. */\nexport const createSitesApi = (request: RequestFn) => ({\n sites: {\n list: () => request<Site[]>(SITES_PATHS.sites),\n get: (id: string) => request<Site>(sitePath(id)),\n create: (body: CreateSiteInput) => request<Site>(SITES_PATHS.sites, { method: 'POST', body }),\n update: (id: string, body: UpdateSiteInput) => request<Site>(sitePath(id), { method: 'PATCH', body }),\n /** Only an empty site (409 `SITE_NOT_EMPTY`); never the primary site (409 `SITE_IS_PRIMARY`). */\n remove: (id: string) => request<void>(sitePath(id), { method: 'DELETE' }),\n /** The app roles bound to the site's anonymous callers (`public`) and signed-in app users (`authenticated`). */\n appRoles: {\n get: (id: string) => request<SiteAppRoles>(`${sitePath(id)}/app-roles`),\n /** Replaces both bindings (`roles.manage`). */\n set: (id: string, body: SetSiteAppRolesInput) =>\n request<SiteAppRoles>(`${sitePath(id)}/app-roles`, { method: 'PUT', body }),\n },\n },\n});\n","import type { RequestFn } from '../request.js';\nimport { toQueryString } from './query.js';\nimport type { FieldUsageQuery, FieldUsageResponse } from './usageTypes.js';\n\nexport const USAGE_PATHS = { fields: '/api/admin/usage/fields' } as const;\n\n/** Who reads which fields (needs `tokens.manage`). */\nexport const createUsageApi = (request: RequestFn) => ({\n usage: {\n fields: (query: FieldUsageQuery) =>\n request<FieldUsageResponse>(`${USAGE_PATHS.fields}${toQueryString(query)}`),\n },\n});\n","import type { SiteSummary } from './sitesTypes.js';\n/**\n * Admin identity API shapes (package B, build plan §4.B), mirroring the TypeBox route schemas in\n * apps/api/src/routes/admin/** and routes/schemas/adminIdentity.ts. JSON is camelCase; timestamps are ISO-8601.\n */\n\nexport type AdminUserStatus = 'active' | 'disabled';\n\n/** A role held on one site, or on every site (`siteId` null). */\nexport type RoleAssignment = { roleId: string; siteId: string | null };\n\nexport type AdminUser = {\n id: string;\n email: string;\n name: string;\n status: AdminUserStatus;\n /** Where each role applies. */\n assignments: RoleAssignment[];\n /** Deprecated: the distinct roles of `assignments`, on any site. */\n roleIds: string[];\n lastLoginAt: string | null;\n createdAt: string;\n updatedAt: string;\n};\n\nexport const CONTENT_ACTIONS = ['read', 'create', 'update', 'delete', 'publish', 'schemaManage'] as const;\nexport type ContentAction = (typeof CONTENT_ACTIONS)[number];\n\n/**\n * Network actions: about the whole instance. Only roles assigned on every site grant them, so a role held\n * on one site never reaches the network.\n */\nexport const NETWORK_ACTIONS = [\n 'schema.create',\n 'users.manage',\n 'roles.manage',\n 'audit.read',\n 'sites.manage',\n] as const;\nexport type NetworkAction = (typeof NETWORK_ACTIONS)[number];\n\n/** Site actions: about one site's library, tokens and publishing. */\nexport const SITE_ACTIONS = [\n 'tokens.manage',\n 'media.read',\n 'media.write',\n 'media.manage',\n 'publishing.manage',\n 'webhooks.manage',\n 'deployments.manage',\n 'deployments.trigger',\n 'changes.manage',\n 'changes.ship',\n] as const;\nexport type SiteAction = (typeof SITE_ACTIONS)[number];\n\n/** Actions not scoped to a model: network actions and site actions. */\nexport const GLOBAL_ACTIONS = [\n 'schema.create',\n 'users.manage',\n 'roles.manage',\n 'tokens.manage',\n 'audit.read',\n 'sites.manage',\n 'media.read',\n 'media.write',\n 'media.manage',\n 'publishing.manage',\n 'webhooks.manage',\n 'deployments.manage',\n 'deployments.trigger',\n 'changes.manage',\n 'changes.ship',\n 'site.settings',\n] as const;\nexport type GlobalAction = (typeof GLOBAL_ACTIONS)[number];\n\nexport type PermissionAction = ContentAction | GlobalAction;\n\nexport type RoleSummary = { id: string; key: string; name: string };\n\n/** Returned whenever a session starts (setup, login, accepting an invitation). */\nexport type SessionStarted = { user: AdminUser; csrfToken: string };\n\nexport type MeResponse = {\n user: AdminUser;\n roles: RoleSummary[];\n /** The site this response is about: the request's `Shapio-Site`, else the primary site. */\n site: SiteSummary;\n /** Every site this admin holds a role on (all of them for a role assigned on every site). */\n sites: SiteSummary[];\n /** Sites on this instance (whether or not the admin holds a role on them); scope is shown only above 1. */\n siteCount: number;\n /** Network actions (roles assigned on every site only). */\n networkPermissions: NetworkAction[];\n /**\n * Site actions on the request's site, plus `schema.create` when a role on the site grants it for the\n * site's own definitions (`networkPermissions` lists it when shared definitions may be created too).\n */\n sitePermissions: Array<SiteAction | 'schema.create'>;\n /** `networkPermissions` and `sitePermissions` together. */\n globalPermissions: GlobalAction[];\n /** Content actions per model ID on the request's site (models without any action are left out). */\n modelPermissions: Record<string, ContentAction[]>;\n /** How the server sends email: `console` writes it to the server log (no real delivery is set up). */\n emailDelivery: EmailDelivery;\n csrfToken: string;\n};\n\nexport type EmailDelivery = 'console' | 'smtp';\n\nexport type SetupStatusResponse = {\n /** No admin exists yet. */\n required: boolean;\n /** SETUP_REQUIRE_TOKEN is set: setup also needs the one-time token from the server log. */\n requiresToken: boolean;\n};\n\n/** `token` is needed only when the server requires it (`requiresToken`); otherwise it is ignored. */\nexport type SetupInput = { token?: string; email: string; name: string; password: string };\n\nexport type LoginInput = { email: string; password: string };\n\nexport type CsrfResponse = { csrfToken: string };\n\nexport type UpdateProfileInput = { name: string };\n\nexport type ChangePasswordInput = { currentPassword: string; newPassword: string };\n\nexport type PasswordResetRequestInput = { email: string };\n\nexport type PasswordResetConfirmInput = { token: string; password: string };\n\nexport type AcceptInvitationInput = { token: string; name: string; password: string };\n\nexport type InspectInvitationResponse = { email: string; expiresAt: string };\n\nexport type AdminSession = {\n id: string;\n current: boolean;\n ip: string | null;\n userAgent: string | null;\n createdAt: string;\n lastSeenAt: string;\n expiresAt: string;\n};\n\nexport type Invitation = {\n id: string;\n email: string;\n /** The role assignments the invitee gets on accepting. */\n assignments: RoleAssignment[];\n /** Deprecated: the distinct roles of `assignments`. */\n roleIds: string[];\n invitedBy: string | null;\n expiresAt: string;\n createdAt: string;\n};\n\n/** A fresh accept link, shown once; issuing it makes earlier links (emailed or copied) stop working. */\nexport type InvitationLink = { acceptUrl: string; expiresAt: string };\n\n/**\n * Either `assignments` or (deprecated) `roleIds`, meaning those roles on every site; never both. Updating\n * either replaces every assignment.\n */\ntype AssignmentsInput =\n { assignments: RoleAssignment[]; roleIds?: never } | { roleIds: string[]; assignments?: never };\n\nexport type InviteUserInput = { email: string } & AssignmentsInput;\n\nexport type UpdateAdminUserInput = { name?: string; status?: AdminUserStatus } & (\n AssignmentsInput | { assignments?: never; roleIds?: never }\n);\n\nexport type RoleKind = 'admin' | 'delivery';\n\nexport type RoleCondition = 'ownedByPrincipal';\n\nexport type RolePermission = {\n action: PermissionAction;\n /** `null` grants the action on every model (and is required for global actions). */\n modelId: string | null;\n condition: RoleCondition | null;\n /** `null` = every field; otherwise only these stable field IDs. */\n fieldIds: string[] | null;\n};\n\nexport type Role = {\n id: string;\n key: string;\n name: string;\n description: string;\n kind: RoleKind;\n isSystem: boolean;\n /** Optimistic-concurrency version: send it back as `expectedVersion` on update. */\n version: number;\n permissions: RolePermission[];\n createdAt: string;\n updatedAt: string;\n};\n\nexport type CreateRoleInput = {\n key: string;\n name: string;\n description?: string;\n kind?: RoleKind;\n permissions: RolePermission[];\n};\n\nexport type UpdateRoleInput = {\n expectedVersion: number;\n name?: string;\n description?: string;\n permissions?: RolePermission[];\n};\n\nexport type ApiToken = {\n id: string;\n name: string;\n /** First characters of the token (`shp_` + 6), for telling tokens apart. */\n tokenPrefix: string;\n roleId: string;\n scope: RoleKind;\n /** The token's site; null for a network admin token (its role applies on every site). */\n siteId: string | null;\n createdBy: string | null;\n expiresAt: string | null;\n lastUsedAt: string | null;\n revokedAt: string | null;\n createdAt: string;\n};\n\nexport type CreateApiTokenInput = {\n name: string;\n roleId: string;\n expiresAt?: string | null;\n /**\n * A network admin token (every site and network actions; needs `users.manage`). Omitted: a network token\n * when the creator may create one, else a token of the request's site. Delivery tokens are always per site.\n */\n network?: boolean;\n};\n\n/** `token` is the plain secret, returned once at creation and never again. */\nexport type CreatedApiToken = { token: string; apiToken: ApiToken };\n\nexport type AuditActorType = 'admin' | 'app_user' | 'token' | 'anonymous' | 'system';\n\nexport type AuditEvent = {\n id: string;\n occurredAt: string;\n actorType: AuditActorType;\n actorId: string | null;\n /** The acting admin's (or app user's) display name, when the actor is a known account. */\n actorName: string | null;\n actorEmail: string | null;\n action: string;\n targetType: string | null;\n targetId: string | null;\n outcome: 'success' | 'failure';\n requestId: string | null;\n ip: string | null;\n metadata: unknown;\n};\n\n/** Newest first, cursor-paginated. */\nexport type AuditQuery = {\n cursor?: string;\n limit?: number;\n actorType?: AuditActorType;\n actorId?: string;\n action?: string;\n actionPrefix?: string;\n targetType?: string;\n targetId?: string;\n outcome?: 'success' | 'failure';\n from?: string;\n to?: string;\n};\n\nexport type AuditPage = { items: AuditEvent[]; nextCursor: string | null };\n","/**\n * Publishing types (package H, `apps/api/src/routes/admin/{jobs,publishing,webhooks,deployments,preview}`).\n * Dates are ISO-8601 strings.\n */\nimport type { SiteRef } from './sitesTypes.js';\n\nexport type Page<T> = { items: T[]; nextCursor: string | null };\n\n// Jobs ---------------------------------------------------------------------------------------------\n\nexport const JOB_STATUSES = ['pending', 'running', 'succeeded', 'dead'] as const;\nexport type JobStatus = (typeof JOB_STATUSES)[number];\n\nexport type Job = {\n id: string;\n type: string;\n status: JobStatus;\n attempts: number;\n maxAttempts: number;\n /** When it runs next (pending) or ran last. */\n runAt: string;\n idempotencyKey: string | null;\n lockedBy: string | null;\n lockedUntil: string | null;\n /** Payload and result with secret-looking values replaced by `[redacted]`. */\n payload: unknown;\n result: unknown;\n /** Progress a long job saved (e.g. an import's phase and counts); null when it saved none. */\n progress: unknown;\n lastError: string | null;\n createdAt: string;\n updatedAt: string;\n finishedAt: string | null;\n};\n\nexport type JobQuery = { status?: JobStatus; type?: string; cursor?: string; limit?: number };\n\nexport type JobSummary = { counts: Record<JobStatus, number>; types: string[] };\n\n// Scheduled publications ---------------------------------------------------------------------------\n\nexport const PUBLICATION_ACTIONS = ['publish', 'unpublish'] as const;\nexport type PublicationAction = (typeof PUBLICATION_ACTIONS)[number];\n\nexport const SCHEDULE_STATUSES = ['scheduled', 'done', 'failed', 'cancelled'] as const;\nexport type ScheduleStatus = (typeof SCHEDULE_STATUSES)[number];\n\nexport type ScheduledPublication = {\n id: string;\n entryId: string;\n modelId: string;\n /** Null when the model no longer exists. */\n modelKey: string | null;\n locale: string;\n action: PublicationAction;\n runAt: string;\n status: ScheduleStatus;\n error: string | null;\n /** Publication sequence the change was published at (once done). */\n snapshot: number | null;\n createdBy: string | null;\n createdAt: string;\n executedAt: string | null;\n};\n\nexport type ScheduleQuery = { status?: ScheduleStatus; entryId?: string; cursor?: string; limit?: number };\n\nexport type CreateScheduleInput = {\n modelKey: string;\n entryId: string;\n /** Omit for non-localized models (and for the default locale). */\n locale?: string;\n action: PublicationAction;\n runAt: string;\n};\n\n// Webhooks -----------------------------------------------------------------------------------------\n\nexport type WebhookEventType = { type: string; group: string };\n\nexport type WebhookDeliveryStatus = 'pending' | 'retrying' | 'succeeded' | 'dead';\n\nexport type Webhook = {\n id: string;\n name: string;\n url: string;\n /** Event types or `group.*` patterns. */\n events: string[];\n enabled: boolean;\n allowPrivateNetwork: boolean;\n maxAttempts: number;\n /** The site whose events it receives; null for a network-wide webhook (every site's events). */\n site: SiteRef | null;\n lastDelivery: { status: WebhookDeliveryStatus; at: string } | null;\n createdBy: string | null;\n createdAt: string;\n updatedAt: string;\n version: number;\n};\n\nexport type CreateWebhookInput = {\n name: string;\n url: string;\n events: string[];\n enabled?: boolean;\n allowPrivateNetwork?: boolean;\n maxAttempts?: number;\n /** A network-wide webhook (every site's events); otherwise it belongs to the request's site. */\n network?: boolean;\n};\n\n/** A webhook's site is fixed once created. */\nexport type UpdateWebhookInput = Partial<Omit<CreateWebhookInput, 'network'>> & { expectedVersion: number };\n\n/** The JSON body every webhook delivery sends (signed; verify it with `verifyWebhookSignature`). */\nexport type WebhookEventBody = {\n id: string;\n type: string;\n createdAt: string;\n /** The site the event is about; null for events about no site (network-wide). */\n site: SiteRef | null;\n data: unknown;\n};\n\n/** `secret` is shown once: on creation and after rotation. */\nexport type WebhookWithSecret = { webhook: Webhook; secret: string };\n\nexport type WebhookAttempt = {\n attempt: number;\n at: string;\n durationMs: number;\n request: { method: string; url: string; headers: Record<string, string> };\n /** Null when no response arrived (refused, timeout, blocked by the network policy). */\n response: { status: number; headers: Record<string, string>; body: string; truncated: boolean } | null;\n error: string | null;\n};\n\nexport type WebhookDelivery = {\n id: string;\n webhookId: string;\n eventId: string | null;\n eventType: string;\n isTest: boolean;\n status: WebhookDeliveryStatus;\n attempts: number;\n lastResponseStatus: number | null;\n lastError: string | null;\n payload: unknown;\n attemptLog: WebhookAttempt[];\n createdAt: string;\n updatedAt: string;\n deliveredAt: string | null;\n};\n\n// Deployments --------------------------------------------------------------------------------------\n\nexport const DEPLOYMENT_PROVIDERS = [\n 'generic_webhook',\n 'cloudflare_pages',\n 'vercel',\n 'netlify',\n 'github',\n] as const;\nexport type DeploymentProvider = (typeof DEPLOYMENT_PROVIDERS)[number];\n\nexport const DEPLOYMENT_TRIGGERS = ['publish', 'change_set', 'schema', 'manual'] as const;\nexport type DeploymentTriggerPolicy = (typeof DEPLOYMENT_TRIGGERS)[number];\n\nexport const DEPLOYMENT_RUN_STATUSES = [\n 'queued',\n 'triggered',\n 'building',\n 'deployed',\n 'failed',\n 'unknown',\n] as const;\nexport type DeploymentRunStatus = (typeof DEPLOYMENT_RUN_STATUSES)[number];\n\nexport type DeploymentRunTrigger = 'publish' | 'change_set' | 'schema' | 'manual' | 'retry';\n\n/**\n * Provider settings (not secret). Generic: `{ url }`. Cloudflare Pages: `{ accountId, projectName }`.\n * GitHub: `{ owner, repo, branch, mode: 'commit' | 'pull_request', directory }`.\n */\nexport type DeploymentSettings = Record<string, string>;\n\n/**\n * Secret names per provider. Generic: `signingSecret` (generated when omitted). Cloudflare Pages:\n * `deployHookUrl`, `apiToken`. GitHub: `token`. Values are write-only. A value of `${ENV:VAR_NAME}`\n * makes the server read the secret from that environment variable instead of storing it.\n */\nexport type DeploymentSecretsInput = Record<string, string>;\n\n/** Which secrets are set; values never leave the server. `envVar`: read from this environment variable. */\nexport type DeploymentSecretState = Record<string, { set: boolean; envVar: string | null }>;\n\nexport type DeploymentTimelineEvent = {\n status: DeploymentRunStatus;\n at: string;\n source: 'shapio' | 'callback' | 'provider';\n message: string | null;\n};\n\nexport type DeploymentRun = {\n id: string;\n connectionId: string;\n connectionName: string;\n provider: DeploymentProvider;\n status: DeploymentRunStatus;\n trigger: DeploymentRunTrigger;\n /** Publication sequence the run was triggered at (`?snapshot=` on delivery). */\n snapshot: number | null;\n schemaVersion: number | null;\n retryOf: string | null;\n providerRef: string | null;\n logUrl: string | null;\n siteUrl: string | null;\n error: string | null;\n /** False for providers that cannot report completion without callbacks (shown as \"completion unknown\"). */\n completionReported: boolean;\n timeline: DeploymentTimelineEvent[];\n triggeredAt: string | null;\n finishedAt: string | null;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type DeploymentConnection = {\n id: string;\n name: string;\n provider: DeploymentProvider;\n settings: DeploymentSettings;\n secrets: DeploymentSecretState;\n previewUrlTemplate: string | null;\n /** Preview tokens issued for this connection show exactly what this delivery role reads. */\n deliveryRoleId: string | null;\n triggerPolicy: DeploymentTriggerPolicy[];\n debounceSeconds: number;\n allowPrivateNetwork: boolean;\n enabled: boolean;\n /** Where the site posts signed build callbacks (generic webhook connections). */\n callbackUrl: string;\n latestRun: DeploymentRun | null;\n /** The newest deployed run by snapshot: what the site is serving, as far as Shapio knows. */\n currentRun: DeploymentRun | null;\n createdBy: string | null;\n createdAt: string;\n updatedAt: string;\n version: number;\n};\n\nexport type CreateDeploymentConnectionInput = {\n name: string;\n provider: DeploymentProvider;\n settings: DeploymentSettings;\n secrets: DeploymentSecretsInput;\n previewUrlTemplate?: string | null;\n triggerPolicy: DeploymentTriggerPolicy[];\n debounceSeconds?: number;\n allowPrivateNetwork?: boolean;\n enabled?: boolean;\n deliveryRoleId?: string | null;\n};\n\nexport type UpdateDeploymentConnectionInput = Partial<Omit<CreateDeploymentConnectionInput, 'provider'>> & {\n expectedVersion: number;\n};\n\n/** `generatedSecrets` holds secrets Shapio generated (the generic signing secret), shown once. */\nexport type DeploymentConnectionCreated = {\n connection: DeploymentConnection;\n generatedSecrets: Record<string, string>;\n};\n\nexport type ConnectionTestResult = {\n ok: boolean;\n checks: Array<{ name: string; ok: boolean; message: string }>;\n};\n\nexport type DeploymentRunQuery = { connectionId?: string; cursor?: string; limit?: number };\n\n// Preview ------------------------------------------------------------------------------------------\n\nexport type PreviewToken = {\n id: string;\n tokenPrefix: string;\n modelId: string;\n modelKey: string | null;\n entryId: string | null;\n locale: string | null;\n connectionId: string | null;\n /** Fields follow this delivery role (within the creator's access); null = the public fields. */\n deliveryRoleId: string | null;\n createdBy: string;\n expiresAt: string;\n revokedAt: string | null;\n lastUsedAt: string | null;\n createdAt: string;\n};\n\nexport type CreatePreviewTokenInput = {\n modelKey: string;\n entryId?: string;\n locale?: string;\n /** Default 1 hour, at most 30 days. */\n ttlSeconds?: number;\n connectionId?: string;\n /** Defaults to the connection's delivery role. */\n deliveryRoleId?: string;\n};\n\n/** `token` is shown once. `url` is rendered from the connection's preview URL template (null without one). */\nexport type PreviewTokenCreated = { token: string; previewToken: PreviewToken; url: string | null };\n\nexport type OpenPreviewInput = {\n modelKey: string;\n entryId: string;\n locale?: string;\n /** Defaults to the first enabled connection with a preview URL template. */\n connectionId?: string;\n};\n\n/** What the entry form's Preview button opens. `apiUrl` is the preview read endpoint for this entry. */\nexport type OpenPreviewResult = {\n /** The token's ID (revoke it when the preview closes). */\n id: string;\n url: string | null;\n apiUrl: string;\n token: string;\n expiresAt: string;\n connectionId: string | null;\n};\n\n/** A connection the site's previews open on (names and origins only). */\nexport type PreviewTarget = {\n connectionId: string;\n name: string;\n /** null when the preview URL template's origin depends on a variable. */\n origin: string | null;\n /** Whether the admin can show it in its preview frame. */\n framable: boolean;\n};\n","/**\n * App users and app roles as administrators manage them (package I), mirroring the TypeBox route schemas in\n * apps/api/src/routes/admin/{appUsers,appRoles}. JSON is camelCase; timestamps are ISO-8601.\n */\nimport type { RoleCondition } from './types.js';\n\nexport type AdminAppUser = {\n id: string;\n email: string;\n name: string;\n confirmed: boolean;\n blocked: boolean;\n /** False for accounts that only sign in with an OAuth provider. */\n hasPassword: boolean;\n /** OAuth providers linked to the account (`google`, `github`). */\n providers: string[];\n /** Custom app roles; `authenticated` applies to every app user implicitly. */\n roleIds: string[];\n lastLoginAt: string | null;\n createdAt: string;\n updatedAt: string;\n};\n\n/** Newest first, cursor-paginated; `search` matches email or name. */\nexport type AppUserQuery = { search?: string; cursor?: string; limit?: number };\n\nexport type AppUserPage = { items: AdminAppUser[]; nextCursor: string | null };\n\nexport type UpdateAppUserInput = { blocked?: boolean; roleIds?: string[] };\n\n/** What app roles may grant: content actions only. */\nexport const APP_CONTENT_ACTIONS = ['read', 'create', 'update', 'delete', 'publish'] as const;\nexport type AppContentAction = (typeof APP_CONTENT_ACTIONS)[number];\n\n/** Built-in app role keys: `public` applies to anonymous callers, `authenticated` to every app user. */\nexport const BUILT_IN_APP_ROLE_KEYS = ['public', 'authenticated'] as const;\n\nexport type AppRolePermission = {\n action: AppContentAction;\n /** `null` grants the action on every model, including ones created later. */\n modelId: string | null;\n condition: RoleCondition | null;\n /** `null` = every public field; otherwise exactly these stable field IDs (non-public ones included). */\n fieldIds: string[] | null;\n};\n\nexport type AppRole = {\n id: string;\n key: string;\n name: string;\n description: string;\n isSystem: boolean;\n version: number;\n permissions: AppRolePermission[];\n userCount: number;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type CreateAppRoleInput = {\n key: string;\n name: string;\n description?: string;\n permissions: AppRolePermission[];\n};\n\n/** Built-in roles accept `permissions` only. */\nexport type UpdateAppRoleInput = {\n expectedVersion: number;\n name?: string;\n description?: string;\n permissions?: AppRolePermission[];\n};\n","import type { SchemaDefinition } from '@shapio/schema';\nimport type { DeploymentRunStatus, Page, PublicationAction } from './publishingTypes.js';\nimport type { ChangePlan, DefinitionCategory, DefinitionPayload, PlanImpact } from './schemaTypes.js';\nimport type { SiteRef } from './sitesTypes.js';\n\n/**\n * Change sets and snapshots (developer-face plan §5), mirroring the TypeBox route schemas in\n * apps/api/src/routes/admin/{changeSets,snapshots}/schemas.ts. Dates are ISO-8601 strings.\n */\n\nexport const CHANGE_SET_STATUSES = [\n 'open',\n 'scheduled',\n 'shipping',\n 'shipped',\n 'failed',\n 'discarded',\n] as const;\nexport type ChangeSetStatus = (typeof CHANGE_SET_STATUSES)[number];\n/** While `shipping`: preparing (prerequisite dry runs, index builds) or activating (the final transaction). */\nexport type ShipPhase = 'preparing' | 'activating';\nexport type ChangeSetSource = 'manual' | 'release' | 'restore' | 'builder' | 'assist';\nexport type ChangeSetItemStatus = 'pending' | 'done' | 'failed';\nexport type SchemaOperation = 'create' | 'update' | 'delete';\n\nexport type ChangeSetActor = { type: 'admin' | 'token' | 'system'; id: string | null; name: string | null };\n\n/** Why a ship failed, and the item that stopped it (null when not tied to one item). */\nexport type ChangeSetError = { code: string; message: string; itemId: string | null; details?: unknown };\n\nexport type ChangeSetEntryItem = {\n id: string;\n kind: 'entry';\n position: number;\n entryId: string;\n modelId: string;\n modelKey: string | null;\n title: string | null;\n locale: string;\n action: PublicationAction;\n /** Restore items publish this exact revision instead of the current draft. */\n sourceRevisionId: string | null;\n status: ChangeSetItemStatus;\n error: string | null;\n};\n\nexport type ChangeSetSchemaItem = {\n id: string;\n kind: 'schema';\n position: number;\n draftId: string;\n definitionId: string;\n category: DefinitionCategory;\n apiKey: string;\n operation: SchemaOperation;\n /** The active version the draft was based on; null for a new definition. */\n baseVersion: number | null;\n draftVersion: number;\n status: ChangeSetItemStatus;\n error: string | null;\n};\n\nexport type ChangeSetItem = ChangeSetEntryItem | ChangeSetSchemaItem;\n\nexport type ChangeSetSummary = {\n id: string;\n title: string;\n description: string;\n status: ChangeSetStatus;\n shipPhase: ShipPhase | null;\n source: ChangeSetSource;\n restoreOfSnapshot: number | null;\n scheduledFor: string | null;\n /** Connection whose deploy is triggered (pinned to the shipped snapshot) after the set ships. */\n deploymentConnectionId: string | null;\n deploymentRunId: string | null;\n shippedAt: string | null;\n /** The publication snapshot the set went live in. */\n shippedSnapshot: number | null;\n schemaVersionAfter: number | null;\n error: ChangeSetError | null;\n entryItemCount: number;\n schemaItemCount: number;\n createdBy: ChangeSetActor;\n createdAt: string;\n updatedAt: string;\n version: number;\n};\n\nexport type ChangeSet = ChangeSetSummary & { items: ChangeSetItem[] };\n\nexport type ChangeSetQuery = {\n /** Comma-separated statuses; default: everything except `discarded`. */\n status?: string;\n cursor?: string;\n limit?: number;\n};\n\nexport type CreateChangeSetInput = {\n title: string;\n description?: string;\n /** `builder`: a one-item set the model builder ships at once (\"Review & ship now\"). Default `manual`. */\n source?: 'manual' | 'builder';\n};\nexport type UpdateChangeSetInput = {\n title?: string;\n description?: string;\n deploymentConnectionId?: string | null;\n expectedVersion: number;\n};\nexport type AddChangeSetEntryInput = {\n modelKey: string;\n entryId: string;\n /** Omit for non-localized models (and for the default locale). */\n locale?: string;\n action: PublicationAction;\n};\n\nexport type SchemaDraft = {\n id: string;\n changeSetId: string;\n definitionId: string;\n category: DefinitionCategory;\n operation: SchemaOperation;\n baseVersion: number | null;\n /** Null when the draft deletes the definition. */\n definition: SchemaDefinition | null;\n /** A new definition the draft creates shared with all sites (otherwise it belongs to the set's site). */\n shared: boolean;\n version: number;\n updatedBy: ChangeSetActor;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type PutSchemaDraftInput = {\n category: DefinitionCategory;\n /** The whole proposed definition, or null to delete the definition when the set ships. */\n definition: DefinitionPayload | null;\n /** The active version the edit is based on (null: a new definition). */\n baseVersion: number | null;\n /** For a new definition: create it shared with all sites (default false: the set's site). */\n shared?: boolean;\n /** The draft row version the caller saw; omit when creating the draft. */\n expectedDraftVersion?: number;\n};\n\nexport type FieldDiff = { fieldId: string; apiKey: string; label: string; before: unknown; after: unknown };\nexport type ReviewIssue = { path: string; code: string; message: string };\n\nexport type ReviewEntryItem = {\n itemId: string;\n entryId: string;\n modelId: string;\n modelKey: string | null;\n title: string | null;\n locale: string;\n action: PublicationAction;\n sourceRevisionId: string | null;\n /** Send back in `ship.itemVersions` (strict ship). Null when the item does not publish the draft. */\n draftVersion: number | null;\n liveState: 'unpublished' | 'published' | 'modified' | 'missing';\n fields: FieldDiff[];\n issues: ReviewIssue[];\n};\n\nexport type ReviewSchemaItem = {\n itemId: string;\n draftId: string;\n definitionId: string;\n category: DefinitionCategory;\n apiKey: string;\n operation: SchemaOperation;\n baseVersion: number | null;\n activeVersion: number | null;\n /** The active version moved since the draft was based on it: shipping refuses until it is rebased. */\n stale: boolean;\n plan: ChangePlan | null;\n impact: PlanImpact | null;\n /** Entries of the affected models per site (a shared definition converts every site's content). */\n affectedEntriesBySite: Array<{ site: SiteRef; entries: number }>;\n issues: ReviewIssue[];\n alsoChangedIn: Array<{ id: string; title: string }>;\n};\n\nexport const NOT_RESTORABLE_REASONS = [\n 'entry_deleted',\n 'model_missing',\n 'publishing_disabled',\n 'localization_changed',\n 'locale_missing',\n 'invalid',\n 'unique_conflict',\n] as const;\nexport type NotRestorableReason = (typeof NOT_RESTORABLE_REASONS)[number];\n\nexport type NotRestorable = {\n entryId: string;\n modelId: string;\n modelKey: string | null;\n locale: string;\n reason: NotRestorableReason;\n detail: string;\n};\n\nexport type FieldConsumer = {\n /** The site the reads were made on. */\n site: SiteRef;\n /** `token:<id>`, `app_users` or `anonymous`. */\n principalKey: string;\n label: string | null;\n reads: number;\n lastReadAt: string | null;\n /** `implicit`: the reader requested the whole model (no field selection). */\n selection: 'explicit' | 'implicit';\n};\n\nexport type FieldConsumers = {\n modelId: string;\n fieldId: string;\n apiKey: string;\n consumers: FieldConsumer[];\n /**\n * Readers on other sites, as totals, when the viewer holds no role on every site; null when the viewer\n * sees every site's readers in `consumers`.\n */\n otherSites: { consumers: number; reads: number } | null;\n};\n\nexport type ChangeSetReview = {\n changeSet: ChangeSet;\n entries: ReviewEntryItem[];\n schema: ReviewSchemaItem[];\n notRestorable: NotRestorable[];\n consumers: FieldConsumers[];\n usageDays: number;\n checks: { breaking: boolean; destructive: boolean; blocking: ReviewIssue[]; warnings: ReviewIssue[] };\n /** Fixed notices, e.g. `NEW_FIELDS_AFTER_SHIP`. */\n notices: string[];\n};\n\nexport type ShipChangeSetInput = {\n expectedVersion: number;\n acknowledgeBreaking?: boolean;\n acknowledgeDestructive?: boolean;\n /** Draft versions the review showed; a moved draft makes the ship refuse with 409 CHANGE_SET_STALE. */\n itemVersions?: Array<{ itemId: string; draftVersion: number }>;\n};\n\nexport type ScheduleChangeSetInput = {\n at: string;\n expectedVersion: number;\n acknowledgeBreaking?: boolean;\n acknowledgeDestructive?: boolean;\n};\n\nexport type ChangeSetTimelineEvent = {\n at: string;\n kind: string;\n actor: ChangeSetActor | null;\n message: string | null;\n snapshot: number | null;\n deploymentRunId: string | null;\n /** `item.changedAfterReview`: the entry whose draft moved between review and a scheduled ship. */\n item: { entryId: string; locale: string; fromVersion: number; toVersion: number } | null;\n};\n\nexport type UnassignedEntry = {\n entryId: string;\n modelId: string;\n modelKey: string | null;\n title: string | null;\n locale: string;\n status: 'draft' | 'modified';\n updatedAt: string;\n};\n\n// Snapshots ----------------------------------------------------------------------------------------\n\nexport const SNAPSHOT_SOURCES = [\n 'publish',\n 'unpublish',\n 'delete',\n 'schedule',\n 'change_set',\n 'schema',\n 'conversion',\n 'import',\n 'legacy',\n] as const;\nexport type SnapshotSource = (typeof SNAPSHOT_SOURCES)[number];\n\nexport type Snapshot = {\n seq: number;\n schemaVersion: number | null;\n source: SnapshotSource;\n changeSetId: string | null;\n changeSetTitle: string | null;\n actor: { type: string; id: string | null };\n changedEntries: number;\n deploymentRuns: Array<{ id: string; connectionId: string; status: DeploymentRunStatus }>;\n createdAt: string;\n};\n\nexport type SnapshotPage = Page<Snapshot> & { current: number };\nexport type SnapshotQuery = { cursor?: string; limit?: number };\n","/**\n * Shapes of the entry document's endpoints (editor experience, E0b): publish pre-flight, content health\n * findings, presence and per-model counts. Sentences are never sent: the admin builds them from `rule` and\n * `params` with its translations.\n */\n\n/** Health rules evaluated per entry (`apps/api/src/services/contentHealth.ts`). */\nexport const HEALTH_RULES = [\n 'requiredEmpty',\n 'altMissing',\n 'localeMissing',\n 'relationMissing',\n 'relationUnpublished',\n 'uniqueConflict',\n 'staleDraft',\n 'unpublishedChanges',\n] as const;\nexport type HealthRule = (typeof HEALTH_RULES)[number];\n\n/** Pre-flight adds the publish checks that are not health rules: validator issues and missing media. */\nexport type PreflightRule = HealthRule | 'invalid' | 'mediaMissing';\n\nexport type CheckSeverity = 'error' | 'warning';\n\n/** Values a sentence needs (field ID, asset ID, locale, counts…). */\nexport type CheckParams = Record<string, string | number | null>;\n\nexport type PreflightCheck = {\n rule: PreflightRule;\n /** Errors block publishing; warnings are informational. */\n severity: CheckSeverity;\n /** JSON pointer (API keys) of the value to fix, e.g. `/body` or `/sections/2/title`. */\n path?: string;\n /** The validator's issue code, for `invalid` and `requiredEmpty` errors. */\n code?: string;\n params: CheckParams;\n};\n\nexport type PreflightLocale = {\n locale: string;\n /** No error-severity check: publishing this locale is expected to succeed. */\n ready: boolean;\n checks: PreflightCheck[];\n};\n\nexport type PreflightInput = { locales?: string[] };\n\nexport type PreflightResponse = {\n locales: PreflightLocale[];\n /** Checks about the entry as a whole, not one locale (e.g. a configured locale not started yet). */\n entry: PreflightCheck[];\n};\n\n/** A finding of the health engine, open until its rule passes again. */\nexport type ContentHealthFinding = {\n id: string;\n entryId: string;\n modelId: string;\n modelKey: string;\n /** The entry's title in the finding's locale (or the default locale), when readable. */\n entryTitle: string | null;\n /** `*` for a finding about the entry as a whole. */\n locale: string;\n rule: HealthRule;\n /** Distinguishes several findings of one rule on one entry (e.g. two images without alt text). */\n subject: string;\n severity: CheckSeverity;\n path?: string;\n params: CheckParams;\n firstSeenAt: string;\n lastSeenAt: string;\n};\n\nexport type ContentHealthQuery = { rule?: HealthRule; modelKey?: string; cursor?: string; limit?: number };\n\nexport type ContentHealthPage = { items: ContentHealthFinding[]; nextCursor: string | null };\n\nexport type ContentHealthSummary = { rules: { rule: HealthRule; count: number }[] };\n\n/** Someone with the entry open. */\nexport type PresencePerson = {\n userId: string;\n name: string;\n /** The locale they are editing, when the model is localized. */\n locale: string | null;\n /** When this tab started editing. */\n since: string;\n /** The caller's own other tab (the calling tab itself is never listed). */\n you: boolean;\n};\n\nexport type PresenceHeartbeatInput = {\n /** A random ID per browser tab, so two tabs of one person are counted apart. */\n tabId: string;\n locale?: string | null;\n};\n\nexport type EntryPresence = { people: PresencePerson[] };\n\nexport type ModelPresence = { entries: { entryId: string; people: PresencePerson[] }[] };\n\nexport type ContentCount = { modelId: string; modelKey: string; total: number };\n\nexport type ContentCounts = { counts: ContentCount[] };\n","import type { SchemaDefinition } from '@shapio/schema';\n\n/** Editor assists (plan agentic-ecosystem §A0). Agents propose, people ship: nothing here publishes. */\nexport type AssistProvider = 'anthropic' | 'openai' | 'openai-compatible';\n\nexport type AssistUsage = { month: string; runs: number; inputTokens: number; outputTokens: number };\n\n/** `usage` only for admins with `changes.manage`; provider and model only while assist is on. */\nexport type AssistStatus = {\n enabled: boolean;\n provider?: AssistProvider;\n model?: string;\n usage?: AssistUsage;\n};\n\nexport type AltTextInput = { assetId: string; locale?: string };\nexport type AltTextResult = { alt: string; model: string };\n\n/** A model-written text; `truncated` when it was cut to the field's or the request's limit. */\nexport type AssistTextResult = { text: string; truncated: boolean; model: string };\n\nexport type SummarizeInput = { modelKey: string; entryId: string; locale?: string; fieldApiKey: string };\n\nexport type TranslateInput = { modelKey: string; entryId: string; from: string; to: string };\nexport type AssistIssue = { path: string; code: string; message: string };\n/** `data` is in the editor's save format: save it as the `to` locale's draft. */\nexport type TranslateResult = { data: Record<string, unknown>; issues: AssistIssue[]; model: string };\n\nexport type RewriteInput = { text: string; instruction: string; maxLength?: number };\n\nexport type SchemaDraftInput = { description: string };\n/** New definitions with new stable IDs, in save order (references first). Nothing is written. */\nexport type SchemaDraftResult = { definitions: SchemaDefinition[]; model: string };\n\nexport const CONTENT_OPS_RULES = ['altMissing', 'localeMissing'] as const;\nexport type ContentOpsRule = (typeof CONTENT_OPS_RULES)[number];\nexport type ContentOpsInput = { rule: ContentOpsRule; modelKey?: string; fromLocale?: string };\nexport type ContentOpsStatus = 'queued' | 'running' | 'succeeded' | 'failed';\n\n/** One library asset's proposed alt text; apply it with the media update at `assetVersion`. */\nexport type AltProposal = {\n assetId: string;\n filename: string;\n currentAlt: string | null;\n proposedAlt: string;\n assetVersion: number;\n findingCount: number;\n};\n\n/** A finding the run left alone, and why (an error code or a reason such as `publishesOnSave`). */\nexport type ContentOpsSkip = {\n key: string;\n entryId?: string;\n assetId?: string;\n locale?: string;\n reason: string;\n detail?: unknown;\n};\nexport type ContentOpsWritten = { entryId: string; modelKey: string; locale: string; version: number };\n\nexport type AltMissingResult = { rule: 'altMissing'; proposals: AltProposal[]; skipped: ContentOpsSkip[] };\n/** The drafts were written into the change set `changeSetId` (null when nothing was written). */\nexport type LocaleMissingResult = {\n rule: 'localeMissing';\n changeSetId: string | null;\n fromLocale: string;\n written: ContentOpsWritten[];\n skipped: ContentOpsSkip[];\n};\nexport type ContentOpsResult = AltMissingResult | LocaleMissingResult;\n\nexport type ContentOpsRun = {\n runId: string;\n rule: ContentOpsRule;\n status: ContentOpsStatus;\n model: string;\n createdAt: string;\n finishedAt: string | null;\n error: { code: string } | null;\n /** Once succeeded (null before, or partial progress while running). */\n result: ContentOpsResult | null;\n};\n","import type { RequestFn } from '../request.js';\nimport { createAppUsersApi } from './appUsers.js';\nimport { createAssistApi } from './assist.js';\nimport { createChangeSetsApi } from './changeSets.js';\nimport { createContentApi } from './content.js';\nimport { createEditingApi } from './editing.js';\nimport { createMediaApi } from './media.js';\nimport { ADMIN_PATHS, withId } from './paths.js';\nimport { createPublishingApi } from './publishing.js';\nimport { toQueryString } from './query.js';\nimport { createSchemaApi } from './schema.js';\nimport { createSitesApi } from './sites.js';\nimport type {\n AcceptInvitationInput,\n AdminSession,\n AdminUser,\n ApiToken,\n AuditPage,\n AuditQuery,\n ChangePasswordInput,\n CreateApiTokenInput,\n CreatedApiToken,\n CreateRoleInput,\n CsrfResponse,\n InspectInvitationResponse,\n Invitation,\n InvitationLink,\n InviteUserInput,\n LoginInput,\n MeResponse,\n PasswordResetConfirmInput,\n PasswordResetRequestInput,\n Role,\n SessionStarted,\n SetupInput,\n SetupStatusResponse,\n UpdateAdminUserInput,\n UpdateProfileInput,\n UpdateRoleInput,\n} from './types.js';\nimport { createUsageApi } from './usage.js';\n\n/**\n * Admin endpoints: identity (setup, auth, sessions, users, invitations, roles, tokens, audit) and the schema\n * registry (models, components, schema, locales), the media library and content.\n */\nexport const createAdminApi = (request: RequestFn) => ({\n setup: {\n status: () => request<SetupStatusResponse>(ADMIN_PATHS.setup),\n complete: (body: SetupInput) => request<SessionStarted>(ADMIN_PATHS.setup, { method: 'POST', body }),\n },\n auth: {\n csrf: () => request<CsrfResponse>(ADMIN_PATHS.csrf),\n login: (body: LoginInput) => request<SessionStarted>(ADMIN_PATHS.login, { method: 'POST', body }),\n logout: () => request<void>(ADMIN_PATHS.logout, { method: 'POST' }),\n me: () => request<MeResponse>(ADMIN_PATHS.me),\n updateProfile: (body: UpdateProfileInput) =>\n request<AdminUser>(ADMIN_PATHS.me, { method: 'PATCH', body }),\n /** The session is rotated: the response carries the new session's CSRF token. */\n changePassword: (body: ChangePasswordInput) =>\n request<CsrfResponse>(ADMIN_PATHS.password, { method: 'POST', body }),\n requestPasswordReset: (body: PasswordResetRequestInput) =>\n request<void>(ADMIN_PATHS.passwordReset, { method: 'POST', body }),\n confirmPasswordReset: (body: PasswordResetConfirmInput) =>\n request<void>(ADMIN_PATHS.passwordResetConfirm, { method: 'POST', body }),\n },\n sessions: {\n list: () => request<AdminSession[]>(ADMIN_PATHS.sessions),\n revoke: (id: string) => request<void>(withId(ADMIN_PATHS.sessions, id), { method: 'DELETE' }),\n },\n users: {\n list: () => request<AdminUser[]>(ADMIN_PATHS.users),\n get: (id: string) => request<AdminUser>(withId(ADMIN_PATHS.users, id)),\n update: (id: string, body: UpdateAdminUserInput) =>\n request<AdminUser>(withId(ADMIN_PATHS.users, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.users, id), { method: 'DELETE' }),\n revokeSessions: (id: string) =>\n request<void>(`${withId(ADMIN_PATHS.users, id)}/sessions`, { method: 'DELETE' }),\n },\n invitations: {\n list: () => request<Invitation[]>(ADMIN_PATHS.invitations),\n create: (body: InviteUserInput) => request<Invitation>(ADMIN_PATHS.invitations, { method: 'POST', body }),\n revoke: (id: string) => request<void>(withId(ADMIN_PATHS.invitations, id), { method: 'DELETE' }),\n /** A fresh link to send by hand; any earlier link for this invitation stops working. */\n link: (id: string) =>\n request<InvitationLink>(`${withId(ADMIN_PATHS.invitations, id)}/link`, { method: 'POST' }),\n /** Public: the token travels in the body, never in a URL the server logs. */\n inspect: (token: string) =>\n request<InspectInvitationResponse>(ADMIN_PATHS.inspectInvitation, { method: 'POST', body: { token } }),\n accept: (body: AcceptInvitationInput) =>\n request<SessionStarted>(ADMIN_PATHS.acceptInvitation, { method: 'POST', body }),\n },\n roles: {\n list: () => request<Role[]>(ADMIN_PATHS.roles),\n get: (id: string) => request<Role>(withId(ADMIN_PATHS.roles, id)),\n create: (body: CreateRoleInput) => request<Role>(ADMIN_PATHS.roles, { method: 'POST', body }),\n update: (id: string, body: UpdateRoleInput) =>\n request<Role>(withId(ADMIN_PATHS.roles, id), { method: 'PATCH', body }),\n remove: (id: string) => request<void>(withId(ADMIN_PATHS.roles, id), { method: 'DELETE' }),\n },\n tokens: {\n list: () => request<ApiToken[]>(ADMIN_PATHS.tokens),\n create: (body: CreateApiTokenInput) =>\n request<CreatedApiToken>(ADMIN_PATHS.tokens, { method: 'POST', body }),\n revoke: (id: string) => request<void>(withId(ADMIN_PATHS.tokens, id), { method: 'DELETE' }),\n },\n audit: {\n list: (query: AuditQuery = {}) => request<AuditPage>(`${ADMIN_PATHS.audit}${toQueryString(query)}`),\n },\n ...createSchemaApi(request),\n ...createMediaApi(request),\n ...createContentApi(request),\n ...createEditingApi(request),\n ...createPublishingApi(request),\n ...createAppUsersApi(request),\n ...createChangeSetsApi(request),\n ...createUsageApi(request),\n ...createSitesApi(request),\n ...createAssistApi(request),\n});\n\nexport type AdminApi = ReturnType<typeof createAdminApi>;\nexport { ADMIN_PATHS } from './paths.js';\nexport * from './types.js';\nexport * from './schemaTypes.js';\nexport * from './schemaSyncTypes.js';\nexport * from './mediaTypes.js';\nexport * from './contentTypes.js';\nexport * from './publishingTypes.js';\nexport * from './appUsersTypes.js';\nexport * from './changeSetTypes.js';\nexport * from './usageTypes.js';\nexport * from './sitesTypes.js';\nexport { SITE_HEADER, SITES_PATHS } from './sites.js';\nexport { toContentQueryString } from './contentQuery.js';\nexport { buildUploadForm, resolveUploadUrl } from './media.js';\nexport { HEALTH_RULES } from './editingTypes.js';\nexport { ASSIST_PATHS } from './assist.js';\nexport { CONTENT_OPS_RULES } from './assistTypes.js';\n","import type { RequestFn } from '../request.js';\nimport type {\n AppChangePasswordInput,\n AppLoginInput,\n AppOAuthProvider,\n AppRegisterInput,\n AppRegisterResult,\n AppSession,\n AppUser,\n} from './types.js';\n\nexport const APP_AUTH_PATHS = {\n register: '/api/app-auth/register',\n login: '/api/app-auth/login',\n refresh: '/api/app-auth/refresh',\n logout: '/api/app-auth/logout',\n me: '/api/app-auth/me',\n password: '/api/app-auth/me/password',\n confirmEmail: '/api/app-auth/confirm-email',\n resendConfirmation: '/api/app-auth/confirm-email/resend',\n passwordReset: '/api/app-auth/password-reset',\n passwordResetConfirm: '/api/app-auth/password-reset/confirm',\n providers: '/api/app-auth/providers',\n oauthExchange: '/api/app-auth/oauth/exchange',\n} as const;\n\n/**\n * App-user endpoints. Calls that act as the signed-in user need a client created with `token: accessToken`.\n * `baseUrl` is the client's base URL, used to build the OAuth start link the browser navigates to.\n */\nexport const createAppAuthApi = (request: RequestFn, baseUrl: string) => ({\n register: (body: AppRegisterInput) =>\n request<AppRegisterResult>(APP_AUTH_PATHS.register, { method: 'POST', body }),\n login: (body: AppLoginInput) => request<AppSession>(APP_AUTH_PATHS.login, { method: 'POST', body }),\n refresh: (refreshToken: string) =>\n request<AppSession>(APP_AUTH_PATHS.refresh, { method: 'POST', body: { refreshToken } }),\n /**\n * Signs the account out everywhere: this login's refresh tokens are revoked, and every access token the\n * account holds (on any device) is refused from the next request. Other logins recover with their own\n * refresh token.\n */\n logout: (refreshToken: string) =>\n request<void>(APP_AUTH_PATHS.logout, { method: 'POST', body: { refreshToken } }),\n /** The signed-in user. Answers 401 once the account logged out anywhere, changed its password or was blocked. */\n me: () => request<AppUser>(APP_AUTH_PATHS.me),\n updateMe: (body: { name: string }) => request<AppUser>(APP_AUTH_PATHS.me, { method: 'PATCH', body }),\n /** Returns a new session; every other sign-in of the account is revoked. */\n changePassword: (body: AppChangePasswordInput) =>\n request<AppSession>(APP_AUTH_PATHS.password, { method: 'POST', body }),\n deleteMe: (body: { password?: string } = {}) =>\n request<void>(APP_AUTH_PATHS.me, { method: 'DELETE', body }),\n /** The token from the `#token=` fragment of the confirmation link. */\n confirmEmail: (token: string) =>\n request<void>(APP_AUTH_PATHS.confirmEmail, { method: 'POST', body: { token } }),\n resendConfirmation: (email: string) =>\n request<void>(APP_AUTH_PATHS.resendConfirmation, { method: 'POST', body: { email } }),\n requestPasswordReset: (email: string) =>\n request<void>(APP_AUTH_PATHS.passwordReset, { method: 'POST', body: { email } }),\n confirmPasswordReset: (body: { token: string; password: string }) =>\n request<void>(APP_AUTH_PATHS.passwordResetConfirm, { method: 'POST', body }),\n providers: async () =>\n (await request<{ providers: AppOAuthProvider[] }>(APP_AUTH_PATHS.providers)).providers,\n /**\n * Where to send the browser to sign in with a provider. `codeChallenge` comes from `createPkcePair()`;\n * keep its `codeVerifier` until the browser returns. It comes back to `redirectTo` (an allowed return URL,\n * by default an origin listed in CORS_ORIGINS) with `?code=` (pass it to `exchangeCode`) or `?error=`.\n */\n oauthStartUrl: (provider: AppOAuthProvider, redirectTo: string, codeChallenge: string) =>\n `${baseUrl.replace(/\\/+$/, '')}/api/app-auth/oauth/${provider}/start?redirectTo=${encodeURIComponent(redirectTo)}&codeChallenge=${encodeURIComponent(codeChallenge)}`,\n /** Trades the one-time code for a session. A wrong verifier spends the code: start the sign-in again. */\n exchangeCode: (code: string, codeVerifier: string) =>\n request<AppSession>(APP_AUTH_PATHS.oauthExchange, { method: 'POST', body: { code, codeVerifier } }),\n});\n\nexport type AppAuthApi = ReturnType<typeof createAppAuthApi>;\n","/**\n * Next.js data-cache support for delivery reads. Under Next (`process.env.NEXT_RUNTIME` is set) or when the\n * client is given a `next` option, every delivery read passes `next: { tags }` to `fetch`, so a site can\n * refresh exactly what changed with `revalidateTag`. The cache mode is only set when asked for, except that a\n * read pinned to a publication snapshot is immutable and always `force-cache`. Elsewhere nothing is added.\n */\n\n/** Next's `fetch` cache modes the client passes through. */\nexport type NextCacheMode = 'force-cache' | 'no-store';\n\nexport type NextCacheOptions = {\n /** Next's `fetch` `cache` option. Unset: Next's own default, except pinned snapshot reads (`force-cache`). */\n cache?: NextCacheMode;\n /** Seconds a cached response stays fresh (`next.revalidate`); `false` keeps it until a tag is revalidated. */\n revalidate?: number | false;\n};\n\n/** The last argument of every delivery read: overrides the client's `next` option; `false` adds nothing. */\nexport type DeliveryReadOptions = { next?: NextCacheOptions | false };\n\n/** What a delivery read adds to its `fetch` init. */\nexport type NextFetchInit = {\n cache?: NextCacheMode;\n next?: { tags: string[]; revalidate?: number | false };\n};\n\nconst TAG_PREFIX = 'shapio';\n\n/**\n * The cache tags delivery reads carry (`revalidateTag(shapioTags.entry('articles', id), { expire: 0 })`).\n * Models are named by their route key: a collection's plural API ID, a singleton's API ID.\n */\nexport const shapioTags = {\n /** Every delivery read of the site; `shapio:site` when the client names no site. */\n site: (siteKey?: string) =>\n siteKey === undefined ? `${TAG_PREFIX}:site` : `${TAG_PREFIX}:site:${siteKey}`,\n /** Every read of one model (lists, singletons and its entries). */\n model: (routeKey: string) => `${TAG_PREFIX}:${routeKey}`,\n /** Reads of one entry by its ID. */\n entry: (routeKey: string, entryId: string) => `${TAG_PREFIX}:${routeKey}:${entryId}`,\n} as const;\n\n/** Spelled out so bundlers that inline `process.env.NEXT_RUNTIME` see it; guarded for browsers. */\nconst isNextRuntime = (): boolean => {\n try {\n return typeof process !== 'undefined' && Boolean(process.env.NEXT_RUNTIME);\n } catch {\n return false;\n }\n};\n\n/** What every delivery read needs to tag itself: the client's site and `next` option. */\nexport type DeliveryCacheContext = {\n site: string | undefined;\n next: NextCacheOptions | false | undefined;\n};\n\nexport type NextReadInput = {\n /** The client's `next` option. */\n client: NextCacheOptions | false | undefined;\n /** The read's own `next` option. */\n read: NextCacheOptions | false | undefined;\n tags: string[];\n /** The read names a publication snapshot (immutable). */\n pinned: boolean;\n};\n\n/** The `cache` and `next` fetch options of one delivery read; empty outside Next unless asked for. */\nexport const nextFetchInit = ({ client, read, tags, pinned }: NextReadInput): NextFetchInit => {\n if (read === false || (read === undefined && client === false)) {\n return {};\n }\n const configured = client === false ? read : read === undefined ? client : { ...client, ...read };\n if (configured === undefined && !isNextRuntime()) {\n return {};\n }\n if (pinned && read?.cache === undefined) {\n return { cache: 'force-cache', next: { tags } };\n }\n const cache = configured?.cache;\n const revalidate = configured?.revalidate;\n return {\n ...(cache === undefined ? {} : { cache }),\n next: { tags, ...(revalidate === undefined ? {} : { revalidate }) },\n };\n};\n","import { toContentQueryString } from './admin/contentQuery.js';\nimport type { DeliveryGetQuery, DeliveryItem, DeliveryList, DeliveryListQuery } from './deliveryTypes.js';\nimport {\n nextFetchInit,\n shapioTags,\n type DeliveryCacheContext,\n type DeliveryReadOptions,\n} from './nextCache.js';\nimport type { RequestFn } from './request.js';\n\nexport const DELIVERY_PATH = '/api/content';\n\nconst routePath = (routeKey: string) => `${DELIVERY_PATH}/${encodeURIComponent(routeKey)}`;\n\n/** The content query string plus `snapshot`, `richText` and `seo`, which only delivery reads take. */\nconst deliveryQueryString = ({ snapshot, richText, seo, ...query }: DeliveryListQuery): string => {\n const extra = [\n ...(snapshot === undefined ? [] : [`snapshot=${encodeURIComponent(String(snapshot))}`]),\n ...(richText === undefined ? [] : [`richText=${encodeURIComponent(richText)}`]),\n ...(seo === undefined ? [] : [`seo=${encodeURIComponent(seo)}`]),\n ];\n const base = toContentQueryString(query);\n if (extra.length === 0) {\n return base;\n }\n return base ? `${base}&${extra.join('&')}` : `?${extra.join('&')}`;\n};\n\n/**\n * Published content, typed by the caller (`delivery.list<Article>('articles', { locale: 'fr', snapshot })`).\n * A collection is read with `list` (a page) and `get` (one entry); a singleton with `singleton`. Each read\n * takes Next.js cache options last and is tagged for `revalidateTag` (nextCache.ts): lists and singletons with\n * the site and model tags, `get` with the entry's tag too.\n */\nexport const createDeliveryApi = (request: RequestFn, cacheContext: DeliveryCacheContext) => {\n const fetchInit = (tags: string[], query: DeliveryGetQuery, { next }: DeliveryReadOptions) =>\n nextFetchInit({ client: cacheContext.next, read: next, tags, pinned: query.snapshot !== undefined });\n const siteTag = shapioTags.site(cacheContext.site);\n return {\n list: <T = Record<string, unknown>>(\n routeKey: string,\n query: DeliveryListQuery = {},\n options: DeliveryReadOptions = {},\n ) =>\n request<DeliveryList<T>>(\n `${routePath(routeKey)}${deliveryQueryString(query)}`,\n fetchInit([siteTag, shapioTags.model(routeKey)], query, options),\n ),\n singleton: <T = Record<string, unknown>>(\n apiKey: string,\n query: DeliveryGetQuery = {},\n options: DeliveryReadOptions = {},\n ) =>\n request<DeliveryItem<T>>(\n `${routePath(apiKey)}${deliveryQueryString(query)}`,\n fetchInit([siteTag, shapioTags.model(apiKey)], query, options),\n ),\n get: <T = Record<string, unknown>>(\n routeKey: string,\n id: string,\n query: DeliveryGetQuery = {},\n options: DeliveryReadOptions = {},\n ) =>\n request<DeliveryItem<T>>(\n `${routePath(routeKey)}/${encodeURIComponent(id)}${deliveryQueryString(query)}`,\n fetchInit([siteTag, shapioTags.model(routeKey), shapioTags.entry(routeKey, id)], query, options),\n ),\n };\n};\n\nexport type DeliveryApi = ReturnType<typeof createDeliveryApi>;\n","import {\n nextFetchInit,\n shapioTags,\n type DeliveryCacheContext,\n type DeliveryReadOptions,\n} from './nextCache.js';\nimport type { RequestFn } from './request.js';\nimport type { DeliverySite } from './seoTypes.js';\n\nexport const DELIVERY_SITE_PATH = '/api/site';\n\n/**\n * The request's site as delivery sees it (key, name, SEO defaults), with the client's token and site. Under\n * Next.js the read carries the site tag (nextCache.ts).\n */\nexport const createSiteApi = (request: RequestFn, cacheContext: DeliveryCacheContext) => ({\n get: ({ next }: DeliveryReadOptions = {}) =>\n request<DeliverySite>(\n DELIVERY_SITE_PATH,\n nextFetchInit({\n client: cacheContext.next,\n read: next,\n tags: [shapioTags.site(cacheContext.site)],\n pinned: false,\n }),\n ),\n});\n\nexport type SiteApi = ReturnType<typeof createSiteApi>;\n","import { toQueryString } from './admin/query.js';\nimport type { RequestFn } from './request.js';\nimport type {\n CurrentSnapshot,\n SnapshotChange,\n SnapshotChangesPage,\n SnapshotChangesQuery,\n} from './snapshotTypes.js';\n\nexport const SNAPSHOT_PATHS = {\n current: '/api/snapshots/current',\n changes: '/api/snapshots/changes',\n} as const;\n\n/** Snapshots and the diff between two of them, for incremental site builds (delivery credentials). */\nexport const createSnapshotsApi = (request: RequestFn) => {\n const changes = (query: SnapshotChangesQuery) =>\n request<SnapshotChangesPage>(`${SNAPSHOT_PATHS.changes}${toQueryString(query)}`);\n return {\n current: () => request<CurrentSnapshot>(SNAPSHOT_PATHS.current),\n changes,\n /** Every change between `from` and `to`, following `nextCursor` until the last page. */\n allChanges: async (query: Omit<SnapshotChangesQuery, 'after'>) => {\n const items: SnapshotChange[] = [];\n let page = await changes(query);\n items.push(...page.items);\n while (page.nextCursor !== null) {\n page = await changes({ ...query, to: page.to, after: page.nextCursor });\n items.push(...page.items);\n }\n return { from: page.from, to: page.to, schemaVersions: page.schemaVersions, items };\n },\n };\n};\n","import { createDeliveryApi } from './delivery.js';\nimport type { NextCacheOptions } from './nextCache.js';\nimport type { RequestFn } from './request.js';\nimport { createSiteApi } from './siteDelivery.js';\nimport { createSnapshotsApi } from './snapshots.js';\n\nexport type DeliveryClientOptions = {\n /** The site key the reads are tagged with (`shapioTags.site`); the transport names the site itself. */\n site?: string;\n /** Next.js data-cache options, as `createClient`'s `next` option. */\n next?: NextCacheOptions | false;\n};\n\n/**\n * The read side of the client over any transport: published content (`delivery`), the site (`site`) and\n * publication snapshots (`snapshots`). `createClient` builds it over HTTP; `@shapio/local` over the delivery\n * API running in the same process. The transport receives exactly the paths the HTTP client sends.\n */\nexport const createDeliveryClient = (request: RequestFn, { site, next }: DeliveryClientOptions = {}) => {\n const cacheContext = { site, next };\n return {\n /** Published content (the delivery API), typed by the caller. */\n delivery: createDeliveryApi(request, cacheContext),\n /** The site as delivery sees it: key, name and SEO defaults (`GET /api/site`). */\n site: createSiteApi(request, cacheContext),\n /** Publication snapshots and the diff between two (incremental builds). */\n snapshots: createSnapshotsApi(request),\n };\n};\n\nexport type ShapioDeliveryClient = ReturnType<typeof createDeliveryClient>;\n","import { SITE_HEADER } from './admin/sites.js';\nimport { DELIVERY_PATH } from './delivery.js';\nimport { DELIVERY_SITE_PATH } from './siteDelivery.js';\nimport { SNAPSHOT_PATHS } from './snapshots.js';\n\n/** Delivery reads name their site with `?site=`; everything else with the `Shapio-Site` header. */\nexport const SITE_QUERY_PARAMETER = 'site';\n\n/** Delivery reads (content, snapshots, the site): a GET there carries the site in its URL. */\nconst DELIVERY_READ_PREFIXES = [\n `${DELIVERY_PATH}/`,\n `${DELIVERY_PATH}?`,\n '/api/snapshots/',\n `${DELIVERY_SITE_PATH}?`,\n] as const;\n\nconst isDeliveryRead = (method: string, path: string) =>\n method === 'GET' &&\n (path === DELIVERY_PATH ||\n path === DELIVERY_SITE_PATH ||\n Object.values(SNAPSHOT_PATHS).some((snapshotPath) => path === snapshotPath) ||\n DELIVERY_READ_PREFIXES.some((prefix) => path.startsWith(prefix)));\n\nconst namesSite = (path: string) => {\n const index = path.indexOf('?');\n return index !== -1 && new URLSearchParams(path.slice(index + 1)).has(SITE_QUERY_PARAMETER);\n};\n\n/**\n * Where a request names the client's site (sites plan §H). Delivery GETs put it in the query string: a\n * simple cross-origin GET needs no CORS preflight, and URL-keyed CDN caches keep sites apart. Every other\n * request sends the `Shapio-Site` header. A path that already names a site is left as it is.\n */\nexport const applySite = (\n site: string | undefined,\n method: string,\n path: string,\n): { path: string; headers: Record<string, string> } => {\n if (site === undefined || namesSite(path)) {\n return { path, headers: {} };\n }\n if (isDeliveryRead(method, path)) {\n const parameter = `${SITE_QUERY_PARAMETER}=${encodeURIComponent(site)}`;\n return { path: `${path}${path.includes('?') ? '&' : '?'}${parameter}`, headers: {} };\n }\n return { path, headers: { [SITE_HEADER]: site } };\n};\n","import { ShapioApiError } from './errors.js';\nimport type { NextFetchInit } from './nextCache.js';\nimport { applySite } from './site.js';\n\n/** Fetch's `credentials` mode (spelled out: the DOM lib type is not available to Node consumers). */\nexport type FetchCredentials = 'omit' | 'same-origin' | 'include';\n\nexport type RequestOptions = {\n method?: string;\n body?: unknown;\n signal?: AbortSignal;\n} & NextFetchInit;\n\nexport type RequestFn = <T>(path: string, options?: RequestOptions) => Promise<T>;\n\nexport type RequestConfig = {\n baseUrl: string;\n token: string | undefined;\n fetch: typeof globalThis.fetch;\n credentials: FetchCredentials | undefined;\n headers: (() => Readonly<Record<string, string>>) | undefined;\n /** The site key every request names (see site.ts); undefined: the credential's site, else the primary. */\n site: string | undefined;\n};\n\nconst parseBody = async (response: Response): Promise<unknown> => {\n const text = await response.text();\n if (text.length === 0) {\n return undefined;\n }\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n};\n\n/** Builds the JSON request function every endpoint group uses. Non-2xx responses throw ShapioApiError. */\nexport const createRequest = ({\n baseUrl,\n token,\n fetch,\n credentials,\n headers,\n site,\n}: RequestConfig): RequestFn => {\n const origin = baseUrl.replace(/\\/+$/, '');\n return async <T>(\n requestPath: string,\n { method = 'GET', body, signal, cache, next }: RequestOptions = {},\n ): Promise<T> => {\n const { path, headers: siteHeaders } = applySite(site, method, requestPath);\n const requestHeaders: Record<string, string> = {\n accept: 'application/json',\n ...siteHeaders,\n ...headers?.(),\n };\n if (token) {\n requestHeaders.authorization = `Bearer ${token}`;\n }\n if (body !== undefined) {\n requestHeaders['content-type'] = 'application/json';\n }\n // `next` is Next.js's extension of fetch (cache tags); other runtimes ignore it, and it is only set there.\n const init: RequestInit & Pick<NextFetchInit, 'next'> = {\n method,\n headers: requestHeaders,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n ...(signal ? { signal } : {}),\n ...(credentials ? { credentials } : {}),\n ...(cache ? { cache } : {}),\n ...(next ? { next } : {}),\n };\n const response = await fetch(`${origin}${path}`, init);\n const parsed = await parseBody(response);\n if (!response.ok) {\n throw new ShapioApiError(response.status, parsed);\n }\n return parsed as T;\n };\n};\n","import { createAdminApi } from './admin/index.js';\nimport { createAppAuthApi } from './appAuth/index.js';\nimport { createDeliveryClient } from './deliveryClient.js';\nimport type { NextCacheOptions } from './nextCache.js';\nimport { createRequest, type FetchCredentials } from './request.js';\nimport type { HealthResponse, ReadyResponse, VersionResponse } from './types.js';\n\nexport type ShapioClientOptions = {\n /** Base URL of the Shapio server including any BASE_PATH, e.g. `https://cms.example.com/cms`. */\n baseUrl: string;\n /** API token sent as a bearer token. */\n token?: string;\n /** Defaults to the global fetch; injectable for tests and custom agents. */\n fetch?: typeof globalThis.fetch;\n /** Fetch credentials mode. The admin uses `same-origin` so its session cookie is sent. */\n credentials?: FetchCredentials;\n /** Extra headers computed per request (the admin's CSRF token). */\n headers?: () => Readonly<Record<string, string>>;\n /**\n * The site key (multi-site instances). Delivery reads send it as `?site=`, every other request as the\n * `Shapio-Site` header. Leave it out to use the token's site, else the primary site. A site token only\n * ever reads its own site: naming another one is refused (403 `SITE_MISMATCH`).\n */\n site?: string;\n /**\n * Next.js data-cache options for delivery reads (`delivery.*`, `site.get`), e.g. `{ cache: 'force-cache' }`.\n * Under Next the reads are tagged for `revalidateTag` whether or not this is set; the cache mode is only\n * passed when asked for, and reads pinned to a snapshot are always `force-cache`. Set it outside Next to send\n * the same fetch options; `false` sends none. A read's own `next` option overrides this one.\n */\n next?: NextCacheOptions | false;\n};\n\nexport const createClient = ({\n baseUrl,\n token,\n fetch = globalThis.fetch,\n credentials,\n headers,\n site,\n next,\n}: ShapioClientOptions) => {\n const request = createRequest({ baseUrl, token, fetch, credentials, headers, site });\n const reads = createDeliveryClient(request, { site, next });\n\n return {\n /**\n * Any Shapio route, e.g. the delivery API. Delivery paths use the model's route key: a collection's\n * plural API ID (`request('/api/content/articles')`, `/api/content/articles/<id>`), a singleton's API ID\n * (`/api/content/homepage`). The admin API (`admin.*`) always uses the singular API ID.\n */\n request,\n system: {\n health: (signal?: AbortSignal) => request<HealthResponse>('/api/health', signal ? { signal } : {}),\n ready: (signal?: AbortSignal) => request<ReadyResponse>('/api/ready', signal ? { signal } : {}),\n version: (signal?: AbortSignal) => request<VersionResponse>('/api/version', signal ? { signal } : {}),\n },\n /** Published content (the delivery API), typed by the caller. */\n delivery: reads.delivery,\n /** The site as delivery sees it: key, name and SEO defaults (`GET /api/site`). */\n site: reads.site,\n admin: createAdminApi(request),\n /** Publication snapshots and the diff between two (incremental builds). */\n snapshots: reads.snapshots,\n /** End users of your sites and apps: sign-up, sign-in, tokens, OAuth. */\n appAuth: createAppAuthApi(request, baseUrl),\n };\n};\n\nexport type ShapioClient = ReturnType<typeof createClient>;\n","/**\n * Verifying Shapio's signed webhooks and deploy triggers on the receiving side (a site's revalidate route,\n * a build hook). The scheme is the server's (`apps/api/src/publishing/signature.ts`):\n * `X-Shapio-Signature: v1=<hex HMAC-SHA256(secret, \"<timestamp>.<raw body>\")>` with\n * `X-Shapio-Timestamp: <unix seconds>`; several comma-separated `v1=` values are accepted (secret rotation).\n * Uses Web Crypto, so it runs in Node, edge runtimes and browsers alike.\n */\nexport const WEBHOOK_SIGNATURE_HEADER = 'x-shapio-signature';\nexport const WEBHOOK_TIMESTAMP_HEADER = 'x-shapio-timestamp';\nexport const WEBHOOK_EVENT_HEADER = 'x-shapio-event';\n/** Requests signed further from now than this are rejected (replay protection). */\nexport const WEBHOOK_TOLERANCE_SECONDS = 300;\n\nconst SIGNATURE_VERSION = 'v1';\n\nexport type WebhookSignatureInput = {\n /** The webhook's or connection's signing secret. */\n secret: string;\n /** The `X-Shapio-Signature` header. */\n signature: string | null | undefined;\n /** The `X-Shapio-Timestamp` header. */\n timestamp: string | null | undefined;\n /** The raw request body, exactly as received (not re-serialised JSON). */\n body: string;\n /** Defaults to the current time. */\n now?: Date;\n /** Defaults to WEBHOOK_TOLERANCE_SECONDS. */\n toleranceSeconds?: number;\n};\n\nexport type WebhookSignatureCheck = { ok: true } | { ok: false; reason: string };\n\nconst toHex = (bytes: ArrayBuffer) =>\n Array.from(new Uint8Array(bytes), (byte) => byte.toString(16).padStart(2, '0')).join('');\n\n/** Compares two strings without returning early on the first difference. */\nconst constantTimeEqual = (a: string, b: string) => {\n let difference = a.length ^ b.length;\n for (let index = 0; index < Math.max(a.length, b.length); index += 1) {\n difference |= (a.charCodeAt(index) || 0) ^ (b.charCodeAt(index) || 0);\n }\n return difference === 0;\n};\n\nconst expectedSignature = async (secret: string, timestamp: number, body: string) => {\n const encoder = new TextEncoder();\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const mac = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(`${timestamp}.${body}`));\n return `${SIGNATURE_VERSION}=${toHex(mac)}`;\n};\n\n/** Checks a Shapio signature; `{ ok: false, reason }` says why it was refused (never throws for bad input). */\nexport const verifyWebhookSignature = async ({\n secret,\n signature,\n timestamp,\n body,\n now = new Date(),\n toleranceSeconds = WEBHOOK_TOLERANCE_SECONDS,\n}: WebhookSignatureInput): Promise<WebhookSignatureCheck> => {\n if (!signature || !timestamp || !/^\\d{1,12}$/.test(timestamp)) {\n return { ok: false, reason: 'missing signature or timestamp' };\n }\n const seconds = Number(timestamp);\n if (Math.abs(now.getTime() / 1000 - seconds) > toleranceSeconds) {\n return { ok: false, reason: 'timestamp outside the allowed window' };\n }\n const expected = await expectedSignature(secret, seconds, body);\n const matches = signature\n .split(',')\n .map((candidate) => candidate.trim())\n .some((candidate) => constantTimeEqual(candidate, expected));\n return matches ? { ok: true } : { ok: false, reason: 'signature mismatch' };\n};\n","/**\n * PKCE (RFC 7636) for the app side of Shapio's OAuth sign-in: the app keeps the verifier (e.g. in\n * sessionStorage) and sends the S256 challenge with the start link; the one-time code it gets back is only\n * exchanged together with that verifier. Uses Web Crypto, so it works in browsers and Node alike.\n */\nexport type AppPkcePair = { codeVerifier: string; codeChallenge: string };\n\nconst toBase64Url = (bytes: Uint8Array): string =>\n btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n\n/** The S256 challenge of a verifier: base64url(SHA-256(verifier)). */\nexport const codeChallengeOf = async (codeVerifier: string): Promise<string> =>\n toBase64Url(\n new Uint8Array(await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier))),\n );\n\n/** A fresh verifier (32 random bytes, 43 characters) and its S256 challenge. */\nexport const createPkcePair = async (): Promise<AppPkcePair> => {\n const codeVerifier = toBase64Url(globalThis.crypto.getRandomValues(new Uint8Array(32)));\n return { codeVerifier, codeChallenge: await codeChallengeOf(codeVerifier) };\n};\n"],"mappings":"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"}
package/dist/node.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Pt as ShapioClient, Qt as MediaAsset, ln as MediaVisibility } from "./index-D-BBgz21.js";
1
+ import { Lt as ShapioClient, fn as MediaVisibility, tn as MediaAsset } from "./index-C48tjTFc.js";
2
2
  //#region src/node.d.ts
3
3
  export declare const mimeTypeOf: (path: string) => string | undefined;
4
4
  export type UploadFileInput = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapio/client",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Typed HTTP client for Shapio APIs.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://shapio.dev",
@@ -32,7 +32,7 @@
32
32
  "dist"
33
33
  ],
34
34
  "dependencies": {
35
- "@shapio/schema": "0.4.1"
35
+ "@shapio/schema": "0.5.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "tsdown": "0.23.0",