@paragraphcms/client 1.0.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/README.md ADDED
@@ -0,0 +1,473 @@
1
+ # Paragraph CMS Client
2
+
3
+ Official TypeScript client for the Paragraph CMS v1 API.
4
+
5
+ The package is built on top of the standard Fetch API, so it works in modern Node.js, Cloudflare Workers, Next.js route handlers/server actions, AWS Lambda, and other server-side JavaScript runtimes that expose `fetch`, `Headers`, `FormData`, `Blob`, and `AbortController`.
6
+
7
+ ## Features
8
+
9
+ - Full coverage for the current Paragraph CMS v1 API surface.
10
+ - `new Client({ apiKey })` entrypoint with a small, typed SDK.
11
+ - Built-in request queue that rate-limits each client instance to `5 req/s` by default.
12
+ - Runtime-agnostic implementation with no runtime dependencies.
13
+ - First-class TypeScript types for request payloads, responses, list metadata, and API errors.
14
+ - Request cancellation with `AbortSignal`.
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @paragraphcms/client
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```ts
25
+ import { Client } from "@paragraphcms/client";
26
+
27
+ const client = new Client({
28
+ apiKey: process.env.PARAGRAPH_API_KEY!,
29
+ });
30
+
31
+ const pages = await client.pages.list({
32
+ limit: 20,
33
+ include_content: false,
34
+ sort: "-updated_at",
35
+ });
36
+
37
+ const created = await client.pages.create({
38
+ title: "Pricing",
39
+ language: "en",
40
+ content: [
41
+ {
42
+ type: "paragraph",
43
+ content: [{ type: "text", text: "Pricing" }],
44
+ },
45
+ ],
46
+ });
47
+
48
+ console.log(pages.meta.total_items);
49
+ console.log(created.page.id);
50
+ ```
51
+
52
+ ## Runtime Notes
53
+
54
+ - The default API base URL is `https://api.paragraphcms.com/v1`.
55
+ - If you pass `baseUrl: "https://api.paragraphcms.com"`, the client automatically normalizes it to `https://api.paragraphcms.com/v1`.
56
+ - The client uses `x-api-key` authentication by default.
57
+ - Field names in request and response payloads intentionally mirror the HTTP API. That means body/query keys stay in `snake_case`.
58
+
59
+ ## Rate Limiting
60
+
61
+ Paragraph CMS v1 is rate-limited to `5 req/s`. Each `Client` instance contains an internal queue that spaces request starts so the instance does not exceed that budget by default.
62
+
63
+ Important details:
64
+
65
+ - The limiter is per client instance, not global across all containers, lambdas, or workers.
66
+ - If your app creates many `Client` instances, each instance will maintain its own queue.
67
+ - The safest pattern is to reuse one shared `Client` instance per process or isolate when possible.
68
+
69
+ You can override the per-instance limit if you need a lower ceiling:
70
+
71
+ ```ts
72
+ const client = new Client({
73
+ apiKey: process.env.PARAGRAPH_API_KEY!,
74
+ maxRequestsPerSecond: 3,
75
+ });
76
+ ```
77
+
78
+ ## Configuration
79
+
80
+ ```ts
81
+ type ClientOptions = {
82
+ apiKey: string;
83
+ baseUrl?: string;
84
+ fetch?: typeof globalThis.fetch;
85
+ headers?: HeadersInit;
86
+ timeoutMs?: number;
87
+ maxRequestsPerSecond?: number;
88
+ };
89
+ ```
90
+
91
+ ### `apiKey`
92
+
93
+ Required. Paragraph CMS organization API key.
94
+
95
+ ### `baseUrl`
96
+
97
+ Optional. Defaults to `https://api.paragraphcms.com/v1`.
98
+
99
+ Examples:
100
+
101
+ - `https://api.paragraphcms.com/v1`
102
+ - `https://api.paragraphcms.com`
103
+ - `http://localhost:3001/v1`
104
+
105
+ ### `fetch`
106
+
107
+ Optional custom fetch implementation. Useful in tests or custom runtimes.
108
+
109
+ ### `headers`
110
+
111
+ Optional default headers added to every request.
112
+
113
+ ### `timeoutMs`
114
+
115
+ Optional default request timeout in milliseconds. Per-call options can override it.
116
+
117
+ ### `maxRequestsPerSecond`
118
+
119
+ Optional per-client limiter ceiling. Defaults to `5`.
120
+
121
+ ## Per-Request Options
122
+
123
+ Every SDK method accepts an optional last argument:
124
+
125
+ ```ts
126
+ type RequestOptions = {
127
+ signal?: AbortSignal;
128
+ headers?: HeadersInit;
129
+ timeoutMs?: number;
130
+ };
131
+ ```
132
+
133
+ Example:
134
+
135
+ ```ts
136
+ const controller = new AbortController();
137
+
138
+ const page = await client.pages.get("page-id", undefined, {
139
+ signal: controller.signal,
140
+ timeoutMs: 10_000,
141
+ });
142
+ ```
143
+
144
+ ## Error Handling
145
+
146
+ The client throws `ParagraphApiError` for non-2xx API responses and `ParagraphClientError` for local runtime/configuration problems.
147
+
148
+ ```ts
149
+ import { Client, ParagraphApiError } from "@paragraphcms/client";
150
+
151
+ const client = new Client({
152
+ apiKey: process.env.PARAGRAPH_API_KEY!,
153
+ });
154
+
155
+ try {
156
+ await client.pages.get("missing-id");
157
+ } catch (error) {
158
+ if (error instanceof ParagraphApiError) {
159
+ console.error(error.status);
160
+ console.error(error.code);
161
+ console.error(error.message);
162
+ console.error(error.details);
163
+ }
164
+ }
165
+ ```
166
+
167
+ ## Return Shapes
168
+
169
+ - Single-resource endpoints return the unwrapped `data` payload.
170
+ - Paginated endpoints return `{ data, meta }`.
171
+ - `locales.list()` returns a plain `Locale[]` because the API endpoint itself is not paginated.
172
+
173
+ ## API Surface
174
+
175
+ ### Root
176
+
177
+ ```ts
178
+ client.getInfo()
179
+ ```
180
+
181
+ Returns the public `/v1` info payload:
182
+
183
+ ```ts
184
+ {
185
+ version: "v1",
186
+ openapi_url: "/v1/openapi.json",
187
+ authentication: {
188
+ type: "api_key",
189
+ supported_headers: ["x-api-key", "authorization"],
190
+ authorization_format: "Bearer <api-key>",
191
+ },
192
+ resources: [...]
193
+ }
194
+ ```
195
+
196
+ ### Pages
197
+
198
+ ```ts
199
+ client.pages.list(query?, options?)
200
+ client.pages.create(body?, options?)
201
+ client.pages.get(pageId, query?, options?)
202
+ client.pages.update(pageId, body, options?)
203
+ client.pages.delete(pageId, options?)
204
+ client.pages.restore(pageId, options?)
205
+ client.pages.permanentlyDelete(pageId, options?)
206
+ client.pages.duplicate(pageId, options?)
207
+ client.pages.createTranslation(pageId, body, options?)
208
+ ```
209
+
210
+ Supported `sort` fields for `pages.list()`:
211
+
212
+ - `title`
213
+ - `language`
214
+ - `created_at`
215
+ - `updated_at`
216
+ - `published_at`
217
+
218
+ Notes:
219
+
220
+ - `label_id` is passed as `string[]` in the SDK and serialized to the API CSV format automatically.
221
+ - `content` is present in page list results only when `include_content: true`.
222
+ - Page responses should be treated as Tiptap JSON arrays. `content_format` is no longer required in the response shape.
223
+
224
+ ### Collections
225
+
226
+ ```ts
227
+ client.collections.list(query?, options?)
228
+ client.collections.create(body, options?)
229
+ client.collections.get(collectionId, options?)
230
+ client.collections.update(collectionId, body, options?)
231
+ client.collections.delete(collectionId, options?)
232
+ ```
233
+
234
+ Supported `sort` fields for `collections.list()`:
235
+
236
+ - `name`
237
+ - `page_count`
238
+ - `last_modified_at`
239
+
240
+ ### Media
241
+
242
+ ```ts
243
+ client.media.list(query?, options?)
244
+ client.media.upload(body, options?)
245
+ client.media.get(mediaId, options?)
246
+ client.media.update(mediaId, body, options?)
247
+ client.media.delete(mediaId, options?)
248
+ ```
249
+
250
+ Supported `sort` fields for `media.list()`:
251
+
252
+ - `file_name`
253
+ - `size`
254
+ - `created_at`
255
+ - `updated_at`
256
+
257
+ `media.upload()` accepts:
258
+
259
+ - `File`
260
+ - `Blob`
261
+ - `ArrayBuffer`
262
+ - Typed arrays like `Uint8Array`
263
+ - Node.js `Buffer`
264
+
265
+ Example:
266
+
267
+ ```ts
268
+ const file = new File([imageBytes], "hero.png", {
269
+ type: "image/png",
270
+ });
271
+
272
+ const upload = await client.media.upload({
273
+ file,
274
+ page_id: "page-id",
275
+ alt: "Homepage hero",
276
+ });
277
+ ```
278
+
279
+ If you upload from a raw `Buffer`, `Uint8Array`, or `ArrayBuffer`, you can also pass `file_name` and `content_type`:
280
+
281
+ ```ts
282
+ await client.media.upload({
283
+ file: imageBuffer,
284
+ file_name: "hero.png",
285
+ content_type: "image/png",
286
+ page_id: "page-id",
287
+ });
288
+ ```
289
+
290
+ ### Members, Authors, Reviewers
291
+
292
+ ```ts
293
+ client.members.list(query?, options?)
294
+ client.authors.list(query?, options?)
295
+ client.reviewers.list(query?, options?)
296
+ ```
297
+
298
+ Supported `sort` fields:
299
+
300
+ - `name`
301
+ - `email`
302
+ - `created_at`
303
+
304
+ `authors` and `reviewers` are aliases of the member listing endpoints exposed by the API.
305
+
306
+ ### Statuses
307
+
308
+ ```ts
309
+ client.statuses.list(query?, options?)
310
+ client.statuses.create(body, options?)
311
+ client.statuses.get(statusId, options?)
312
+ client.statuses.update(statusId, body, options?)
313
+ client.statuses.reorder(body, options?)
314
+ client.statuses.delete(statusId, options?)
315
+ ```
316
+
317
+ Supported `sort` fields for `statuses.list()`:
318
+
319
+ - `type`
320
+ - `order`
321
+ - `name`
322
+ - `created_at`
323
+
324
+ ### Labels
325
+
326
+ ```ts
327
+ client.labels.list(query?, options?)
328
+ client.labels.create(body, options?)
329
+ client.labels.get(labelId, options?)
330
+ client.labels.update(labelId, body, options?)
331
+ client.labels.reorder(body, options?)
332
+ client.labels.delete(labelId, options?)
333
+ ```
334
+
335
+ Supported `sort` fields for `labels.list()`:
336
+
337
+ - `order`
338
+ - `name`
339
+ - `created_at`
340
+
341
+ ### Data Models
342
+
343
+ ```ts
344
+ client.dataModels.list(query?, options?)
345
+ client.dataModels.create(body, options?)
346
+ client.dataModels.get(dataModelId, options?)
347
+ client.dataModels.update(dataModelId, body, options?)
348
+ client.dataModels.delete(dataModelId, options?)
349
+ ```
350
+
351
+ Supported `sort` fields for `dataModels.list()`:
352
+
353
+ - `name`
354
+ - `created_at`
355
+ - `updated_at`
356
+
357
+ ### Locales
358
+
359
+ ```ts
360
+ client.locales.list(options?)
361
+ client.locales.create(body, options?)
362
+ client.locales.delete(code, options?)
363
+ ```
364
+
365
+ ### AI
366
+
367
+ ```ts
368
+ client.ai.generateMetaName(body, options?)
369
+ client.ai.generateMetaDescription(body, options?)
370
+ client.ai.generateContent(body, options?)
371
+ ```
372
+
373
+ ## End-to-End Examples
374
+
375
+ ### Create a page and upload its hero image
376
+
377
+ ```ts
378
+ const pageResult = await client.pages.create({
379
+ title: "About",
380
+ language: "en",
381
+ content: [
382
+ {
383
+ type: "paragraph",
384
+ content: [{ type: "text", text: "About" }],
385
+ },
386
+ ],
387
+ });
388
+
389
+ await client.media.upload({
390
+ file: heroBytes,
391
+ file_name: "about-hero.png",
392
+ content_type: "image/png",
393
+ page_id: pageResult.page.id,
394
+ alt: "About page hero image",
395
+ });
396
+ ```
397
+
398
+ ### Create a translated page variant
399
+
400
+ ```ts
401
+ await client.pages.createTranslation("page-id", {
402
+ language: "de",
403
+ mode: "translate",
404
+ model: "openai/gpt-5.4",
405
+ });
406
+ ```
407
+
408
+ ### Generate SEO fields with AI
409
+
410
+ ```ts
411
+ const generatedMeta = await client.ai.generateMetaDescription({
412
+ model: "openai/gpt-5.4",
413
+ title: "Platform overview",
414
+ content: [],
415
+ });
416
+
417
+ console.log(generatedMeta.meta_description);
418
+ ```
419
+
420
+ ## Exported Types
421
+
422
+ The package exports the `Client` class, both error classes, and the main request/response/domain types used by the SDK, including:
423
+
424
+ - `ClientOptions`
425
+ - `RequestOptions`
426
+ - `ListResponse`
427
+ - `PaginationMeta`
428
+ - `Page`
429
+ - `PageSummary`
430
+ - `Collection`
431
+ - `Media`
432
+ - `MediaDetail`
433
+ - `Status`
434
+ - `Label`
435
+ - `DataModel`
436
+ - `Locale`
437
+ - `Member`
438
+ - `CreatePageRequest`
439
+ - `UpdatePageRequest`
440
+ - `UploadMediaRequest`
441
+ - `GenerateContentRequest`
442
+
443
+ ## Testing
444
+
445
+ The repository contains two test layers:
446
+
447
+ - Unit tests for request serialization, multipart uploads, error handling, and rate limiting.
448
+ - Live integration tests that create, update, fetch, reorder, delete, and clean up real resources against the Paragraph API.
449
+
450
+ Commands:
451
+
452
+ ```bash
453
+ npm test
454
+ npm run test:unit
455
+ npm run test:integration
456
+ ```
457
+
458
+ Environment variables for integration tests:
459
+
460
+ - `PARAGRAPH_API_KEY` required to run live API tests.
461
+ - `PARAGRAPH_API_BASE_URL` optional override for local/staging API targets.
462
+ - `PARAGRAPH_AI_MODEL` optional model id for AI endpoint tests. When omitted, AI integration tests are skipped.
463
+
464
+ The integration suite is self-contained and generates its own resources, so it does not rely on any existing content in the target organization.
465
+
466
+ ## Requirements
467
+
468
+ - Node.js `18+` for direct Node usage.
469
+ - A runtime with standard Fetch API primitives for edge/serverless usage.
470
+
471
+ ## License
472
+
473
+ ISC
@@ -0,0 +1,82 @@
1
+ import type { AiContentResult, AiMetaDescriptionResult, AiMetaNameResult, ApiInfo, ClientOptions, Collection, CollectionListQuery, CollectionMutationResult, CreateCollectionRequest, CreateDataModelRequest, CreateLabelRequest, CreateLocaleRequest, CreatePageRequest, CreatePageTranslationRequest, CreateStatusRequest, DataModel, DataModelListQuery, DataModelMutationResult, DeleteByCodeResult, DeleteResult, GenerateContentRequest, GenerateMetaRequest, GetPageQuery, Label, LabelMutationResult, LabelListQuery, ListResponse, Locale, LocaleMutationResult, Media, MediaDeleteResult, MediaDetail, MediaListQuery, MediaMutationResult, MediaUploadResult, Member, MemberListQuery, Page, PageListQuery, PageSummary, PageMutationResult, PageRestoreResult, PermanentDeleteResult, ReorderLabelsRequest, ReorderResult, ReorderStatusesRequest, RequestOptions, Status, StatusListQuery, StatusMutationResult, UpdateCollectionRequest, UpdateDataModelRequest, UpdateLabelRequest, UpdateMediaRequest, UpdatePageRequest, UpdateStatusRequest, UploadMediaRequest } from "./types.js";
2
+ export declare class Client {
3
+ private readonly apiKey;
4
+ private readonly baseUrl;
5
+ private readonly fetchImpl;
6
+ private readonly defaultHeaders;
7
+ private readonly timeoutMs?;
8
+ private readonly limiter;
9
+ readonly pages: {
10
+ list: (query?: PageListQuery, options?: RequestOptions) => Promise<ListResponse<PageSummary>>;
11
+ create: (body?: CreatePageRequest, options?: RequestOptions) => Promise<PageMutationResult>;
12
+ get: (pageId: string, query?: GetPageQuery, options?: RequestOptions) => Promise<Page>;
13
+ update: (pageId: string, body: UpdatePageRequest, options?: RequestOptions) => Promise<PageMutationResult>;
14
+ delete: (pageId: string, options?: RequestOptions) => Promise<DeleteResult>;
15
+ restore: (pageId: string, options?: RequestOptions) => Promise<PageRestoreResult>;
16
+ permanentlyDelete: (pageId: string, options?: RequestOptions) => Promise<PermanentDeleteResult>;
17
+ duplicate: (pageId: string, options?: RequestOptions) => Promise<PageMutationResult>;
18
+ createTranslation: (pageId: string, body: CreatePageTranslationRequest, options?: RequestOptions) => Promise<PageMutationResult>;
19
+ };
20
+ readonly collections: {
21
+ list: (query?: CollectionListQuery, options?: RequestOptions) => Promise<ListResponse<Collection>>;
22
+ create: (body: CreateCollectionRequest, options?: RequestOptions) => Promise<CollectionMutationResult>;
23
+ get: (collectionId: string, options?: RequestOptions) => Promise<Collection>;
24
+ update: (collectionId: string, body: UpdateCollectionRequest, options?: RequestOptions) => Promise<CollectionMutationResult>;
25
+ delete: (collectionId: string, options?: RequestOptions) => Promise<DeleteResult>;
26
+ };
27
+ readonly media: {
28
+ list: (query?: MediaListQuery, options?: RequestOptions) => Promise<ListResponse<Media>>;
29
+ upload: (body: UploadMediaRequest, options?: RequestOptions) => Promise<MediaUploadResult>;
30
+ get: (mediaId: string, options?: RequestOptions) => Promise<MediaDetail>;
31
+ update: (mediaId: string, body: UpdateMediaRequest, options?: RequestOptions) => Promise<MediaMutationResult>;
32
+ delete: (mediaId: string, options?: RequestOptions) => Promise<MediaDeleteResult>;
33
+ };
34
+ readonly members: {
35
+ list: (query?: MemberListQuery, options?: RequestOptions) => Promise<ListResponse<Member>>;
36
+ };
37
+ readonly authors: {
38
+ list: (query?: MemberListQuery, options?: RequestOptions) => Promise<ListResponse<Member>>;
39
+ };
40
+ readonly reviewers: {
41
+ list: (query?: MemberListQuery, options?: RequestOptions) => Promise<ListResponse<Member>>;
42
+ };
43
+ readonly statuses: {
44
+ list: (query?: StatusListQuery, options?: RequestOptions) => Promise<ListResponse<Status>>;
45
+ create: (body: CreateStatusRequest, options?: RequestOptions) => Promise<StatusMutationResult>;
46
+ get: (statusId: string, options?: RequestOptions) => Promise<Status>;
47
+ update: (statusId: string, body: UpdateStatusRequest, options?: RequestOptions) => Promise<StatusMutationResult>;
48
+ reorder: (body: ReorderStatusesRequest, options?: RequestOptions) => Promise<ReorderResult>;
49
+ delete: (statusId: string, options?: RequestOptions) => Promise<DeleteResult>;
50
+ };
51
+ readonly labels: {
52
+ list: (query?: LabelListQuery, options?: RequestOptions) => Promise<ListResponse<Label>>;
53
+ create: (body: CreateLabelRequest, options?: RequestOptions) => Promise<LabelMutationResult>;
54
+ get: (labelId: string, options?: RequestOptions) => Promise<Label>;
55
+ update: (labelId: string, body: UpdateLabelRequest, options?: RequestOptions) => Promise<LabelMutationResult>;
56
+ reorder: (body: ReorderLabelsRequest, options?: RequestOptions) => Promise<ReorderResult>;
57
+ delete: (labelId: string, options?: RequestOptions) => Promise<DeleteResult>;
58
+ };
59
+ readonly dataModels: {
60
+ list: (query?: DataModelListQuery, options?: RequestOptions) => Promise<ListResponse<DataModel>>;
61
+ create: (body: CreateDataModelRequest, options?: RequestOptions) => Promise<DataModelMutationResult>;
62
+ get: (dataModelId: string, options?: RequestOptions) => Promise<DataModel>;
63
+ update: (dataModelId: string, body: UpdateDataModelRequest, options?: RequestOptions) => Promise<DataModelMutationResult>;
64
+ delete: (dataModelId: string, options?: RequestOptions) => Promise<DeleteResult>;
65
+ };
66
+ readonly locales: {
67
+ list: (options?: RequestOptions) => Promise<Locale[]>;
68
+ create: (body: CreateLocaleRequest, options?: RequestOptions) => Promise<LocaleMutationResult>;
69
+ delete: (code: string, options?: RequestOptions) => Promise<DeleteByCodeResult>;
70
+ };
71
+ readonly ai: {
72
+ generateMetaName: (body: GenerateMetaRequest, options?: RequestOptions) => Promise<AiMetaNameResult>;
73
+ generateMetaDescription: (body: GenerateMetaRequest, options?: RequestOptions) => Promise<AiMetaDescriptionResult>;
74
+ generateContent: (body: GenerateContentRequest, options?: RequestOptions) => Promise<AiContentResult>;
75
+ };
76
+ constructor(options: ClientOptions);
77
+ getInfo(options?: RequestOptions): Promise<ApiInfo>;
78
+ private requestData;
79
+ private requestList;
80
+ private requestJson;
81
+ }
82
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}