@plasmicpkgs/contentful 0.0.7 → 0.0.8
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 +83 -14
- package/dist/index.esm.js +342 -38
- package/dist/index.esm.js.map +3 -3
- package/dist/index.js +342 -38
- package/dist/index.js.map +3 -3
- package/package.json +5 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
space: string;
|
|
3
|
-
accessToken: string;
|
|
4
|
-
environment?: string;
|
|
5
|
-
contentType: string;
|
|
6
|
-
filterField?: string;
|
|
7
|
-
searchParameter?: string;
|
|
8
|
-
filterValue?: string | number;
|
|
9
|
-
order?: string;
|
|
10
|
-
reverseOrder?: boolean;
|
|
11
|
-
limit?: number;
|
|
12
|
-
include?: number;
|
|
13
|
-
}
|
|
1
|
+
import type { RulesLogic } from 'json-logic-js';
|
|
14
2
|
|
|
15
3
|
export declare function _denormalizeData(data: any | null): any;
|
|
16
4
|
|
|
@@ -25,7 +13,88 @@ export declare interface _Entry {
|
|
|
25
13
|
};
|
|
26
14
|
}
|
|
27
15
|
|
|
28
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Query a Contentful content type with optional filtering and ordering.
|
|
18
|
+
*
|
|
19
|
+
* @param opts - Query options including space, accessToken, contentType, filter logic, and pagination
|
|
20
|
+
* @returns Promise resolving to the Contentful query response with denormalized data
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* // Fetch all entries
|
|
25
|
+
* const result = await queryContentful({
|
|
26
|
+
* space: 'your-space-id',
|
|
27
|
+
* accessToken: 'your-access-token',
|
|
28
|
+
* contentType: 'blogPost'
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // Fetch with filter
|
|
32
|
+
* const filtered = await queryContentful({
|
|
33
|
+
* space: 'your-space-id',
|
|
34
|
+
* accessToken: 'your-access-token',
|
|
35
|
+
* contentType: 'blogPost',
|
|
36
|
+
* filterLogic: { "==": [{ var: "status" }, "published"] }
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function queryContentful({ space, accessToken, environment, contentType, filterLogic, }: QueryContentfulOpts): Promise<any>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Query Contentful with simplified filter props.
|
|
44
|
+
*
|
|
45
|
+
* @deprecated Use {@link queryContentful} with `filterLogic` parameter instead.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* // Old way (deprecated)
|
|
50
|
+
* _queryContentful({
|
|
51
|
+
* space: 'space-id',
|
|
52
|
+
* accessToken: 'token',
|
|
53
|
+
* contentType: 'article',
|
|
54
|
+
* filterField: 'title',
|
|
55
|
+
* searchParameter: '[match]',
|
|
56
|
+
* filterValue: 'Hello'
|
|
57
|
+
* })
|
|
58
|
+
*
|
|
59
|
+
* // New way
|
|
60
|
+
* queryContentful({
|
|
61
|
+
* space: 'space-id',
|
|
62
|
+
* accessToken: 'token',
|
|
63
|
+
* contentType: 'article',
|
|
64
|
+
* filterLogic: { "==": [{ var: "title" }, "Hello"] }
|
|
65
|
+
* })
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare function _queryContentful({ space, accessToken, environment, contentType, filterLogic, filterField, searchParameter, filterValue, order, reverseOrder, limit, skip, include, select, locale, }: QueryContentfulOpts & QueryContentfulOldFilterProps): Promise<any>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @deprecated These filter props are deprecated. Use `filterLogic` with the query builder instead.
|
|
72
|
+
* Only used by the deprecated ContentfulCollection component for backward compatibility.
|
|
73
|
+
*/
|
|
74
|
+
declare interface QueryContentfulOldFilterProps {
|
|
75
|
+
filterField?: string;
|
|
76
|
+
searchParameter?: string;
|
|
77
|
+
filterValue?: string | number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
declare interface QueryContentfulOpts {
|
|
81
|
+
space?: string;
|
|
82
|
+
accessToken?: string;
|
|
83
|
+
environment?: string;
|
|
84
|
+
contentType?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Filter logic using JSON Logic format to filter Contentful entries.
|
|
87
|
+
* See {@link https://www.npmjs.com/package/@types/json-logic-js?activeTab=readme}
|
|
88
|
+
*/
|
|
89
|
+
filterLogic?: RulesLogic;
|
|
90
|
+
order?: string;
|
|
91
|
+
reverseOrder?: boolean;
|
|
92
|
+
limit?: number;
|
|
93
|
+
skip?: number;
|
|
94
|
+
include?: number;
|
|
95
|
+
select?: string | string[];
|
|
96
|
+
locale?: string;
|
|
97
|
+
}
|
|
29
98
|
|
|
30
99
|
export declare function registerContentful(loader?: {
|
|
31
100
|
registerFunction: any;
|
package/dist/index.esm.js
CHANGED
|
@@ -41,6 +41,174 @@ var __async = (__this, __arguments, generator) => {
|
|
|
41
41
|
// src/index.ts
|
|
42
42
|
import registerFunction from "@plasmicapp/host/registerFunction";
|
|
43
43
|
|
|
44
|
+
// src/utils.ts
|
|
45
|
+
var _uniq = (xs) => Array.from(new Set(xs));
|
|
46
|
+
var BASE_URL = "https://cdn.contentful.com";
|
|
47
|
+
function _ensure(x, msg) {
|
|
48
|
+
if (x === null || x === void 0) {
|
|
49
|
+
throw new Error(msg != null ? msg : `Value must not be undefined or null`);
|
|
50
|
+
} else {
|
|
51
|
+
return x;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function capitalize(str) {
|
|
55
|
+
if (!str) {
|
|
56
|
+
return str;
|
|
57
|
+
}
|
|
58
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/schema.ts
|
|
62
|
+
function fetchContentTypes(space, accessToken, environment = "master") {
|
|
63
|
+
return __async(this, null, function* () {
|
|
64
|
+
const url = `${BASE_URL}/spaces/${space}/environments/${environment}/content_types`;
|
|
65
|
+
const params = new URLSearchParams({ access_token: accessToken });
|
|
66
|
+
const resp = yield fetch(`${url}?${params.toString()}`);
|
|
67
|
+
if (!resp.ok) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Failed to fetch content types: ${resp.status} ${resp.statusText}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const data = yield resp.json();
|
|
73
|
+
return data.items;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function findContentTypeSchema(contentType, contentTypes) {
|
|
77
|
+
if (!contentType || !contentTypes) {
|
|
78
|
+
return void 0;
|
|
79
|
+
}
|
|
80
|
+
return contentTypes.find((ct) => ct.sys.id === contentType);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/where.ts
|
|
84
|
+
function contentfulSchemaFieldToQueryBuilderField(field) {
|
|
85
|
+
switch (field.type) {
|
|
86
|
+
case "Integer":
|
|
87
|
+
case "Number":
|
|
88
|
+
return {
|
|
89
|
+
label: capitalize(field.name),
|
|
90
|
+
type: "number",
|
|
91
|
+
operators: [
|
|
92
|
+
"equal",
|
|
93
|
+
"not_equal",
|
|
94
|
+
"less",
|
|
95
|
+
"less_or_equal",
|
|
96
|
+
"greater",
|
|
97
|
+
"greater_or_equal",
|
|
98
|
+
"is_null",
|
|
99
|
+
"is_not_null"
|
|
100
|
+
]
|
|
101
|
+
};
|
|
102
|
+
case "Boolean":
|
|
103
|
+
return {
|
|
104
|
+
label: capitalize(field.name),
|
|
105
|
+
type: "boolean"
|
|
106
|
+
};
|
|
107
|
+
case "Date":
|
|
108
|
+
return {
|
|
109
|
+
label: capitalize(field.name),
|
|
110
|
+
type: "datetime",
|
|
111
|
+
operators: [
|
|
112
|
+
"equal",
|
|
113
|
+
"not_equal",
|
|
114
|
+
"less",
|
|
115
|
+
"less_or_equal",
|
|
116
|
+
"greater",
|
|
117
|
+
"greater_or_equal",
|
|
118
|
+
"is_null",
|
|
119
|
+
"is_not_null"
|
|
120
|
+
]
|
|
121
|
+
};
|
|
122
|
+
case "Symbol":
|
|
123
|
+
case "Text":
|
|
124
|
+
return {
|
|
125
|
+
label: capitalize(field.name),
|
|
126
|
+
type: "text",
|
|
127
|
+
operators: ["equal", "not_equal", "like", "is_null", "is_not_null"]
|
|
128
|
+
};
|
|
129
|
+
default:
|
|
130
|
+
return void 0;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function schemaToQueryBuilderConfig(schema) {
|
|
134
|
+
const fields = {};
|
|
135
|
+
for (const field of schema.fields) {
|
|
136
|
+
const qbField = contentfulSchemaFieldToQueryBuilderField(field);
|
|
137
|
+
if (qbField) {
|
|
138
|
+
fields[field.id] = qbField;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
fields,
|
|
143
|
+
conjunctions: {
|
|
144
|
+
AND: {
|
|
145
|
+
label: "All"
|
|
146
|
+
}
|
|
147
|
+
// OR explicitly omitted - not supported by Contentful API
|
|
148
|
+
},
|
|
149
|
+
settings: {
|
|
150
|
+
showNot: false,
|
|
151
|
+
maxNesting: 1,
|
|
152
|
+
canRegroup: false,
|
|
153
|
+
canLeaveEmptyGroup: false
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function rulesLogicToContentfulFilters(logic) {
|
|
158
|
+
if (logic === null || logic === void 0) {
|
|
159
|
+
return {};
|
|
160
|
+
} else if (typeof logic !== "object") {
|
|
161
|
+
throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);
|
|
162
|
+
} else if ("and" in logic) {
|
|
163
|
+
return logic["and"].reduce((acc, condition) => {
|
|
164
|
+
return __spreadValues(__spreadValues({}, acc), rulesLogicToContentfulFilters(condition));
|
|
165
|
+
}, {});
|
|
166
|
+
} else if ("or" in logic) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
"Contentful API does not support OR operations. Please restructure your query using only AND conditions."
|
|
169
|
+
);
|
|
170
|
+
} else if ("!" in logic) {
|
|
171
|
+
throw new Error(
|
|
172
|
+
"Contentful API does not support NOT operations. Please use field-level negation operators like 'not_equal' ([ne]) instead."
|
|
173
|
+
);
|
|
174
|
+
} else if ("==" in logic) {
|
|
175
|
+
const [{ var: field }, operand] = logic["=="];
|
|
176
|
+
if (operand === null) {
|
|
177
|
+
return { [`fields.${field}[exists]`]: "false" };
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
[`fields.${field}`]: operand
|
|
181
|
+
};
|
|
182
|
+
} else if ("!=" in logic) {
|
|
183
|
+
const [{ var: field }, operand] = logic["!="];
|
|
184
|
+
if (operand === null) {
|
|
185
|
+
return { [`fields.${field}[exists]`]: "true" };
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
[`fields.${field}[ne]`]: operand
|
|
189
|
+
};
|
|
190
|
+
} else if ("in" in logic) {
|
|
191
|
+
const [operand, { var: field }] = logic["in"];
|
|
192
|
+
return {
|
|
193
|
+
[`fields.${field}[match]`]: operand
|
|
194
|
+
};
|
|
195
|
+
} else {
|
|
196
|
+
const [key, value] = Object.entries(logic)[0];
|
|
197
|
+
const apiOp = operatorMapping[key];
|
|
198
|
+
if (apiOp) {
|
|
199
|
+
const [{ var: field }, operand] = value;
|
|
200
|
+
return { [`fields.${field}[${apiOp}]`]: operand };
|
|
201
|
+
}
|
|
202
|
+
throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
var operatorMapping = {
|
|
206
|
+
"<": "lt",
|
|
207
|
+
"<=": "lte",
|
|
208
|
+
">": "gt",
|
|
209
|
+
">=": "gte"
|
|
210
|
+
};
|
|
211
|
+
|
|
44
212
|
// src/query-contentful.ts
|
|
45
213
|
var modulePath = "@plasmicpkgs/contentful";
|
|
46
214
|
function denormalizeData(data) {
|
|
@@ -125,19 +293,23 @@ function denormalizeData(data) {
|
|
|
125
293
|
items: itemsWithDenormalizedFields
|
|
126
294
|
});
|
|
127
295
|
}
|
|
128
|
-
function
|
|
296
|
+
function _queryContentful(_0) {
|
|
129
297
|
return __async(this, arguments, function* ({
|
|
130
298
|
space,
|
|
131
299
|
accessToken,
|
|
132
300
|
environment = "master",
|
|
133
301
|
contentType,
|
|
302
|
+
filterLogic,
|
|
134
303
|
filterField,
|
|
135
304
|
searchParameter,
|
|
136
305
|
filterValue,
|
|
137
306
|
order,
|
|
138
307
|
reverseOrder,
|
|
139
308
|
limit,
|
|
140
|
-
|
|
309
|
+
skip,
|
|
310
|
+
include,
|
|
311
|
+
select,
|
|
312
|
+
locale
|
|
141
313
|
}) {
|
|
142
314
|
if (!space || !accessToken) {
|
|
143
315
|
throw new Error("Space and accessToken are required");
|
|
@@ -145,14 +317,25 @@ function queryContentful(_0) {
|
|
|
145
317
|
if (!contentType) {
|
|
146
318
|
return null;
|
|
147
319
|
}
|
|
148
|
-
const baseUrl = "https://cdn.contentful.com";
|
|
149
320
|
const path = `/spaces/${space}/environments/${environment}/entries`;
|
|
150
321
|
const searchParams = new URLSearchParams();
|
|
151
322
|
searchParams.set("access_token", accessToken);
|
|
152
323
|
searchParams.set("content_type", contentType);
|
|
324
|
+
let filters = {};
|
|
325
|
+
if (filterLogic) {
|
|
326
|
+
filters = rulesLogicToContentfulFilters(filterLogic);
|
|
327
|
+
} else if (filterField && searchParameter && filterValue !== void 0) {
|
|
328
|
+
filters[`fields.${filterField}${searchParameter}`] = filterValue.toString();
|
|
329
|
+
}
|
|
330
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
331
|
+
searchParams.set(key, value.toString());
|
|
332
|
+
}
|
|
153
333
|
if (limit) {
|
|
154
334
|
searchParams.set("limit", limit.toString());
|
|
155
335
|
}
|
|
336
|
+
if (skip !== void 0) {
|
|
337
|
+
searchParams.set("skip", skip.toString());
|
|
338
|
+
}
|
|
156
339
|
if (order) {
|
|
157
340
|
searchParams.set(
|
|
158
341
|
"order",
|
|
@@ -162,17 +345,40 @@ function queryContentful(_0) {
|
|
|
162
345
|
if (include !== void 0) {
|
|
163
346
|
searchParams.set("include", include.toString());
|
|
164
347
|
}
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
348
|
+
if (select) {
|
|
349
|
+
if (Array.isArray(select)) {
|
|
350
|
+
if (select.length > 0) {
|
|
351
|
+
searchParams.set("select", select.join(","));
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
searchParams.set("select", select);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (locale) {
|
|
358
|
+
searchParams.set("locale", locale);
|
|
170
359
|
}
|
|
171
|
-
const resp = yield fetch(`${
|
|
360
|
+
const resp = yield fetch(`${BASE_URL}${path}?${searchParams.toString()}`);
|
|
172
361
|
const data = yield resp.json();
|
|
173
362
|
return denormalizeData(data);
|
|
174
363
|
});
|
|
175
364
|
}
|
|
365
|
+
function queryContentful(_0) {
|
|
366
|
+
return __async(this, arguments, function* ({
|
|
367
|
+
space,
|
|
368
|
+
accessToken,
|
|
369
|
+
environment = "master",
|
|
370
|
+
contentType,
|
|
371
|
+
filterLogic
|
|
372
|
+
}) {
|
|
373
|
+
return _queryContentful({
|
|
374
|
+
space,
|
|
375
|
+
accessToken,
|
|
376
|
+
environment,
|
|
377
|
+
contentType,
|
|
378
|
+
filterLogic
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
}
|
|
176
382
|
var queryContentfulMeta = {
|
|
177
383
|
name: "queryContentful",
|
|
178
384
|
displayName: "Query Contentful",
|
|
@@ -197,51 +403,148 @@ var queryContentfulMeta = {
|
|
|
197
403
|
description: "Contentful environment (default: master)"
|
|
198
404
|
},
|
|
199
405
|
contentType: {
|
|
200
|
-
type: "
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
406
|
+
type: "choice",
|
|
407
|
+
displayName: "Content Type",
|
|
408
|
+
description: "Content type to query",
|
|
409
|
+
options: (_, ctx) => {
|
|
410
|
+
var _a, _b;
|
|
411
|
+
return (_b = (_a = ctx == null ? void 0 : ctx.contentTypes) == null ? void 0 : _a.map((ct) => ({
|
|
412
|
+
label: ct.name,
|
|
413
|
+
value: ct.sys.id
|
|
414
|
+
}))) != null ? _b : [];
|
|
415
|
+
}
|
|
210
416
|
},
|
|
211
|
-
|
|
212
|
-
type: "
|
|
213
|
-
|
|
417
|
+
filterLogic: {
|
|
418
|
+
type: "queryBuilder",
|
|
419
|
+
displayName: "Filter",
|
|
420
|
+
description: "Filter fetched entries. Defaults to fetch all entries.",
|
|
421
|
+
config: ([opts], ctx) => {
|
|
422
|
+
const schema = findContentTypeSchema(
|
|
423
|
+
opts == null ? void 0 : opts.contentType,
|
|
424
|
+
ctx == null ? void 0 : ctx.contentTypes
|
|
425
|
+
);
|
|
426
|
+
if (schema) {
|
|
427
|
+
return schemaToQueryBuilderConfig(schema);
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
fields: {}
|
|
431
|
+
};
|
|
432
|
+
}
|
|
214
433
|
},
|
|
215
434
|
order: {
|
|
216
|
-
type: "
|
|
217
|
-
|
|
435
|
+
type: "choice",
|
|
436
|
+
displayName: "Order by",
|
|
437
|
+
description: "Field to order by (optional)",
|
|
438
|
+
defaultValueHint: "sys.updatedAt",
|
|
439
|
+
options: ([opts], ctx) => {
|
|
440
|
+
const systemFields = [
|
|
441
|
+
{ label: "Created at", value: "sys.createdAt" },
|
|
442
|
+
{ label: "Updated at", value: "sys.updatedAt" },
|
|
443
|
+
{ label: "ID", value: "sys.id" }
|
|
444
|
+
];
|
|
445
|
+
const schema = findContentTypeSchema(
|
|
446
|
+
opts == null ? void 0 : opts.contentType,
|
|
447
|
+
ctx == null ? void 0 : ctx.contentTypes
|
|
448
|
+
);
|
|
449
|
+
if (schema) {
|
|
450
|
+
const contentFields = schema.fields.filter((field) => !field.disabled).map((field) => ({
|
|
451
|
+
label: capitalize(field.name),
|
|
452
|
+
value: `fields.${field.id}`
|
|
453
|
+
}));
|
|
454
|
+
return [...systemFields, ...contentFields];
|
|
455
|
+
}
|
|
456
|
+
return systemFields;
|
|
457
|
+
}
|
|
218
458
|
},
|
|
219
459
|
reverseOrder: {
|
|
220
460
|
type: "boolean",
|
|
221
|
-
description: "Reverse the order"
|
|
461
|
+
description: "Reverse the order",
|
|
462
|
+
hidden: ([opts]) => !(opts == null ? void 0 : opts.order),
|
|
463
|
+
defaultValueHint: false
|
|
222
464
|
},
|
|
223
465
|
limit: {
|
|
224
466
|
type: "number",
|
|
225
|
-
description: "Limit number of results"
|
|
467
|
+
description: "Limit number of results",
|
|
468
|
+
defaultValueHint: 100
|
|
469
|
+
},
|
|
470
|
+
skip: {
|
|
471
|
+
type: "number",
|
|
472
|
+
description: "Skip number of results (for pagination)",
|
|
473
|
+
defaultValueHint: 0
|
|
226
474
|
},
|
|
227
475
|
include: {
|
|
228
476
|
type: "number",
|
|
229
|
-
description: "Depth of linked items to include (max 10)"
|
|
477
|
+
description: "Depth of linked items to include (max 10)",
|
|
478
|
+
max: 10,
|
|
479
|
+
min: 0,
|
|
480
|
+
defaultValueHint: 1
|
|
481
|
+
},
|
|
482
|
+
select: {
|
|
483
|
+
type: "choice",
|
|
484
|
+
multiSelect: true,
|
|
485
|
+
description: "Fields to select. Defaults to all fields.",
|
|
486
|
+
options: ([opts], ctx) => {
|
|
487
|
+
const schema = findContentTypeSchema(
|
|
488
|
+
opts == null ? void 0 : opts.contentType,
|
|
489
|
+
ctx == null ? void 0 : ctx.contentTypes
|
|
490
|
+
);
|
|
491
|
+
const fieldOptions = schema ? schema.fields.filter((field) => !field.disabled).map((field) => ({
|
|
492
|
+
label: capitalize(field.name),
|
|
493
|
+
// Use capitalized friendly name from schema
|
|
494
|
+
value: `fields.${field.id}`
|
|
495
|
+
})) : [];
|
|
496
|
+
return [
|
|
497
|
+
...fieldOptions,
|
|
498
|
+
{ label: "Fields only", value: "fields" },
|
|
499
|
+
{ label: "Metadata only", value: "sys" }
|
|
500
|
+
];
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
locale: {
|
|
504
|
+
type: "string",
|
|
505
|
+
description: "Locale code (e.g., en-US)"
|
|
230
506
|
}
|
|
231
507
|
}
|
|
232
508
|
}
|
|
233
|
-
]
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
509
|
+
],
|
|
510
|
+
fnContext: (contentfulOpts) => {
|
|
511
|
+
if (!(contentfulOpts == null ? void 0 : contentfulOpts.space) || !(contentfulOpts == null ? void 0 : contentfulOpts.accessToken)) {
|
|
512
|
+
return {
|
|
513
|
+
dataKey: "",
|
|
514
|
+
fetcher: () => __async(void 0, null, function* () {
|
|
515
|
+
return {
|
|
516
|
+
contentTypes: []
|
|
517
|
+
};
|
|
518
|
+
})
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
const workspaceCacheKey = JSON.stringify({
|
|
522
|
+
space: contentfulOpts.space,
|
|
523
|
+
accessToken: contentfulOpts.accessToken,
|
|
524
|
+
environment: contentfulOpts.environment
|
|
525
|
+
});
|
|
526
|
+
return {
|
|
527
|
+
dataKey: workspaceCacheKey,
|
|
528
|
+
fetcher: () => __async(void 0, null, function* () {
|
|
529
|
+
try {
|
|
530
|
+
const contentTypes = yield fetchContentTypes(
|
|
531
|
+
contentfulOpts.space,
|
|
532
|
+
contentfulOpts.accessToken,
|
|
533
|
+
contentfulOpts.environment
|
|
534
|
+
);
|
|
535
|
+
return {
|
|
536
|
+
contentTypes
|
|
537
|
+
};
|
|
538
|
+
} catch (error) {
|
|
539
|
+
console.error("Failed to fetch content types:", error);
|
|
540
|
+
return {
|
|
541
|
+
contentTypes: []
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
})
|
|
545
|
+
};
|
|
243
546
|
}
|
|
244
|
-
}
|
|
547
|
+
};
|
|
245
548
|
|
|
246
549
|
// src/index.ts
|
|
247
550
|
function registerContentful(loader) {
|
|
@@ -257,6 +560,7 @@ function registerContentful(loader) {
|
|
|
257
560
|
export {
|
|
258
561
|
denormalizeData as _denormalizeData,
|
|
259
562
|
_ensure,
|
|
563
|
+
_queryContentful,
|
|
260
564
|
_uniq,
|
|
261
565
|
queryContentful,
|
|
262
566
|
registerContentful
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/
|
|
4
|
-
"sourcesContent": ["import registerFunction, {\n CustomFunctionMeta,\n} from \"@plasmicapp/host/registerFunction\";\nimport { queryContentful, queryContentfulMeta } from \"./query-contentful\";\n\nexport function registerContentful(loader?: { registerFunction: any }) {\n function _registerFunction<T extends (...args: any[]) => any>(\n fn: T,\n meta: CustomFunctionMeta<T>\n ) {\n if (loader) {\n loader.registerFunction(fn, meta);\n } else {\n registerFunction(fn, meta);\n }\n }\n\n _registerFunction(queryContentful, queryContentfulMeta);\n}\n\nexport { queryContentful };\n\n// Exports for @plasmicpkgs/plasmic-contentful\nexport { denormalizeData as _denormalizeData } from \"./query-contentful\";\nexport type { _Entry } from \"./types\";\nexport { _ensure, _uniq } from \"./utils\";\n", "import { CustomFunctionMeta } from \"@plasmicapp/host/registerFunction\";\nimport { _Entry } from \"./types\";\n\nexport const modulePath = \"@plasmicpkgs/contentful\";\n\nexport interface ContentfulQueryOptions {\n space: string;\n accessToken: string;\n environment?: string;\n contentType: string;\n filterField?: string;\n searchParameter?: string;\n filterValue?: string | number;\n order?: string;\n reverseOrder?: boolean;\n limit?: number;\n include?: number;\n}\n\nexport function denormalizeData(data: any | null): any {\n if (!data?.items || !data?.includes) {\n return data;\n }\n\n const entryMap: { [id: string]: any } = {};\n\n if (data.includes.Entry) {\n data.includes.Entry.forEach((entry: any) => {\n entryMap[entry.sys.id] = entry;\n });\n }\n\n // Track processed fields to avoid following circular references\n const processedFields = new Set<string>();\n\n const denormalizeField = (fieldValue: any): any => {\n if (Array.isArray(fieldValue)) {\n const updatedArray: any[] = fieldValue.map((arrayItem) => {\n return denormalizeField(arrayItem);\n });\n return updatedArray;\n } else if (fieldValue && typeof fieldValue === \"object\") {\n if (\n data.includes.Asset &&\n \"sys\" in fieldValue &&\n fieldValue.sys.linkType === \"Asset\"\n ) {\n const fieldId = fieldValue.sys.id;\n const asset = data.includes.Asset.find(\n (a: any) => a.sys.id === fieldId\n );\n if (asset) {\n fieldValue = {\n ...fieldValue,\n url: \"https:\" + asset.fields?.file?.url,\n };\n } else {\n console.log(`Asset URL not found for ID: ${fieldId}`);\n }\n } else if (\n data.includes.Entry &&\n \"sys\" in fieldValue &&\n fieldValue.sys.linkType === \"Entry\"\n ) {\n const fieldId = fieldValue.sys.id;\n if (entryMap[fieldId]) {\n if (processedFields.has(fieldId)) {\n console.warn(\n `Circular reference detected for Entry ID: ${fieldId}.`\n );\n } else {\n fieldValue = {\n ...fieldValue,\n fields: denormalizeItem(entryMap[fieldId]).fields,\n };\n }\n } else {\n console.log(`Entry not found for ID: ${fieldId}`);\n }\n }\n fieldValue = Object.entries(fieldValue).reduce((obj, [key, value]) => {\n if (key === \"sys\" || key === \"fields\") {\n obj[key] = value;\n } else {\n obj[key] = denormalizeField(value);\n }\n return obj;\n }, {} as Record<string, any>);\n }\n\n return fieldValue;\n };\n\n const denormalizeItem = (item: any) => {\n const itemId = item.sys?.id;\n if (itemId) {\n processedFields.add(itemId);\n }\n\n const updatedFields: { [fieldName: string]: unknown | unknown[] } = {};\n for (const fieldName in item.fields) {\n updatedFields[fieldName] = denormalizeField(item.fields[fieldName]);\n }\n\n if (itemId) {\n processedFields.delete(itemId);\n }\n\n return {\n ...item,\n fields: updatedFields ?? undefined,\n };\n };\n\n const itemsWithDenormalizedFields: _Entry[] = data.items.map((item: any) => {\n return denormalizeItem(item);\n });\n\n return {\n ...data,\n items: itemsWithDenormalizedFields,\n };\n}\n\nexport interface QueryContentfulOpts {\n space?: string;\n accessToken?: string;\n environment?: string;\n contentType?: string;\n filterField?: string;\n searchParameter?: string;\n filterValue?: string | number;\n order?: string;\n reverseOrder?: boolean;\n limit?: number;\n include?: number;\n}\n\nexport async function queryContentful({\n space,\n accessToken,\n environment = \"master\",\n contentType,\n filterField,\n searchParameter,\n filterValue,\n order,\n reverseOrder,\n limit,\n include,\n}: ContentfulQueryOptions): Promise<any> {\n if (!space || !accessToken) {\n throw new Error(\"Space and accessToken are required\");\n }\n\n if (!contentType) {\n return null;\n }\n\n const baseUrl = \"https://cdn.contentful.com\";\n const path = `/spaces/${space}/environments/${environment}/entries`;\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"access_token\", accessToken);\n searchParams.set(\"content_type\", contentType);\n\n if (limit) {\n searchParams.set(\"limit\", limit.toString());\n }\n\n if (order) {\n searchParams.set(\n \"order\",\n `${reverseOrder ? \"-\" : \"\"}${\n order.startsWith(\"sys.\") ? order : `fields.${order}`\n }`\n );\n }\n\n if (include !== undefined) {\n searchParams.set(\"include\", include.toString());\n }\n\n if (filterField && searchParameter && filterValue !== undefined) {\n searchParams.set(\n `fields.${filterField}${searchParameter}`,\n filterValue.toString()\n );\n }\n\n const resp = await fetch(`${baseUrl}${path}?${searchParams.toString()}`);\n const data = await resp.json();\n\n return denormalizeData(data);\n}\n\nexport const queryContentfulMeta: CustomFunctionMeta<typeof queryContentful> = {\n name: \"queryContentful\",\n displayName: \"Query Contentful\",\n description: \"Query Contentful entries with filtering and ordering\",\n importPath: modulePath,\n params: [\n {\n name: \"opts\",\n type: \"object\",\n display: \"flatten\",\n fields: {\n space: {\n type: \"string\",\n description: \"Contentful space ID\",\n },\n accessToken: {\n type: \"string\",\n description: \"Contentful access token\",\n },\n environment: {\n type: \"string\",\n description: \"Contentful environment (default: master)\",\n },\n contentType: {\n type: \"string\",\n description: \"Content type to query\",\n },\n filterField: {\n type: \"string\",\n description: \"Field to filter by (optional)\",\n },\n searchParameter: {\n type: \"string\",\n description:\n \"Search parameter for filtering (e.g., [match], [lt], [gte])\",\n },\n filterValue: {\n type: \"string\",\n description: \"Value to filter by\",\n },\n order: {\n type: \"string\",\n description: \"Field to order by (optional)\",\n },\n reverseOrder: {\n type: \"boolean\",\n description: \"Reverse the order\",\n },\n limit: {\n type: \"number\",\n description: \"Limit number of results\",\n },\n include: {\n type: \"number\",\n description: \"Depth of linked items to include (max 10)\",\n },\n },\n },\n ],\n};\n", "export const _uniq = <T>(xs: Array<T>): T[] => Array.from(new Set(xs));\n\nexport function _ensure<T>(x: T | null | undefined, msg?: string): T {\n if (x === null || x === undefined) {\n throw new Error(msg ?? `Value must not be undefined or null`);\n } else {\n return x;\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,sBAEA;;;
|
|
3
|
+
"sources": ["../src/index.ts", "../src/utils.ts", "../src/schema.ts", "../src/where.ts", "../src/query-contentful.ts"],
|
|
4
|
+
"sourcesContent": ["import registerFunction, {\n CustomFunctionMeta,\n} from \"@plasmicapp/host/registerFunction\";\nimport {\n _queryContentful,\n queryContentful,\n queryContentfulMeta,\n} from \"./query-contentful\";\n\nexport function registerContentful(loader?: { registerFunction: any }) {\n function _registerFunction<T extends (...args: any[]) => any>(\n fn: T,\n meta: CustomFunctionMeta<T>\n ) {\n if (loader) {\n loader.registerFunction(fn, meta);\n } else {\n registerFunction(fn, meta);\n }\n }\n\n _registerFunction(queryContentful, queryContentfulMeta);\n}\n\nexport {\n // Exports for @plasmicpkgs/plasmic-contentful\n _queryContentful,\n queryContentful,\n};\n\n// Exports for @plasmicpkgs/plasmic-contentful\nexport { denormalizeData as _denormalizeData } from \"./query-contentful\";\nexport type { _Entry } from \"./types\";\nexport { _ensure, _uniq } from \"./utils\";\n", "export const _uniq = <T>(xs: Array<T>): T[] => Array.from(new Set(xs));\nexport const BASE_URL = \"https://cdn.contentful.com\";\n\nexport function _ensure<T>(x: T | null | undefined, msg?: string): T {\n if (x === null || x === undefined) {\n throw new Error(msg ?? `Value must not be undefined or null`);\n } else {\n return x;\n }\n}\n\n/**\n * Capitalizes the first letter of a string\n */\nexport function capitalize(str: string): string {\n if (!str) {\n return str;\n }\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n", "import { BASE_URL } from \"./utils\";\n\nexport interface ContentTypeField {\n id: string;\n name: string;\n type: string;\n required: boolean;\n localized: boolean;\n disabled: boolean;\n}\n\nexport interface ContentTypeSchema {\n sys: { id: string };\n name: string;\n displayField?: string;\n fields: ContentTypeField[];\n}\n\n/**\n * Fetch all content types for a space/environment\n * Returns full schemas which can be used for both dropdown population and field discovery\n */\nexport async function fetchContentTypes(\n space: string,\n accessToken: string,\n environment: string = \"master\"\n): Promise<ContentTypeSchema[]> {\n const url = `${BASE_URL}/spaces/${space}/environments/${environment}/content_types`;\n const params = new URLSearchParams({ access_token: accessToken });\n\n const resp = await fetch(`${url}?${params.toString()}`);\n\n if (!resp.ok) {\n throw new Error(\n `Failed to fetch content types: ${resp.status} ${resp.statusText}`\n );\n }\n\n const data = await resp.json();\n return data.items;\n}\n\n/**\n * Helper to find a specific content type schema from a list\n */\nexport function findContentTypeSchema(\n contentType: string | undefined,\n contentTypes: ContentTypeSchema[] | undefined\n): ContentTypeSchema | undefined {\n if (!contentType || !contentTypes) {\n return undefined;\n }\n return contentTypes.find((ct) => ct.sys.id === contentType);\n}\n", "import type { Field } from \"@react-awesome-query-builder/core\";\nimport type { RulesLogic } from \"json-logic-js\";\nimport type { ContentTypeField, ContentTypeSchema } from \"./schema\";\nimport { capitalize } from \"./utils\";\n\n/**\n * Convert Contentful field type to query builder field configuration\n */\nfunction contentfulSchemaFieldToQueryBuilderField(\n field: ContentTypeField\n): Field | undefined {\n switch (field.type) {\n case \"Integer\":\n case \"Number\":\n return {\n label: capitalize(field.name),\n type: \"number\",\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n\n case \"Boolean\":\n return {\n label: capitalize(field.name),\n type: \"boolean\",\n };\n\n case \"Date\":\n return {\n label: capitalize(field.name),\n type: \"datetime\",\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n\n case \"Symbol\":\n case \"Text\":\n return {\n label: capitalize(field.name),\n type: \"text\",\n operators: [\"equal\", \"not_equal\", \"like\", \"is_null\", \"is_not_null\"],\n };\n\n default:\n return undefined;\n }\n}\n\n/**\n * Build query builder config from content type schema\n */\nexport function schemaToQueryBuilderConfig(schema: ContentTypeSchema) {\n const fields: Record<string, Field> = {};\n\n for (const field of schema.fields) {\n const qbField = contentfulSchemaFieldToQueryBuilderField(field);\n if (qbField) {\n fields[field.id] = qbField;\n }\n }\n\n return {\n fields,\n conjunctions: {\n AND: {\n label: \"All\",\n },\n // OR explicitly omitted - not supported by Contentful API\n },\n settings: {\n showNot: false,\n maxNesting: 1,\n canRegroup: false,\n canLeaveEmptyGroup: false,\n },\n };\n}\n\n/**\n * Maps JsonLogic to Contentful API filters format.\n *\n * See also:\n * - https://www.contentful.com/developers/docs/references/content-delivery-api/\n */\nexport function rulesLogicToContentfulFilters(\n logic: RulesLogic | undefined\n): Record<string, any> {\n if (logic === null || logic === undefined) {\n return {};\n } else if (typeof logic !== \"object\") {\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n } else if (\"and\" in logic) {\n // Handle AND - flatten to multiple parameters\n // Contentful supports implicit AND between all query parameters\n return logic[\"and\"].reduce((acc: Record<string, any>, condition: any) => {\n return { ...acc, ...rulesLogicToContentfulFilters(condition) };\n }, {});\n } else if (\"or\" in logic) {\n // OR is not supported by Contentful API\n throw new Error(\n \"Contentful API does not support OR operations. Please restructure your query using only AND conditions.\"\n );\n } else if (\"!\" in logic) {\n // NOT is not supported by Contentful API\n throw new Error(\n \"Contentful API does not support NOT operations. Please use field-level negation operators like 'not_equal' ([ne]) instead.\"\n );\n } else if (\"==\" in logic) {\n const [{ var: field }, operand] = logic[\"==\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [`fields.${field}[exists]`]: \"false\" };\n }\n return {\n [`fields.${field}`]: operand,\n };\n } else if (\"!=\" in logic) {\n const [{ var: field }, operand] = logic[\"!=\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [`fields.${field}[exists]`]: \"true\" };\n }\n return {\n [`fields.${field}[ne]`]: operand,\n };\n } else if (\"in\" in logic) {\n // Map in operator to Contentful filters format:\n // JsonLogic: { \"in\": [\"searchText\", { \"var\": \"fieldName\" }] }\n // Contentful filters: { \"fields.fieldName[match]\": \"searchText\" }\n const [operand, { var: field }] = logic[\"in\"] as [string, { var: string }];\n return {\n [`fields.${field}[match]`]: operand,\n };\n } else {\n // Map JsonLogic comparison operators to Contentful filters format:\n // JsonLogic: { \"<=\": [{ \"var\": \"age\" }, 18] }\n // Contentful filters: { \"fields.age[lte]\": 18 }\n const [key, value] = Object.entries(logic)[0];\n const apiOp: string | undefined = operatorMapping[key];\n if (apiOp) {\n const [{ var: field }, operand] = value as [{ var: string }, unknown];\n return { [`fields.${field}[${apiOp}]`]: operand };\n }\n\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n }\n}\n\n/** Maps JsonLogic operator to Contentful filter operator. */\nconst operatorMapping: Record<string, string> = {\n \"<\": \"lt\",\n \"<=\": \"lte\",\n \">\": \"gt\",\n \">=\": \"gte\",\n};\n", "import { CustomFunctionMeta } from \"@plasmicapp/host/registerFunction\";\nimport type { RulesLogic } from \"json-logic-js\";\nimport {\n ContentTypeField,\n ContentTypeSchema,\n fetchContentTypes,\n findContentTypeSchema,\n} from \"./schema\";\nimport { _Entry } from \"./types\";\nimport { BASE_URL, capitalize } from \"./utils\";\nimport {\n rulesLogicToContentfulFilters,\n schemaToQueryBuilderConfig,\n} from \"./where\";\n\nexport const modulePath = \"@plasmicpkgs/contentful\";\n\nexport function denormalizeData(data: any | null): any {\n if (!data?.items || !data?.includes) {\n return data;\n }\n\n const entryMap: { [id: string]: any } = {};\n\n if (data.includes.Entry) {\n data.includes.Entry.forEach((entry: any) => {\n entryMap[entry.sys.id] = entry;\n });\n }\n\n // Track processed fields to avoid following circular references\n const processedFields = new Set<string>();\n\n const denormalizeField = (fieldValue: any): any => {\n if (Array.isArray(fieldValue)) {\n const updatedArray: any[] = fieldValue.map((arrayItem) => {\n return denormalizeField(arrayItem);\n });\n return updatedArray;\n } else if (fieldValue && typeof fieldValue === \"object\") {\n if (\n data.includes.Asset &&\n \"sys\" in fieldValue &&\n fieldValue.sys.linkType === \"Asset\"\n ) {\n const fieldId = fieldValue.sys.id;\n const asset = data.includes.Asset.find(\n (a: any) => a.sys.id === fieldId\n );\n if (asset) {\n fieldValue = {\n ...fieldValue,\n url: \"https:\" + asset.fields?.file?.url,\n };\n } else {\n console.log(`Asset URL not found for ID: ${fieldId}`);\n }\n } else if (\n data.includes.Entry &&\n \"sys\" in fieldValue &&\n fieldValue.sys.linkType === \"Entry\"\n ) {\n const fieldId = fieldValue.sys.id;\n if (entryMap[fieldId]) {\n if (processedFields.has(fieldId)) {\n console.warn(\n `Circular reference detected for Entry ID: ${fieldId}.`\n );\n } else {\n fieldValue = {\n ...fieldValue,\n fields: denormalizeItem(entryMap[fieldId]).fields,\n };\n }\n } else {\n console.log(`Entry not found for ID: ${fieldId}`);\n }\n }\n fieldValue = Object.entries(fieldValue).reduce((obj, [key, value]) => {\n if (key === \"sys\" || key === \"fields\") {\n obj[key] = value;\n } else {\n obj[key] = denormalizeField(value);\n }\n return obj;\n }, {} as Record<string, any>);\n }\n\n return fieldValue;\n };\n\n const denormalizeItem = (item: any) => {\n const itemId = item.sys?.id;\n if (itemId) {\n processedFields.add(itemId);\n }\n\n const updatedFields: { [fieldName: string]: unknown | unknown[] } = {};\n for (const fieldName in item.fields) {\n updatedFields[fieldName] = denormalizeField(item.fields[fieldName]);\n }\n\n if (itemId) {\n processedFields.delete(itemId);\n }\n\n return {\n ...item,\n fields: updatedFields ?? undefined,\n };\n };\n\n const itemsWithDenormalizedFields: _Entry[] = data.items.map((item: any) => {\n return denormalizeItem(item);\n });\n\n return {\n ...data,\n items: itemsWithDenormalizedFields,\n };\n}\n\n/**\n * @deprecated These filter props are deprecated. Use `filterLogic` with the query builder instead.\n * Only used by the deprecated ContentfulCollection component for backward compatibility.\n */\nexport interface QueryContentfulOldFilterProps {\n filterField?: string;\n searchParameter?: string;\n filterValue?: string | number;\n}\n\nexport interface QueryContentfulOpts {\n space?: string;\n accessToken?: string;\n environment?: string;\n contentType?: string;\n /**\n * Filter logic using JSON Logic format to filter Contentful entries.\n * See {@link https://www.npmjs.com/package/@types/json-logic-js?activeTab=readme}\n */\n filterLogic?: RulesLogic;\n order?: string;\n reverseOrder?: boolean;\n limit?: number;\n skip?: number;\n include?: number;\n // string type supports comma-separated string as documented in the Contentful API, inserted via the dynamic value editor\n // array type supports multiple fields to be selected via the choice prop editor for convenience\n select?: string | string[];\n locale?: string;\n}\n\n/**\n * Query Contentful with simplified filter props.\n *\n * @deprecated Use {@link queryContentful} with `filterLogic` parameter instead.\n *\n * @example\n * ```ts\n * // Old way (deprecated)\n * _queryContentful({\n * space: 'space-id',\n * accessToken: 'token',\n * contentType: 'article',\n * filterField: 'title',\n * searchParameter: '[match]',\n * filterValue: 'Hello'\n * })\n *\n * // New way\n * queryContentful({\n * space: 'space-id',\n * accessToken: 'token',\n * contentType: 'article',\n * filterLogic: { \"==\": [{ var: \"title\" }, \"Hello\"] }\n * })\n * ```\n */\nexport async function _queryContentful({\n space,\n accessToken,\n environment = \"master\",\n contentType,\n filterLogic,\n filterField,\n searchParameter,\n filterValue,\n order,\n reverseOrder,\n limit,\n skip,\n include,\n select,\n locale,\n}: QueryContentfulOpts & QueryContentfulOldFilterProps): Promise<any> {\n if (!space || !accessToken) {\n throw new Error(\"Space and accessToken are required\");\n }\n\n if (!contentType) {\n return null;\n }\n\n const path = `/spaces/${space}/environments/${environment}/entries`;\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"access_token\", accessToken);\n searchParams.set(\"content_type\", contentType);\n\n // Convert filterLogic to Contentful filters\n let filters: Record<string, any> = {};\n if (filterLogic) {\n filters = rulesLogicToContentfulFilters(filterLogic);\n } else if (filterField && searchParameter && filterValue !== undefined) {\n // BACKWARD COMPATIBILITY: Legacy filter props\n filters[`fields.${filterField}${searchParameter}`] = filterValue.toString();\n }\n\n // Apply all filter parameters\n for (const [key, value] of Object.entries(filters)) {\n searchParams.set(key, value.toString());\n }\n\n if (limit) {\n searchParams.set(\"limit\", limit.toString());\n }\n\n if (skip !== undefined) {\n searchParams.set(\"skip\", skip.toString());\n }\n\n if (order) {\n searchParams.set(\n \"order\",\n `${reverseOrder ? \"-\" : \"\"}${\n order.startsWith(\"sys.\") ? order : `fields.${order}`\n }`\n );\n }\n\n if (include !== undefined) {\n searchParams.set(\"include\", include.toString());\n }\n\n if (select) {\n if (Array.isArray(select)) {\n if (select.length > 0) {\n searchParams.set(\"select\", select.join(\",\"));\n }\n } else {\n // The user may pass a comma-separated string as documented in the Contentful API\n searchParams.set(\"select\", select);\n }\n }\n\n if (locale) {\n searchParams.set(\"locale\", locale);\n }\n\n const resp = await fetch(`${BASE_URL}${path}?${searchParams.toString()}`);\n const data = await resp.json();\n\n return denormalizeData(data);\n}\n\n/**\n * Query a Contentful content type with optional filtering and ordering.\n *\n * @param opts - Query options including space, accessToken, contentType, filter logic, and pagination\n * @returns Promise resolving to the Contentful query response with denormalized data\n *\n * @example\n * ```ts\n * // Fetch all entries\n * const result = await queryContentful({\n * space: 'your-space-id',\n * accessToken: 'your-access-token',\n * contentType: 'blogPost'\n * });\n *\n * // Fetch with filter\n * const filtered = await queryContentful({\n * space: 'your-space-id',\n * accessToken: 'your-access-token',\n * contentType: 'blogPost',\n * filterLogic: { \"==\": [{ var: \"status\" }, \"published\"] }\n * });\n * ```\n */\nexport async function queryContentful({\n space,\n accessToken,\n environment = \"master\",\n contentType,\n filterLogic,\n}: QueryContentfulOpts): Promise<any> {\n return _queryContentful({\n space,\n accessToken,\n environment,\n contentType,\n filterLogic,\n });\n}\n\nexport const queryContentfulMeta: CustomFunctionMeta<typeof queryContentful> = {\n name: \"queryContentful\",\n displayName: \"Query Contentful\",\n description: \"Query Contentful entries with filtering and ordering\",\n importPath: modulePath,\n params: [\n {\n name: \"opts\",\n type: \"object\",\n display: \"flatten\",\n fields: {\n space: {\n type: \"string\",\n description: \"Contentful space ID\",\n },\n accessToken: {\n type: \"string\",\n description: \"Contentful access token\",\n },\n environment: {\n type: \"string\",\n description: \"Contentful environment (default: master)\",\n },\n contentType: {\n type: \"choice\",\n displayName: \"Content Type\",\n description: \"Content type to query\",\n options: (_: any, ctx: any) => {\n return (\n ctx?.contentTypes?.map((ct: ContentTypeSchema) => ({\n label: ct.name,\n value: ct.sys.id,\n })) ?? []\n );\n },\n },\n filterLogic: {\n type: \"queryBuilder\",\n displayName: \"Filter\",\n description: \"Filter fetched entries. Defaults to fetch all entries.\",\n config: ([opts], ctx: any) => {\n const schema = findContentTypeSchema(\n opts?.contentType,\n ctx?.contentTypes\n );\n\n if (schema) {\n return schemaToQueryBuilderConfig(schema);\n }\n\n return {\n fields: {},\n };\n },\n },\n order: {\n type: \"choice\",\n displayName: \"Order by\",\n description: \"Field to order by (optional)\",\n defaultValueHint: \"sys.updatedAt\",\n options: ([opts], ctx: any) => {\n const systemFields = [\n { label: \"Created at\", value: \"sys.createdAt\" },\n { label: \"Updated at\", value: \"sys.updatedAt\" },\n { label: \"ID\", value: \"sys.id\" },\n ];\n\n const schema = findContentTypeSchema(\n opts?.contentType,\n ctx?.contentTypes\n );\n\n if (schema) {\n const contentFields = schema.fields\n .filter((field: ContentTypeField) => !field.disabled)\n .map((field: ContentTypeField) => ({\n label: capitalize(field.name),\n value: `fields.${field.id}`,\n }));\n\n return [...systemFields, ...contentFields];\n }\n\n return systemFields;\n },\n },\n reverseOrder: {\n type: \"boolean\",\n description: \"Reverse the order\",\n hidden: ([opts]: [QueryContentfulOpts | undefined]) => !opts?.order,\n defaultValueHint: false,\n },\n limit: {\n type: \"number\",\n description: \"Limit number of results\",\n defaultValueHint: 100,\n },\n skip: {\n type: \"number\",\n description: \"Skip number of results (for pagination)\",\n defaultValueHint: 0,\n },\n include: {\n type: \"number\",\n description: \"Depth of linked items to include (max 10)\",\n max: 10,\n min: 0,\n defaultValueHint: 1,\n },\n select: {\n type: \"choice\",\n multiSelect: true,\n description: \"Fields to select. Defaults to all fields.\",\n options: ([opts], ctx: any) => {\n const schema = findContentTypeSchema(\n opts?.contentType,\n ctx?.contentTypes\n );\n\n const fieldOptions = schema\n ? schema.fields\n .filter((field: ContentTypeField) => !field.disabled)\n .map((field: ContentTypeField) => ({\n label: capitalize(field.name), // Use capitalized friendly name from schema\n value: `fields.${field.id}`,\n }))\n : [];\n\n return [\n ...fieldOptions,\n { label: \"Fields only\", value: \"fields\" },\n { label: \"Metadata only\", value: \"sys\" },\n ];\n },\n },\n locale: {\n type: \"string\",\n description: \"Locale code (e.g., en-US)\",\n },\n },\n },\n ],\n fnContext: (contentfulOpts?: QueryContentfulOpts) => {\n if (!contentfulOpts?.space || !contentfulOpts?.accessToken) {\n return {\n dataKey: \"\",\n fetcher: async () => ({\n contentTypes: [],\n }),\n };\n }\n\n // Cache at workspace level (space + environment) to fetch all schemas once.\n // Excluding contentType from cache key means switching content types won't\n // trigger new API calls - we just find the schema in the cached array.\n const workspaceCacheKey = JSON.stringify({\n space: contentfulOpts.space,\n accessToken: contentfulOpts.accessToken,\n environment: contentfulOpts.environment,\n });\n\n return {\n dataKey: workspaceCacheKey,\n fetcher: async () => {\n try {\n // Fetch all content types once (includes full schemas with fields)\n const contentTypes = await fetchContentTypes(\n contentfulOpts.space!,\n contentfulOpts.accessToken!,\n contentfulOpts.environment\n );\n\n return {\n contentTypes,\n };\n } catch (error) {\n console.error(\"Failed to fetch content types:\", error);\n return {\n contentTypes: [],\n };\n }\n },\n };\n },\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -69,6 +69,7 @@ var src_exports = {};
|
|
|
69
69
|
__export(src_exports, {
|
|
70
70
|
_denormalizeData: () => denormalizeData,
|
|
71
71
|
_ensure: () => _ensure,
|
|
72
|
+
_queryContentful: () => _queryContentful,
|
|
72
73
|
_uniq: () => _uniq,
|
|
73
74
|
queryContentful: () => queryContentful,
|
|
74
75
|
registerContentful: () => registerContentful
|
|
@@ -76,6 +77,174 @@ __export(src_exports, {
|
|
|
76
77
|
module.exports = __toCommonJS(src_exports);
|
|
77
78
|
var import_registerFunction = __toESM(require("@plasmicapp/host/registerFunction"));
|
|
78
79
|
|
|
80
|
+
// src/utils.ts
|
|
81
|
+
var _uniq = (xs) => Array.from(new Set(xs));
|
|
82
|
+
var BASE_URL = "https://cdn.contentful.com";
|
|
83
|
+
function _ensure(x, msg) {
|
|
84
|
+
if (x === null || x === void 0) {
|
|
85
|
+
throw new Error(msg != null ? msg : `Value must not be undefined or null`);
|
|
86
|
+
} else {
|
|
87
|
+
return x;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function capitalize(str) {
|
|
91
|
+
if (!str) {
|
|
92
|
+
return str;
|
|
93
|
+
}
|
|
94
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/schema.ts
|
|
98
|
+
function fetchContentTypes(space, accessToken, environment = "master") {
|
|
99
|
+
return __async(this, null, function* () {
|
|
100
|
+
const url = `${BASE_URL}/spaces/${space}/environments/${environment}/content_types`;
|
|
101
|
+
const params = new URLSearchParams({ access_token: accessToken });
|
|
102
|
+
const resp = yield fetch(`${url}?${params.toString()}`);
|
|
103
|
+
if (!resp.ok) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Failed to fetch content types: ${resp.status} ${resp.statusText}`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
const data = yield resp.json();
|
|
109
|
+
return data.items;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function findContentTypeSchema(contentType, contentTypes) {
|
|
113
|
+
if (!contentType || !contentTypes) {
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
return contentTypes.find((ct) => ct.sys.id === contentType);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/where.ts
|
|
120
|
+
function contentfulSchemaFieldToQueryBuilderField(field) {
|
|
121
|
+
switch (field.type) {
|
|
122
|
+
case "Integer":
|
|
123
|
+
case "Number":
|
|
124
|
+
return {
|
|
125
|
+
label: capitalize(field.name),
|
|
126
|
+
type: "number",
|
|
127
|
+
operators: [
|
|
128
|
+
"equal",
|
|
129
|
+
"not_equal",
|
|
130
|
+
"less",
|
|
131
|
+
"less_or_equal",
|
|
132
|
+
"greater",
|
|
133
|
+
"greater_or_equal",
|
|
134
|
+
"is_null",
|
|
135
|
+
"is_not_null"
|
|
136
|
+
]
|
|
137
|
+
};
|
|
138
|
+
case "Boolean":
|
|
139
|
+
return {
|
|
140
|
+
label: capitalize(field.name),
|
|
141
|
+
type: "boolean"
|
|
142
|
+
};
|
|
143
|
+
case "Date":
|
|
144
|
+
return {
|
|
145
|
+
label: capitalize(field.name),
|
|
146
|
+
type: "datetime",
|
|
147
|
+
operators: [
|
|
148
|
+
"equal",
|
|
149
|
+
"not_equal",
|
|
150
|
+
"less",
|
|
151
|
+
"less_or_equal",
|
|
152
|
+
"greater",
|
|
153
|
+
"greater_or_equal",
|
|
154
|
+
"is_null",
|
|
155
|
+
"is_not_null"
|
|
156
|
+
]
|
|
157
|
+
};
|
|
158
|
+
case "Symbol":
|
|
159
|
+
case "Text":
|
|
160
|
+
return {
|
|
161
|
+
label: capitalize(field.name),
|
|
162
|
+
type: "text",
|
|
163
|
+
operators: ["equal", "not_equal", "like", "is_null", "is_not_null"]
|
|
164
|
+
};
|
|
165
|
+
default:
|
|
166
|
+
return void 0;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function schemaToQueryBuilderConfig(schema) {
|
|
170
|
+
const fields = {};
|
|
171
|
+
for (const field of schema.fields) {
|
|
172
|
+
const qbField = contentfulSchemaFieldToQueryBuilderField(field);
|
|
173
|
+
if (qbField) {
|
|
174
|
+
fields[field.id] = qbField;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
fields,
|
|
179
|
+
conjunctions: {
|
|
180
|
+
AND: {
|
|
181
|
+
label: "All"
|
|
182
|
+
}
|
|
183
|
+
// OR explicitly omitted - not supported by Contentful API
|
|
184
|
+
},
|
|
185
|
+
settings: {
|
|
186
|
+
showNot: false,
|
|
187
|
+
maxNesting: 1,
|
|
188
|
+
canRegroup: false,
|
|
189
|
+
canLeaveEmptyGroup: false
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function rulesLogicToContentfulFilters(logic) {
|
|
194
|
+
if (logic === null || logic === void 0) {
|
|
195
|
+
return {};
|
|
196
|
+
} else if (typeof logic !== "object") {
|
|
197
|
+
throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);
|
|
198
|
+
} else if ("and" in logic) {
|
|
199
|
+
return logic["and"].reduce((acc, condition) => {
|
|
200
|
+
return __spreadValues(__spreadValues({}, acc), rulesLogicToContentfulFilters(condition));
|
|
201
|
+
}, {});
|
|
202
|
+
} else if ("or" in logic) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
"Contentful API does not support OR operations. Please restructure your query using only AND conditions."
|
|
205
|
+
);
|
|
206
|
+
} else if ("!" in logic) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
"Contentful API does not support NOT operations. Please use field-level negation operators like 'not_equal' ([ne]) instead."
|
|
209
|
+
);
|
|
210
|
+
} else if ("==" in logic) {
|
|
211
|
+
const [{ var: field }, operand] = logic["=="];
|
|
212
|
+
if (operand === null) {
|
|
213
|
+
return { [`fields.${field}[exists]`]: "false" };
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
[`fields.${field}`]: operand
|
|
217
|
+
};
|
|
218
|
+
} else if ("!=" in logic) {
|
|
219
|
+
const [{ var: field }, operand] = logic["!="];
|
|
220
|
+
if (operand === null) {
|
|
221
|
+
return { [`fields.${field}[exists]`]: "true" };
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
[`fields.${field}[ne]`]: operand
|
|
225
|
+
};
|
|
226
|
+
} else if ("in" in logic) {
|
|
227
|
+
const [operand, { var: field }] = logic["in"];
|
|
228
|
+
return {
|
|
229
|
+
[`fields.${field}[match]`]: operand
|
|
230
|
+
};
|
|
231
|
+
} else {
|
|
232
|
+
const [key, value] = Object.entries(logic)[0];
|
|
233
|
+
const apiOp = operatorMapping[key];
|
|
234
|
+
if (apiOp) {
|
|
235
|
+
const [{ var: field }, operand] = value;
|
|
236
|
+
return { [`fields.${field}[${apiOp}]`]: operand };
|
|
237
|
+
}
|
|
238
|
+
throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
var operatorMapping = {
|
|
242
|
+
"<": "lt",
|
|
243
|
+
"<=": "lte",
|
|
244
|
+
">": "gt",
|
|
245
|
+
">=": "gte"
|
|
246
|
+
};
|
|
247
|
+
|
|
79
248
|
// src/query-contentful.ts
|
|
80
249
|
var modulePath = "@plasmicpkgs/contentful";
|
|
81
250
|
function denormalizeData(data) {
|
|
@@ -160,19 +329,23 @@ function denormalizeData(data) {
|
|
|
160
329
|
items: itemsWithDenormalizedFields
|
|
161
330
|
});
|
|
162
331
|
}
|
|
163
|
-
function
|
|
332
|
+
function _queryContentful(_0) {
|
|
164
333
|
return __async(this, arguments, function* ({
|
|
165
334
|
space,
|
|
166
335
|
accessToken,
|
|
167
336
|
environment = "master",
|
|
168
337
|
contentType,
|
|
338
|
+
filterLogic,
|
|
169
339
|
filterField,
|
|
170
340
|
searchParameter,
|
|
171
341
|
filterValue,
|
|
172
342
|
order,
|
|
173
343
|
reverseOrder,
|
|
174
344
|
limit,
|
|
175
|
-
|
|
345
|
+
skip,
|
|
346
|
+
include,
|
|
347
|
+
select,
|
|
348
|
+
locale
|
|
176
349
|
}) {
|
|
177
350
|
if (!space || !accessToken) {
|
|
178
351
|
throw new Error("Space and accessToken are required");
|
|
@@ -180,14 +353,25 @@ function queryContentful(_0) {
|
|
|
180
353
|
if (!contentType) {
|
|
181
354
|
return null;
|
|
182
355
|
}
|
|
183
|
-
const baseUrl = "https://cdn.contentful.com";
|
|
184
356
|
const path = `/spaces/${space}/environments/${environment}/entries`;
|
|
185
357
|
const searchParams = new URLSearchParams();
|
|
186
358
|
searchParams.set("access_token", accessToken);
|
|
187
359
|
searchParams.set("content_type", contentType);
|
|
360
|
+
let filters = {};
|
|
361
|
+
if (filterLogic) {
|
|
362
|
+
filters = rulesLogicToContentfulFilters(filterLogic);
|
|
363
|
+
} else if (filterField && searchParameter && filterValue !== void 0) {
|
|
364
|
+
filters[`fields.${filterField}${searchParameter}`] = filterValue.toString();
|
|
365
|
+
}
|
|
366
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
367
|
+
searchParams.set(key, value.toString());
|
|
368
|
+
}
|
|
188
369
|
if (limit) {
|
|
189
370
|
searchParams.set("limit", limit.toString());
|
|
190
371
|
}
|
|
372
|
+
if (skip !== void 0) {
|
|
373
|
+
searchParams.set("skip", skip.toString());
|
|
374
|
+
}
|
|
191
375
|
if (order) {
|
|
192
376
|
searchParams.set(
|
|
193
377
|
"order",
|
|
@@ -197,17 +381,40 @@ function queryContentful(_0) {
|
|
|
197
381
|
if (include !== void 0) {
|
|
198
382
|
searchParams.set("include", include.toString());
|
|
199
383
|
}
|
|
200
|
-
if (
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
384
|
+
if (select) {
|
|
385
|
+
if (Array.isArray(select)) {
|
|
386
|
+
if (select.length > 0) {
|
|
387
|
+
searchParams.set("select", select.join(","));
|
|
388
|
+
}
|
|
389
|
+
} else {
|
|
390
|
+
searchParams.set("select", select);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (locale) {
|
|
394
|
+
searchParams.set("locale", locale);
|
|
205
395
|
}
|
|
206
|
-
const resp = yield fetch(`${
|
|
396
|
+
const resp = yield fetch(`${BASE_URL}${path}?${searchParams.toString()}`);
|
|
207
397
|
const data = yield resp.json();
|
|
208
398
|
return denormalizeData(data);
|
|
209
399
|
});
|
|
210
400
|
}
|
|
401
|
+
function queryContentful(_0) {
|
|
402
|
+
return __async(this, arguments, function* ({
|
|
403
|
+
space,
|
|
404
|
+
accessToken,
|
|
405
|
+
environment = "master",
|
|
406
|
+
contentType,
|
|
407
|
+
filterLogic
|
|
408
|
+
}) {
|
|
409
|
+
return _queryContentful({
|
|
410
|
+
space,
|
|
411
|
+
accessToken,
|
|
412
|
+
environment,
|
|
413
|
+
contentType,
|
|
414
|
+
filterLogic
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
}
|
|
211
418
|
var queryContentfulMeta = {
|
|
212
419
|
name: "queryContentful",
|
|
213
420
|
displayName: "Query Contentful",
|
|
@@ -232,51 +439,148 @@ var queryContentfulMeta = {
|
|
|
232
439
|
description: "Contentful environment (default: master)"
|
|
233
440
|
},
|
|
234
441
|
contentType: {
|
|
235
|
-
type: "
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
442
|
+
type: "choice",
|
|
443
|
+
displayName: "Content Type",
|
|
444
|
+
description: "Content type to query",
|
|
445
|
+
options: (_, ctx) => {
|
|
446
|
+
var _a, _b;
|
|
447
|
+
return (_b = (_a = ctx == null ? void 0 : ctx.contentTypes) == null ? void 0 : _a.map((ct) => ({
|
|
448
|
+
label: ct.name,
|
|
449
|
+
value: ct.sys.id
|
|
450
|
+
}))) != null ? _b : [];
|
|
451
|
+
}
|
|
245
452
|
},
|
|
246
|
-
|
|
247
|
-
type: "
|
|
248
|
-
|
|
453
|
+
filterLogic: {
|
|
454
|
+
type: "queryBuilder",
|
|
455
|
+
displayName: "Filter",
|
|
456
|
+
description: "Filter fetched entries. Defaults to fetch all entries.",
|
|
457
|
+
config: ([opts], ctx) => {
|
|
458
|
+
const schema = findContentTypeSchema(
|
|
459
|
+
opts == null ? void 0 : opts.contentType,
|
|
460
|
+
ctx == null ? void 0 : ctx.contentTypes
|
|
461
|
+
);
|
|
462
|
+
if (schema) {
|
|
463
|
+
return schemaToQueryBuilderConfig(schema);
|
|
464
|
+
}
|
|
465
|
+
return {
|
|
466
|
+
fields: {}
|
|
467
|
+
};
|
|
468
|
+
}
|
|
249
469
|
},
|
|
250
470
|
order: {
|
|
251
|
-
type: "
|
|
252
|
-
|
|
471
|
+
type: "choice",
|
|
472
|
+
displayName: "Order by",
|
|
473
|
+
description: "Field to order by (optional)",
|
|
474
|
+
defaultValueHint: "sys.updatedAt",
|
|
475
|
+
options: ([opts], ctx) => {
|
|
476
|
+
const systemFields = [
|
|
477
|
+
{ label: "Created at", value: "sys.createdAt" },
|
|
478
|
+
{ label: "Updated at", value: "sys.updatedAt" },
|
|
479
|
+
{ label: "ID", value: "sys.id" }
|
|
480
|
+
];
|
|
481
|
+
const schema = findContentTypeSchema(
|
|
482
|
+
opts == null ? void 0 : opts.contentType,
|
|
483
|
+
ctx == null ? void 0 : ctx.contentTypes
|
|
484
|
+
);
|
|
485
|
+
if (schema) {
|
|
486
|
+
const contentFields = schema.fields.filter((field) => !field.disabled).map((field) => ({
|
|
487
|
+
label: capitalize(field.name),
|
|
488
|
+
value: `fields.${field.id}`
|
|
489
|
+
}));
|
|
490
|
+
return [...systemFields, ...contentFields];
|
|
491
|
+
}
|
|
492
|
+
return systemFields;
|
|
493
|
+
}
|
|
253
494
|
},
|
|
254
495
|
reverseOrder: {
|
|
255
496
|
type: "boolean",
|
|
256
|
-
description: "Reverse the order"
|
|
497
|
+
description: "Reverse the order",
|
|
498
|
+
hidden: ([opts]) => !(opts == null ? void 0 : opts.order),
|
|
499
|
+
defaultValueHint: false
|
|
257
500
|
},
|
|
258
501
|
limit: {
|
|
259
502
|
type: "number",
|
|
260
|
-
description: "Limit number of results"
|
|
503
|
+
description: "Limit number of results",
|
|
504
|
+
defaultValueHint: 100
|
|
505
|
+
},
|
|
506
|
+
skip: {
|
|
507
|
+
type: "number",
|
|
508
|
+
description: "Skip number of results (for pagination)",
|
|
509
|
+
defaultValueHint: 0
|
|
261
510
|
},
|
|
262
511
|
include: {
|
|
263
512
|
type: "number",
|
|
264
|
-
description: "Depth of linked items to include (max 10)"
|
|
513
|
+
description: "Depth of linked items to include (max 10)",
|
|
514
|
+
max: 10,
|
|
515
|
+
min: 0,
|
|
516
|
+
defaultValueHint: 1
|
|
517
|
+
},
|
|
518
|
+
select: {
|
|
519
|
+
type: "choice",
|
|
520
|
+
multiSelect: true,
|
|
521
|
+
description: "Fields to select. Defaults to all fields.",
|
|
522
|
+
options: ([opts], ctx) => {
|
|
523
|
+
const schema = findContentTypeSchema(
|
|
524
|
+
opts == null ? void 0 : opts.contentType,
|
|
525
|
+
ctx == null ? void 0 : ctx.contentTypes
|
|
526
|
+
);
|
|
527
|
+
const fieldOptions = schema ? schema.fields.filter((field) => !field.disabled).map((field) => ({
|
|
528
|
+
label: capitalize(field.name),
|
|
529
|
+
// Use capitalized friendly name from schema
|
|
530
|
+
value: `fields.${field.id}`
|
|
531
|
+
})) : [];
|
|
532
|
+
return [
|
|
533
|
+
...fieldOptions,
|
|
534
|
+
{ label: "Fields only", value: "fields" },
|
|
535
|
+
{ label: "Metadata only", value: "sys" }
|
|
536
|
+
];
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
locale: {
|
|
540
|
+
type: "string",
|
|
541
|
+
description: "Locale code (e.g., en-US)"
|
|
265
542
|
}
|
|
266
543
|
}
|
|
267
544
|
}
|
|
268
|
-
]
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
545
|
+
],
|
|
546
|
+
fnContext: (contentfulOpts) => {
|
|
547
|
+
if (!(contentfulOpts == null ? void 0 : contentfulOpts.space) || !(contentfulOpts == null ? void 0 : contentfulOpts.accessToken)) {
|
|
548
|
+
return {
|
|
549
|
+
dataKey: "",
|
|
550
|
+
fetcher: () => __async(void 0, null, function* () {
|
|
551
|
+
return {
|
|
552
|
+
contentTypes: []
|
|
553
|
+
};
|
|
554
|
+
})
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
const workspaceCacheKey = JSON.stringify({
|
|
558
|
+
space: contentfulOpts.space,
|
|
559
|
+
accessToken: contentfulOpts.accessToken,
|
|
560
|
+
environment: contentfulOpts.environment
|
|
561
|
+
});
|
|
562
|
+
return {
|
|
563
|
+
dataKey: workspaceCacheKey,
|
|
564
|
+
fetcher: () => __async(void 0, null, function* () {
|
|
565
|
+
try {
|
|
566
|
+
const contentTypes = yield fetchContentTypes(
|
|
567
|
+
contentfulOpts.space,
|
|
568
|
+
contentfulOpts.accessToken,
|
|
569
|
+
contentfulOpts.environment
|
|
570
|
+
);
|
|
571
|
+
return {
|
|
572
|
+
contentTypes
|
|
573
|
+
};
|
|
574
|
+
} catch (error) {
|
|
575
|
+
console.error("Failed to fetch content types:", error);
|
|
576
|
+
return {
|
|
577
|
+
contentTypes: []
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
})
|
|
581
|
+
};
|
|
278
582
|
}
|
|
279
|
-
}
|
|
583
|
+
};
|
|
280
584
|
|
|
281
585
|
// src/index.ts
|
|
282
586
|
function registerContentful(loader) {
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/
|
|
4
|
-
"sourcesContent": ["import registerFunction, {\n CustomFunctionMeta,\n} from \"@plasmicapp/host/registerFunction\";\nimport { queryContentful, queryContentfulMeta } from \"./query-contentful\";\n\nexport function registerContentful(loader?: { registerFunction: any }) {\n function _registerFunction<T extends (...args: any[]) => any>(\n fn: T,\n meta: CustomFunctionMeta<T>\n ) {\n if (loader) {\n loader.registerFunction(fn, meta);\n } else {\n registerFunction(fn, meta);\n }\n }\n\n _registerFunction(queryContentful, queryContentfulMeta);\n}\n\nexport { queryContentful };\n\n// Exports for @plasmicpkgs/plasmic-contentful\nexport { denormalizeData as _denormalizeData } from \"./query-contentful\";\nexport type { _Entry } from \"./types\";\nexport { _ensure, _uniq } from \"./utils\";\n", "import { CustomFunctionMeta } from \"@plasmicapp/host/registerFunction\";\nimport { _Entry } from \"./types\";\n\nexport const modulePath = \"@plasmicpkgs/contentful\";\n\nexport interface ContentfulQueryOptions {\n space: string;\n accessToken: string;\n environment?: string;\n contentType: string;\n filterField?: string;\n searchParameter?: string;\n filterValue?: string | number;\n order?: string;\n reverseOrder?: boolean;\n limit?: number;\n include?: number;\n}\n\nexport function denormalizeData(data: any | null): any {\n if (!data?.items || !data?.includes) {\n return data;\n }\n\n const entryMap: { [id: string]: any } = {};\n\n if (data.includes.Entry) {\n data.includes.Entry.forEach((entry: any) => {\n entryMap[entry.sys.id] = entry;\n });\n }\n\n // Track processed fields to avoid following circular references\n const processedFields = new Set<string>();\n\n const denormalizeField = (fieldValue: any): any => {\n if (Array.isArray(fieldValue)) {\n const updatedArray: any[] = fieldValue.map((arrayItem) => {\n return denormalizeField(arrayItem);\n });\n return updatedArray;\n } else if (fieldValue && typeof fieldValue === \"object\") {\n if (\n data.includes.Asset &&\n \"sys\" in fieldValue &&\n fieldValue.sys.linkType === \"Asset\"\n ) {\n const fieldId = fieldValue.sys.id;\n const asset = data.includes.Asset.find(\n (a: any) => a.sys.id === fieldId\n );\n if (asset) {\n fieldValue = {\n ...fieldValue,\n url: \"https:\" + asset.fields?.file?.url,\n };\n } else {\n console.log(`Asset URL not found for ID: ${fieldId}`);\n }\n } else if (\n data.includes.Entry &&\n \"sys\" in fieldValue &&\n fieldValue.sys.linkType === \"Entry\"\n ) {\n const fieldId = fieldValue.sys.id;\n if (entryMap[fieldId]) {\n if (processedFields.has(fieldId)) {\n console.warn(\n `Circular reference detected for Entry ID: ${fieldId}.`\n );\n } else {\n fieldValue = {\n ...fieldValue,\n fields: denormalizeItem(entryMap[fieldId]).fields,\n };\n }\n } else {\n console.log(`Entry not found for ID: ${fieldId}`);\n }\n }\n fieldValue = Object.entries(fieldValue).reduce((obj, [key, value]) => {\n if (key === \"sys\" || key === \"fields\") {\n obj[key] = value;\n } else {\n obj[key] = denormalizeField(value);\n }\n return obj;\n }, {} as Record<string, any>);\n }\n\n return fieldValue;\n };\n\n const denormalizeItem = (item: any) => {\n const itemId = item.sys?.id;\n if (itemId) {\n processedFields.add(itemId);\n }\n\n const updatedFields: { [fieldName: string]: unknown | unknown[] } = {};\n for (const fieldName in item.fields) {\n updatedFields[fieldName] = denormalizeField(item.fields[fieldName]);\n }\n\n if (itemId) {\n processedFields.delete(itemId);\n }\n\n return {\n ...item,\n fields: updatedFields ?? undefined,\n };\n };\n\n const itemsWithDenormalizedFields: _Entry[] = data.items.map((item: any) => {\n return denormalizeItem(item);\n });\n\n return {\n ...data,\n items: itemsWithDenormalizedFields,\n };\n}\n\nexport interface QueryContentfulOpts {\n space?: string;\n accessToken?: string;\n environment?: string;\n contentType?: string;\n filterField?: string;\n searchParameter?: string;\n filterValue?: string | number;\n order?: string;\n reverseOrder?: boolean;\n limit?: number;\n include?: number;\n}\n\nexport async function queryContentful({\n space,\n accessToken,\n environment = \"master\",\n contentType,\n filterField,\n searchParameter,\n filterValue,\n order,\n reverseOrder,\n limit,\n include,\n}: ContentfulQueryOptions): Promise<any> {\n if (!space || !accessToken) {\n throw new Error(\"Space and accessToken are required\");\n }\n\n if (!contentType) {\n return null;\n }\n\n const baseUrl = \"https://cdn.contentful.com\";\n const path = `/spaces/${space}/environments/${environment}/entries`;\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"access_token\", accessToken);\n searchParams.set(\"content_type\", contentType);\n\n if (limit) {\n searchParams.set(\"limit\", limit.toString());\n }\n\n if (order) {\n searchParams.set(\n \"order\",\n `${reverseOrder ? \"-\" : \"\"}${\n order.startsWith(\"sys.\") ? order : `fields.${order}`\n }`\n );\n }\n\n if (include !== undefined) {\n searchParams.set(\"include\", include.toString());\n }\n\n if (filterField && searchParameter && filterValue !== undefined) {\n searchParams.set(\n `fields.${filterField}${searchParameter}`,\n filterValue.toString()\n );\n }\n\n const resp = await fetch(`${baseUrl}${path}?${searchParams.toString()}`);\n const data = await resp.json();\n\n return denormalizeData(data);\n}\n\nexport const queryContentfulMeta: CustomFunctionMeta<typeof queryContentful> = {\n name: \"queryContentful\",\n displayName: \"Query Contentful\",\n description: \"Query Contentful entries with filtering and ordering\",\n importPath: modulePath,\n params: [\n {\n name: \"opts\",\n type: \"object\",\n display: \"flatten\",\n fields: {\n space: {\n type: \"string\",\n description: \"Contentful space ID\",\n },\n accessToken: {\n type: \"string\",\n description: \"Contentful access token\",\n },\n environment: {\n type: \"string\",\n description: \"Contentful environment (default: master)\",\n },\n contentType: {\n type: \"string\",\n description: \"Content type to query\",\n },\n filterField: {\n type: \"string\",\n description: \"Field to filter by (optional)\",\n },\n searchParameter: {\n type: \"string\",\n description:\n \"Search parameter for filtering (e.g., [match], [lt], [gte])\",\n },\n filterValue: {\n type: \"string\",\n description: \"Value to filter by\",\n },\n order: {\n type: \"string\",\n description: \"Field to order by (optional)\",\n },\n reverseOrder: {\n type: \"boolean\",\n description: \"Reverse the order\",\n },\n limit: {\n type: \"number\",\n description: \"Limit number of results\",\n },\n include: {\n type: \"number\",\n description: \"Depth of linked items to include (max 10)\",\n },\n },\n },\n ],\n};\n", "export const _uniq = <T>(xs: Array<T>): T[] => Array.from(new Set(xs));\n\nexport function _ensure<T>(x: T | null | undefined, msg?: string): T {\n if (x === null || x === undefined) {\n throw new Error(msg ?? `Value must not be undefined or null`);\n } else {\n return x;\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAEO;;;
|
|
3
|
+
"sources": ["../src/index.ts", "../src/utils.ts", "../src/schema.ts", "../src/where.ts", "../src/query-contentful.ts"],
|
|
4
|
+
"sourcesContent": ["import registerFunction, {\n CustomFunctionMeta,\n} from \"@plasmicapp/host/registerFunction\";\nimport {\n _queryContentful,\n queryContentful,\n queryContentfulMeta,\n} from \"./query-contentful\";\n\nexport function registerContentful(loader?: { registerFunction: any }) {\n function _registerFunction<T extends (...args: any[]) => any>(\n fn: T,\n meta: CustomFunctionMeta<T>\n ) {\n if (loader) {\n loader.registerFunction(fn, meta);\n } else {\n registerFunction(fn, meta);\n }\n }\n\n _registerFunction(queryContentful, queryContentfulMeta);\n}\n\nexport {\n // Exports for @plasmicpkgs/plasmic-contentful\n _queryContentful,\n queryContentful,\n};\n\n// Exports for @plasmicpkgs/plasmic-contentful\nexport { denormalizeData as _denormalizeData } from \"./query-contentful\";\nexport type { _Entry } from \"./types\";\nexport { _ensure, _uniq } from \"./utils\";\n", "export const _uniq = <T>(xs: Array<T>): T[] => Array.from(new Set(xs));\nexport const BASE_URL = \"https://cdn.contentful.com\";\n\nexport function _ensure<T>(x: T | null | undefined, msg?: string): T {\n if (x === null || x === undefined) {\n throw new Error(msg ?? `Value must not be undefined or null`);\n } else {\n return x;\n }\n}\n\n/**\n * Capitalizes the first letter of a string\n */\nexport function capitalize(str: string): string {\n if (!str) {\n return str;\n }\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n", "import { BASE_URL } from \"./utils\";\n\nexport interface ContentTypeField {\n id: string;\n name: string;\n type: string;\n required: boolean;\n localized: boolean;\n disabled: boolean;\n}\n\nexport interface ContentTypeSchema {\n sys: { id: string };\n name: string;\n displayField?: string;\n fields: ContentTypeField[];\n}\n\n/**\n * Fetch all content types for a space/environment\n * Returns full schemas which can be used for both dropdown population and field discovery\n */\nexport async function fetchContentTypes(\n space: string,\n accessToken: string,\n environment: string = \"master\"\n): Promise<ContentTypeSchema[]> {\n const url = `${BASE_URL}/spaces/${space}/environments/${environment}/content_types`;\n const params = new URLSearchParams({ access_token: accessToken });\n\n const resp = await fetch(`${url}?${params.toString()}`);\n\n if (!resp.ok) {\n throw new Error(\n `Failed to fetch content types: ${resp.status} ${resp.statusText}`\n );\n }\n\n const data = await resp.json();\n return data.items;\n}\n\n/**\n * Helper to find a specific content type schema from a list\n */\nexport function findContentTypeSchema(\n contentType: string | undefined,\n contentTypes: ContentTypeSchema[] | undefined\n): ContentTypeSchema | undefined {\n if (!contentType || !contentTypes) {\n return undefined;\n }\n return contentTypes.find((ct) => ct.sys.id === contentType);\n}\n", "import type { Field } from \"@react-awesome-query-builder/core\";\nimport type { RulesLogic } from \"json-logic-js\";\nimport type { ContentTypeField, ContentTypeSchema } from \"./schema\";\nimport { capitalize } from \"./utils\";\n\n/**\n * Convert Contentful field type to query builder field configuration\n */\nfunction contentfulSchemaFieldToQueryBuilderField(\n field: ContentTypeField\n): Field | undefined {\n switch (field.type) {\n case \"Integer\":\n case \"Number\":\n return {\n label: capitalize(field.name),\n type: \"number\",\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n\n case \"Boolean\":\n return {\n label: capitalize(field.name),\n type: \"boolean\",\n };\n\n case \"Date\":\n return {\n label: capitalize(field.name),\n type: \"datetime\",\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n\n case \"Symbol\":\n case \"Text\":\n return {\n label: capitalize(field.name),\n type: \"text\",\n operators: [\"equal\", \"not_equal\", \"like\", \"is_null\", \"is_not_null\"],\n };\n\n default:\n return undefined;\n }\n}\n\n/**\n * Build query builder config from content type schema\n */\nexport function schemaToQueryBuilderConfig(schema: ContentTypeSchema) {\n const fields: Record<string, Field> = {};\n\n for (const field of schema.fields) {\n const qbField = contentfulSchemaFieldToQueryBuilderField(field);\n if (qbField) {\n fields[field.id] = qbField;\n }\n }\n\n return {\n fields,\n conjunctions: {\n AND: {\n label: \"All\",\n },\n // OR explicitly omitted - not supported by Contentful API\n },\n settings: {\n showNot: false,\n maxNesting: 1,\n canRegroup: false,\n canLeaveEmptyGroup: false,\n },\n };\n}\n\n/**\n * Maps JsonLogic to Contentful API filters format.\n *\n * See also:\n * - https://www.contentful.com/developers/docs/references/content-delivery-api/\n */\nexport function rulesLogicToContentfulFilters(\n logic: RulesLogic | undefined\n): Record<string, any> {\n if (logic === null || logic === undefined) {\n return {};\n } else if (typeof logic !== \"object\") {\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n } else if (\"and\" in logic) {\n // Handle AND - flatten to multiple parameters\n // Contentful supports implicit AND between all query parameters\n return logic[\"and\"].reduce((acc: Record<string, any>, condition: any) => {\n return { ...acc, ...rulesLogicToContentfulFilters(condition) };\n }, {});\n } else if (\"or\" in logic) {\n // OR is not supported by Contentful API\n throw new Error(\n \"Contentful API does not support OR operations. Please restructure your query using only AND conditions.\"\n );\n } else if (\"!\" in logic) {\n // NOT is not supported by Contentful API\n throw new Error(\n \"Contentful API does not support NOT operations. Please use field-level negation operators like 'not_equal' ([ne]) instead.\"\n );\n } else if (\"==\" in logic) {\n const [{ var: field }, operand] = logic[\"==\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [`fields.${field}[exists]`]: \"false\" };\n }\n return {\n [`fields.${field}`]: operand,\n };\n } else if (\"!=\" in logic) {\n const [{ var: field }, operand] = logic[\"!=\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [`fields.${field}[exists]`]: \"true\" };\n }\n return {\n [`fields.${field}[ne]`]: operand,\n };\n } else if (\"in\" in logic) {\n // Map in operator to Contentful filters format:\n // JsonLogic: { \"in\": [\"searchText\", { \"var\": \"fieldName\" }] }\n // Contentful filters: { \"fields.fieldName[match]\": \"searchText\" }\n const [operand, { var: field }] = logic[\"in\"] as [string, { var: string }];\n return {\n [`fields.${field}[match]`]: operand,\n };\n } else {\n // Map JsonLogic comparison operators to Contentful filters format:\n // JsonLogic: { \"<=\": [{ \"var\": \"age\" }, 18] }\n // Contentful filters: { \"fields.age[lte]\": 18 }\n const [key, value] = Object.entries(logic)[0];\n const apiOp: string | undefined = operatorMapping[key];\n if (apiOp) {\n const [{ var: field }, operand] = value as [{ var: string }, unknown];\n return { [`fields.${field}[${apiOp}]`]: operand };\n }\n\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n }\n}\n\n/** Maps JsonLogic operator to Contentful filter operator. */\nconst operatorMapping: Record<string, string> = {\n \"<\": \"lt\",\n \"<=\": \"lte\",\n \">\": \"gt\",\n \">=\": \"gte\",\n};\n", "import { CustomFunctionMeta } from \"@plasmicapp/host/registerFunction\";\nimport type { RulesLogic } from \"json-logic-js\";\nimport {\n ContentTypeField,\n ContentTypeSchema,\n fetchContentTypes,\n findContentTypeSchema,\n} from \"./schema\";\nimport { _Entry } from \"./types\";\nimport { BASE_URL, capitalize } from \"./utils\";\nimport {\n rulesLogicToContentfulFilters,\n schemaToQueryBuilderConfig,\n} from \"./where\";\n\nexport const modulePath = \"@plasmicpkgs/contentful\";\n\nexport function denormalizeData(data: any | null): any {\n if (!data?.items || !data?.includes) {\n return data;\n }\n\n const entryMap: { [id: string]: any } = {};\n\n if (data.includes.Entry) {\n data.includes.Entry.forEach((entry: any) => {\n entryMap[entry.sys.id] = entry;\n });\n }\n\n // Track processed fields to avoid following circular references\n const processedFields = new Set<string>();\n\n const denormalizeField = (fieldValue: any): any => {\n if (Array.isArray(fieldValue)) {\n const updatedArray: any[] = fieldValue.map((arrayItem) => {\n return denormalizeField(arrayItem);\n });\n return updatedArray;\n } else if (fieldValue && typeof fieldValue === \"object\") {\n if (\n data.includes.Asset &&\n \"sys\" in fieldValue &&\n fieldValue.sys.linkType === \"Asset\"\n ) {\n const fieldId = fieldValue.sys.id;\n const asset = data.includes.Asset.find(\n (a: any) => a.sys.id === fieldId\n );\n if (asset) {\n fieldValue = {\n ...fieldValue,\n url: \"https:\" + asset.fields?.file?.url,\n };\n } else {\n console.log(`Asset URL not found for ID: ${fieldId}`);\n }\n } else if (\n data.includes.Entry &&\n \"sys\" in fieldValue &&\n fieldValue.sys.linkType === \"Entry\"\n ) {\n const fieldId = fieldValue.sys.id;\n if (entryMap[fieldId]) {\n if (processedFields.has(fieldId)) {\n console.warn(\n `Circular reference detected for Entry ID: ${fieldId}.`\n );\n } else {\n fieldValue = {\n ...fieldValue,\n fields: denormalizeItem(entryMap[fieldId]).fields,\n };\n }\n } else {\n console.log(`Entry not found for ID: ${fieldId}`);\n }\n }\n fieldValue = Object.entries(fieldValue).reduce((obj, [key, value]) => {\n if (key === \"sys\" || key === \"fields\") {\n obj[key] = value;\n } else {\n obj[key] = denormalizeField(value);\n }\n return obj;\n }, {} as Record<string, any>);\n }\n\n return fieldValue;\n };\n\n const denormalizeItem = (item: any) => {\n const itemId = item.sys?.id;\n if (itemId) {\n processedFields.add(itemId);\n }\n\n const updatedFields: { [fieldName: string]: unknown | unknown[] } = {};\n for (const fieldName in item.fields) {\n updatedFields[fieldName] = denormalizeField(item.fields[fieldName]);\n }\n\n if (itemId) {\n processedFields.delete(itemId);\n }\n\n return {\n ...item,\n fields: updatedFields ?? undefined,\n };\n };\n\n const itemsWithDenormalizedFields: _Entry[] = data.items.map((item: any) => {\n return denormalizeItem(item);\n });\n\n return {\n ...data,\n items: itemsWithDenormalizedFields,\n };\n}\n\n/**\n * @deprecated These filter props are deprecated. Use `filterLogic` with the query builder instead.\n * Only used by the deprecated ContentfulCollection component for backward compatibility.\n */\nexport interface QueryContentfulOldFilterProps {\n filterField?: string;\n searchParameter?: string;\n filterValue?: string | number;\n}\n\nexport interface QueryContentfulOpts {\n space?: string;\n accessToken?: string;\n environment?: string;\n contentType?: string;\n /**\n * Filter logic using JSON Logic format to filter Contentful entries.\n * See {@link https://www.npmjs.com/package/@types/json-logic-js?activeTab=readme}\n */\n filterLogic?: RulesLogic;\n order?: string;\n reverseOrder?: boolean;\n limit?: number;\n skip?: number;\n include?: number;\n // string type supports comma-separated string as documented in the Contentful API, inserted via the dynamic value editor\n // array type supports multiple fields to be selected via the choice prop editor for convenience\n select?: string | string[];\n locale?: string;\n}\n\n/**\n * Query Contentful with simplified filter props.\n *\n * @deprecated Use {@link queryContentful} with `filterLogic` parameter instead.\n *\n * @example\n * ```ts\n * // Old way (deprecated)\n * _queryContentful({\n * space: 'space-id',\n * accessToken: 'token',\n * contentType: 'article',\n * filterField: 'title',\n * searchParameter: '[match]',\n * filterValue: 'Hello'\n * })\n *\n * // New way\n * queryContentful({\n * space: 'space-id',\n * accessToken: 'token',\n * contentType: 'article',\n * filterLogic: { \"==\": [{ var: \"title\" }, \"Hello\"] }\n * })\n * ```\n */\nexport async function _queryContentful({\n space,\n accessToken,\n environment = \"master\",\n contentType,\n filterLogic,\n filterField,\n searchParameter,\n filterValue,\n order,\n reverseOrder,\n limit,\n skip,\n include,\n select,\n locale,\n}: QueryContentfulOpts & QueryContentfulOldFilterProps): Promise<any> {\n if (!space || !accessToken) {\n throw new Error(\"Space and accessToken are required\");\n }\n\n if (!contentType) {\n return null;\n }\n\n const path = `/spaces/${space}/environments/${environment}/entries`;\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"access_token\", accessToken);\n searchParams.set(\"content_type\", contentType);\n\n // Convert filterLogic to Contentful filters\n let filters: Record<string, any> = {};\n if (filterLogic) {\n filters = rulesLogicToContentfulFilters(filterLogic);\n } else if (filterField && searchParameter && filterValue !== undefined) {\n // BACKWARD COMPATIBILITY: Legacy filter props\n filters[`fields.${filterField}${searchParameter}`] = filterValue.toString();\n }\n\n // Apply all filter parameters\n for (const [key, value] of Object.entries(filters)) {\n searchParams.set(key, value.toString());\n }\n\n if (limit) {\n searchParams.set(\"limit\", limit.toString());\n }\n\n if (skip !== undefined) {\n searchParams.set(\"skip\", skip.toString());\n }\n\n if (order) {\n searchParams.set(\n \"order\",\n `${reverseOrder ? \"-\" : \"\"}${\n order.startsWith(\"sys.\") ? order : `fields.${order}`\n }`\n );\n }\n\n if (include !== undefined) {\n searchParams.set(\"include\", include.toString());\n }\n\n if (select) {\n if (Array.isArray(select)) {\n if (select.length > 0) {\n searchParams.set(\"select\", select.join(\",\"));\n }\n } else {\n // The user may pass a comma-separated string as documented in the Contentful API\n searchParams.set(\"select\", select);\n }\n }\n\n if (locale) {\n searchParams.set(\"locale\", locale);\n }\n\n const resp = await fetch(`${BASE_URL}${path}?${searchParams.toString()}`);\n const data = await resp.json();\n\n return denormalizeData(data);\n}\n\n/**\n * Query a Contentful content type with optional filtering and ordering.\n *\n * @param opts - Query options including space, accessToken, contentType, filter logic, and pagination\n * @returns Promise resolving to the Contentful query response with denormalized data\n *\n * @example\n * ```ts\n * // Fetch all entries\n * const result = await queryContentful({\n * space: 'your-space-id',\n * accessToken: 'your-access-token',\n * contentType: 'blogPost'\n * });\n *\n * // Fetch with filter\n * const filtered = await queryContentful({\n * space: 'your-space-id',\n * accessToken: 'your-access-token',\n * contentType: 'blogPost',\n * filterLogic: { \"==\": [{ var: \"status\" }, \"published\"] }\n * });\n * ```\n */\nexport async function queryContentful({\n space,\n accessToken,\n environment = \"master\",\n contentType,\n filterLogic,\n}: QueryContentfulOpts): Promise<any> {\n return _queryContentful({\n space,\n accessToken,\n environment,\n contentType,\n filterLogic,\n });\n}\n\nexport const queryContentfulMeta: CustomFunctionMeta<typeof queryContentful> = {\n name: \"queryContentful\",\n displayName: \"Query Contentful\",\n description: \"Query Contentful entries with filtering and ordering\",\n importPath: modulePath,\n params: [\n {\n name: \"opts\",\n type: \"object\",\n display: \"flatten\",\n fields: {\n space: {\n type: \"string\",\n description: \"Contentful space ID\",\n },\n accessToken: {\n type: \"string\",\n description: \"Contentful access token\",\n },\n environment: {\n type: \"string\",\n description: \"Contentful environment (default: master)\",\n },\n contentType: {\n type: \"choice\",\n displayName: \"Content Type\",\n description: \"Content type to query\",\n options: (_: any, ctx: any) => {\n return (\n ctx?.contentTypes?.map((ct: ContentTypeSchema) => ({\n label: ct.name,\n value: ct.sys.id,\n })) ?? []\n );\n },\n },\n filterLogic: {\n type: \"queryBuilder\",\n displayName: \"Filter\",\n description: \"Filter fetched entries. Defaults to fetch all entries.\",\n config: ([opts], ctx: any) => {\n const schema = findContentTypeSchema(\n opts?.contentType,\n ctx?.contentTypes\n );\n\n if (schema) {\n return schemaToQueryBuilderConfig(schema);\n }\n\n return {\n fields: {},\n };\n },\n },\n order: {\n type: \"choice\",\n displayName: \"Order by\",\n description: \"Field to order by (optional)\",\n defaultValueHint: \"sys.updatedAt\",\n options: ([opts], ctx: any) => {\n const systemFields = [\n { label: \"Created at\", value: \"sys.createdAt\" },\n { label: \"Updated at\", value: \"sys.updatedAt\" },\n { label: \"ID\", value: \"sys.id\" },\n ];\n\n const schema = findContentTypeSchema(\n opts?.contentType,\n ctx?.contentTypes\n );\n\n if (schema) {\n const contentFields = schema.fields\n .filter((field: ContentTypeField) => !field.disabled)\n .map((field: ContentTypeField) => ({\n label: capitalize(field.name),\n value: `fields.${field.id}`,\n }));\n\n return [...systemFields, ...contentFields];\n }\n\n return systemFields;\n },\n },\n reverseOrder: {\n type: \"boolean\",\n description: \"Reverse the order\",\n hidden: ([opts]: [QueryContentfulOpts | undefined]) => !opts?.order,\n defaultValueHint: false,\n },\n limit: {\n type: \"number\",\n description: \"Limit number of results\",\n defaultValueHint: 100,\n },\n skip: {\n type: \"number\",\n description: \"Skip number of results (for pagination)\",\n defaultValueHint: 0,\n },\n include: {\n type: \"number\",\n description: \"Depth of linked items to include (max 10)\",\n max: 10,\n min: 0,\n defaultValueHint: 1,\n },\n select: {\n type: \"choice\",\n multiSelect: true,\n description: \"Fields to select. Defaults to all fields.\",\n options: ([opts], ctx: any) => {\n const schema = findContentTypeSchema(\n opts?.contentType,\n ctx?.contentTypes\n );\n\n const fieldOptions = schema\n ? schema.fields\n .filter((field: ContentTypeField) => !field.disabled)\n .map((field: ContentTypeField) => ({\n label: capitalize(field.name), // Use capitalized friendly name from schema\n value: `fields.${field.id}`,\n }))\n : [];\n\n return [\n ...fieldOptions,\n { label: \"Fields only\", value: \"fields\" },\n { label: \"Metadata only\", value: \"sys\" },\n ];\n },\n },\n locale: {\n type: \"string\",\n description: \"Locale code (e.g., en-US)\",\n },\n },\n },\n ],\n fnContext: (contentfulOpts?: QueryContentfulOpts) => {\n if (!contentfulOpts?.space || !contentfulOpts?.accessToken) {\n return {\n dataKey: \"\",\n fetcher: async () => ({\n contentTypes: [],\n }),\n };\n }\n\n // Cache at workspace level (space + environment) to fetch all schemas once.\n // Excluding contentType from cache key means switching content types won't\n // trigger new API calls - we just find the schema in the cached array.\n const workspaceCacheKey = JSON.stringify({\n space: contentfulOpts.space,\n accessToken: contentfulOpts.accessToken,\n environment: contentfulOpts.environment,\n });\n\n return {\n dataKey: workspaceCacheKey,\n fetcher: async () => {\n try {\n // Fetch all content types once (includes full schemas with fields)\n const contentTypes = await fetchContentTypes(\n contentfulOpts.space!,\n contentfulOpts.accessToken!,\n contentfulOpts.environment\n );\n\n return {\n contentTypes,\n };\n } catch (error) {\n console.error(\"Failed to fetch content types:\", error);\n return {\n contentTypes: [],\n };\n }\n },\n };\n },\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAEO;;;ACFA,IAAM,QAAQ,CAAI,OAAsB,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;AAC9D,IAAM,WAAW;AAEjB,SAAS,QAAW,GAAyB,KAAiB;AACnE,MAAI,MAAM,QAAQ,MAAM,QAAW;AACjC,UAAM,IAAI,MAAM,oBAAO,qCAAqC;AAAA,EAC9D,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAKO,SAAS,WAAW,KAAqB;AAC9C,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AACA,SAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAClD;;;ACGA,SAAsB,kBACpB,OACA,aACA,cAAsB,UACQ;AAAA;AAC9B,UAAM,MAAM,GAAG,mBAAmB,sBAAsB;AACxD,UAAM,SAAS,IAAI,gBAAgB,EAAE,cAAc,YAAY,CAAC;AAEhE,UAAM,OAAO,MAAM,MAAM,GAAG,OAAO,OAAO,SAAS,GAAG;AAEtD,QAAI,CAAC,KAAK,IAAI;AACZ,YAAM,IAAI;AAAA,QACR,kCAAkC,KAAK,UAAU,KAAK;AAAA,MACxD;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA;AAKO,SAAS,sBACd,aACA,cAC+B;AAC/B,MAAI,CAAC,eAAe,CAAC,cAAc;AACjC,WAAO;AAAA,EACT;AACA,SAAO,aAAa,KAAK,CAAC,OAAO,GAAG,IAAI,OAAO,WAAW;AAC5D;;;AC7CA,SAAS,yCACP,OACmB;AACnB,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,QACL,OAAO,WAAW,MAAM,IAAI;AAAA,QAC5B,MAAM;AAAA,QACN,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IAEF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,WAAW,MAAM,IAAI;AAAA,QAC5B,MAAM;AAAA,MACR;AAAA,IAEF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,WAAW,MAAM,IAAI;AAAA,QAC5B,MAAM;AAAA,QACN,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IAEF,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,QACL,OAAO,WAAW,MAAM,IAAI;AAAA,QAC5B,MAAM;AAAA,QACN,WAAW,CAAC,SAAS,aAAa,QAAQ,WAAW,aAAa;AAAA,MACpE;AAAA,IAEF;AACE,aAAO;AAAA,EACX;AACF;AAKO,SAAS,2BAA2B,QAA2B;AACpE,QAAM,SAAgC,CAAC;AAEvC,aAAW,SAAS,OAAO,QAAQ;AACjC,UAAM,UAAU,yCAAyC,KAAK;AAC9D,QAAI,SAAS;AACX,aAAO,MAAM,EAAE,IAAI;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,cAAc;AAAA,MACZ,KAAK;AAAA,QACH,OAAO;AAAA,MACT;AAAA;AAAA,IAEF;AAAA,IACA,UAAU;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,oBAAoB;AAAA,IACtB;AAAA,EACF;AACF;AAQO,SAAS,8BACd,OACqB;AACrB,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO,CAAC;AAAA,EACV,WAAW,OAAO,UAAU,UAAU;AACpC,UAAM,IAAI,MAAM,qBAAqB,KAAK,UAAU,KAAK,GAAG;AAAA,EAC9D,WAAW,SAAS,OAAO;AAGzB,WAAO,MAAM,KAAK,EAAE,OAAO,CAAC,KAA0B,cAAmB;AACvE,aAAO,kCAAK,MAAQ,8BAA8B,SAAS;AAAA,IAC7D,GAAG,CAAC,CAAC;AAAA,EACP,WAAW,QAAQ,OAAO;AAExB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF,WAAW,OAAO,OAAO;AAEvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF,WAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,EAAE,KAAK,MAAM,GAAG,OAAO,IAAI,MAAM,IAAI;AAC5C,QAAI,YAAY,MAAM;AACpB,aAAO,EAAE,CAAC,UAAU,eAAe,GAAG,QAAQ;AAAA,IAChD;AACA,WAAO;AAAA,MACL,CAAC,UAAU,OAAO,GAAG;AAAA,IACvB;AAAA,EACF,WAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,EAAE,KAAK,MAAM,GAAG,OAAO,IAAI,MAAM,IAAI;AAC5C,QAAI,YAAY,MAAM;AACpB,aAAO,EAAE,CAAC,UAAU,eAAe,GAAG,OAAO;AAAA,IAC/C;AACA,WAAO;AAAA,MACL,CAAC,UAAU,WAAW,GAAG;AAAA,IAC3B;AAAA,EACF,WAAW,QAAQ,OAAO;AAIxB,UAAM,CAAC,SAAS,EAAE,KAAK,MAAM,CAAC,IAAI,MAAM,IAAI;AAC5C,WAAO;AAAA,MACL,CAAC,UAAU,cAAc,GAAG;AAAA,IAC9B;AAAA,EACF,OAAO;AAIL,UAAM,CAAC,KAAK,KAAK,IAAI,OAAO,QAAQ,KAAK,EAAE,CAAC;AAC5C,UAAM,QAA4B,gBAAgB,GAAG;AACrD,QAAI,OAAO;AACT,YAAM,CAAC,EAAE,KAAK,MAAM,GAAG,OAAO,IAAI;AAClC,aAAO,EAAE,CAAC,UAAU,SAAS,QAAQ,GAAG,QAAQ;AAAA,IAClD;AAEA,UAAM,IAAI,MAAM,qBAAqB,KAAK,UAAU,KAAK,GAAG;AAAA,EAC9D;AACF;AAGA,IAAM,kBAA0C;AAAA,EAC9C,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AACR;;;ACzJO,IAAM,aAAa;AAEnB,SAAS,gBAAgB,MAAuB;AACrD,MAAI,EAAC,6BAAM,UAAS,EAAC,6BAAM,WAAU;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,WAAkC,CAAC;AAEzC,MAAI,KAAK,SAAS,OAAO;AACvB,SAAK,SAAS,MAAM,QAAQ,CAAC,UAAe;AAC1C,eAAS,MAAM,IAAI,EAAE,IAAI;AAAA,IAC3B,CAAC;AAAA,EACH;AAGA,QAAM,kBAAkB,oBAAI,IAAY;AAExC,QAAM,mBAAmB,CAAC,eAAyB;AAjCrD;AAkCI,QAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,YAAM,eAAsB,WAAW,IAAI,CAAC,cAAc;AACxD,eAAO,iBAAiB,SAAS;AAAA,MACnC,CAAC;AACD,aAAO;AAAA,IACT,WAAW,cAAc,OAAO,eAAe,UAAU;AACvD,UACE,KAAK,SAAS,SACd,SAAS,cACT,WAAW,IAAI,aAAa,SAC5B;AACA,cAAM,UAAU,WAAW,IAAI;AAC/B,cAAM,QAAQ,KAAK,SAAS,MAAM;AAAA,UAChC,CAAC,MAAW,EAAE,IAAI,OAAO;AAAA,QAC3B;AACA,YAAI,OAAO;AACT,uBAAa,iCACR,aADQ;AAAA,YAEX,KAAK,aAAW,iBAAM,WAAN,mBAAc,SAAd,mBAAoB;AAAA,UACtC;AAAA,QACF,OAAO;AACL,kBAAQ,IAAI,+BAA+B,SAAS;AAAA,QACtD;AAAA,MACF,WACE,KAAK,SAAS,SACd,SAAS,cACT,WAAW,IAAI,aAAa,SAC5B;AACA,cAAM,UAAU,WAAW,IAAI;AAC/B,YAAI,SAAS,OAAO,GAAG;AACrB,cAAI,gBAAgB,IAAI,OAAO,GAAG;AAChC,oBAAQ;AAAA,cACN,6CAA6C;AAAA,YAC/C;AAAA,UACF,OAAO;AACL,yBAAa,iCACR,aADQ;AAAA,cAEX,QAAQ,gBAAgB,SAAS,OAAO,CAAC,EAAE;AAAA,YAC7C;AAAA,UACF;AAAA,QACF,OAAO;AACL,kBAAQ,IAAI,2BAA2B,SAAS;AAAA,QAClD;AAAA,MACF;AACA,mBAAa,OAAO,QAAQ,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACpE,YAAI,QAAQ,SAAS,QAAQ,UAAU;AACrC,cAAI,GAAG,IAAI;AAAA,QACb,OAAO;AACL,cAAI,GAAG,IAAI,iBAAiB,KAAK;AAAA,QACnC;AACA,eAAO;AAAA,MACT,GAAG,CAAC,CAAwB;AAAA,IAC9B;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,CAAC,SAAc;AA3FzC;AA4FI,UAAM,UAAS,UAAK,QAAL,mBAAU;AACzB,QAAI,QAAQ;AACV,sBAAgB,IAAI,MAAM;AAAA,IAC5B;AAEA,UAAM,gBAA8D,CAAC;AACrE,eAAW,aAAa,KAAK,QAAQ;AACnC,oBAAc,SAAS,IAAI,iBAAiB,KAAK,OAAO,SAAS,CAAC;AAAA,IACpE;AAEA,QAAI,QAAQ;AACV,sBAAgB,OAAO,MAAM;AAAA,IAC/B;AAEA,WAAO,iCACF,OADE;AAAA,MAEL,QAAQ,wCAAiB;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,8BAAwC,KAAK,MAAM,IAAI,CAAC,SAAc;AAC1E,WAAO,gBAAgB,IAAI;AAAA,EAC7B,CAAC;AAED,SAAO,iCACF,OADE;AAAA,IAEL,OAAO;AAAA,EACT;AACF;AA2DA,SAAsB,iBAAiB,IAgB+B;AAAA,6CAhB/B;AAAA,IACrC;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAsE;AACpE,QAAI,CAAC,SAAS,CAAC,aAAa;AAC1B,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AAEA,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,WAAW,sBAAsB;AAC9C,UAAM,eAAe,IAAI,gBAAgB;AAEzC,iBAAa,IAAI,gBAAgB,WAAW;AAC5C,iBAAa,IAAI,gBAAgB,WAAW;AAG5C,QAAI,UAA+B,CAAC;AACpC,QAAI,aAAa;AACf,gBAAU,8BAA8B,WAAW;AAAA,IACrD,WAAW,eAAe,mBAAmB,gBAAgB,QAAW;AAEtE,cAAQ,UAAU,cAAc,iBAAiB,IAAI,YAAY,SAAS;AAAA,IAC5E;AAGA,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,mBAAa,IAAI,KAAK,MAAM,SAAS,CAAC;AAAA,IACxC;AAEA,QAAI,OAAO;AACT,mBAAa,IAAI,SAAS,MAAM,SAAS,CAAC;AAAA,IAC5C;AAEA,QAAI,SAAS,QAAW;AACtB,mBAAa,IAAI,QAAQ,KAAK,SAAS,CAAC;AAAA,IAC1C;AAEA,QAAI,OAAO;AACT,mBAAa;AAAA,QACX;AAAA,QACA,GAAG,eAAe,MAAM,KACtB,MAAM,WAAW,MAAM,IAAI,QAAQ,UAAU;AAAA,MAEjD;AAAA,IACF;AAEA,QAAI,YAAY,QAAW;AACzB,mBAAa,IAAI,WAAW,QAAQ,SAAS,CAAC;AAAA,IAChD;AAEA,QAAI,QAAQ;AACV,UAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAI,OAAO,SAAS,GAAG;AACrB,uBAAa,IAAI,UAAU,OAAO,KAAK,GAAG,CAAC;AAAA,QAC7C;AAAA,MACF,OAAO;AAEL,qBAAa,IAAI,UAAU,MAAM;AAAA,MACnC;AAAA,IACF;AAEA,QAAI,QAAQ;AACV,mBAAa,IAAI,UAAU,MAAM;AAAA,IACnC;AAEA,UAAM,OAAO,MAAM,MAAM,GAAG,WAAW,QAAQ,aAAa,SAAS,GAAG;AACxE,UAAM,OAAO,MAAM,KAAK,KAAK;AAE7B,WAAO,gBAAgB,IAAI;AAAA,EAC7B;AAAA;AA0BA,SAAsB,gBAAgB,IAMA;AAAA,6CANA;AAAA,IACpC;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,GAAsC;AACpC,WAAO,iBAAiB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAEO,IAAM,sBAAkE;AAAA,EAC7E,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,SAAS,CAAC,GAAQ,QAAa;AA7UzC;AA8UY,oBACE,sCAAK,iBAAL,mBAAmB,IAAI,CAAC,QAA2B;AAAA,cACjD,OAAO,GAAG;AAAA,cACV,OAAO,GAAG,IAAI;AAAA,YAChB,QAHA,YAGO,CAAC;AAAA,UAEZ;AAAA,QACF;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,QAAQ,CAAC,CAAC,IAAI,GAAG,QAAa;AAC5B,kBAAM,SAAS;AAAA,cACb,6BAAM;AAAA,cACN,2BAAK;AAAA,YACP;AAEA,gBAAI,QAAQ;AACV,qBAAO,2BAA2B,MAAM;AAAA,YAC1C;AAEA,mBAAO;AAAA,cACL,QAAQ,CAAC;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,kBAAkB;AAAA,UAClB,SAAS,CAAC,CAAC,IAAI,GAAG,QAAa;AAC7B,kBAAM,eAAe;AAAA,cACnB,EAAE,OAAO,cAAc,OAAO,gBAAgB;AAAA,cAC9C,EAAE,OAAO,cAAc,OAAO,gBAAgB;AAAA,cAC9C,EAAE,OAAO,MAAM,OAAO,SAAS;AAAA,YACjC;AAEA,kBAAM,SAAS;AAAA,cACb,6BAAM;AAAA,cACN,2BAAK;AAAA,YACP;AAEA,gBAAI,QAAQ;AACV,oBAAM,gBAAgB,OAAO,OAC1B,OAAO,CAAC,UAA4B,CAAC,MAAM,QAAQ,EACnD,IAAI,CAAC,WAA6B;AAAA,gBACjC,OAAO,WAAW,MAAM,IAAI;AAAA,gBAC5B,OAAO,UAAU,MAAM;AAAA,cACzB,EAAE;AAEJ,qBAAO,CAAC,GAAG,cAAc,GAAG,aAAa;AAAA,YAC3C;AAEA,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,QAAQ,CAAC,CAAC,IAAI,MAAyC,EAAC,6BAAM;AAAA,UAC9D,kBAAkB;AAAA,QACpB;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,UACb,kBAAkB;AAAA,QACpB;AAAA,QACA,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,kBAAkB;AAAA,QACpB;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,UACb,KAAK;AAAA,UACL,KAAK;AAAA,UACL,kBAAkB;AAAA,QACpB;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,SAAS,CAAC,CAAC,IAAI,GAAG,QAAa;AAC7B,kBAAM,SAAS;AAAA,cACb,6BAAM;AAAA,cACN,2BAAK;AAAA,YACP;AAEA,kBAAM,eAAe,SACjB,OAAO,OACJ,OAAO,CAAC,UAA4B,CAAC,MAAM,QAAQ,EACnD,IAAI,CAAC,WAA6B;AAAA,cACjC,OAAO,WAAW,MAAM,IAAI;AAAA;AAAA,cAC5B,OAAO,UAAU,MAAM;AAAA,YACzB,EAAE,IACJ,CAAC;AAEL,mBAAO;AAAA,cACL,GAAG;AAAA,cACH,EAAE,OAAO,eAAe,OAAO,SAAS;AAAA,cACxC,EAAE,OAAO,iBAAiB,OAAO,MAAM;AAAA,YACzC;AAAA,UACF;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW,CAAC,mBAAyC;AACnD,QAAI,EAAC,iDAAgB,UAAS,EAAC,iDAAgB,cAAa;AAC1D,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,MAAS;AAAI;AAAA,YACpB,cAAc,CAAC;AAAA,UACjB;AAAA;AAAA,MACF;AAAA,IACF;AAKA,UAAM,oBAAoB,KAAK,UAAU;AAAA,MACvC,OAAO,eAAe;AAAA,MACtB,aAAa,eAAe;AAAA,MAC5B,aAAa,eAAe;AAAA,IAC9B,CAAC;AAED,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,MAAY;AACnB,YAAI;AAEF,gBAAM,eAAe,MAAM;AAAA,YACzB,eAAe;AAAA,YACf,eAAe;AAAA,YACf,eAAe;AAAA,UACjB;AAEA,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF,SAAS,OAAP;AACA,kBAAQ,MAAM,kCAAkC,KAAK;AACrD,iBAAO;AAAA,YACL,cAAc,CAAC;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AJjeO,SAAS,mBAAmB,QAAoC;AACrE,WAAS,kBACP,IACA,MACA;AACA,QAAI,QAAQ;AACV,aAAO,iBAAiB,IAAI,IAAI;AAAA,IAClC,OAAO;AACL,kCAAAA,SAAiB,IAAI,IAAI;AAAA,IAC3B;AAAA,EACF;AAEA,oBAAkB,iBAAiB,mBAAmB;AACxD;",
|
|
6
6
|
"names": ["registerFunction"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plasmicpkgs/contentful",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Plasmic registration for Contentful",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,12 +32,14 @@
|
|
|
32
32
|
"postpublish": "bash ../../scripts/publish-api-doc-model.sh"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@plasmicapp/host": "1.0.
|
|
35
|
+
"@plasmicapp/host": "1.0.235",
|
|
36
|
+
"@react-awesome-query-builder/core": "^6.6.15",
|
|
37
|
+
"@types/json-logic-js": "^2.0.8",
|
|
36
38
|
"typescript": "^5.7.3",
|
|
37
39
|
"vitest": "3.2.4"
|
|
38
40
|
},
|
|
39
41
|
"peerDependencies": {
|
|
40
42
|
"@plasmicapp/host": "^1.0.211"
|
|
41
43
|
},
|
|
42
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "380a91b2e7eac342c9b2ddafdacd84b4a812b795"
|
|
43
45
|
}
|