@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/dist/api.js
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import { print } from "graphql";
|
|
2
|
-
import { logger } from "./cockpit-logger.js";
|
|
3
|
-
import { LRUCache } from 'lru-cache';
|
|
4
|
-
const dataCache = new LRUCache({
|
|
5
|
-
max: process.env.COCKPIT_CACHE__MAX_LIMIT ? parseInt(process.env.COCKPIT_CACHE__MAX_LIMIT, 10) : 100,
|
|
6
|
-
ttl: process.env.COCKPIT_CACHE_TTL ? parseInt(process.env.COCKPIT_CACHE_TTL, 10) : 100000,
|
|
7
|
-
allowStale: false,
|
|
8
|
-
});
|
|
9
|
-
export var ImageSizeMode;
|
|
10
|
-
(function (ImageSizeMode) {
|
|
11
|
-
ImageSizeMode["Thumbnail"] = "thumbnail";
|
|
12
|
-
ImageSizeMode["BestFit"] = "bestFit";
|
|
13
|
-
ImageSizeMode["Resize"] = "resize";
|
|
14
|
-
ImageSizeMode["FitToWidth"] = "fitToWidth";
|
|
15
|
-
ImageSizeMode["FitToHeight"] = "fitToHeight";
|
|
16
|
-
})(ImageSizeMode || (ImageSizeMode = {}));
|
|
17
|
-
export var MimeType;
|
|
18
|
-
(function (MimeType) {
|
|
19
|
-
MimeType["AUTO"] = "auto";
|
|
20
|
-
MimeType["GIF"] = "gif";
|
|
21
|
-
MimeType["JPEG"] = "jpeg";
|
|
22
|
-
MimeType["PNG"] = "png";
|
|
23
|
-
MimeType["WEBP"] = "webp";
|
|
24
|
-
MimeType["BMP"] = "bmp";
|
|
25
|
-
})(MimeType || (MimeType = {}));
|
|
26
|
-
const cockpitURL = () => new URL(process.env.COCKPIT_GRAPHQL_ENDPOINT);
|
|
27
|
-
export const getTenantIds = () => {
|
|
28
|
-
const env = { ...process.env };
|
|
29
|
-
const cockpitSecretKeys = Object.keys(env).filter((key) => key.includes("COCKPIT_SECRET") &&
|
|
30
|
-
key !== "COCKPIT_SECRET" &&
|
|
31
|
-
!key.endsWith("_FILE"));
|
|
32
|
-
const tenantIds = cockpitSecretKeys.map((key) => {
|
|
33
|
-
return key.slice("COCKPIT_SECRET_".length).toLowerCase();
|
|
34
|
-
});
|
|
35
|
-
return tenantIds;
|
|
36
|
-
};
|
|
37
|
-
export const generateCmsRouteReplacements = async (tenant) => {
|
|
38
|
-
const cachedReplacement = dataCache.get(`ROUTE_REPLACEMENT_MAP${tenant}`);
|
|
39
|
-
if (cachedReplacement)
|
|
40
|
-
return cachedReplacement;
|
|
41
|
-
const filterParams = {
|
|
42
|
-
fields: JSON.stringify({ _id: 1, slug: 1, _r: 1 }),
|
|
43
|
-
};
|
|
44
|
-
const cmsPages = await fetch(`${cockpitURL().origin}${tenant ? `/:${tenant}/api` : "/api"}/pages/pages?${new URLSearchParams(filterParams).toString()}`);
|
|
45
|
-
const pagesArr = (await cmsPages.json()) || [];
|
|
46
|
-
const replacement = pagesArr.reduce((result, item) => {
|
|
47
|
-
const key = `pages://${item._id}`;
|
|
48
|
-
const value = item._r;
|
|
49
|
-
return { ...result, [key]: value };
|
|
50
|
-
}, {});
|
|
51
|
-
dataCache.set(`ROUTE_REPLACEMENT_MAP${tenant}`, replacement);
|
|
52
|
-
return replacement;
|
|
53
|
-
};
|
|
54
|
-
export const generateCollectionAndSingletonSlugRouteMap = async (tenant) => {
|
|
55
|
-
const cacheKey = `SLUG_ROUTE_MAP_${tenant}`;
|
|
56
|
-
const cachedMap = dataCache.get(cacheKey);
|
|
57
|
-
if (cachedMap)
|
|
58
|
-
return cachedMap;
|
|
59
|
-
const filterParams = {
|
|
60
|
-
fields: JSON.stringify({
|
|
61
|
-
data: { collection: 1, singleton: 1 },
|
|
62
|
-
_r: 1,
|
|
63
|
-
type: 1,
|
|
64
|
-
}),
|
|
65
|
-
filter: JSON.stringify({ 'data.collection': { $ne: null } }),
|
|
66
|
-
};
|
|
67
|
-
const cmsPages = await fetch(`${cockpitURL().origin}${tenant ? `/:${tenant}/api` : "/api"}/pages/pages?locale=default&${new URLSearchParams(filterParams).toString()}`);
|
|
68
|
-
const pagesArr = (await cmsPages.json()) || [];
|
|
69
|
-
const pageMap = pagesArr.reduce((result, { data, _r }) => {
|
|
70
|
-
const entityName = data?.collection || data?.singleton;
|
|
71
|
-
if (!entityName)
|
|
72
|
-
return result;
|
|
73
|
-
return { ...result, [entityName]: _r };
|
|
74
|
-
}, {});
|
|
75
|
-
dataCache.set(cacheKey, pageMap);
|
|
76
|
-
return pageMap;
|
|
77
|
-
};
|
|
78
|
-
export const FixImagePaths = (replacements, tenant) => {
|
|
79
|
-
const pattern = new RegExp(Object.keys(replacements).join("|"), "g");
|
|
80
|
-
const url = `${cockpitURL().origin}${tenant ? `/:${tenant}` : ""}`;
|
|
81
|
-
return {
|
|
82
|
-
transformResult(originalResponse) {
|
|
83
|
-
try {
|
|
84
|
-
const rawResponseDataString = JSON.stringify(originalResponse);
|
|
85
|
-
const fixedDataString = rawResponseDataString
|
|
86
|
-
// fixes asset paths
|
|
87
|
-
.replace(/"path":"\//g, `"path":"${url}/storage/uploads/`)
|
|
88
|
-
.replace(/src=\\"(\/[^"]*?)storage/gi, `src=\\"${cockpitURL().origin}$1storage`)
|
|
89
|
-
.replace(/href=\\"(\/[^"]*?)storage/gi, `href=\\"${cockpitURL().origin}$1storage`)
|
|
90
|
-
.replace(pattern, (match) => replacements[match])
|
|
91
|
-
// fixes image paths which already had a path including storage/uploads
|
|
92
|
-
.replace(/\/storage\/uploads\/storage\/uploads\//g, `/storage/uploads/`);
|
|
93
|
-
return JSON.parse(fixedDataString);
|
|
94
|
-
}
|
|
95
|
-
catch (e) {
|
|
96
|
-
return originalResponse;
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
const encodeQueryParam = (key, value) => {
|
|
102
|
-
return `${encodeURIComponent(key)}=${encodeURIComponent(typeof value !== "string" ? JSON.stringify(value) : value)}`;
|
|
103
|
-
};
|
|
104
|
-
const buildQueryString = (params) => {
|
|
105
|
-
if (!Object.keys(params).length)
|
|
106
|
-
return null;
|
|
107
|
-
return Object.entries(params)
|
|
108
|
-
.map(([key, value]) => encodeQueryParam(key, value))
|
|
109
|
-
.join("&");
|
|
110
|
-
};
|
|
111
|
-
const handleErrorAndLog = (e) => {
|
|
112
|
-
logger.error('Cockpit API Error', e);
|
|
113
|
-
return null;
|
|
114
|
-
};
|
|
115
|
-
export const CockpitAPI = async (tenant, cockpitOptions) => {
|
|
116
|
-
const useAdminAccess = cockpitOptions?.useAdminAccess || false;
|
|
117
|
-
if (!process.env.COCKPIT_GRAPHQL_ENDPOINT && !cockpitOptions?.endpoint)
|
|
118
|
-
throw Error("COCKPIT_GRAPHQL_ENDPOINT is not set");
|
|
119
|
-
const cockpitEndpoint = cockpitOptions?.endpoint || process.env.COCKPIT_GRAPHQL_ENDPOINT;
|
|
120
|
-
const buildUrl = (path, { locale = "de", queryParams = {} } = {}) => {
|
|
121
|
-
const normalizedLocale = locale === "de" ? "default" : locale;
|
|
122
|
-
const url = new URL(cockpitURL());
|
|
123
|
-
url.pathname = `${tenant ? `/:${tenant}/api` : "/api"}${path}`;
|
|
124
|
-
const queryString = buildQueryString({
|
|
125
|
-
...queryParams,
|
|
126
|
-
locale: normalizedLocale,
|
|
127
|
-
});
|
|
128
|
-
url.search = queryString;
|
|
129
|
-
return url;
|
|
130
|
-
};
|
|
131
|
-
const routeReplaceMents = await generateCmsRouteReplacements(tenant);
|
|
132
|
-
const { transformResult } = FixImagePaths(routeReplaceMents, tenant);
|
|
133
|
-
const handleResponse = async (result) => {
|
|
134
|
-
if (result.status === 404)
|
|
135
|
-
return null;
|
|
136
|
-
if (result.status !== 200) {
|
|
137
|
-
logger.error(`Error accessing ${result.url}`, result);
|
|
138
|
-
throw new Error(`Cockpit: Error accessing ${result.url} ${await result.text()}`);
|
|
139
|
-
}
|
|
140
|
-
return transformResult(await result.json());
|
|
141
|
-
};
|
|
142
|
-
const fetchData = async (url, options = {}) => {
|
|
143
|
-
const headers = options?.headers ?? {};
|
|
144
|
-
if (useAdminAccess) {
|
|
145
|
-
const secretName = ["COCKPIT_SECRET", tenant].filter(Boolean).join("_").toUpperCase();
|
|
146
|
-
const token = cockpitOptions?.apiKey || process.env[secretName];
|
|
147
|
-
headers["api-Key"] = token;
|
|
148
|
-
}
|
|
149
|
-
try {
|
|
150
|
-
logger.debug(`Requesting ${url}`);
|
|
151
|
-
const result = await fetch(url, {
|
|
152
|
-
...options,
|
|
153
|
-
headers: {
|
|
154
|
-
...headers,
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
return handleResponse(result);
|
|
158
|
-
}
|
|
159
|
-
catch (e) {
|
|
160
|
-
return handleErrorAndLog(e);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
return {
|
|
164
|
-
async graphQL(document, variables) {
|
|
165
|
-
const query = print(document);
|
|
166
|
-
const cockpitEndpointUrl = new URL(cockpitEndpoint);
|
|
167
|
-
if (tenant) {
|
|
168
|
-
cockpitEndpointUrl.pathname = `/:${tenant}${cockpitEndpointUrl.pathname}`;
|
|
169
|
-
}
|
|
170
|
-
return fetchData(cockpitEndpointUrl, {
|
|
171
|
-
method: "POST",
|
|
172
|
-
headers: { "Content-Type": "application/json" },
|
|
173
|
-
body: JSON.stringify({ query, variables }),
|
|
174
|
-
});
|
|
175
|
-
},
|
|
176
|
-
async getContentItem({ model, id }, locale = "default", queryParams = {}) {
|
|
177
|
-
if (!model)
|
|
178
|
-
throw new Error("Cockpit: Please provide a model");
|
|
179
|
-
const url = buildUrl(`/content/item/${model}${id ? `/${id}` : ""}`, {
|
|
180
|
-
locale,
|
|
181
|
-
queryParams,
|
|
182
|
-
});
|
|
183
|
-
return fetchData(url);
|
|
184
|
-
},
|
|
185
|
-
async getAggregateModel({ model, pipeline }, locale = "default") {
|
|
186
|
-
if (!model)
|
|
187
|
-
throw new Error("Cockpit: Please provide a model");
|
|
188
|
-
const url = buildUrl(`/content/aggregate/${model}`, {
|
|
189
|
-
locale,
|
|
190
|
-
queryParams: {
|
|
191
|
-
pipeline,
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
return fetchData(url);
|
|
195
|
-
},
|
|
196
|
-
async getContentItems(model, locale = "default", queryParams = {}) {
|
|
197
|
-
if (!model)
|
|
198
|
-
throw new Error("Cockpit: Please provide a model");
|
|
199
|
-
const url = buildUrl(`/content/items/${model}`, {
|
|
200
|
-
locale,
|
|
201
|
-
queryParams,
|
|
202
|
-
});
|
|
203
|
-
return fetchData(url);
|
|
204
|
-
},
|
|
205
|
-
async getContentTree(model, locale = "default", queryParams = { filter: {} }) {
|
|
206
|
-
if (!model)
|
|
207
|
-
throw new Error("Cockpit: Please provide a model");
|
|
208
|
-
const url = buildUrl(`/content/tree/${model}`, {
|
|
209
|
-
locale,
|
|
210
|
-
queryParams,
|
|
211
|
-
});
|
|
212
|
-
return fetchData(url);
|
|
213
|
-
},
|
|
214
|
-
async postContentItem(model, item) {
|
|
215
|
-
if (!model)
|
|
216
|
-
throw new Error("Cockpit: Please provide a model");
|
|
217
|
-
const url = buildUrl(`/content/item/${model}`, {});
|
|
218
|
-
return fetchData(url, {
|
|
219
|
-
method: "POST",
|
|
220
|
-
headers: { "Content-Type": "application/json" },
|
|
221
|
-
body: JSON.stringify({ data: item }),
|
|
222
|
-
});
|
|
223
|
-
},
|
|
224
|
-
async deleteContentItem(model, id) {
|
|
225
|
-
if (!model || !id)
|
|
226
|
-
throw new Error("Cockpit: Please provide a model and id");
|
|
227
|
-
const url = buildUrl(`/content/item/${model}/${id}`, {});
|
|
228
|
-
return fetchData(url, {
|
|
229
|
-
method: "DELETE",
|
|
230
|
-
headers: { "Content-Type": "application/json" },
|
|
231
|
-
});
|
|
232
|
-
},
|
|
233
|
-
async pages(locale = "default", queryParams = {}) {
|
|
234
|
-
const url = buildUrl("/pages/pages", {
|
|
235
|
-
locale,
|
|
236
|
-
queryParams,
|
|
237
|
-
});
|
|
238
|
-
return fetchData(url);
|
|
239
|
-
},
|
|
240
|
-
async pageById({ page, id }, locale = "default", queryParams = {}) {
|
|
241
|
-
if (!page || !id)
|
|
242
|
-
throw new Error("GetCockpit: Please provide a page and id");
|
|
243
|
-
const url = buildUrl(`/pages/page/${page}/${id}`, {
|
|
244
|
-
locale,
|
|
245
|
-
queryParams,
|
|
246
|
-
});
|
|
247
|
-
return fetchData(url);
|
|
248
|
-
},
|
|
249
|
-
async pageByRoute(route, locale = "default") {
|
|
250
|
-
const url = buildUrl("/pages/page", {
|
|
251
|
-
locale,
|
|
252
|
-
queryParams: { route },
|
|
253
|
-
});
|
|
254
|
-
return fetchData(url);
|
|
255
|
-
},
|
|
256
|
-
async pagesMenus(locale = "default") {
|
|
257
|
-
const url = buildUrl("/pages/menus", { locale });
|
|
258
|
-
return fetchData(url);
|
|
259
|
-
},
|
|
260
|
-
async pagesMenu(name, locale = "default") {
|
|
261
|
-
const url = buildUrl(`/pages/menu/${name}`, { locale });
|
|
262
|
-
return fetchData(url);
|
|
263
|
-
},
|
|
264
|
-
async pagesRoutes(locale = "default") {
|
|
265
|
-
const url = buildUrl("/pages/routes", { locale });
|
|
266
|
-
return fetchData(url);
|
|
267
|
-
},
|
|
268
|
-
async pagesSitemap() {
|
|
269
|
-
const url = buildUrl("/pages/sitemap", {});
|
|
270
|
-
return fetchData(url);
|
|
271
|
-
},
|
|
272
|
-
async pagesSetting(locale = "default") {
|
|
273
|
-
const url = buildUrl("/pages/settings", { locale });
|
|
274
|
-
return fetchData(url);
|
|
275
|
-
},
|
|
276
|
-
async healthCheck() {
|
|
277
|
-
const url = buildUrl("/system/healthcheck");
|
|
278
|
-
return fetchData(url);
|
|
279
|
-
},
|
|
280
|
-
async lokalize(projectName, locale = "default", nested = null) {
|
|
281
|
-
if (!projectName)
|
|
282
|
-
throw new Error("GetCockpit: Please provide projectName");
|
|
283
|
-
const url = buildUrl(`/lokalize/project/${projectName}`, { locale, queryParams: { nested } });
|
|
284
|
-
return fetchData(url);
|
|
285
|
-
},
|
|
286
|
-
async assetById(assetId) {
|
|
287
|
-
if (!assetId)
|
|
288
|
-
throw new Error("GetCockpit: Please provide assetId");
|
|
289
|
-
const url = buildUrl(`/assets/${assetId}`);
|
|
290
|
-
return fetchData(url);
|
|
291
|
-
},
|
|
292
|
-
async imageAssetById(assetId, queryParams) {
|
|
293
|
-
if (!assetId)
|
|
294
|
-
throw new Error("GetCockpit: Please provide assetId");
|
|
295
|
-
const url = buildUrl(`/assets/image/${assetId}`, { queryParams });
|
|
296
|
-
return fetchData(url);
|
|
297
|
-
},
|
|
298
|
-
async getFullRouteForSlug(slug) {
|
|
299
|
-
const routeSlugMap = await generateCollectionAndSingletonSlugRouteMap(tenant);
|
|
300
|
-
return routeSlugMap?.[slug];
|
|
301
|
-
},
|
|
302
|
-
};
|
|
303
|
-
};
|