@unchainedshop/cockpit-api 1.0.34 → 2.1.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 +330 -65
- package/dist/client.d.ts +72 -0
- package/dist/client.js +101 -0
- package/dist/cockpit-logger.d.ts +8 -5
- package/dist/cockpit-logger.js +7 -20
- package/dist/core/cache.d.ts +19 -0
- package/dist/core/cache.js +32 -0
- package/dist/core/config.d.ts +45 -0
- package/dist/core/config.js +32 -0
- package/dist/core/http.d.ts +34 -0
- package/dist/core/http.js +98 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.js +10 -0
- package/dist/core/locale.d.ts +11 -0
- package/dist/core/locale.js +17 -0
- package/dist/core/query-string.d.ts +18 -0
- package/dist/core/query-string.js +20 -0
- package/dist/core/url-builder.d.ts +22 -0
- package/dist/core/url-builder.js +35 -0
- package/dist/core/validation.d.ts +13 -0
- package/dist/core/validation.js +22 -0
- package/dist/fetch/client.d.ts +85 -0
- package/dist/fetch/client.js +143 -0
- package/dist/fetch/index.d.ts +19 -0
- package/dist/fetch/index.js +18 -0
- package/dist/index.d.ts +28 -2
- package/dist/index.js +13 -2
- package/dist/methods/assets.d.ts +65 -0
- package/dist/methods/assets.js +37 -0
- package/dist/methods/content.d.ts +77 -0
- package/dist/methods/content.js +79 -0
- package/dist/methods/graphql.d.ts +9 -0
- package/dist/methods/graphql.js +13 -0
- package/dist/methods/index.d.ts +22 -0
- package/dist/methods/index.js +12 -0
- package/dist/methods/localize.d.ts +12 -0
- package/dist/methods/localize.js +17 -0
- package/dist/methods/menus.d.ts +42 -0
- package/dist/methods/menus.js +25 -0
- package/dist/methods/pages.d.ts +49 -0
- package/dist/methods/pages.js +34 -0
- package/dist/methods/routes.d.ts +46 -0
- package/dist/methods/routes.js +24 -0
- package/dist/methods/search.d.ts +27 -0
- package/dist/methods/search.js +16 -0
- package/dist/methods/system.d.ts +15 -0
- package/dist/methods/system.js +14 -0
- package/dist/schema/executor.d.ts +67 -0
- package/dist/schema/executor.js +81 -0
- package/dist/schema/index.d.ts +26 -0
- package/dist/schema/index.js +26 -0
- package/dist/schema/schema-builder.d.ts +42 -0
- package/dist/schema/schema-builder.js +77 -0
- package/dist/transformers/asset-path.d.ts +20 -0
- package/dist/transformers/asset-path.js +40 -0
- package/dist/transformers/compose.d.ts +9 -0
- package/dist/transformers/compose.js +14 -0
- package/dist/transformers/image-path.d.ts +28 -0
- package/dist/transformers/image-path.js +60 -0
- package/dist/transformers/index.d.ts +8 -0
- package/dist/transformers/index.js +9 -0
- package/dist/transformers/page-link.d.ts +18 -0
- package/dist/transformers/page-link.js +45 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/route-map.d.ts +12 -0
- package/dist/utils/route-map.js +86 -0
- package/dist/utils/tenant.d.ts +71 -0
- package/dist/utils/tenant.js +88 -0
- package/package.json +49 -7
- package/dist/api.d.ts +0 -69
- package/dist/api.js +0 -303
package/README.md
CHANGED
|
@@ -1,36 +1,80 @@
|
|
|
1
1
|
# Cockpit API
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@unchainedshop/cockpit-api)
|
|
4
|
+
[](https://github.com/unchainedshop/cockpit-api/actions/workflows/ci.yml)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
|
|
8
|
+
A TypeScript client for interacting with [Cockpit CMS](https://github.com/Cockpit-HQ/Cockpit), including GraphQL requests, content management, and schema stitching support.
|
|
5
9
|
|
|
6
|
-
|
|
10
|
+
## Installation
|
|
7
11
|
|
|
8
12
|
```sh
|
|
9
13
|
npm install --save @unchainedshop/cockpit-api
|
|
10
14
|
```
|
|
11
15
|
|
|
12
|
-
##
|
|
16
|
+
## Package Exports
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
This package provides three entry points:
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
| Export | Description |
|
|
21
|
+
|--------|-------------|
|
|
22
|
+
| `@unchainedshop/cockpit-api` | Full-featured async API client with caching and response transformation |
|
|
23
|
+
| `@unchainedshop/cockpit-api/schema` | GraphQL schema stitching utilities |
|
|
24
|
+
| `@unchainedshop/cockpit-api/fetch` | Lightweight client for edge/RSC environments |
|
|
17
25
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
then import and initialize the API:
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
### Main Client
|
|
22
29
|
|
|
23
|
-
```
|
|
30
|
+
```typescript
|
|
24
31
|
import { CockpitAPI } from '@unchainedshop/cockpit-api';
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
// With explicit endpoint
|
|
34
|
+
const cockpit = await CockpitAPI({
|
|
35
|
+
endpoint: 'https://your-cockpit-instance.com/api/graphql',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Or using environment variables
|
|
39
|
+
const cockpit = await CockpitAPI(); // Uses COCKPIT_GRAPHQL_ENDPOINT
|
|
27
40
|
```
|
|
28
41
|
|
|
29
|
-
###
|
|
42
|
+
### Lightweight Fetch Client (Edge/RSC)
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { createFetchClient } from '@unchainedshop/cockpit-api/fetch';
|
|
46
|
+
|
|
47
|
+
// Synchronous initialization - no await needed
|
|
48
|
+
const cockpit = createFetchClient({
|
|
49
|
+
endpoint: process.env.NEXT_PUBLIC_COCKPIT_ENDPOINT,
|
|
50
|
+
tenant: 'mytenant',
|
|
51
|
+
cache: 'force-cache', // Uses platform caching
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const page = await cockpit.pageByRoute('/about', { locale: 'en' });
|
|
55
|
+
```
|
|
30
56
|
|
|
31
|
-
|
|
57
|
+
### GraphQL Schema Stitching
|
|
32
58
|
|
|
33
|
-
```
|
|
59
|
+
```typescript
|
|
60
|
+
import { makeCockpitGraphQLSchema } from '@unchainedshop/cockpit-api/schema';
|
|
61
|
+
import { stitchSchemas } from '@graphql-tools/stitch';
|
|
62
|
+
|
|
63
|
+
const cockpitSchema = await makeCockpitGraphQLSchema({
|
|
64
|
+
tenantHeader: 'x-cockpit-space',
|
|
65
|
+
filterMutations: true,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const gatewaySchema = stitchSchemas({
|
|
69
|
+
subschemas: [{ schema: cockpitSchema }],
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Main Client API
|
|
74
|
+
|
|
75
|
+
### GraphQL Requests
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
34
78
|
import { gql } from 'graphql-tag';
|
|
35
79
|
|
|
36
80
|
const query = gql`
|
|
@@ -43,67 +87,288 @@ const query = gql`
|
|
|
43
87
|
`;
|
|
44
88
|
|
|
45
89
|
const result = await cockpit.graphQL(query, {});
|
|
46
|
-
console.log(result);
|
|
47
90
|
```
|
|
48
91
|
|
|
49
92
|
### Content Operations
|
|
50
93
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
```typescript
|
|
95
|
+
// Get a single content item
|
|
96
|
+
const post = await cockpit.getContentItem({ model: 'posts', id: '123' });
|
|
97
|
+
|
|
98
|
+
// With locale and field selection
|
|
99
|
+
const localizedPost = await cockpit.getContentItem({
|
|
100
|
+
model: 'posts',
|
|
101
|
+
id: '123',
|
|
102
|
+
locale: 'en',
|
|
103
|
+
queryParams: { fields: { title: 1, content: 1 } }
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Get multiple content items with pagination
|
|
107
|
+
const posts = await cockpit.getContentItems('posts', {
|
|
108
|
+
limit: 10,
|
|
109
|
+
skip: 0,
|
|
110
|
+
sort: { _created: -1 },
|
|
111
|
+
filter: { published: true }
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Get tree structure
|
|
115
|
+
const tree = await cockpit.getContentTree('categories', {
|
|
116
|
+
parent: 'root-id',
|
|
117
|
+
populate: 2
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Aggregation pipeline
|
|
121
|
+
const stats = await cockpit.getAggregateModel({
|
|
122
|
+
model: 'orders',
|
|
123
|
+
pipeline: [{ $group: { _id: '$status', count: { $sum: 1 } } }]
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Create content item
|
|
127
|
+
const newPost = await cockpit.postContentItem('posts', { title: 'New Post' });
|
|
128
|
+
|
|
129
|
+
// Delete content item
|
|
130
|
+
await cockpit.deleteContentItem('posts', '123');
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Pages
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// List pages
|
|
137
|
+
const allPages = await cockpit.pages({ locale: 'en', limit: 50 });
|
|
138
|
+
|
|
139
|
+
// Get page by ID
|
|
140
|
+
const page = await cockpit.pageById({ page: 'blog', id: '123', locale: 'en' });
|
|
141
|
+
|
|
142
|
+
// Get page by route
|
|
143
|
+
const aboutPage = await cockpit.pageByRoute('/about', { locale: 'en', populate: 2 });
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Menus
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Get all menus
|
|
150
|
+
const menus = await cockpit.pagesMenus({ locale: 'en' });
|
|
151
|
+
|
|
152
|
+
// Get specific menu
|
|
153
|
+
const mainMenu = await cockpit.pagesMenu('main-navigation', { locale: 'en' });
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Routes & Sitemap
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
const routes = await cockpit.pagesRoutes('en');
|
|
160
|
+
const sitemap = await cockpit.pagesSitemap();
|
|
161
|
+
const settings = await cockpit.pagesSetting('en');
|
|
162
|
+
const fullRoute = await cockpit.getFullRouteForSlug('my-slug');
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Search (Detektivo addon)
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const results = await cockpit.search({
|
|
169
|
+
index: 'products',
|
|
170
|
+
q: 'search term',
|
|
171
|
+
limit: 10,
|
|
172
|
+
offset: 0
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Localization (Lokalize addon)
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
const translations = await cockpit.localize('my-project', {
|
|
180
|
+
locale: 'en',
|
|
181
|
+
nested: true
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Assets
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import { ImageSizeMode, MimeType } from '@unchainedshop/cockpit-api';
|
|
189
|
+
|
|
190
|
+
// Get asset metadata
|
|
191
|
+
const asset = await cockpit.assetById('asset-id');
|
|
192
|
+
|
|
193
|
+
// Get transformed image
|
|
194
|
+
const image = await cockpit.imageAssetById('asset-id', {
|
|
195
|
+
m: ImageSizeMode.BestFit,
|
|
196
|
+
w: 800,
|
|
197
|
+
h: 600,
|
|
198
|
+
q: 80,
|
|
199
|
+
mime: MimeType.WEBP
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### System
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// Health check
|
|
207
|
+
const health = await cockpit.healthCheck();
|
|
208
|
+
|
|
209
|
+
// Clear cache
|
|
210
|
+
cockpit.clearCache(); // Clear all
|
|
211
|
+
cockpit.clearCache('pages'); // Clear by pattern
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Lightweight Fetch Client API
|
|
215
|
+
|
|
216
|
+
The fetch client is designed for edge/RSC environments with minimal overhead:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import { createFetchClient } from '@unchainedshop/cockpit-api/fetch';
|
|
220
|
+
|
|
221
|
+
const cockpit = createFetchClient({
|
|
222
|
+
endpoint: process.env.NEXT_PUBLIC_COCKPIT_ENDPOINT,
|
|
223
|
+
tenant: 'mytenant',
|
|
224
|
+
cache: 'force-cache',
|
|
225
|
+
apiKey: 'your-api-key',
|
|
226
|
+
headers: { 'X-Custom-Header': 'value' }
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Available methods
|
|
230
|
+
const page = await cockpit.pageByRoute('/about', { locale: 'en' });
|
|
231
|
+
const pages = await cockpit.pages({ locale: 'en' });
|
|
232
|
+
const pageById = await cockpit.pageById('blog', '123', { locale: 'en' });
|
|
233
|
+
const items = await cockpit.getContentItems('news', { locale: 'en', limit: 10 });
|
|
234
|
+
const item = await cockpit.getContentItem('news', '123', { locale: 'en' });
|
|
235
|
+
const custom = await cockpit.fetchRaw('/custom/endpoint', { param: 'value' });
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Schema Stitching API
|
|
239
|
+
|
|
240
|
+
For building GraphQL gateways with Cockpit:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { makeCockpitGraphQLSchema, createRemoteExecutor } from '@unchainedshop/cockpit-api/schema';
|
|
244
|
+
|
|
245
|
+
// Create schema for stitching
|
|
246
|
+
const schema = await makeCockpitGraphQLSchema({
|
|
247
|
+
tenantHeader: 'x-cockpit-space',
|
|
248
|
+
filterMutations: true,
|
|
249
|
+
transforms: [], // Additional GraphQL transforms
|
|
250
|
+
extractTenant: (ctx) => ctx.req?.headers['x-tenant'],
|
|
251
|
+
cockpitOptions: {
|
|
252
|
+
endpoint: 'https://cms.example.com/api/graphql',
|
|
253
|
+
apiKey: 'your-api-key',
|
|
254
|
+
useAdminAccess: true
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Or use the executor directly for custom implementations
|
|
259
|
+
const executor = createRemoteExecutor({
|
|
260
|
+
tenantHeader: 'x-cockpit-space',
|
|
261
|
+
cockpitOptions: { endpoint: '...' }
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Configuration Options
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
const cockpit = await CockpitAPI({
|
|
269
|
+
endpoint: 'https://...', // Falls back to COCKPIT_GRAPHQL_ENDPOINT
|
|
270
|
+
tenant: 'mytenant', // Optional: for multi-tenant setups
|
|
271
|
+
apiKey: 'your-api-key', // Falls back to COCKPIT_SECRET env var
|
|
272
|
+
useAdminAccess: true, // Optional: inject api-Key header
|
|
273
|
+
defaultLanguage: 'de', // Language that maps to Cockpit's "default" locale (default: "de")
|
|
274
|
+
preloadRoutes: true, // Optional: preload route replacements
|
|
275
|
+
cache: {
|
|
276
|
+
max: 100, // Falls back to COCKPIT_CACHE_MAX (default: 100)
|
|
277
|
+
ttl: 100000, // Falls back to COCKPIT_CACHE_TTL (default: 100000)
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Environment Variables
|
|
283
|
+
|
|
89
284
|
```bash
|
|
90
|
-
|
|
91
|
-
|
|
285
|
+
COCKPIT_GRAPHQL_ENDPOINT=https://your-cockpit-instance.com/api/graphql
|
|
286
|
+
COCKPIT_SECRET=your-api-key # Default API key
|
|
287
|
+
COCKPIT_SECRET_MYTENANT=tenant-api-key # Tenant-specific API key
|
|
288
|
+
COCKPIT_CACHE_MAX=100 # Max cache entries (default: 100)
|
|
289
|
+
COCKPIT_CACHE_TTL=100000 # Cache TTL in ms (default: 100000)
|
|
92
290
|
```
|
|
93
291
|
|
|
292
|
+
## Multi-Tenant Support
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
// Tenant-specific client
|
|
296
|
+
const cockpit = await CockpitAPI({
|
|
297
|
+
endpoint: 'https://cms.example.com/api/graphql',
|
|
298
|
+
tenant: 'mytenant', // Requests use /:mytenant/api/... path
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// Resolve tenant from URL
|
|
302
|
+
import { resolveTenantFromUrl, getTenantIds } from '@unchainedshop/cockpit-api';
|
|
303
|
+
|
|
304
|
+
const { tenant, slug } = resolveTenantFromUrl('https://mytenant.example.com/page');
|
|
305
|
+
const allTenants = getTenantIds(); // From COCKPIT_SECRET_* env vars
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## TypeScript Support
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
import type {
|
|
312
|
+
// Client
|
|
313
|
+
CockpitAPIClient,
|
|
314
|
+
CockpitAPIOptions,
|
|
315
|
+
CacheManager,
|
|
316
|
+
CacheOptions,
|
|
317
|
+
|
|
318
|
+
// Query Options
|
|
319
|
+
ContentItemQueryOptions,
|
|
320
|
+
ContentListQueryOptions,
|
|
321
|
+
TreeQueryOptions,
|
|
322
|
+
PageQueryOptions,
|
|
323
|
+
SearchQueryOptions,
|
|
324
|
+
ImageAssetQueryParams,
|
|
325
|
+
|
|
326
|
+
// Response Types
|
|
327
|
+
CockpitPage,
|
|
328
|
+
CockpitAsset,
|
|
329
|
+
CockpitMenu,
|
|
330
|
+
CockpitRoute,
|
|
331
|
+
CockpitSearchResult,
|
|
332
|
+
CockpitContentItem,
|
|
333
|
+
|
|
334
|
+
// Schema Types
|
|
335
|
+
MakeCockpitSchemaOptions,
|
|
336
|
+
CockpitExecutorContext,
|
|
337
|
+
|
|
338
|
+
// Fetch Types
|
|
339
|
+
FetchClientOptions,
|
|
340
|
+
FetchCacheMode,
|
|
341
|
+
} from '@unchainedshop/cockpit-api';
|
|
342
|
+
|
|
343
|
+
import { ImageSizeMode, MimeType } from '@unchainedshop/cockpit-api';
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Breaking Changes
|
|
347
|
+
|
|
348
|
+
### v2.0.0
|
|
349
|
+
|
|
350
|
+
- `lokalize()` renamed to `localize()`
|
|
351
|
+
- Methods use options objects instead of positional parameters
|
|
352
|
+
- HTTP errors now throw instead of returning `null` (404 still returns `null`)
|
|
353
|
+
- Each client instance has its own cache (no shared state)
|
|
354
|
+
|
|
355
|
+
### v2.1.0 (New Features)
|
|
356
|
+
|
|
357
|
+
- `/schema` subpackage for GraphQL schema stitching
|
|
358
|
+
- `/fetch` subpackage for lightweight edge/RSC environments
|
|
359
|
+
- `preloadRoutes` option for preloading route replacements
|
|
360
|
+
- `defaultLanguage` option to configure which language maps to Cockpit's "default" locale
|
|
361
|
+
- Expanded tenant utilities: `resolveTenantFromUrl()`, `resolveTenantFromSubdomain()`
|
|
362
|
+
|
|
363
|
+
## Peer Dependencies
|
|
364
|
+
|
|
365
|
+
- `graphql` (optional) - Required for the `graphQL()` method
|
|
366
|
+
- `@graphql-tools/wrap` (optional) - Required for the `/schema` subpackage
|
|
367
|
+
|
|
94
368
|
## Contributing
|
|
95
369
|
|
|
96
370
|
Contributions are welcome! Please open an issue or submit a pull request.
|
|
97
371
|
|
|
98
|
-
1. Fork the repository.
|
|
99
|
-
2. Create a new branch: `git checkout -b feature-branch-name`.
|
|
100
|
-
3. Make your changes and commit them: `git commit -m 'Add new feature'`.
|
|
101
|
-
4. Push to the branch: `git push origin feature-branch-name`.
|
|
102
|
-
5. Open a pull request.
|
|
103
|
-
|
|
104
372
|
## License
|
|
105
373
|
|
|
106
374
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
This `README.md` covers installation, basic usage, detailed API reference, contribution guidelines, and licensing information. Adjust the details as needed for your specific implementation.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cockpit API Client Factory
|
|
3
|
+
*/
|
|
4
|
+
import type { DocumentNode } from "graphql";
|
|
5
|
+
import { type CockpitAPIOptions } from "./core/config.ts";
|
|
6
|
+
import { type ContentItemQueryOptions, type ContentListQueryOptions, type TreeQueryOptions, type AggregateQueryOptions, type CockpitContentItem, type CockpitTreeNode } from "./methods/content.ts";
|
|
7
|
+
import { type PageByIdOptions, type CockpitPage } from "./methods/pages.ts";
|
|
8
|
+
import { type MenuQueryOptions, type CockpitMenu } from "./methods/menus.ts";
|
|
9
|
+
import { type CockpitRoutesResponse, type CockpitSitemapEntry, type CockpitSettings } from "./methods/routes.ts";
|
|
10
|
+
import { type ImageAssetQueryParams, type CockpitAsset } from "./methods/assets.ts";
|
|
11
|
+
import { type SearchQueryOptions, type CockpitSearchResult } from "./methods/search.ts";
|
|
12
|
+
import { type LocalizeOptions } from "./methods/localize.ts";
|
|
13
|
+
/**
|
|
14
|
+
* Cockpit API Client interface
|
|
15
|
+
*/
|
|
16
|
+
export interface CockpitAPIClient {
|
|
17
|
+
graphQL<T = unknown>(document: DocumentNode, variables?: Record<string, unknown>): Promise<T | null>;
|
|
18
|
+
getContentItem<T = unknown>(options: ContentItemQueryOptions): Promise<T | null>;
|
|
19
|
+
getContentItems<T = CockpitContentItem>(model: string, options?: ContentListQueryOptions): Promise<T[] | null>;
|
|
20
|
+
getContentTree<T = CockpitContentItem>(model: string, options?: TreeQueryOptions): Promise<CockpitTreeNode<T>[] | null>;
|
|
21
|
+
getAggregateModel<T = unknown>(options: AggregateQueryOptions): Promise<T[] | null>;
|
|
22
|
+
postContentItem<T = unknown>(model: string, item: Record<string, unknown>): Promise<T | null>;
|
|
23
|
+
deleteContentItem<T = unknown>(model: string, id: string): Promise<T | null>;
|
|
24
|
+
pages<T = CockpitPage>(options?: ContentListQueryOptions): Promise<T[] | null>;
|
|
25
|
+
pageById<T = CockpitPage>(id: string, options?: PageByIdOptions): Promise<T | null>;
|
|
26
|
+
pageByRoute<T = CockpitPage>(route: string, options?: {
|
|
27
|
+
locale?: string;
|
|
28
|
+
populate?: number;
|
|
29
|
+
} | string): Promise<T | null>;
|
|
30
|
+
pagesMenus<T = CockpitMenu>(options?: MenuQueryOptions | string): Promise<T[] | null>;
|
|
31
|
+
pagesMenu<T = CockpitMenu>(name: string, options?: MenuQueryOptions | string): Promise<T | null>;
|
|
32
|
+
pagesRoutes<T = CockpitRoutesResponse>(locale?: string): Promise<T | null>;
|
|
33
|
+
pagesSitemap<T = CockpitSitemapEntry>(): Promise<T[] | null>;
|
|
34
|
+
pagesSetting<T = CockpitSettings>(locale?: string): Promise<T | null>;
|
|
35
|
+
search<T = CockpitSearchResult>(options: SearchQueryOptions): Promise<T | null>;
|
|
36
|
+
healthCheck<T = unknown>(): Promise<T | null>;
|
|
37
|
+
localize<T = unknown>(projectName: string, options?: LocalizeOptions): Promise<T | null>;
|
|
38
|
+
assetById<T = CockpitAsset>(assetId: string): Promise<T | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Get a transformed image asset URL.
|
|
41
|
+
*
|
|
42
|
+
* **Important:** The `w` (width) or `h` (height) parameter is required by the API.
|
|
43
|
+
* Without it, the API returns a 400 error.
|
|
44
|
+
*
|
|
45
|
+
* @param assetId - The asset ID
|
|
46
|
+
* @param queryParams - Image transformation parameters (w or h required)
|
|
47
|
+
* @returns URL string to the generated image, or null if not found
|
|
48
|
+
*/
|
|
49
|
+
imageAssetById(assetId: string, queryParams?: ImageAssetQueryParams): Promise<string | null>;
|
|
50
|
+
getFullRouteForSlug(slug: string): Promise<string | undefined>;
|
|
51
|
+
clearCache(pattern?: string): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Creates a Cockpit API client
|
|
55
|
+
*
|
|
56
|
+
* @param options - Configuration options (falls back to env vars if not provided)
|
|
57
|
+
* @returns Promise resolving to the API client
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* // With explicit options
|
|
62
|
+
* const client = await CockpitAPI({
|
|
63
|
+
* endpoint: 'https://cms.example.com/api/graphql',
|
|
64
|
+
* tenant: 'mytenant',
|
|
65
|
+
* useAdminAccess: true,
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* // Or using environment variables (COCKPIT_GRAPHQL_ENDPOINT, etc.)
|
|
69
|
+
* const client = await CockpitAPI();
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function CockpitAPI(options?: CockpitAPIOptions): Promise<CockpitAPIClient>;
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cockpit API Client Factory
|
|
3
|
+
*/
|
|
4
|
+
import { createConfig } from "./core/config.js";
|
|
5
|
+
import { createCacheManager } from "./core/cache.js";
|
|
6
|
+
import { createUrlBuilder } from "./core/url-builder.js";
|
|
7
|
+
import { createHttpClient } from "./core/http.js";
|
|
8
|
+
import { createImagePathTransformer } from "./transformers/image-path.js";
|
|
9
|
+
import { generateCmsRouteReplacements } from "./utils/route-map.js";
|
|
10
|
+
import { createContentMethods, } from "./methods/content.js";
|
|
11
|
+
import { createPagesMethods, } from "./methods/pages.js";
|
|
12
|
+
import { createMenuMethods, } from "./methods/menus.js";
|
|
13
|
+
import { createRouteMethods, } from "./methods/routes.js";
|
|
14
|
+
import { createAssetMethods, } from "./methods/assets.js";
|
|
15
|
+
import { createGraphQLMethods } from "./methods/graphql.js";
|
|
16
|
+
import { createSearchMethods, } from "./methods/search.js";
|
|
17
|
+
import { createLocalizeMethods, } from "./methods/localize.js";
|
|
18
|
+
import { createSystemMethods } from "./methods/system.js";
|
|
19
|
+
/**
|
|
20
|
+
* Creates a Cockpit API client
|
|
21
|
+
*
|
|
22
|
+
* @param options - Configuration options (falls back to env vars if not provided)
|
|
23
|
+
* @returns Promise resolving to the API client
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // With explicit options
|
|
28
|
+
* const client = await CockpitAPI({
|
|
29
|
+
* endpoint: 'https://cms.example.com/api/graphql',
|
|
30
|
+
* tenant: 'mytenant',
|
|
31
|
+
* useAdminAccess: true,
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* // Or using environment variables (COCKPIT_GRAPHQL_ENDPOINT, etc.)
|
|
35
|
+
* const client = await CockpitAPI();
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export async function CockpitAPI(options = {}) {
|
|
39
|
+
// Create configuration
|
|
40
|
+
const config = createConfig(options);
|
|
41
|
+
const endpointString = config.endpoint.toString();
|
|
42
|
+
// Create cache manager - env vars take precedence, then options, then cache.ts defaults
|
|
43
|
+
const envCacheMax = process.env["COCKPIT_CACHE_MAX"];
|
|
44
|
+
const envCacheTtl = process.env["COCKPIT_CACHE_TTL"];
|
|
45
|
+
const cacheOptions = {};
|
|
46
|
+
const maxValue = options.cache?.max ??
|
|
47
|
+
(envCacheMax !== undefined ? parseInt(envCacheMax, 10) : undefined);
|
|
48
|
+
const ttlValue = options.cache?.ttl ??
|
|
49
|
+
(envCacheTtl !== undefined ? parseInt(envCacheTtl, 10) : undefined);
|
|
50
|
+
if (maxValue !== undefined)
|
|
51
|
+
cacheOptions.max = maxValue;
|
|
52
|
+
if (ttlValue !== undefined)
|
|
53
|
+
cacheOptions.ttl = ttlValue;
|
|
54
|
+
const cache = createCacheManager(config.cachePrefix, cacheOptions);
|
|
55
|
+
// Generate route replacements for image path transformer (optional)
|
|
56
|
+
const routeReplacements = options.preloadRoutes === true
|
|
57
|
+
? await generateCmsRouteReplacements(endpointString, options.tenant, cache)
|
|
58
|
+
: {};
|
|
59
|
+
// Create response transformer
|
|
60
|
+
const transformerConfig = {
|
|
61
|
+
baseUrl: config.endpoint.origin,
|
|
62
|
+
replacements: routeReplacements,
|
|
63
|
+
};
|
|
64
|
+
if (options.tenant !== undefined)
|
|
65
|
+
transformerConfig.tenant = options.tenant;
|
|
66
|
+
const transformer = createImagePathTransformer(transformerConfig);
|
|
67
|
+
// Create URL builder
|
|
68
|
+
const urlBuilder = createUrlBuilder(config);
|
|
69
|
+
// Create HTTP client
|
|
70
|
+
const http = createHttpClient(config, transformer);
|
|
71
|
+
// Create method context
|
|
72
|
+
const ctx = {
|
|
73
|
+
http,
|
|
74
|
+
url: urlBuilder,
|
|
75
|
+
cache,
|
|
76
|
+
endpoint: endpointString,
|
|
77
|
+
...(options.tenant !== undefined && { tenant: options.tenant }),
|
|
78
|
+
};
|
|
79
|
+
// Create method groups
|
|
80
|
+
const contentMethods = createContentMethods(ctx);
|
|
81
|
+
const pagesMethods = createPagesMethods(ctx);
|
|
82
|
+
const menuMethods = createMenuMethods(ctx);
|
|
83
|
+
const routeMethods = createRouteMethods(ctx);
|
|
84
|
+
const assetMethods = createAssetMethods(ctx);
|
|
85
|
+
const graphqlMethods = createGraphQLMethods(ctx);
|
|
86
|
+
const searchMethods = createSearchMethods(ctx);
|
|
87
|
+
const localizeMethods = createLocalizeMethods(ctx);
|
|
88
|
+
const systemMethods = createSystemMethods(ctx);
|
|
89
|
+
// Compose the client
|
|
90
|
+
return {
|
|
91
|
+
...contentMethods,
|
|
92
|
+
...pagesMethods,
|
|
93
|
+
...menuMethods,
|
|
94
|
+
...routeMethods,
|
|
95
|
+
...assetMethods,
|
|
96
|
+
...graphqlMethods,
|
|
97
|
+
...searchMethods,
|
|
98
|
+
...localizeMethods,
|
|
99
|
+
...systemMethods,
|
|
100
|
+
};
|
|
101
|
+
}
|
package/dist/cockpit-logger.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Logger for Cockpit API
|
|
3
|
+
*/
|
|
4
|
+
import { createLogger } from "@unchainedshop/logger";
|
|
5
|
+
type Logger = ReturnType<typeof createLogger>;
|
|
6
|
+
export declare const logger: Logger;
|
|
7
|
+
declare const logInfo: Logger["info"];
|
|
8
|
+
export default logInfo;
|
package/dist/cockpit-logger.js
CHANGED
|
@@ -1,20 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
async function loadLogger() {
|
|
9
|
-
try {
|
|
10
|
-
const { createLogger } = await import("@unchainedshop/logger");
|
|
11
|
-
logger = createLogger("cockpit") || logger;
|
|
12
|
-
}
|
|
13
|
-
catch (e) {
|
|
14
|
-
// console.warn(e);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
loadLogger();
|
|
18
|
-
const log = logger.info;
|
|
19
|
-
export { logger };
|
|
20
|
-
export default log;
|
|
1
|
+
/**
|
|
2
|
+
* Logger for Cockpit API
|
|
3
|
+
*/
|
|
4
|
+
import { createLogger } from "@unchainedshop/logger";
|
|
5
|
+
export const logger = createLogger("cockpit");
|
|
6
|
+
const logInfo = logger.info;
|
|
7
|
+
export default logInfo;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache management with LRU cache and tenant isolation
|
|
3
|
+
*/
|
|
4
|
+
export interface CacheOptions {
|
|
5
|
+
/** Maximum number of entries (default: 100) */
|
|
6
|
+
max?: number;
|
|
7
|
+
/** Time-to-live in milliseconds (default: 100000) */
|
|
8
|
+
ttl?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface CacheManager {
|
|
11
|
+
get(key: string): unknown;
|
|
12
|
+
set(key: string, value: NonNullable<unknown>): void;
|
|
13
|
+
clear(pattern?: string): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Creates a cache manager with prefixed keys
|
|
17
|
+
* Each call creates a new LRU cache instance - no shared state
|
|
18
|
+
*/
|
|
19
|
+
export declare function createCacheManager(cachePrefix: string, options?: CacheOptions): CacheManager;
|