@forumulate/sdk 0.5.0 → 0.7.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/dist/index.d.ts CHANGED
@@ -1,17 +1,18 @@
1
1
  export * from './types';
2
- export { verifyWebhookSignature, type VerifyWebhookInput } from './webhooks';
2
+ export { verifyWebhookSignature, constructWebhookEvent, type VerifyWebhookInput } from './webhooks';
3
3
  export * from './content';
4
- export type { paths } from './schema';
4
+ export * from './translations';
5
+ export type { paths, operations } from './schema';
5
6
  export type { HttpMethod, MethodsOf, OperationOf, TypedRequestInit, TypedResponse } from './typed';
7
+ export { ForumulateError, SDK_VERSION, retryDelayMs, type CallOptions, type ForumulateErrorInit, } from './http';
8
+ export { rowsOf, type PagePromise } from './pagination';
9
+ export type { Namespace, NamespaceName, OperationArgs, OperationFn, OperationId, OperationResult, OperationRow, PagedOperationId, Resources, } from './resources';
10
+ export { API_VERSION } from './operations.gen';
6
11
  import type { paths } from './schema';
7
12
  import type { HttpMethod, TypedRequestInit, TypedResponse } from './typed';
8
- import type { Organization, Space, SpaceType, SpaceVisibility, Collection, Page, BlockDoc, SearchHit, UnifiedHit, Comment, Webhook, WebhookFormat, PublicPage, Conformance, DomainSetup, DomainSummary, Item, PageInfo, EffectiveShape, ShapeOverride } from './types';
9
- /** Thrown for any non-2xx API response. Mirrors the API's error envelope. */
10
- export declare class ForumulateError extends Error {
11
- readonly status: number;
12
- readonly code: string;
13
- constructor(status: number, code: string, message: string);
14
- }
13
+ import { type Query } from './http';
14
+ import { type PositionalHelpers } from './helpers';
15
+ import { type Merged, type Namespace, type OperationArgs, type OptionalArgsOperationId, type OperationId, type OperationReturn, type OperationRow, type PagedOperationId, type Resources } from './resources';
15
16
  export interface ForumulateClientOptions {
16
17
  /** API base, `https://forumulate.com/api` for the hosted product (see `fromEnv`). */
17
18
  baseUrl: string;
@@ -33,25 +34,57 @@ export interface ForumulateClientOptions {
33
34
  * from the SDK that advertised it.
34
35
  */
35
36
  headers?: Record<string, string>;
37
+ /**
38
+ * The `Forumulate-Version` to state. The namespace methods and
39
+ * `request(operationId)` always state one — this, or {@link API_VERSION}
40
+ * (the version the SDK was generated against) — because auto-pagination reads
41
+ * the envelope only a versioned answer carries. The 0.5 positional helpers,
42
+ * `typed()` and `request(method, path)` send it only when you set it here,
43
+ * so code written against them sees exactly the answers it always saw.
44
+ */
45
+ apiVersion?: string;
46
+ /**
47
+ * Retries for 408/429/502/503/504 and network failures. Default 2. Only
48
+ * requests that are safe to repeat are retried: GET/PUT/DELETE, and writes
49
+ * carrying an `Idempotency-Key`. `Retry-After` is honoured.
50
+ */
51
+ maxRetries?: number;
52
+ /**
53
+ * Give every POST and PATCH a generated `Idempotency-Key` (the same one on
54
+ * each of its retries), so a write that timed out can be retried without
55
+ * running twice. Default true; a key you pass always wins.
56
+ */
57
+ autoIdempotencyKey?: boolean;
58
+ /**
59
+ * The `User-Agent` outside a browser. Default `forumulate-sdk-js/<version>`:
60
+ * the edge challenges default library agents, which reads as an outage to a
61
+ * first-time integration. Ignored where the runtime forbids the header.
62
+ */
63
+ userAgent?: string;
36
64
  }
37
- type Query = Record<string, string | number | boolean | undefined>;
65
+ type HandWritten = keyof PositionalHelpers | 'content';
38
66
  /**
39
67
  * Typed client for the Forumulate REST API.
40
68
  *
41
69
  * ```ts
42
70
  * const forumulate = new ForumulateClient({ baseUrl: 'https://forumulate.com/api', token: pat });
43
- * const { orgs } = await forumulate.orgs.list();
71
+ *
72
+ * for await (const post of forumulate.blog.list({ orgId, spaceId })) console.log(post);
73
+ * await forumulate.webhooks.rotate({ orgId, webhookId });
74
+ * await forumulate.request('Space_get', { orgId, spaceId });
44
75
  *
45
76
  * // or, from FORUMULATE_TOKEN / FORUMULATE_URL:
46
77
  * const fromEnv = ForumulateClient.fromEnv();
47
78
  * ```
79
+ *
80
+ * Every operation in the API is a method: `client.<namespace>[.<sub>].<method>`,
81
+ * named after its operationId (`ForumTopics_list` → `forum.topics.list`).
48
82
  */
83
+ export interface ForumulateClient extends Omit<Resources, HandWritten> {
84
+ }
49
85
  export declare class ForumulateClient {
50
- private readonly baseUrl;
51
- private readonly token?;
52
- private readonly credentials;
53
- private readonly defaultHeaders;
54
- private readonly _fetch;
86
+ private readonly transport;
87
+ private readonly apiVersion?;
55
88
  constructor(opts: ForumulateClientOptions);
56
89
  /**
57
90
  * A client configured from the environment, by the same names the CLI and
@@ -67,7 +100,18 @@ export declare class ForumulateClient {
67
100
  * anything in `opts` overrides what the environment said.
68
101
  */
69
102
  static fromEnv(env?: Record<string, string | undefined>, opts?: Partial<ForumulateClientOptions>): ForumulateClient;
70
- /** Low-level request. Exposed so callers can reach endpoints the typed helpers don't cover yet. */
103
+ /**
104
+ * Call any operation by its operationId, fully typed:
105
+ *
106
+ * ```ts
107
+ * const { space } = await forumulate.request('Space_get', { orgId, spaceId });
108
+ * ```
109
+ *
110
+ * The two-string form `request(method, path, opts)` is the untyped escape
111
+ * hatch it has always been.
112
+ */
113
+ request<K extends OptionalArgsOperationId>(operationId: K, args?: OperationArgs<NoInfer<K>>): OperationReturn<K>;
114
+ request<K extends OperationId>(operationId: K, args: OperationArgs<NoInfer<K>>): OperationReturn<K>;
71
115
  request<T>(method: string, path: string, opts?: {
72
116
  body?: unknown;
73
117
  query?: Query;
@@ -75,55 +119,37 @@ export declare class ForumulateClient {
75
119
  headers?: Record<string, string>;
76
120
  }): Promise<T>;
77
121
  /**
78
- * Fully-typed request against ANY endpoint in the OpenAPI spec.
122
+ * Every row of a paged operation, across every page — the same walk a
123
+ * namespace `list` gives, by operationId.
124
+ *
125
+ * ```ts
126
+ * for await (const space of forumulate.paginate('Space_list', { orgId })) { … }
127
+ * ```
128
+ */
129
+ paginate<K extends PagedOperationId & OptionalArgsOperationId>(operationId: K, args?: OperationArgs<NoInfer<K>>): AsyncIterable<OperationRow<K>>;
130
+ paginate<K extends PagedOperationId>(operationId: K, args: OperationArgs<NoInfer<K>>): AsyncIterable<OperationRow<K>>;
131
+ /**
132
+ * Fully-typed request against ANY endpoint in the OpenAPI spec, by path.
79
133
  *
80
- * Where the ~30 hand-written helpers above cover the stable, ergonomic
81
- * surface, `typed` covers the *whole* API: the generated `paths` interface
82
- * (`src/schema.ts`, produced from `openapi.json`) infers the path params,
83
- * query params, JSON body and success response for the `(method, path)` you
84
- * pass, so every one of the 600+ routes gets types and autocomplete without a
85
- * bespoke wrapper. Path templates like `/orgs/{orgId}/spaces` are filled from
86
- * `init.params`.
134
+ * The generated `paths` interface (`src/schema.ts`, produced from
135
+ * `openapi.json`) infers the path params, query params, JSON body and success
136
+ * response for the `(method, path)` you pass. Path templates like
137
+ * `/orgs/{orgId}/spaces` are filled from `init.params`.
87
138
  *
88
139
  * ```ts
89
- * // GET a list — path param is required and checked; response is typed.
90
140
  * const { spaces } = await forumulate.typed('get', '/orgs/{orgId}/spaces', {
91
- * params: { orgId }, query: { deleted: 'false', limit: '50', cursor: '' },
92
- * });
93
- *
94
- * // POST with a body the spec knows the shape of.
95
- * await forumulate.typed('post', '/orgs/{orgId}/spaces', {
96
- * params: { orgId },
97
- * body: { name: 'Docs', slug: 'docs', type: 'DOCS', visibility: 'PUBLIC' },
141
+ * params: { orgId }, query: { limit: 50 },
98
142
  * });
99
143
  * ```
100
- *
101
- * Regenerate the types after an API change with
102
- * `pnpm --filter @forumulate/sdk dump-spec` then
103
- * `npx openapi-typescript packages/sdk/openapi.json -o src/schema.ts`.
104
144
  */
105
145
  typed<P extends keyof paths, M extends keyof paths[P] & HttpMethod>(method: M, path: P, init: TypedRequestInit<paths[P][M]>): Promise<TypedResponse<paths[P][M]>>;
106
- private toError;
107
- readonly auth: {
108
- register: (input: {
109
- email: string;
110
- name: string;
111
- password: string;
112
- }) => Promise<{
113
- user: {
114
- id: string;
115
- email: string;
116
- };
117
- }>;
118
- login: (input: {
119
- email: string;
120
- password: string;
121
- }) => Promise<{
122
- user: {
123
- id: string;
124
- email: string;
125
- };
126
- }>;
146
+ /** The 0.5 door: no version stated unless the client pins one. */
147
+ private http;
148
+ /** The generated door: path filled from the args, version always stated, lists iterable. */
149
+ private readonly invoke;
150
+ private ns;
151
+ private readonly helpers;
152
+ readonly auth: Merged<Namespace<"auth">, {
127
153
  me: () => Promise<{
128
154
  user: {
129
155
  id: string;
@@ -131,7 +157,6 @@ export declare class ForumulateClient {
131
157
  name: string;
132
158
  };
133
159
  }>;
134
- /** Mint a Personal Access Token (requires an authenticated session). */
135
160
  createToken: (input: {
136
161
  name: string;
137
162
  scopes?: string[];
@@ -142,8 +167,8 @@ export declare class ForumulateClient {
142
167
  name: string;
143
168
  };
144
169
  }>;
145
- };
146
- readonly content: {
170
+ }>;
171
+ readonly content: Merged<Namespace<"content">, {
147
172
  libraries: {
148
173
  list: (orgId: string) => Promise<{
149
174
  libraries: import("./content").ContentLibrary[];
@@ -310,65 +335,208 @@ export declare class ForumulateClient {
310
335
  ok: true;
311
336
  }>;
312
337
  };
338
+ }>;
339
+ /** Translations of every kind of piece, routed by space type — see ./translations. */
340
+ readonly translations: {
341
+ locales: {
342
+ list: (orgId: string, target: import("./translations").LocaleTarget) => Promise<import("./translations").TranslationLocale[]>;
343
+ add: (orgId: string, target: import("./translations").LocaleTarget, input: {
344
+ code: string;
345
+ label: string;
346
+ }) => Promise<{
347
+ code: string;
348
+ label: string;
349
+ isSource: boolean;
350
+ }[]>;
351
+ relabel: (orgId: string, target: import("./translations").LocaleTarget, code: string, label: string) => Promise<{
352
+ code: string;
353
+ label: string;
354
+ isSource: boolean;
355
+ }[]>;
356
+ remove: (orgId: string, target: import("./translations").LocaleTarget, code: string) => Promise<{
357
+ code: string;
358
+ label: string;
359
+ isSource: boolean;
360
+ }[]>;
361
+ set: (orgId: string, target: import("./translations").LocaleTarget, want: {
362
+ code: string;
363
+ label: string;
364
+ }[], opts?: {
365
+ prune?: boolean;
366
+ }) => Promise<{
367
+ locales: import("./translations").TranslationLocale[];
368
+ added: string[];
369
+ relabeled: string[];
370
+ removed: string[];
371
+ }>;
372
+ };
373
+ status: (orgId: string, spaceId: string) => Promise<import("./translations").TranslationCoverage>;
374
+ list: (orgId: string, spaceId: string, pieceId: string, opts?: {
375
+ door?: import("./translations").TranslationDoor;
376
+ }) => Promise<{
377
+ translations: unknown[];
378
+ }>;
379
+ get: (orgId: string, spaceId: string, pieceId: string, locale: string, opts?: {
380
+ door?: import("./translations").TranslationDoor;
381
+ }) => Promise<import("./translations").PieceTranslation>;
382
+ put: (orgId: string, spaceId: string, pieceId: string, locale: string, input: import("./translations").PieceTranslationInput, opts?: {
383
+ door?: import("./translations").TranslationDoor;
384
+ }) => Promise<import("./translations").PieceTranslation>;
385
+ remove: (orgId: string, spaceId: string, pieceId: string, locale: string, opts?: {
386
+ door?: import("./translations").TranslationDoor;
387
+ }) => Promise<void>;
388
+ auto: (orgId: string, spaceId: string, pieceId: string, locale: string, opts?: import("./translations").AutoTranslateOptions & {
389
+ door?: import("./translations").TranslationDoor;
390
+ }) => Promise<{
391
+ translation: unknown;
392
+ }>;
393
+ autoEntry: (orgId: string, libraryId: string, entryId: string, locale: string, opts?: {
394
+ force?: boolean;
395
+ }) => Promise<{
396
+ locale: string;
397
+ results: {
398
+ entryId: string;
399
+ ok: boolean;
400
+ translationEntryId: string | null;
401
+ error: string | null;
402
+ }[];
403
+ }>;
404
+ setItemLocale: (orgId: string, spaceId: string, itemId: string, locale: string | null) => Promise<{
405
+ item: {
406
+ id: string;
407
+ locale?: string | null;
408
+ };
409
+ }>;
410
+ names: {
411
+ get: (orgId: string, spaceId: string, opts?: {
412
+ collectionId?: string;
413
+ }) => Promise<import("./translations").NamedTranslations>;
414
+ set: (orgId: string, spaceId: string, locale: string, words: {
415
+ name?: string;
416
+ description?: string;
417
+ } | null, opts?: {
418
+ collectionId?: string;
419
+ }) => Promise<import("./translations").NamedTranslations>;
420
+ };
421
+ entryLocale: {
422
+ get: (orgId: string, libraryId: string, entryId: string, locale: string) => Promise<{
423
+ entryId: string;
424
+ locale: string;
425
+ fields: Record<string, unknown>;
426
+ }>;
427
+ put: (orgId: string, libraryId: string, entryId: string, locale: string, fields: Record<string, unknown>) => Promise<{
428
+ locale: string;
429
+ sourceEntryId: string;
430
+ entryId: string;
431
+ created: boolean;
432
+ }>;
433
+ };
434
+ labels: {
435
+ strings: (orgId: string, scope: import("./translations").LabelScope) => Promise<{
436
+ languages: string[];
437
+ labels: import("./translations").LabelDictionary;
438
+ strings: unknown[];
439
+ coverage: Record<string, {
440
+ translated: number;
441
+ total: number;
442
+ }>;
443
+ }>;
444
+ replace: (orgId: string, scope: import("./translations").LabelScope, labels: import("./translations").LabelDictionary) => Promise<{
445
+ labels: import("./translations").LabelDictionary;
446
+ }>;
447
+ merge: (orgId: string, scope: import("./translations").LabelScope, labels: Record<string, Record<string, unknown> | null>) => Promise<{
448
+ labels: import("./translations").LabelDictionary;
449
+ }>;
450
+ };
451
+ overrides: {
452
+ list: (orgId: string, locale?: string) => Promise<{
453
+ overrides: import("./translations").TranslationOverride[];
454
+ }>;
455
+ set: (orgId: string, input: {
456
+ locale: string;
457
+ key: string;
458
+ value: string;
459
+ }) => Promise<{
460
+ override: import("./translations").TranslationOverride;
461
+ }>;
462
+ remove: (orgId: string, input: {
463
+ locale: string;
464
+ key: string;
465
+ }) => Promise<{
466
+ ok: true;
467
+ }>;
468
+ catalog: (orgId: string) => Promise<{
469
+ catalog: Record<string, string>;
470
+ }>;
471
+ forLocale: (orgId: string, locale: string) => Promise<{
472
+ overrides: Record<string, string>;
473
+ }>;
474
+ };
475
+ switcher: {
476
+ get: (orgId: string) => Promise<Record<string, unknown>>;
477
+ set: (orgId: string, config: Record<string, unknown>) => Promise<Record<string, unknown>>;
478
+ };
479
+ deepl: {
480
+ status: (orgId: string) => Promise<{
481
+ configured: boolean;
482
+ }>;
483
+ connect: (orgId: string, apiKey: string) => Promise<{
484
+ ok: true;
485
+ }>;
486
+ disconnect: (orgId: string) => Promise<{
487
+ ok: true;
488
+ }>;
489
+ };
313
490
  };
314
- readonly orgs: {
491
+ readonly orgs: Merged<Namespace<"orgs">, {
315
492
  list: () => Promise<{
316
- orgs: Organization[];
493
+ orgs: import("./types").Organization[];
317
494
  }>;
318
495
  create: (input: {
319
496
  name: string;
320
497
  slug: string;
321
498
  }) => Promise<{
322
- organization: Organization;
499
+ organization: import("./types").Organization;
323
500
  }>;
324
- };
325
- readonly spaces: {
501
+ }>;
502
+ readonly spaces: Merged<Namespace<"spaces">, {
326
503
  list: (orgId: string) => Promise<{
327
- spaces: Space[];
504
+ spaces: import("./types").Space[];
328
505
  }>;
329
506
  create: (orgId: string, input: {
330
507
  name: string;
331
508
  slug: string;
332
- type: SpaceType;
333
- visibility: SpaceVisibility;
509
+ type: import("./types").SpaceType;
510
+ visibility: import("./types").SpaceVisibility;
334
511
  }) => Promise<{
335
- space: Space;
512
+ space: import("./types").Space;
336
513
  }>;
337
514
  createCollection: (orgId: string, spaceId: string, input: {
338
515
  name: string;
339
516
  slug: string;
340
517
  }) => Promise<{
341
- collection: Collection;
518
+ collection: import("./types").Collection;
342
519
  }>;
343
520
  createPage: (orgId: string, spaceId: string, collectionId: string, input: {
344
521
  title: string;
345
522
  slug: string;
346
523
  }) => Promise<{
347
- page: Page;
524
+ page: import("./types").Page;
348
525
  }>;
349
526
  setPageContent: (orgId: string, spaceId: string, pageId: string, input: {
350
527
  title: string;
351
- content: BlockDoc;
528
+ content: import("./types").BlockDoc;
352
529
  }) => Promise<{
353
- page: Page;
530
+ page: import("./types").Page;
354
531
  }>;
355
532
  publishPage: (orgId: string, spaceId: string, pageId: string) => Promise<{
356
- page: Page;
533
+ page: import("./types").Page;
357
534
  }>;
358
- };
359
- /**
360
- * Shapes and pieces — the surface an agent works through.
361
- *
362
- * `shape` says what one piece of a space is made of and hands back JSON
363
- * Schema; `items` writes one, whatever a piece happens to be in that space:
364
- * a documentation page, a blog post, a release, an incident. The reply says
365
- * which required sections are still empty, so an agent can create a piece,
366
- * ask what it forgot, and close the gap.
367
- */
368
- readonly shapes: {
535
+ }>;
536
+ readonly shapes: Merged<Namespace<"shapes">, {
369
537
  get: (orgId: string, spaceId: string) => Promise<{
370
- shape: EffectiveShape;
371
- base: EffectiveShape;
538
+ shape: import("./types").EffectiveShape;
539
+ base: import("./types").EffectiveShape;
372
540
  presets: {
373
541
  name: string;
374
542
  label: string;
@@ -376,133 +544,91 @@ export declare class ForumulateClient {
376
544
  }[];
377
545
  jsonSchema: Record<string, unknown>;
378
546
  }>;
379
- set: (orgId: string, spaceId: string, patch: ShapeOverride) => Promise<{
380
- shape: EffectiveShape;
547
+ set: (orgId: string, spaceId: string, patch: import("./types").ShapeOverride) => Promise<{
548
+ shape: import("./types").EffectiveShape;
381
549
  }>;
382
550
  applyPreset: (orgId: string, spaceId: string, name: string) => Promise<{
383
- shape: EffectiveShape;
551
+ shape: import("./types").EffectiveShape;
384
552
  }>;
385
- };
386
- readonly items: {
553
+ }>;
554
+ readonly items: Merged<Namespace<"items">, {
387
555
  create: (orgId: string, spaceId: string, input: {
388
556
  title: string;
389
557
  slug?: string;
390
- /** Which kind of piece, where the space holds more than one. */
391
558
  preset?: string | null;
392
559
  sections?: Record<string, string>;
393
560
  body?: string;
394
561
  params?: Record<string, unknown>;
395
562
  }) => Promise<{
396
- item: Item;
397
- }>;
398
- /**
399
- * What is in a space: how something finds a piece it has no words for.
400
- *
401
- * Pass `include: ['body']` to get content. Asking for `sections` ALONE is
402
- * the trap: it is populated only for pieces written against a shape, so a
403
- * space of free-form pages answers with empty objects and a sync carries
404
- * nothing while reporting success. Every row says which field holds its
405
- * content in `contentIn`.
406
- *
407
- * Any option here puts the response in its paged form, so `page` and
408
- * `sync` come back — `page.total` is what a walk should check its own
409
- * count against, and `sync.checkpoint` is what an incremental sync stores.
410
- */
563
+ item: import("./types").Item;
564
+ }>;
411
565
  list: (orgId: string, spaceId: string, opts?: number | {
412
566
  limit?: number;
413
567
  include?: ("sections" | "body")[];
414
568
  cursor?: string;
415
- /** A `sync.checkpoint` from a previous walk, not a timestamp you made. */
416
569
  updatedSince?: string;
417
570
  includeDeleted?: boolean;
418
571
  fields?: string[];
419
572
  }) => Promise<{
420
- items: Item[];
421
- page?: PageInfo;
573
+ items: import("./types").Item[];
574
+ page?: import("./types").PageInfo;
422
575
  sync?: {
423
576
  checkpoint: string;
424
577
  };
425
578
  }>;
426
579
  get: (orgId: string, spaceId: string, itemId: string) => Promise<{
427
- item: Item & {
580
+ item: import("./types").Item & {
428
581
  sections: Record<string, string>;
429
582
  };
430
583
  }>;
431
- /**
432
- * Make it readable. Kinds that are live on creation say so and change nothing.
433
- *
434
- * `conformance` describes the piece AFTER publishing — which declared slots
435
- * are filled and which are still missing — so an agent that has just made
436
- * its work readable can tell a complete piece from one with holes in it
437
- * without fetching it again. The server has always sent it and this type
438
- * omitted it, so a TypeScript caller could not see the field the docs
439
- * promise (E-11).
440
- */
441
584
  publish: (orgId: string, spaceId: string, itemId: string) => Promise<{
442
585
  published: boolean;
443
586
  note?: string;
444
- conformance: Conformance;
445
- }>;
446
- /**
447
- * Replace a piece's whole body — as markdown, or as blocks.
448
- *
449
- * The create door has always taken markdown and this one took blocks only,
450
- * so "make it from this file" worked and "update it from the same file" did
451
- * not. Both now; blocks win if a caller sends both.
452
- */
587
+ conformance: import("./types").Conformance;
588
+ }>;
453
589
  setContent: (orgId: string, spaceId: string, itemId: string, input: {
454
590
  body?: string;
455
- content?: BlockDoc;
591
+ content?: import("./types").BlockDoc;
456
592
  }) => Promise<{
457
- conformance: Conformance;
593
+ conformance: import("./types").Conformance;
458
594
  }>;
459
- /** Replace one named section. Idempotent — sending it twice writes it once. */
460
595
  setSection: (orgId: string, spaceId: string, itemId: string, key: string, markdown: string) => Promise<{
461
- conformance: Conformance;
596
+ conformance: import("./types").Conformance;
462
597
  }>;
463
- };
464
- /**
465
- * The addresses a space answers at.
466
- *
467
- * Published because the question a customer asks about a custom domain —
468
- * "why is it not live yet" — is answerable only from `verified`, `active` and
469
- * the setup records, and the SDK could not reach any of them (DX-2). A failed
470
- * verification is a 200 with `verified: false`: read the body, not the status.
471
- */
472
- readonly domains: {
598
+ }>;
599
+ readonly domains: Merged<Namespace<"domains">, {
473
600
  list: (orgId: string, spaceId: string) => Promise<{
474
- domains: DomainSummary[];
601
+ domains: import("./types").DomainSummary[];
475
602
  }>;
476
603
  add: (orgId: string, spaceId: string, input: {
477
604
  hostname: string;
478
605
  basePath?: string;
479
606
  }) => Promise<{
480
- domain: DomainSummary;
607
+ domain: import("./types").DomainSummary;
481
608
  }>;
482
- /** Re-run the ownership check. `activate: false` proves it without switching traffic. */
483
609
  verify: (orgId: string, spaceId: string, domainId: string, activate?: boolean) => Promise<{
484
- domain: DomainSummary;
610
+ domain: import("./types").DomainSummary;
485
611
  }>;
486
- /** Switch traffic to an address whose ownership is already proven. */
487
612
  activate: (orgId: string, spaceId: string, domainId: string) => Promise<{
488
- domain: DomainSummary;
613
+ domain: import("./types").DomainSummary;
489
614
  }>;
490
- /** What to configure, and what is still missing. */
491
- setup: (orgId: string, spaceId: string, domainId: string) => Promise<DomainSetup>;
492
- };
493
- readonly webhooks: {
615
+ setup: (orgId: string, spaceId: string, domainId: string) => Promise<import("./types").DomainSetup>;
616
+ }>;
617
+ readonly webhooks: Merged<Namespace<"webhooks">, {
494
618
  list: (orgId: string) => Promise<{
495
- webhooks: Webhook[];
619
+ webhooks: import("./types").Webhook[];
496
620
  }>;
497
621
  create: (orgId: string, input: {
498
622
  url: string;
499
623
  events: string[];
500
- format?: WebhookFormat;
624
+ format?: import("./types").WebhookFormat;
501
625
  }) => Promise<{
502
- webhook: Webhook;
626
+ webhook: import("./types").Webhook;
503
627
  }>;
504
- };
505
- readonly snapshots: {
628
+ verifySignature: typeof import("./webhooks").verifyWebhookSignature;
629
+ constructEvent: typeof import("./webhooks").constructWebhookEvent;
630
+ }>;
631
+ readonly snapshots: Merged<Namespace<"snapshots">, {
506
632
  list: (orgId: string, spaceId: string) => Promise<{
507
633
  snapshots: unknown[];
508
634
  }>;
@@ -513,8 +639,8 @@ export declare class ForumulateClient {
513
639
  restored: number;
514
640
  skipped: number;
515
641
  }>;
516
- };
517
- readonly forum: {
642
+ }>;
643
+ readonly forum: Merged<Namespace<"forum">, {
518
644
  listTopics: (orgId: string, spaceId: string, query?: {
519
645
  sort?: string;
520
646
  category?: string;
@@ -525,48 +651,47 @@ export declare class ForumulateClient {
525
651
  }>;
526
652
  createTopic: (orgId: string, spaceId: string, input: {
527
653
  title: string;
528
- content: BlockDoc;
654
+ content: import("./types").BlockDoc;
529
655
  kind?: string;
530
656
  tags?: string[];
531
657
  categoryId?: string | null;
532
658
  }) => Promise<{
533
659
  topic: unknown;
534
660
  }>;
535
- reply: (orgId: string, spaceId: string, topicId: string, content: BlockDoc) => Promise<{
661
+ reply: (orgId: string, spaceId: string, topicId: string, content: import("./types").BlockDoc) => Promise<{
536
662
  post: unknown;
537
663
  }>;
538
- };
539
- readonly search: {
664
+ }>;
665
+ readonly search: Merged<Namespace<"search">, {
540
666
  unified: (orgId: string, q: string, opts?: {
541
667
  type?: string;
542
668
  limit?: number;
543
669
  }) => Promise<{
544
- hits: UnifiedHit[];
670
+ hits: import("./types").UnifiedHit[];
545
671
  }>;
546
- };
547
- readonly analytics: {
672
+ }>;
673
+ readonly analytics: Merged<Namespace<"analytics">, {
548
674
  orgEvents: (orgId: string, days?: number) => Promise<unknown>;
549
- };
550
- readonly public: {
551
- getPage: (orgId: string, spaceId: string, pageId: string) => Promise<PublicPage>;
675
+ }>;
676
+ readonly public: Merged<Namespace<"public">, {
677
+ getPage: (orgId: string, spaceId: string, pageId: string) => Promise<import("./types").PublicPage>;
552
678
  search: (orgId: string, spaceId: string, query: string) => Promise<{
553
- hits: SearchHit[];
679
+ hits: import("./types").SearchHit[];
554
680
  }>;
555
681
  listComments: (orgId: string, spaceId: string, pageId: string) => Promise<{
556
- comments: Comment[];
682
+ comments: import("./types").Comment[];
557
683
  }>;
558
684
  postComment: (orgId: string, spaceId: string, pageId: string, input: {
559
685
  authorName: string;
560
686
  body: string;
561
687
  parentId?: string | null;
562
688
  }) => Promise<{
563
- comment: Comment;
689
+ comment: import("./types").Comment;
564
690
  }>;
565
691
  reactToComment: (orgId: string, spaceId: string, commentId: string, emoji: string) => Promise<{
566
- comment: Comment;
692
+ comment: import("./types").Comment;
567
693
  }>;
568
- /** Download the whole space as a PDF. Returns the raw `Response` (read `.blob()` / `.arrayBuffer()`). */
569
694
  pdf: (orgId: string, spaceId: string) => Promise<Response>;
570
- };
695
+ }>;
571
696
  }
572
697
  //# sourceMappingURL=index.d.ts.map