@nuskin/contentstack-lib 2.0.0 → 2.0.2-pa-1190.1
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/.eslintrc.json +1 -1
- package/.releaserc +1 -1
- package/README.md +5 -14
- package/__tests__/api.spec.js +227 -14
- package/docs/CHANGELOG.md +1 -1
- package/package.json +2 -2
- package/src/api.js +145 -3
- package/src/index.js +1 -2
package/.eslintrc.json
CHANGED
package/.releaserc
CHANGED
package/README.md
CHANGED
|
@@ -10,13 +10,13 @@ FOR COMMON SPANISH AND MX-es FOR EXAMPLE.
|
|
|
10
10
|
|
|
11
11
|
## Installing
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Using npm:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npm install @nuskin/contentstack-lib
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Using yarn:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
yarn add @nuskin/contentstack-lib
|
|
@@ -27,8 +27,9 @@ yarn add @nuskin/contentstack-lib
|
|
|
27
27
|
```js
|
|
28
28
|
const { getStack } = require('@nuskin/contentstack-lib')
|
|
29
29
|
|
|
30
|
-
//
|
|
31
|
-
|
|
30
|
+
// Pass an environment explicitly outside the browser.
|
|
31
|
+
// In the browser, getStack() can infer the env from the hostname.
|
|
32
|
+
const Stack = getStack('prod')
|
|
32
33
|
|
|
33
34
|
// get all languages
|
|
34
35
|
const languages = await Stack.ContentType('supported_language').Query().toJSON().find();
|
|
@@ -36,16 +37,6 @@ const languages = await Stack.ContentType('supported_language').Query().toJSON()
|
|
|
36
37
|
// get all markets
|
|
37
38
|
const markets = await Stack.ContentType('market').Query().toJSON().find();
|
|
38
39
|
|
|
39
|
-
// Use the extended getStrings function to get translations
|
|
40
|
-
// ==================== Deprecated - Dont use this function ==========================
|
|
41
|
-
const translations = Stack.getStrings({
|
|
42
|
-
contentTypes: ['checkout_adr_strings', 'checkout_cart_strings'], // List of content types you want to get translations for
|
|
43
|
-
language: 'en',
|
|
44
|
-
country: 'US',
|
|
45
|
-
merge: true // Will combine checkout_adr_strings and checkout_cart_strings object with single list of strings
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// Use this function instead to get your translations
|
|
49
40
|
// The entries are returned in the order they were requested so you can destructure the array accordingly
|
|
50
41
|
// To get the result in camelcase instead of snake case you can pass in the option.camelcase: true
|
|
51
42
|
// Contentstack does not merge common english strings with en_US strings. This function allows you to merge the two with mergeWithFallback: true
|
package/__tests__/api.spec.js
CHANGED
|
@@ -15,6 +15,9 @@ const {contentstack: prodEnvConfig} = require(`../config/prod.json`);
|
|
|
15
15
|
const mockPromiseResult = jest.fn();
|
|
16
16
|
const mockSinglePromiseResult = jest.fn();
|
|
17
17
|
const mockStack = jest.fn();
|
|
18
|
+
const mockContainedIn = jest.fn();
|
|
19
|
+
const mockIncludeReference = jest.fn();
|
|
20
|
+
const mockFetch = jest.fn();
|
|
18
21
|
|
|
19
22
|
function getConfig(env) {
|
|
20
23
|
let config = {};
|
|
@@ -42,27 +45,150 @@ function getConfig(env) {
|
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
beforeEach(() => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
find: mockPromiseResult,
|
|
52
|
-
findOne: mockSinglePromiseResult
|
|
53
|
-
})
|
|
54
|
-
})
|
|
48
|
+
const mockQuery = {
|
|
49
|
+
language: jest.fn(() => ({
|
|
50
|
+
includeFallback: () => ({
|
|
51
|
+
toJSON: () => ({
|
|
52
|
+
find: mockPromiseResult,
|
|
53
|
+
findOne: mockSinglePromiseResult
|
|
55
54
|
})
|
|
56
55
|
})
|
|
56
|
+
})),
|
|
57
|
+
containedIn: mockContainedIn,
|
|
58
|
+
includeReference: mockIncludeReference,
|
|
59
|
+
toJSON: jest.fn(() => ({
|
|
60
|
+
find: mockPromiseResult
|
|
61
|
+
}))
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
mockContainedIn.mockImplementation(() => mockQuery);
|
|
65
|
+
mockIncludeReference.mockImplementation(() => mockQuery);
|
|
66
|
+
mockStack.mockImplementation(() => ({
|
|
67
|
+
ContentType: (contentType) => ({
|
|
68
|
+
Query: () => mockQuery,
|
|
69
|
+
fetch: () => mockFetch(contentType)
|
|
57
70
|
})
|
|
58
71
|
}));
|
|
59
72
|
|
|
73
|
+
mockFetch.mockImplementation((contentType) => {
|
|
74
|
+
const schemas = {
|
|
75
|
+
shipping_address_form: {
|
|
76
|
+
content_type: {
|
|
77
|
+
schema: [
|
|
78
|
+
{
|
|
79
|
+
uid: 'countries',
|
|
80
|
+
data_type: 'reference',
|
|
81
|
+
reference_to: 'market'
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
uid: 'details',
|
|
85
|
+
data_type: 'group',
|
|
86
|
+
schema: [
|
|
87
|
+
{
|
|
88
|
+
uid: 'address_form',
|
|
89
|
+
data_type: 'reference',
|
|
90
|
+
reference_to: 'address_form'
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
uid: 'promo_blocks',
|
|
96
|
+
data_type: 'blocks',
|
|
97
|
+
blocks: [
|
|
98
|
+
{
|
|
99
|
+
uid: 'hero',
|
|
100
|
+
schema: [
|
|
101
|
+
{
|
|
102
|
+
uid: 'banner',
|
|
103
|
+
data_type: 'reference',
|
|
104
|
+
reference_to: 'banner'
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
address_form: {
|
|
114
|
+
content_type: {
|
|
115
|
+
schema: [
|
|
116
|
+
{
|
|
117
|
+
uid: 'address_elements',
|
|
118
|
+
data_type: 'reference',
|
|
119
|
+
reference_to: 'address_form_field'
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
market: {
|
|
125
|
+
content_type: {
|
|
126
|
+
schema: []
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
banner: {
|
|
130
|
+
content_type: {
|
|
131
|
+
schema: []
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
address_form_field: {
|
|
135
|
+
content_type: {
|
|
136
|
+
schema: [
|
|
137
|
+
{
|
|
138
|
+
uid: 'field_config',
|
|
139
|
+
data_type: 'reference',
|
|
140
|
+
reference_to: 'field_config'
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
field_config: {
|
|
146
|
+
content_type: {
|
|
147
|
+
schema: [
|
|
148
|
+
{
|
|
149
|
+
uid: 'validation_rule',
|
|
150
|
+
data_type: 'reference',
|
|
151
|
+
reference_to: 'validation_rule'
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
validation_rule: {
|
|
157
|
+
content_type: {
|
|
158
|
+
schema: [
|
|
159
|
+
{
|
|
160
|
+
uid: 'too_deep_reference',
|
|
161
|
+
data_type: 'reference',
|
|
162
|
+
reference_to: 'too_deep_reference'
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
too_deep_reference: {
|
|
168
|
+
content_type: {
|
|
169
|
+
schema: [
|
|
170
|
+
{
|
|
171
|
+
uid: 'should_not_be_included',
|
|
172
|
+
data_type: 'reference',
|
|
173
|
+
reference_to: 'market'
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
return Promise.resolve(schemas[contentType] || {content_type: {schema: []}});
|
|
181
|
+
});
|
|
182
|
+
|
|
60
183
|
jest.mock("contentstack", () => ({Stack: mockStack}));
|
|
61
184
|
});
|
|
62
185
|
|
|
63
186
|
afterEach(() => {
|
|
64
187
|
mockSinglePromiseResult.mockReset();
|
|
65
188
|
mockPromiseResult.mockReset();
|
|
189
|
+
mockContainedIn.mockReset();
|
|
190
|
+
mockIncludeReference.mockReset();
|
|
191
|
+
mockFetch.mockReset();
|
|
66
192
|
//jest.resetAllMocks(); don't reset the mockStack function
|
|
67
193
|
});
|
|
68
194
|
|
|
@@ -71,7 +197,7 @@ const mockResults = () => {
|
|
|
71
197
|
mockPromiseResult.mockResolvedValueOnce(checkoutAdrStrings);
|
|
72
198
|
mockSinglePromiseResult.mockResolvedValueOnce(singleCheckoutAdrStrings);
|
|
73
199
|
mockSinglePromiseResult.mockResolvedValueOnce(singleCheckoutCartStrings);
|
|
74
|
-
}
|
|
200
|
+
};
|
|
75
201
|
|
|
76
202
|
describe("ContentstackApi", () => {
|
|
77
203
|
test("getSingletonEntries", async () => {
|
|
@@ -133,8 +259,95 @@ describe("ContentstackApi", () => {
|
|
|
133
259
|
global.window = Object.create(window);
|
|
134
260
|
global.window.location = { hostname };
|
|
135
261
|
const {getStack} = require('../src/api');
|
|
136
|
-
getStack(
|
|
262
|
+
getStack();
|
|
137
263
|
expect(mockStack).toHaveBeenCalledWith({api_key: csCfg.apiKey, delivery_token: csCfg.deliveryToken, environment: csCfg.environment});
|
|
138
|
-
})
|
|
139
|
-
})
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
test('getSingletonEntries maps language code in to id', async () => {
|
|
268
|
+
mockSinglePromiseResult.mockResolvedValueOnce(singleCheckoutAdrStrings);
|
|
269
|
+
const {getStack} = require('../src/api');
|
|
270
|
+
const Stack = getStack('dev');
|
|
271
|
+
await Stack.getSingletonEntries({contentTypeUIDs: ['checkout_adr_strings'], language: 'in'});
|
|
272
|
+
expect(mockSinglePromiseResult).toHaveBeenCalled();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test('getMultiEntries does not include references when includeRefs is false', async () => {
|
|
276
|
+
mockPromiseResult.mockResolvedValueOnce([[{title: 'United States'}]]);
|
|
277
|
+
const {getStack} = require('../src/api');
|
|
278
|
+
const Stack = getStack('dev');
|
|
279
|
+
await Stack.getMultiEntries('market', false, ['United States']);
|
|
280
|
+
expect(mockContainedIn).toHaveBeenCalledWith('title', ['United States']);
|
|
281
|
+
expect(mockIncludeReference).not.toHaveBeenCalled();
|
|
282
|
+
expect(mockFetch).not.toHaveBeenCalled();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
test('getMultiEntries includes explicit reference paths', async () => {
|
|
286
|
+
mockPromiseResult.mockResolvedValueOnce([[{title: 'United States'}]]);
|
|
287
|
+
const {getStack} = require('../src/api');
|
|
288
|
+
const Stack = getStack('dev');
|
|
289
|
+
await Stack.getMultiEntries('market', ['countries', 'address_form.address_elements'], ['United States']);
|
|
290
|
+
expect(mockIncludeReference).toHaveBeenCalledWith(['countries', 'address_form.address_elements']);
|
|
291
|
+
expect(mockFetch).not.toHaveBeenCalled();
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
test('getMultiEntries discovers reference paths from schema when includeRefs is true', async () => {
|
|
295
|
+
mockPromiseResult.mockResolvedValueOnce([[{title: 'United States'}]]);
|
|
296
|
+
const {getStack} = require('../src/api');
|
|
297
|
+
const Stack = getStack('dev');
|
|
298
|
+
await Stack.getMultiEntries('shipping_address_form', true, ['United States']);
|
|
299
|
+
expect(mockFetch).toHaveBeenCalledTimes(6);
|
|
300
|
+
expect(mockIncludeReference).toHaveBeenCalledWith([
|
|
301
|
+
'countries',
|
|
302
|
+
'details.address_form',
|
|
303
|
+
'details.address_form.address_elements',
|
|
304
|
+
'details.address_form.address_elements.field_config',
|
|
305
|
+
'details.address_form.address_elements.field_config.validation_rule',
|
|
306
|
+
'promo_blocks.hero.banner'
|
|
307
|
+
]);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test('getMultiEntries caches discovered reference paths per content type', async () => {
|
|
311
|
+
mockPromiseResult.mockResolvedValue([[{title: 'United States'}]]);
|
|
312
|
+
const {getStack} = require('../src/api');
|
|
313
|
+
const Stack = getStack('test');
|
|
314
|
+
await Stack.getMultiEntries('shipping_address_form', true, ['United States']);
|
|
315
|
+
await Stack.getMultiEntries('shipping_address_form', true, ['Canada']);
|
|
316
|
+
expect(mockFetch).toHaveBeenCalledTimes(6);
|
|
317
|
+
expect(mockIncludeReference).toHaveBeenNthCalledWith(1, [
|
|
318
|
+
'countries',
|
|
319
|
+
'details.address_form',
|
|
320
|
+
'details.address_form.address_elements',
|
|
321
|
+
'details.address_form.address_elements.field_config',
|
|
322
|
+
'details.address_form.address_elements.field_config.validation_rule',
|
|
323
|
+
'promo_blocks.hero.banner'
|
|
324
|
+
]);
|
|
325
|
+
expect(mockIncludeReference).toHaveBeenNthCalledWith(2, [
|
|
326
|
+
'countries',
|
|
327
|
+
'details.address_form',
|
|
328
|
+
'details.address_form.address_elements',
|
|
329
|
+
'details.address_form.address_elements.field_config',
|
|
330
|
+
'details.address_form.address_elements.field_config.validation_rule',
|
|
331
|
+
'promo_blocks.hero.banner'
|
|
332
|
+
]);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test('getMultiEntries limits automatic reference traversal to four levels deep', async () => {
|
|
336
|
+
mockPromiseResult.mockResolvedValueOnce([[{title: 'United States'}]]);
|
|
337
|
+
const {getStack} = require('../src/api');
|
|
338
|
+
const Stack = getStack('stage');
|
|
339
|
+
await Stack.getMultiEntries('shipping_address_form', true, ['United States']);
|
|
340
|
+
expect(mockIncludeReference).toHaveBeenCalledWith([
|
|
341
|
+
'countries',
|
|
342
|
+
'details.address_form',
|
|
343
|
+
'details.address_form.address_elements',
|
|
344
|
+
'details.address_form.address_elements.field_config',
|
|
345
|
+
'details.address_form.address_elements.field_config.validation_rule',
|
|
346
|
+
'promo_blocks.hero.banner'
|
|
347
|
+
]);
|
|
348
|
+
expect(mockIncludeReference).not.toHaveBeenCalledWith(expect.arrayContaining([
|
|
349
|
+
'details.address_form.address_elements.field_config.validation_rule.too_deep_reference',
|
|
350
|
+
'details.address_form.address_elements.field_config.validation_rule.too_deep_reference.should_not_be_included'
|
|
351
|
+
]));
|
|
352
|
+
});
|
|
140
353
|
});
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
## [2.0.2-pa-1190.1](https://code.tls.nuskin.io/ns-am/utility/npm/contentstack-lib/compare/v2.0.1...v2.0.2-pa-1190.1) (2026-06-02)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuskin/contentstack-lib",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2-pa-1190.1",
|
|
4
4
|
"description": "This project contains configuration and api code to access Contentstack, to be shared between the backend (AWS Lambda) and frontend (Vue, etc).",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"license": "ISC",
|
|
20
20
|
"homepage": "https://code.tls.nuskin.io/ns-am/utility/npm/contentstack-lib/blob/master/README.md",
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"eslint": "
|
|
22
|
+
"eslint": "7.32.0",
|
|
23
23
|
"eslint-config-google": "0.14.0",
|
|
24
24
|
"eslint-config-prettier": "4.1.0",
|
|
25
25
|
"eslint-plugin-json": "2.1.1",
|
package/src/api.js
CHANGED
|
@@ -8,6 +8,9 @@ const {contentstack: prodEnvConfig} = require(`../config/prod.json`);
|
|
|
8
8
|
|
|
9
9
|
let env = null;
|
|
10
10
|
let Stack = null;
|
|
11
|
+
const referenceFieldCache = new Map();
|
|
12
|
+
const contentTypeSchemaCache = new Map();
|
|
13
|
+
const MAX_REFERENCE_DEPTH = 4;
|
|
11
14
|
|
|
12
15
|
const COMMON_LANGUAGES = {
|
|
13
16
|
'da': 'da-dk',
|
|
@@ -173,10 +176,146 @@ async function getSingletonEntries(options) {
|
|
|
173
176
|
}
|
|
174
177
|
}
|
|
175
178
|
|
|
179
|
+
async function _getContentTypeSchema(contentType) {
|
|
180
|
+
if (contentTypeSchemaCache.has(contentType)) {
|
|
181
|
+
return contentTypeSchemaCache.get(contentType);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const contentTypeSchema = await Stack.ContentType(contentType).fetch();
|
|
185
|
+
const schema = contentTypeSchema.content_type.schema || [];
|
|
186
|
+
contentTypeSchemaCache.set(contentType, schema);
|
|
187
|
+
return schema;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async function _collectReferenceFieldPathsForSchema(schema = [], parentPath = '', visited = new Set(), depth = 0) {
|
|
191
|
+
const allPaths = [];
|
|
192
|
+
|
|
193
|
+
for (const field of schema) {
|
|
194
|
+
const currentPath = parentPath ? `${parentPath}.${field.uid}` : field.uid;
|
|
195
|
+
|
|
196
|
+
if (Array.isArray(field.schema)) {
|
|
197
|
+
const nestedSchemaPaths = await _collectReferenceFieldPathsForSchema(field.schema, currentPath, visited, depth);
|
|
198
|
+
allPaths.push(...nestedSchemaPaths);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (field.data_type === 'blocks' && Array.isArray(field.blocks)) {
|
|
202
|
+
for (const block of field.blocks) {
|
|
203
|
+
if (Array.isArray(block.schema)) {
|
|
204
|
+
const blockPaths = await _collectReferenceFieldPathsForSchema(
|
|
205
|
+
block.schema,
|
|
206
|
+
`${currentPath}.${block.uid}`,
|
|
207
|
+
visited,
|
|
208
|
+
depth
|
|
209
|
+
);
|
|
210
|
+
allPaths.push(...blockPaths);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (field.data_type === 'reference') {
|
|
216
|
+
const currentDepth = depth + 1;
|
|
217
|
+
if (currentDepth > MAX_REFERENCE_DEPTH) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
allPaths.push(currentPath);
|
|
221
|
+
const referenceTargets = Array.isArray(field.reference_to) ?
|
|
222
|
+
field.reference_to :
|
|
223
|
+
field.reference_to ? [field.reference_to] : [];
|
|
224
|
+
|
|
225
|
+
if (currentDepth >= MAX_REFERENCE_DEPTH) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for (const referencedContentType of referenceTargets) {
|
|
230
|
+
const nestedReferencePaths = await _collectReferenceFieldPathsForContentType(
|
|
231
|
+
referencedContentType,
|
|
232
|
+
currentPath,
|
|
233
|
+
visited,
|
|
234
|
+
currentDepth
|
|
235
|
+
);
|
|
236
|
+
allPaths.push(...nestedReferencePaths);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return [...new Set(allPaths)];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function _collectReferenceFieldPathsForContentType(contentType, parentPath = '', visited = new Set(), depth = 0) {
|
|
245
|
+
const visitKey = `${contentType}|${parentPath}|${depth}`;
|
|
246
|
+
if (visited.has(visitKey)) {
|
|
247
|
+
return [];
|
|
248
|
+
}
|
|
249
|
+
visited.add(visitKey);
|
|
250
|
+
|
|
251
|
+
const schema = await _getContentTypeSchema(contentType);
|
|
252
|
+
return _collectReferenceFieldPathsForSchema(schema, parentPath, visited, depth);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Resolve reference include paths from a boolean, string, or array input.
|
|
257
|
+
* @param {string} contentType
|
|
258
|
+
* @param {boolean|string|string[]} includeRefs
|
|
259
|
+
* @return {Promise<string[]>}
|
|
260
|
+
* @private
|
|
261
|
+
*/
|
|
262
|
+
async function _resolveIncludeRefs(contentType, includeRefs) {
|
|
263
|
+
if (!includeRefs) {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (typeof includeRefs === 'string') {
|
|
268
|
+
return [includeRefs];
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (Array.isArray(includeRefs)) {
|
|
272
|
+
return includeRefs;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (includeRefs !== true) {
|
|
276
|
+
return [];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (referenceFieldCache.has(contentType)) {
|
|
280
|
+
return referenceFieldCache.get(contentType);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const referenceFields = await _collectReferenceFieldPathsForContentType(contentType);
|
|
284
|
+
referenceFieldCache.set(contentType, referenceFields);
|
|
285
|
+
return referenceFields;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Gets all the specified entries for a multiple content type
|
|
290
|
+
* @param {string} contentType
|
|
291
|
+
* @param {string[]} values
|
|
292
|
+
* @return {Promise<{Object}>} config
|
|
293
|
+
*/
|
|
294
|
+
const getMultiEntries = async (contentType, includeRefs, values) => {
|
|
295
|
+
try {
|
|
296
|
+
const resolvedIncludeRefs = await _resolveIncludeRefs(contentType, includeRefs);
|
|
297
|
+
|
|
298
|
+
let query = Stack
|
|
299
|
+
.ContentType(contentType)
|
|
300
|
+
.Query()
|
|
301
|
+
.containedIn('title', values);
|
|
302
|
+
|
|
303
|
+
if (resolvedIncludeRefs.length) {
|
|
304
|
+
query = query.includeReference(resolvedIncludeRefs);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const [results] = await query.toJSON().find();
|
|
308
|
+
|
|
309
|
+
return results;
|
|
310
|
+
} catch(err) {
|
|
311
|
+
console.error(err);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
176
315
|
/**
|
|
177
316
|
* Returns contentstack Stack object initialized with the api key, deliveryToken, and extended with custom functionality
|
|
178
317
|
* @param {'dev' | 'test' | 'stage' | 'prod'} envrnmnt
|
|
179
|
-
* @return {Object} Stack - contentstack Stack sdk object with additional
|
|
318
|
+
* @return {Object} Stack - contentstack Stack sdk object with additional helper functions
|
|
180
319
|
*/
|
|
181
320
|
function getStack(envrnmnt) {
|
|
182
321
|
if (!envrnmnt) {
|
|
@@ -192,11 +331,14 @@ function getStack(envrnmnt) {
|
|
|
192
331
|
}
|
|
193
332
|
|
|
194
333
|
env = envrnmnt;
|
|
195
|
-
|
|
196
|
-
|
|
334
|
+
referenceFieldCache.clear();
|
|
335
|
+
contentTypeSchemaCache.clear();
|
|
336
|
+
const {apiKey: api_key, deliveryToken: delivery_token, environment} = getConfig(env);
|
|
337
|
+
Stack = Contentstack.Stack({api_key, delivery_token, environment});
|
|
197
338
|
|
|
198
339
|
// extend the Stack with a custom function to get translations
|
|
199
340
|
Stack.getSingletonEntries = getSingletonEntries;
|
|
341
|
+
Stack.getMultiEntries = getMultiEntries;
|
|
200
342
|
|
|
201
343
|
return Stack;
|
|
202
344
|
}
|