@botlr/sdk 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +66 -2
- package/dist/index.cjs +437 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +661 -0
- package/dist/index.d.ts +661 -0
- package/dist/index.js +414 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -3
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
type BotlrContext = {
|
|
2
|
+
appId: string;
|
|
3
|
+
locale?: string;
|
|
4
|
+
preview?: boolean;
|
|
5
|
+
};
|
|
6
|
+
type BotlrClientConfig = {
|
|
7
|
+
/** API origin, for example `https://api.botlr.io`. No trailing slash. */
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
/** App instance ID. Sent as `x-botlr-app-id` on every request. */
|
|
10
|
+
appId: string;
|
|
11
|
+
/** Site token. Sent as `Authorization: Bearer` on every read. Optional in dev mode. */
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
/** Preview JWT, passed as `token` to `/api/resolve` when `preview` is on. */
|
|
14
|
+
previewToken?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Personal access token with `write:sections`. Used only by `sections.push`;
|
|
17
|
+
* the server never accepts it for reads.
|
|
18
|
+
*/
|
|
19
|
+
personalToken?: string;
|
|
20
|
+
/** A fetch implementation; defaults to the global `fetch`. */
|
|
21
|
+
fetch?: typeof fetch;
|
|
22
|
+
locale?: string;
|
|
23
|
+
preview?: boolean;
|
|
24
|
+
};
|
|
25
|
+
type BotlrQueryValue = string | number | boolean | null | undefined;
|
|
26
|
+
type BotlrQuery = Record<string, BotlrQueryValue | BotlrQueryValue[]>;
|
|
27
|
+
type BotlrEntryMeta = {
|
|
28
|
+
id: string;
|
|
29
|
+
contentType: string;
|
|
30
|
+
createdAt?: string;
|
|
31
|
+
updatedAt?: string;
|
|
32
|
+
publishedAt?: string;
|
|
33
|
+
locale?: string;
|
|
34
|
+
};
|
|
35
|
+
type BotlrEntry<TFields> = BotlrEntryMeta & {
|
|
36
|
+
fields: TFields;
|
|
37
|
+
};
|
|
38
|
+
type GetEntryBySlugParams = {
|
|
39
|
+
contentType: string;
|
|
40
|
+
slug: string;
|
|
41
|
+
locale?: string;
|
|
42
|
+
};
|
|
43
|
+
type GetEntriesParams = {
|
|
44
|
+
contentType: string;
|
|
45
|
+
locale?: string;
|
|
46
|
+
limit?: number;
|
|
47
|
+
offset?: number;
|
|
48
|
+
sort?: string;
|
|
49
|
+
filters?: Record<string, BotlrQueryValue>;
|
|
50
|
+
};
|
|
51
|
+
type GetSingletonParams = {
|
|
52
|
+
key: string;
|
|
53
|
+
locale?: string;
|
|
54
|
+
};
|
|
55
|
+
type GetPageListParams = {
|
|
56
|
+
parentId?: string;
|
|
57
|
+
appInstanceId?: string;
|
|
58
|
+
tags?: string[];
|
|
59
|
+
limit?: number;
|
|
60
|
+
offset?: number;
|
|
61
|
+
locale?: string;
|
|
62
|
+
orderBy?: string;
|
|
63
|
+
type?: string;
|
|
64
|
+
};
|
|
65
|
+
type GetPageSlugListParams = {
|
|
66
|
+
appInstanceId?: string;
|
|
67
|
+
locale?: string;
|
|
68
|
+
limit?: number;
|
|
69
|
+
offset?: number;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Publisher scope: the app instance a page is rendered for. Injected into
|
|
73
|
+
* every section component so it can build asset URLs and scope content.
|
|
74
|
+
*/
|
|
75
|
+
interface PublisherScope {
|
|
76
|
+
/** Organization slug (for example "acme") */
|
|
77
|
+
orgSlug: string;
|
|
78
|
+
/** Project slug (for example "website") */
|
|
79
|
+
projectSlug: string;
|
|
80
|
+
/** App instance slug (for example "production") */
|
|
81
|
+
appInstanceSlug: string;
|
|
82
|
+
/** App instance ID (UUID) */
|
|
83
|
+
appInstanceId: string;
|
|
84
|
+
/** Current locale (for example "en", "da") */
|
|
85
|
+
locale: string;
|
|
86
|
+
/**
|
|
87
|
+
* URL prefix for the current locale ("" for the default locale, "en" for
|
|
88
|
+
* English). Used to strip locale prefixes from hard-coded hrefs when
|
|
89
|
+
* matching against page slugs. No leading or trailing slash.
|
|
90
|
+
*/
|
|
91
|
+
localePrefix?: string;
|
|
92
|
+
}
|
|
93
|
+
type BreadcrumbItem = {
|
|
94
|
+
id: string;
|
|
95
|
+
name: string;
|
|
96
|
+
slug?: string;
|
|
97
|
+
full_slug?: string;
|
|
98
|
+
};
|
|
99
|
+
/** The page a section is rendered on. */
|
|
100
|
+
interface PageScope {
|
|
101
|
+
id: string;
|
|
102
|
+
kind: string;
|
|
103
|
+
name: string;
|
|
104
|
+
/** Full slug without locale and leading slash */
|
|
105
|
+
slug: string;
|
|
106
|
+
breadcrumbs?: BreadcrumbItem[];
|
|
107
|
+
}
|
|
108
|
+
type ResponsiveSpan = {
|
|
109
|
+
mobile: number;
|
|
110
|
+
tablet?: number;
|
|
111
|
+
desktop?: number;
|
|
112
|
+
};
|
|
113
|
+
type ResponsiveGap = {
|
|
114
|
+
mobile?: number;
|
|
115
|
+
tablet?: number;
|
|
116
|
+
desktop?: number;
|
|
117
|
+
};
|
|
118
|
+
type GridColumn = {
|
|
119
|
+
span: ResponsiveSpan;
|
|
120
|
+
sections: LayoutNode[];
|
|
121
|
+
hideOnMobile?: boolean;
|
|
122
|
+
hideOnTablet?: boolean;
|
|
123
|
+
hideOnDesktop?: boolean;
|
|
124
|
+
};
|
|
125
|
+
type SpacingSize = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
|
|
126
|
+
type GridContainerInstance = {
|
|
127
|
+
_key: string;
|
|
128
|
+
type: "grid-container";
|
|
129
|
+
columns: GridColumn[];
|
|
130
|
+
gap?: ResponsiveGap;
|
|
131
|
+
status?: "draft" | "published";
|
|
132
|
+
publishedAt?: string;
|
|
133
|
+
collapsed?: boolean;
|
|
134
|
+
visibility?: VisibilityRules[];
|
|
135
|
+
maxWidth?: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl" | "full" | "none";
|
|
136
|
+
paddingX?: SpacingSize;
|
|
137
|
+
paddingY?: SpacingSize;
|
|
138
|
+
marginX?: SpacingSize | "auto";
|
|
139
|
+
marginY?: SpacingSize;
|
|
140
|
+
background?: string;
|
|
141
|
+
fullWidthBackground?: boolean;
|
|
142
|
+
border?: boolean;
|
|
143
|
+
borderRadius?: "none" | "sm" | "md" | "lg" | "xl" | "2xl" | "full";
|
|
144
|
+
shadow?: "none" | "sm" | "md" | "lg" | "xl" | "2xl";
|
|
145
|
+
alignItems?: "start" | "center" | "end" | "stretch";
|
|
146
|
+
justifyContent?: "start" | "center" | "end" | "between" | "around" | "evenly";
|
|
147
|
+
};
|
|
148
|
+
type InlineSectionInstance = {
|
|
149
|
+
_key: string;
|
|
150
|
+
mode: "inline";
|
|
151
|
+
sectionType: string;
|
|
152
|
+
props: Record<string, any>;
|
|
153
|
+
status?: "draft" | "published";
|
|
154
|
+
publishedAt?: string;
|
|
155
|
+
visibility?: VisibilityRules[];
|
|
156
|
+
};
|
|
157
|
+
type SharedSectionInstance = {
|
|
158
|
+
_key: string;
|
|
159
|
+
mode: "shared";
|
|
160
|
+
sharedSectionId: string;
|
|
161
|
+
overrides?: Record<string, any>;
|
|
162
|
+
visibility?: VisibilityRules[];
|
|
163
|
+
};
|
|
164
|
+
type LayoutNode = InlineSectionInstance | SharedSectionInstance | GridContainerInstance;
|
|
165
|
+
/** Per-locale visibility rules on a layout node. */
|
|
166
|
+
interface VisibilityRules {
|
|
167
|
+
locale: string;
|
|
168
|
+
includePages?: string[];
|
|
169
|
+
excludePages?: string[];
|
|
170
|
+
includePatterns?: string[];
|
|
171
|
+
excludePatterns?: string[];
|
|
172
|
+
includeDocTypes?: string[];
|
|
173
|
+
excludeDocTypes?: string[];
|
|
174
|
+
includeEnvironments?: string[];
|
|
175
|
+
excludeEnvironments?: string[];
|
|
176
|
+
requireRoles?: string[];
|
|
177
|
+
excludeRoles?: string[];
|
|
178
|
+
}
|
|
179
|
+
type AssetData = {
|
|
180
|
+
id: string;
|
|
181
|
+
filename: string;
|
|
182
|
+
mime_type: string;
|
|
183
|
+
url?: string;
|
|
184
|
+
metadata?: Record<string, any>;
|
|
185
|
+
};
|
|
186
|
+
type PageDiscoveryData = {
|
|
187
|
+
id: string;
|
|
188
|
+
name: string;
|
|
189
|
+
slug?: string;
|
|
190
|
+
full_slug?: string;
|
|
191
|
+
description?: string;
|
|
192
|
+
image?: AssetData;
|
|
193
|
+
published_at?: string;
|
|
194
|
+
seo_meta?: Record<string, any>;
|
|
195
|
+
display_meta?: Record<string, any>;
|
|
196
|
+
};
|
|
197
|
+
type ThemeData = {
|
|
198
|
+
id: string;
|
|
199
|
+
name: string;
|
|
200
|
+
default_template_html: string;
|
|
201
|
+
default_template_css?: string;
|
|
202
|
+
settings?: Record<string, any>;
|
|
203
|
+
};
|
|
204
|
+
type PageTemplateData = {
|
|
205
|
+
template_html?: string;
|
|
206
|
+
template_css?: string;
|
|
207
|
+
layout?: Record<string, LayoutNode[]>;
|
|
208
|
+
};
|
|
209
|
+
type PageResponse = {
|
|
210
|
+
id: string;
|
|
211
|
+
name: string;
|
|
212
|
+
slug?: string;
|
|
213
|
+
/** Full slug without locale prefix, set by `resolvePage`. */
|
|
214
|
+
full_slug?: string;
|
|
215
|
+
layout: Record<string, LayoutNode[]>;
|
|
216
|
+
status: string;
|
|
217
|
+
theme?: ThemeData;
|
|
218
|
+
page_template?: PageTemplateData;
|
|
219
|
+
seo_meta?: Record<string, any>;
|
|
220
|
+
/** The same page in other locales, for hreflang links. */
|
|
221
|
+
alternate_translations?: AlternateTranslation[];
|
|
222
|
+
breadcrumbs?: BreadcrumbItem[];
|
|
223
|
+
};
|
|
224
|
+
/** One translation of a page: its locale and full slug with leading slash. */
|
|
225
|
+
type AlternateTranslation = {
|
|
226
|
+
locale: string;
|
|
227
|
+
full_slug: string;
|
|
228
|
+
} & Record<string, string>;
|
|
229
|
+
type PageListResponse = {
|
|
230
|
+
success: boolean;
|
|
231
|
+
data: PageDiscoveryData[];
|
|
232
|
+
total: number;
|
|
233
|
+
};
|
|
234
|
+
type PageSlugListResponse = {
|
|
235
|
+
data: string[];
|
|
236
|
+
};
|
|
237
|
+
type MenuResponse = {
|
|
238
|
+
success: boolean;
|
|
239
|
+
menu: any;
|
|
240
|
+
};
|
|
241
|
+
type FormResponse = {
|
|
242
|
+
success: boolean;
|
|
243
|
+
form: any;
|
|
244
|
+
};
|
|
245
|
+
type ContentData = {
|
|
246
|
+
id: string;
|
|
247
|
+
type: string;
|
|
248
|
+
name: string;
|
|
249
|
+
slug?: string;
|
|
250
|
+
full_slug?: string;
|
|
251
|
+
content?: Record<string, any>;
|
|
252
|
+
layout?: Record<string, LayoutNode[]>;
|
|
253
|
+
seo_meta?: Record<string, any>;
|
|
254
|
+
status: string;
|
|
255
|
+
theme?: ThemeData;
|
|
256
|
+
page_template?: PageTemplateData;
|
|
257
|
+
};
|
|
258
|
+
type RedirectData = {
|
|
259
|
+
destination: string;
|
|
260
|
+
status_code: number;
|
|
261
|
+
};
|
|
262
|
+
/** Build-time redirect list. `source`/`destination` are full paths, locale prefix included. */
|
|
263
|
+
type RedirectEntry = {
|
|
264
|
+
source: string;
|
|
265
|
+
/** Internal path or absolute URL */
|
|
266
|
+
destination: string;
|
|
267
|
+
/** Defaults to 308 */
|
|
268
|
+
status_code?: number;
|
|
269
|
+
locale?: string | null;
|
|
270
|
+
};
|
|
271
|
+
type RedirectsResponse = {
|
|
272
|
+
redirects?: RedirectEntry[];
|
|
273
|
+
};
|
|
274
|
+
type ResolveResponse = {
|
|
275
|
+
kind: "page" | "redirect" | "dynamic" | "404";
|
|
276
|
+
data?: ContentData;
|
|
277
|
+
redirect?: RedirectData;
|
|
278
|
+
breadcrumbs?: BreadcrumbItem[];
|
|
279
|
+
alternate_translations?: AlternateTranslation[];
|
|
280
|
+
};
|
|
281
|
+
type ListField = {
|
|
282
|
+
id: string;
|
|
283
|
+
key: string;
|
|
284
|
+
label: string;
|
|
285
|
+
type: string;
|
|
286
|
+
isLocalized: boolean;
|
|
287
|
+
isRequired: boolean;
|
|
288
|
+
sortOrder: number;
|
|
289
|
+
config: Record<string, any>;
|
|
290
|
+
visibility: string;
|
|
291
|
+
isReadOnly: boolean;
|
|
292
|
+
alignment: string;
|
|
293
|
+
};
|
|
294
|
+
type ListResponse = {
|
|
295
|
+
success: boolean;
|
|
296
|
+
data: {
|
|
297
|
+
id: string;
|
|
298
|
+
slug: string;
|
|
299
|
+
name: string;
|
|
300
|
+
description?: string;
|
|
301
|
+
defaultLang: string;
|
|
302
|
+
enabledLanguages: string[];
|
|
303
|
+
fields: ListField[];
|
|
304
|
+
rows: Record<string, any>[];
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Section source bridge: types and hash helpers.
|
|
310
|
+
*
|
|
311
|
+
* Mirrors the contract in xam-mono's docs/SECTION_SOURCE_BRIDGE.md. The hash
|
|
312
|
+
* rules are reproduced here exactly as the server computes them, so a client
|
|
313
|
+
* can tell "clean", "modified", "behind" and "diverged" apart without a
|
|
314
|
+
* round trip:
|
|
315
|
+
*
|
|
316
|
+
* - `file.sha256` = sha256 of the UTF-8 content, hex, content exactly as sent
|
|
317
|
+
* - `contentHash` = sha256 over `"{path}\n{sha256}\n"` for every file, sorted by path
|
|
318
|
+
*
|
|
319
|
+
* The manifest is not hashed.
|
|
320
|
+
*/
|
|
321
|
+
/** The source variant a section is stored for, for example `react-next` or `html`. */
|
|
322
|
+
type SectionFramework = string;
|
|
323
|
+
type SectionSourceScope = "instance" | "shared";
|
|
324
|
+
/** `<slug>.botlr.json`, kept next to the section's entry file. */
|
|
325
|
+
interface SectionManifest {
|
|
326
|
+
/** Section definition slug. Must equal the name used in the URL on push. */
|
|
327
|
+
section: string;
|
|
328
|
+
framework: SectionFramework;
|
|
329
|
+
/** Entry file, relative to the manifest's directory. Must be listed in `files`. */
|
|
330
|
+
entry: string;
|
|
331
|
+
/** Named export of the component in `entry`. */
|
|
332
|
+
exportName?: string;
|
|
333
|
+
/** Every file of the section, relative to the manifest's directory, forward slashes only. */
|
|
334
|
+
files: string[];
|
|
335
|
+
title?: string;
|
|
336
|
+
description?: string;
|
|
337
|
+
category?: string;
|
|
338
|
+
icon?: string;
|
|
339
|
+
dependencies?: SectionDependencies;
|
|
340
|
+
/** Unknown keys are kept by the server. */
|
|
341
|
+
[key: string]: unknown;
|
|
342
|
+
}
|
|
343
|
+
interface SectionDependencies {
|
|
344
|
+
/** npm packages the section imports, with the ranges the app uses. */
|
|
345
|
+
npm?: Record<string, string>;
|
|
346
|
+
/** Local modules the section imports; the pulling app must already have them. */
|
|
347
|
+
internal?: string[];
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Pull state keys the server strips from a manifest. The CLI keeps these in
|
|
351
|
+
* `.botlr/sections.lock.json`, never in the manifest.
|
|
352
|
+
*/
|
|
353
|
+
declare const MANIFEST_STATE_KEYS: readonly ["version", "hash", "contentHash", "pulledAt", "scope"];
|
|
354
|
+
interface SectionSourceFileInput {
|
|
355
|
+
path: string;
|
|
356
|
+
content: string;
|
|
357
|
+
}
|
|
358
|
+
interface SectionSourceFile extends SectionSourceFileInput {
|
|
359
|
+
sha256: string;
|
|
360
|
+
}
|
|
361
|
+
interface SectionDefinitionScope {
|
|
362
|
+
tenantId: string;
|
|
363
|
+
organizationId: string | null;
|
|
364
|
+
projectId: string | null;
|
|
365
|
+
}
|
|
366
|
+
interface SectionDefinition {
|
|
367
|
+
id: string;
|
|
368
|
+
name: string;
|
|
369
|
+
title: string;
|
|
370
|
+
schema: Record<string, unknown>;
|
|
371
|
+
scope: SectionDefinitionScope;
|
|
372
|
+
}
|
|
373
|
+
interface SectionSource {
|
|
374
|
+
scope: SectionSourceScope;
|
|
375
|
+
framework: SectionFramework;
|
|
376
|
+
version: number;
|
|
377
|
+
contentHash: string;
|
|
378
|
+
manifest: SectionManifest;
|
|
379
|
+
message: string | null;
|
|
380
|
+
createdAt: string;
|
|
381
|
+
files: SectionSourceFile[];
|
|
382
|
+
}
|
|
383
|
+
interface SectionSourceScopeSummary {
|
|
384
|
+
version: number;
|
|
385
|
+
contentHash: string;
|
|
386
|
+
updatedAt: string;
|
|
387
|
+
}
|
|
388
|
+
interface SectionSourceSummary {
|
|
389
|
+
name: string;
|
|
390
|
+
title: string;
|
|
391
|
+
definitionId: string;
|
|
392
|
+
instance: SectionSourceScopeSummary | null;
|
|
393
|
+
shared: SectionSourceScopeSummary | null;
|
|
394
|
+
/** Which scope a pull without `scope` returns. */
|
|
395
|
+
effective: SectionSourceScope;
|
|
396
|
+
}
|
|
397
|
+
interface SectionSourceListResponse {
|
|
398
|
+
framework: SectionFramework;
|
|
399
|
+
sections: SectionSourceSummary[];
|
|
400
|
+
}
|
|
401
|
+
interface SectionSourcePullResponse {
|
|
402
|
+
/** null only for an instance row whose section no longer resolves to a definition */
|
|
403
|
+
definition: SectionDefinition | null;
|
|
404
|
+
source: SectionSource;
|
|
405
|
+
}
|
|
406
|
+
interface SectionSourceListParams {
|
|
407
|
+
framework: SectionFramework;
|
|
408
|
+
}
|
|
409
|
+
interface SectionSourcePullParams {
|
|
410
|
+
framework: SectionFramework;
|
|
411
|
+
/** A specific version; latest when omitted. */
|
|
412
|
+
version?: number;
|
|
413
|
+
/** Force one scope instead of "instance first, shared second". */
|
|
414
|
+
scope?: SectionSourceScope;
|
|
415
|
+
}
|
|
416
|
+
interface SectionSourcePushBody {
|
|
417
|
+
framework: SectionFramework;
|
|
418
|
+
manifest: SectionManifest;
|
|
419
|
+
files: SectionSourceFileInput[];
|
|
420
|
+
/** Defaults to the client's `appId`. */
|
|
421
|
+
appInstanceId?: string;
|
|
422
|
+
/** Write the shared row (per section definition) instead of this app's row. */
|
|
423
|
+
shared?: boolean;
|
|
424
|
+
/**
|
|
425
|
+
* The version the push is based on; 0 means "none yet". Omit to force the
|
|
426
|
+
* push without a conflict check.
|
|
427
|
+
*/
|
|
428
|
+
baseVersion?: number;
|
|
429
|
+
/** At most 500 characters. */
|
|
430
|
+
message?: string;
|
|
431
|
+
/** Add a project-scoped section definition when none exists. */
|
|
432
|
+
create?: boolean;
|
|
433
|
+
}
|
|
434
|
+
interface SectionSourcePushResponse {
|
|
435
|
+
/** true on 201 (new version), false on 200 (nothing changed) */
|
|
436
|
+
created: boolean;
|
|
437
|
+
scope: SectionSourceScope;
|
|
438
|
+
definition: SectionDefinition;
|
|
439
|
+
version: number;
|
|
440
|
+
contentHash: string;
|
|
441
|
+
}
|
|
442
|
+
declare const SECTION_SOURCE_LIMITS: {
|
|
443
|
+
readonly maxFiles: 50;
|
|
444
|
+
readonly maxFileBytes: number;
|
|
445
|
+
readonly maxTotalBytes: number;
|
|
446
|
+
readonly maxPathLength: 200;
|
|
447
|
+
readonly maxMessageLength: 500;
|
|
448
|
+
};
|
|
449
|
+
declare const SECTION_PATH_RE: RegExp;
|
|
450
|
+
declare const SECTION_FRAMEWORK_RE: RegExp;
|
|
451
|
+
/** True when `path` is a relative path the bridge accepts. */
|
|
452
|
+
declare function isValidSectionPath(path: string): boolean;
|
|
453
|
+
declare function isValidFramework(framework: string): boolean;
|
|
454
|
+
/** sha256 of the UTF-8 encoding of `content`, as lowercase hex. */
|
|
455
|
+
declare function fileSha256(content: string): Promise<string>;
|
|
456
|
+
/**
|
|
457
|
+
* The content hash of a file set: sha256 over `"{path}\n{sha256}\n"` for every
|
|
458
|
+
* file, sorted by path. Accepts files with a precomputed `sha256` or plain
|
|
459
|
+
* `{ path, content }` pairs.
|
|
460
|
+
*/
|
|
461
|
+
declare function contentHash(files: ReadonlyArray<SectionSourceFileInput | SectionSourceFile>): Promise<string>;
|
|
462
|
+
/** Every file with its `sha256`, in the order given. Files that already carry one are kept as is. */
|
|
463
|
+
declare function hashFiles(files: ReadonlyArray<SectionSourceFileInput | SectionSourceFile>): Promise<SectionSourceFile[]>;
|
|
464
|
+
/** A copy of `manifest` without the pull-state keys the server strips. */
|
|
465
|
+
declare function stripManifestState<T extends Record<string, unknown>>(manifest: T): SectionManifest;
|
|
466
|
+
|
|
467
|
+
type RequestOptions = Omit<RequestInit, "headers"> & {
|
|
468
|
+
query?: BotlrQuery;
|
|
469
|
+
context?: Partial<BotlrContext>;
|
|
470
|
+
headers?: Record<string, string>;
|
|
471
|
+
};
|
|
472
|
+
declare function toQueryString(query: BotlrQuery): string;
|
|
473
|
+
declare function contextToHeaders(context?: Partial<BotlrContext>): Record<string, string>;
|
|
474
|
+
type BotlrClient = ReturnType<typeof createBotlrClient>;
|
|
475
|
+
/**
|
|
476
|
+
* A Botlr client. Every call sends the site token as `Authorization: Bearer`
|
|
477
|
+
* plus `x-botlr-app-id`, `x-botlr-locale` and `x-botlr-preview` from the
|
|
478
|
+
* config; `sections.push` sends the personal token instead.
|
|
479
|
+
*/
|
|
480
|
+
declare function createBotlrClient(config: BotlrClientConfig): {
|
|
481
|
+
request: <T>(path: string, options?: RequestOptions) => Promise<T>;
|
|
482
|
+
/** The resolved config, for wrappers that need `baseUrl` or `appId`. */
|
|
483
|
+
config: Readonly<BotlrClientConfig>;
|
|
484
|
+
withContext(contextOverride: Partial<BotlrContext>): {
|
|
485
|
+
request: <T>(path: string, options?: RequestOptions) => Promise<T>;
|
|
486
|
+
/** The resolved config, for wrappers that need `baseUrl` or `appId`. */
|
|
487
|
+
config: Readonly<BotlrClientConfig>;
|
|
488
|
+
withContext(contextOverride: Partial<BotlrContext>): /*elided*/ any;
|
|
489
|
+
getEntryBySlug<TFields>(params: GetEntryBySlugParams): Promise<BotlrEntry<TFields> | null>;
|
|
490
|
+
getEntries<TFields>(params: GetEntriesParams): Promise<{
|
|
491
|
+
items: BotlrEntry<TFields>[];
|
|
492
|
+
total: number;
|
|
493
|
+
}>;
|
|
494
|
+
getSingleton<TFields>(params: GetSingletonParams): Promise<BotlrEntry<TFields> | null>;
|
|
495
|
+
getPageBySlug(slug: string, locale?: string): Promise<PageResponse>;
|
|
496
|
+
resolveUrl(slug: string, locale?: string): Promise<ResolveResponse>;
|
|
497
|
+
getPageList(params?: GetPageListParams): Promise<PageListResponse>;
|
|
498
|
+
getPageSlugList(params?: GetPageSlugListParams): Promise<PageSlugListResponse>;
|
|
499
|
+
getMenu(key: string, locale?: string): Promise<MenuResponse>;
|
|
500
|
+
getForm(key: string, locale?: string): Promise<FormResponse>;
|
|
501
|
+
getList(appId: string, listId: string, locale?: string): Promise<ListResponse>;
|
|
502
|
+
getConfigurator<T = unknown>(configuratorId: string, versionId?: string): Promise<T>;
|
|
503
|
+
/** GET `/api/{endpoint}` with the app and locale added to the query. */
|
|
504
|
+
getData<T = unknown>(endpoint: string, queryParams?: BotlrQuery, locale?: string): Promise<T>;
|
|
505
|
+
/** POST `data` as JSON to `/api/{endpoint}`, for forms and other submissions. */
|
|
506
|
+
submitData<T = unknown>(endpoint: string, data: Record<string, unknown>, locale?: string, queryParams?: BotlrQuery): Promise<T>;
|
|
507
|
+
getAppInfo<T = unknown>(): Promise<T>;
|
|
508
|
+
getSitemap<T = unknown>(): Promise<T>;
|
|
509
|
+
/** Every redirect for the app, across all locales. */
|
|
510
|
+
getRedirects(): Promise<RedirectsResponse>;
|
|
511
|
+
getAssetById<T = unknown>(assetId: string): Promise<T>;
|
|
512
|
+
sections: {
|
|
513
|
+
/** Every section the app can pull for `framework`, with the latest version per scope. */
|
|
514
|
+
list(params: SectionSourceListParams): Promise<SectionSourceListResponse>;
|
|
515
|
+
/** The section's source: this app's row first, the shared row second. */
|
|
516
|
+
pull(name: string, params: SectionSourcePullParams): Promise<SectionSourcePullResponse>;
|
|
517
|
+
/**
|
|
518
|
+
* Push a new version with the personal access token (`write:sections`).
|
|
519
|
+
* Resolves with `created: true` on 201 and `created: false` when nothing
|
|
520
|
+
* changed; throws `BotlrConflictError` when `baseVersion` is not the latest.
|
|
521
|
+
*/
|
|
522
|
+
push(name: string, body: SectionSourcePushBody): Promise<SectionSourcePushResponse>;
|
|
523
|
+
};
|
|
524
|
+
};
|
|
525
|
+
getEntryBySlug<TFields>(params: GetEntryBySlugParams): Promise<BotlrEntry<TFields> | null>;
|
|
526
|
+
getEntries<TFields>(params: GetEntriesParams): Promise<{
|
|
527
|
+
items: BotlrEntry<TFields>[];
|
|
528
|
+
total: number;
|
|
529
|
+
}>;
|
|
530
|
+
getSingleton<TFields>(params: GetSingletonParams): Promise<BotlrEntry<TFields> | null>;
|
|
531
|
+
getPageBySlug(slug: string, locale?: string): Promise<PageResponse>;
|
|
532
|
+
resolveUrl(slug: string, locale?: string): Promise<ResolveResponse>;
|
|
533
|
+
getPageList(params?: GetPageListParams): Promise<PageListResponse>;
|
|
534
|
+
getPageSlugList(params?: GetPageSlugListParams): Promise<PageSlugListResponse>;
|
|
535
|
+
getMenu(key: string, locale?: string): Promise<MenuResponse>;
|
|
536
|
+
getForm(key: string, locale?: string): Promise<FormResponse>;
|
|
537
|
+
getList(appId: string, listId: string, locale?: string): Promise<ListResponse>;
|
|
538
|
+
getConfigurator<T = unknown>(configuratorId: string, versionId?: string): Promise<T>;
|
|
539
|
+
/** GET `/api/{endpoint}` with the app and locale added to the query. */
|
|
540
|
+
getData<T = unknown>(endpoint: string, queryParams?: BotlrQuery, locale?: string): Promise<T>;
|
|
541
|
+
/** POST `data` as JSON to `/api/{endpoint}`, for forms and other submissions. */
|
|
542
|
+
submitData<T = unknown>(endpoint: string, data: Record<string, unknown>, locale?: string, queryParams?: BotlrQuery): Promise<T>;
|
|
543
|
+
getAppInfo<T = unknown>(): Promise<T>;
|
|
544
|
+
getSitemap<T = unknown>(): Promise<T>;
|
|
545
|
+
/** Every redirect for the app, across all locales. */
|
|
546
|
+
getRedirects(): Promise<RedirectsResponse>;
|
|
547
|
+
getAssetById<T = unknown>(assetId: string): Promise<T>;
|
|
548
|
+
sections: {
|
|
549
|
+
/** Every section the app can pull for `framework`, with the latest version per scope. */
|
|
550
|
+
list(params: SectionSourceListParams): Promise<SectionSourceListResponse>;
|
|
551
|
+
/** The section's source: this app's row first, the shared row second. */
|
|
552
|
+
pull(name: string, params: SectionSourcePullParams): Promise<SectionSourcePullResponse>;
|
|
553
|
+
/**
|
|
554
|
+
* Push a new version with the personal access token (`write:sections`).
|
|
555
|
+
* Resolves with `created: true` on 201 and `created: false` when nothing
|
|
556
|
+
* changed; throws `BotlrConflictError` when `baseVersion` is not the latest.
|
|
557
|
+
*/
|
|
558
|
+
push(name: string, body: SectionSourcePushBody): Promise<SectionSourcePushResponse>;
|
|
559
|
+
};
|
|
560
|
+
};
|
|
561
|
+
declare function createBotlrFactory(defaults?: {
|
|
562
|
+
fetch?: typeof fetch;
|
|
563
|
+
}): {
|
|
564
|
+
create(config: Omit<BotlrClientConfig, "fetch">): {
|
|
565
|
+
request: <T>(path: string, options?: RequestOptions) => Promise<T>;
|
|
566
|
+
/** The resolved config, for wrappers that need `baseUrl` or `appId`. */
|
|
567
|
+
config: Readonly<BotlrClientConfig>;
|
|
568
|
+
withContext(contextOverride: Partial<BotlrContext>): /*elided*/ any;
|
|
569
|
+
getEntryBySlug<TFields>(params: GetEntryBySlugParams): Promise<BotlrEntry<TFields> | null>;
|
|
570
|
+
getEntries<TFields>(params: GetEntriesParams): Promise<{
|
|
571
|
+
items: BotlrEntry<TFields>[];
|
|
572
|
+
total: number;
|
|
573
|
+
}>;
|
|
574
|
+
getSingleton<TFields>(params: GetSingletonParams): Promise<BotlrEntry<TFields> | null>;
|
|
575
|
+
getPageBySlug(slug: string, locale?: string): Promise<PageResponse>;
|
|
576
|
+
resolveUrl(slug: string, locale?: string): Promise<ResolveResponse>;
|
|
577
|
+
getPageList(params?: GetPageListParams): Promise<PageListResponse>;
|
|
578
|
+
getPageSlugList(params?: GetPageSlugListParams): Promise<PageSlugListResponse>;
|
|
579
|
+
getMenu(key: string, locale?: string): Promise<MenuResponse>;
|
|
580
|
+
getForm(key: string, locale?: string): Promise<FormResponse>;
|
|
581
|
+
getList(appId: string, listId: string, locale?: string): Promise<ListResponse>;
|
|
582
|
+
getConfigurator<T = unknown>(configuratorId: string, versionId?: string): Promise<T>;
|
|
583
|
+
/** GET `/api/{endpoint}` with the app and locale added to the query. */
|
|
584
|
+
getData<T = unknown>(endpoint: string, queryParams?: BotlrQuery, locale?: string): Promise<T>;
|
|
585
|
+
/** POST `data` as JSON to `/api/{endpoint}`, for forms and other submissions. */
|
|
586
|
+
submitData<T = unknown>(endpoint: string, data: Record<string, unknown>, locale?: string, queryParams?: BotlrQuery): Promise<T>;
|
|
587
|
+
getAppInfo<T = unknown>(): Promise<T>;
|
|
588
|
+
getSitemap<T = unknown>(): Promise<T>;
|
|
589
|
+
/** Every redirect for the app, across all locales. */
|
|
590
|
+
getRedirects(): Promise<RedirectsResponse>;
|
|
591
|
+
getAssetById<T = unknown>(assetId: string): Promise<T>;
|
|
592
|
+
sections: {
|
|
593
|
+
/** Every section the app can pull for `framework`, with the latest version per scope. */
|
|
594
|
+
list(params: SectionSourceListParams): Promise<SectionSourceListResponse>;
|
|
595
|
+
/** The section's source: this app's row first, the shared row second. */
|
|
596
|
+
pull(name: string, params: SectionSourcePullParams): Promise<SectionSourcePullResponse>;
|
|
597
|
+
/**
|
|
598
|
+
* Push a new version with the personal access token (`write:sections`).
|
|
599
|
+
* Resolves with `created: true` on 201 and `created: false` when nothing
|
|
600
|
+
* changed; throws `BotlrConflictError` when `baseVersion` is not the latest.
|
|
601
|
+
*/
|
|
602
|
+
push(name: string, body: SectionSourcePushBody): Promise<SectionSourcePushResponse>;
|
|
603
|
+
};
|
|
604
|
+
};
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Thrown for every non-2xx response. `status` is the HTTP status and
|
|
609
|
+
* `details` the parsed JSON body (or the raw text when the body is not JSON).
|
|
610
|
+
*/
|
|
611
|
+
declare class BotlrError extends Error {
|
|
612
|
+
readonly status: number | undefined;
|
|
613
|
+
readonly details: unknown;
|
|
614
|
+
constructor(message: string, status?: number, details?: unknown);
|
|
615
|
+
}
|
|
616
|
+
/** The latest version of a section source, as reported on a push conflict. */
|
|
617
|
+
type ConflictLatest = {
|
|
618
|
+
version: number;
|
|
619
|
+
contentHash: string;
|
|
620
|
+
};
|
|
621
|
+
/**
|
|
622
|
+
* Thrown by `sections.push` on 409: `baseVersion` was not the latest version,
|
|
623
|
+
* or a concurrent push won. `latest` is null when the server has no version
|
|
624
|
+
* at all (the client sent a `baseVersion` above 0 for a section with no source).
|
|
625
|
+
*/
|
|
626
|
+
declare class BotlrConflictError extends BotlrError {
|
|
627
|
+
readonly latest: ConflictLatest | null;
|
|
628
|
+
constructor(message: string, latest: ConflictLatest | null, details?: unknown);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/** An asset as a section prop: the legacy bare id, or the `AssetData` object. */
|
|
632
|
+
type AssetRef = string | AssetData | null | undefined;
|
|
633
|
+
declare function isAssetData(value: unknown): value is AssetData;
|
|
634
|
+
declare function getAssetId(asset: AssetRef): string | undefined;
|
|
635
|
+
/** The filename, when the asset is an `AssetData` object. A bare id has none. */
|
|
636
|
+
declare function getAssetFilename(asset: AssetRef): string | undefined;
|
|
637
|
+
interface AssetUrlOptions {
|
|
638
|
+
/** The media server origin, for example `https://media.example.com`. */
|
|
639
|
+
mediaUrl: string;
|
|
640
|
+
/** The image recipe segment; defaults to `view`. */
|
|
641
|
+
recipe?: string;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* The media server URL of an asset:
|
|
645
|
+
* `{mediaUrl}/images/{orgSlug}/{assetId}/{recipe}/{filename}`.
|
|
646
|
+
*
|
|
647
|
+
* Falls back to `image.jpg` for a bare id, and to `{mediaUrl}/images/{assetId}`
|
|
648
|
+
* when no org slug is known.
|
|
649
|
+
*/
|
|
650
|
+
declare function getAssetUrl(asset: AssetRef, scope: Partial<Pick<PublisherScope, "orgSlug">> | undefined, options: AssetUrlOptions): string | undefined;
|
|
651
|
+
/**
|
|
652
|
+
* `getAssetUrl` bound to a media server, for an app's own `getAssetUrl`:
|
|
653
|
+
*
|
|
654
|
+
* ```ts
|
|
655
|
+
* export const getAssetUrl = createAssetUrl({ mediaUrl: process.env.NEXT_PUBLIC_MEDIA_URL! });
|
|
656
|
+
* getAssetUrl(asset, scope, "thumb");
|
|
657
|
+
* ```
|
|
658
|
+
*/
|
|
659
|
+
declare function createAssetUrl(options: AssetUrlOptions): (asset: AssetRef, scope: Partial<Pick<PublisherScope, "orgSlug">> | undefined, recipe?: string) => string | undefined;
|
|
660
|
+
|
|
661
|
+
export { type AlternateTranslation, type AssetData, type AssetRef, type AssetUrlOptions, type BotlrClient, type BotlrClientConfig, BotlrConflictError, type BotlrContext, type BotlrEntry, type BotlrEntryMeta, BotlrError, type BotlrQuery, type BotlrQueryValue, type BreadcrumbItem, type ConflictLatest, type ContentData, type FormResponse, type GetEntriesParams, type GetEntryBySlugParams, type GetPageListParams, type GetPageSlugListParams, type GetSingletonParams, type GridColumn, type GridContainerInstance, type InlineSectionInstance, type LayoutNode, type ListField, type ListResponse, MANIFEST_STATE_KEYS, type MenuResponse, type PageDiscoveryData, type PageListResponse, type PageResponse, type PageScope, type PageSlugListResponse, type PageTemplateData, type PublisherScope, type RedirectData, type RedirectEntry, type RedirectsResponse, type RequestOptions, type ResolveResponse, type ResponsiveGap, type ResponsiveSpan, SECTION_FRAMEWORK_RE, SECTION_PATH_RE, SECTION_SOURCE_LIMITS, type SectionDefinition, type SectionDefinitionScope, type SectionDependencies, type SectionFramework, type SectionManifest, type SectionSource, type SectionSourceFile, type SectionSourceFileInput, type SectionSourceListParams, type SectionSourceListResponse, type SectionSourcePullParams, type SectionSourcePullResponse, type SectionSourcePushBody, type SectionSourcePushResponse, type SectionSourceScope, type SectionSourceScopeSummary, type SectionSourceSummary, type SharedSectionInstance, type SpacingSize, type ThemeData, type VisibilityRules, contentHash, contextToHeaders, createAssetUrl, createBotlrClient, createBotlrFactory, fileSha256, getAssetFilename, getAssetId, getAssetUrl, hashFiles, isAssetData, isValidFramework, isValidSectionPath, stripManifestState, toQueryString };
|