@stackbit/cms-contentstack 0.1.1-staging.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/contentstack-api-client.d.ts +63 -0
- package/dist/contentstack-api-client.d.ts.map +1 -0
- package/dist/contentstack-api-client.js +295 -0
- package/dist/contentstack-api-client.js.map +1 -0
- package/dist/contentstack-content-poller.d.ts +46 -0
- package/dist/contentstack-content-poller.d.ts.map +1 -0
- package/dist/contentstack-content-poller.js +111 -0
- package/dist/contentstack-content-poller.js.map +1 -0
- package/dist/contentstack-content-source.d.ts +138 -0
- package/dist/contentstack-content-source.d.ts.map +1 -0
- package/dist/contentstack-content-source.js +544 -0
- package/dist/contentstack-content-source.js.map +1 -0
- package/dist/contentstack-conversion-utils.d.ts +41 -0
- package/dist/contentstack-conversion-utils.d.ts.map +1 -0
- package/dist/contentstack-conversion-utils.js +504 -0
- package/dist/contentstack-conversion-utils.js.map +1 -0
- package/dist/contentstack-entries-converter.d.ts +39 -0
- package/dist/contentstack-entries-converter.d.ts.map +1 -0
- package/dist/contentstack-entries-converter.js +333 -0
- package/dist/contentstack-entries-converter.js.map +1 -0
- package/dist/contentstack-operation-converter.d.ts +42 -0
- package/dist/contentstack-operation-converter.d.ts.map +1 -0
- package/dist/contentstack-operation-converter.js +535 -0
- package/dist/contentstack-operation-converter.js.map +1 -0
- package/dist/contentstack-schema-converter.d.ts +26 -0
- package/dist/contentstack-schema-converter.d.ts.map +1 -0
- package/dist/contentstack-schema-converter.js +379 -0
- package/dist/contentstack-schema-converter.js.map +1 -0
- package/dist/contentstack-types.d.ts +429 -0
- package/dist/contentstack-types.d.ts.map +1 -0
- package/dist/contentstack-types.js +3 -0
- package/dist/contentstack-types.js.map +1 -0
- package/dist/contentstack-utils.d.ts +31 -0
- package/dist/contentstack-utils.d.ts.map +1 -0
- package/dist/contentstack-utils.js +144 -0
- package/dist/contentstack-utils.js.map +1 -0
- package/dist/entries-converter.d.ts +10 -0
- package/dist/entries-converter.d.ts.map +1 -0
- package/dist/entries-converter.js +245 -0
- package/dist/entries-converter.js.map +1 -0
- package/dist/file-download.d.ts +2 -0
- package/dist/file-download.d.ts.map +1 -0
- package/dist/file-download.js +33 -0
- package/dist/file-download.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/schema-converter.d.ts +3 -0
- package/dist/schema-converter.d.ts.map +1 -0
- package/dist/schema-converter.js +169 -0
- package/dist/schema-converter.js.map +1 -0
- package/dist/transformation-utils.d.ts +41 -0
- package/dist/transformation-utils.d.ts.map +1 -0
- package/dist/transformation-utils.js +730 -0
- package/dist/transformation-utils.js.map +1 -0
- package/dist/types.d.ts +120 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
- package/src/contentstack-api-client.ts +330 -0
- package/src/contentstack-content-poller.ts +157 -0
- package/src/contentstack-content-source.ts +687 -0
- package/src/contentstack-entries-converter.ts +438 -0
- package/src/contentstack-operation-converter.ts +703 -0
- package/src/contentstack-schema-converter.ts +486 -0
- package/src/contentstack-types.ts +527 -0
- package/src/contentstack-utils.ts +174 -0
- package/src/index.ts +3 -0
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import * as StackbitTypes from '@stackbit/types';
|
|
3
|
+
import { getAssetUrl, getEntryUrl } from './contentstack-utils';
|
|
4
|
+
import type { Entry, Asset, Environment, User } from './contentstack-types';
|
|
5
|
+
import type { ModelWithContext } from './contentstack-schema-converter';
|
|
6
|
+
|
|
7
|
+
export type DocumentWithContext = StackbitTypes.Document<DocumentContext>;
|
|
8
|
+
export type DocumentContext = unknown;
|
|
9
|
+
export type AssetWithContext = StackbitTypes.Asset<AssetContext>;
|
|
10
|
+
export type AssetContext = unknown;
|
|
11
|
+
|
|
12
|
+
type GetModelByName = (modelName: string) => ModelWithContext | undefined;
|
|
13
|
+
|
|
14
|
+
export function convertEntries(options: {
|
|
15
|
+
entries: Entry[];
|
|
16
|
+
apiKey: string;
|
|
17
|
+
getModelByName: GetModelByName;
|
|
18
|
+
usersById: Record<string, User>;
|
|
19
|
+
publishEnvironment: Environment;
|
|
20
|
+
logger: StackbitTypes.Logger;
|
|
21
|
+
}): DocumentWithContext[] {
|
|
22
|
+
const { entries, ...rest } = options;
|
|
23
|
+
return entries.map((entry) =>
|
|
24
|
+
convertEntry({
|
|
25
|
+
entry,
|
|
26
|
+
...rest
|
|
27
|
+
})
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function convertEntry({
|
|
32
|
+
entry,
|
|
33
|
+
apiKey,
|
|
34
|
+
getModelByName,
|
|
35
|
+
usersById,
|
|
36
|
+
publishEnvironment,
|
|
37
|
+
status,
|
|
38
|
+
logger
|
|
39
|
+
}: {
|
|
40
|
+
entry: Entry;
|
|
41
|
+
apiKey: string;
|
|
42
|
+
getModelByName: GetModelByName;
|
|
43
|
+
usersById: Record<string, User>;
|
|
44
|
+
publishEnvironment: Environment;
|
|
45
|
+
status?: StackbitTypes.DocumentStatus;
|
|
46
|
+
logger: StackbitTypes.Logger;
|
|
47
|
+
}): DocumentWithContext {
|
|
48
|
+
const model = getModelByName(entry.content_type_uid);
|
|
49
|
+
if (!model) {
|
|
50
|
+
throw new Error(`error converting an entry, model '${entry.content_type_uid}' not found`);
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
type: 'document',
|
|
54
|
+
id: entry.uid,
|
|
55
|
+
manageUrl: getEntryUrl({ apiKey, entry }),
|
|
56
|
+
modelName: entry.content_type_uid,
|
|
57
|
+
status: status ?? getEntryPublishStatus(entry, publishEnvironment),
|
|
58
|
+
createdAt: entry.created_at,
|
|
59
|
+
updatedAt: entry.updated_at,
|
|
60
|
+
...getEntityCreatedAndUpdatedBy(usersById, entry),
|
|
61
|
+
locale: entry.locale,
|
|
62
|
+
context: {},
|
|
63
|
+
fields: convertFields({
|
|
64
|
+
entry,
|
|
65
|
+
modelFields: model.fields ?? [],
|
|
66
|
+
rootEntry: entry,
|
|
67
|
+
rootModel: model,
|
|
68
|
+
entryFieldPath: [],
|
|
69
|
+
modelFieldPath: [],
|
|
70
|
+
getModelByName,
|
|
71
|
+
logger
|
|
72
|
+
})
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function convertFields({
|
|
77
|
+
entry,
|
|
78
|
+
modelFields,
|
|
79
|
+
rootEntry,
|
|
80
|
+
rootModel,
|
|
81
|
+
entryFieldPath,
|
|
82
|
+
modelFieldPath,
|
|
83
|
+
getModelByName,
|
|
84
|
+
logger
|
|
85
|
+
}: {
|
|
86
|
+
entry: Record<string, unknown>;
|
|
87
|
+
modelFields: StackbitTypes.Field[];
|
|
88
|
+
rootEntry: Entry;
|
|
89
|
+
rootModel: ModelWithContext;
|
|
90
|
+
entryFieldPath: (string | number)[];
|
|
91
|
+
modelFieldPath: string[];
|
|
92
|
+
getModelByName: GetModelByName;
|
|
93
|
+
logger: StackbitTypes.Logger;
|
|
94
|
+
}): Record<string, StackbitTypes.DocumentField> {
|
|
95
|
+
const modelFieldsByName = _.keyBy(modelFields, 'name');
|
|
96
|
+
return _.entries(entry).reduce((documentFields: Record<string, StackbitTypes.DocumentField>, [fieldName, fieldValue]) => {
|
|
97
|
+
const modelField = modelFieldsByName[fieldName];
|
|
98
|
+
if (!modelField) {
|
|
99
|
+
return documentFields;
|
|
100
|
+
}
|
|
101
|
+
const documentField = convertField({
|
|
102
|
+
fieldValue: fieldValue,
|
|
103
|
+
modelField: modelField,
|
|
104
|
+
rootEntry: rootEntry,
|
|
105
|
+
rootModel: rootModel,
|
|
106
|
+
entryFieldPath: entryFieldPath.concat(fieldName),
|
|
107
|
+
modelFieldPath: modelFieldPath.concat(fieldName),
|
|
108
|
+
getModelByName,
|
|
109
|
+
logger
|
|
110
|
+
});
|
|
111
|
+
if (typeof documentField !== 'undefined') {
|
|
112
|
+
documentFields[fieldName] = documentField;
|
|
113
|
+
}
|
|
114
|
+
return documentFields;
|
|
115
|
+
}, {});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
type ConvertFieldOptions<ModelField extends StackbitTypes.Field | StackbitTypes.FieldListItems> = {
|
|
119
|
+
fieldValue: unknown;
|
|
120
|
+
modelField: ModelField;
|
|
121
|
+
rootEntry: Entry;
|
|
122
|
+
rootModel: ModelWithContext;
|
|
123
|
+
entryFieldPath: (string | number)[];
|
|
124
|
+
modelFieldPath: string[];
|
|
125
|
+
getModelByName: GetModelByName;
|
|
126
|
+
logger: StackbitTypes.Logger;
|
|
127
|
+
};
|
|
128
|
+
function convertField(options: ConvertFieldOptions<StackbitTypes.Field>): StackbitTypes.DocumentField | undefined;
|
|
129
|
+
function convertField(options: ConvertFieldOptions<StackbitTypes.FieldListItems>): StackbitTypes.DocumentListFieldItems | undefined;
|
|
130
|
+
function convertField<ModelField extends StackbitTypes.Field | StackbitTypes.FieldListItems>({
|
|
131
|
+
fieldValue,
|
|
132
|
+
modelField,
|
|
133
|
+
rootEntry,
|
|
134
|
+
rootModel,
|
|
135
|
+
entryFieldPath,
|
|
136
|
+
modelFieldPath,
|
|
137
|
+
getModelByName,
|
|
138
|
+
logger
|
|
139
|
+
}: {
|
|
140
|
+
fieldValue: unknown;
|
|
141
|
+
modelField: ModelField;
|
|
142
|
+
rootEntry: Entry;
|
|
143
|
+
rootModel: ModelWithContext;
|
|
144
|
+
entryFieldPath: (string | number)[];
|
|
145
|
+
modelFieldPath: string[];
|
|
146
|
+
getModelByName: GetModelByName;
|
|
147
|
+
logger: StackbitTypes.Logger;
|
|
148
|
+
}): StackbitTypes.DocumentField | StackbitTypes.DocumentListFieldItems | undefined {
|
|
149
|
+
if (_.isNil(fieldValue) || fieldValue === '') {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const errorPrefix = `Error occurred while converting entry '${rootEntry.uid}'.`;
|
|
154
|
+
|
|
155
|
+
switch (modelField.type) {
|
|
156
|
+
case 'string':
|
|
157
|
+
case 'url':
|
|
158
|
+
case 'slug':
|
|
159
|
+
case 'text':
|
|
160
|
+
case 'markdown':
|
|
161
|
+
case 'html':
|
|
162
|
+
case 'date':
|
|
163
|
+
case 'datetime':
|
|
164
|
+
case 'color':
|
|
165
|
+
case 'enum':
|
|
166
|
+
return {
|
|
167
|
+
type: modelField.type,
|
|
168
|
+
value: fieldValue as string
|
|
169
|
+
};
|
|
170
|
+
case 'number':
|
|
171
|
+
case 'boolean':
|
|
172
|
+
case 'json':
|
|
173
|
+
return {
|
|
174
|
+
type: modelField.type,
|
|
175
|
+
value: fieldValue as any
|
|
176
|
+
};
|
|
177
|
+
case 'richText':
|
|
178
|
+
return {
|
|
179
|
+
type: modelField.type,
|
|
180
|
+
value: fieldValue
|
|
181
|
+
};
|
|
182
|
+
case 'image':
|
|
183
|
+
if (!isObject(fieldValue) || typeof fieldValue.uid !== 'string') {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
type: 'reference',
|
|
188
|
+
refType: 'asset',
|
|
189
|
+
refId: fieldValue.uid
|
|
190
|
+
};
|
|
191
|
+
case 'file':
|
|
192
|
+
if (!isObject(fieldValue) || typeof fieldValue.uid !== 'string') {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
type: 'file',
|
|
197
|
+
value: fieldValue.uid
|
|
198
|
+
};
|
|
199
|
+
case 'reference':
|
|
200
|
+
// references fields always returned as arrays, even if they are not marked as multiple
|
|
201
|
+
if (Array.isArray(fieldValue) && fieldValue.length === 1) {
|
|
202
|
+
fieldValue = fieldValue[0];
|
|
203
|
+
}
|
|
204
|
+
if (!isObject(fieldValue) || typeof fieldValue.uid !== 'string') {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
type: 'reference',
|
|
209
|
+
refType: 'document',
|
|
210
|
+
refId: fieldValue.uid
|
|
211
|
+
};
|
|
212
|
+
case 'object': {
|
|
213
|
+
if (!isObject(fieldValue)) {
|
|
214
|
+
logger.warn(`${errorPrefix} The value of a group field at field path ${entryFieldPath.join('.')} is not an object.`);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
type: 'object',
|
|
219
|
+
fields: convertFields({
|
|
220
|
+
entry: fieldValue,
|
|
221
|
+
modelFields: modelField.fields,
|
|
222
|
+
rootEntry,
|
|
223
|
+
rootModel,
|
|
224
|
+
modelFieldPath,
|
|
225
|
+
entryFieldPath,
|
|
226
|
+
getModelByName,
|
|
227
|
+
logger
|
|
228
|
+
})
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
case 'model': {
|
|
232
|
+
const fieldPathStr = modelFieldPath.join('.');
|
|
233
|
+
const blockMap = rootModel.context?.blockMap?.[fieldPathStr];
|
|
234
|
+
if (blockMap) {
|
|
235
|
+
// this is a modular blocks field with keys mapping to inline (object) or global (model) fields
|
|
236
|
+
// mapped by context.blockMap[blockUID]
|
|
237
|
+
if (!isObject(fieldValue)) {
|
|
238
|
+
logger.warn(`${errorPrefix} The value of a modular block at field path ${entryFieldPath.join('.')} is not an object.`);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
// The fieldValue must be an object with a single property matching the block uid
|
|
242
|
+
const blockUIDs = _.keys(fieldValue);
|
|
243
|
+
const blockUID = blockUIDs[0];
|
|
244
|
+
if (blockUIDs.length !== 1 || !blockUID) {
|
|
245
|
+
logger.warn(
|
|
246
|
+
`${errorPrefix} The object wrapping a modular block at field path ${entryFieldPath.join('.')} ` +
|
|
247
|
+
`does not have a modular block uid property.`
|
|
248
|
+
);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const nestedEntry = fieldValue[blockUID];
|
|
252
|
+
if (!isObject(nestedEntry)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const modelName = blockMap.blockIdToModelName[blockUID];
|
|
256
|
+
if (!modelName) {
|
|
257
|
+
logger.warn(`${errorPrefix} Could not match model name for modular block '${blockUID}' at field path ${entryFieldPath.join('.')}.`);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const nestedModel = getModelByName(modelName);
|
|
261
|
+
if (!nestedModel) {
|
|
262
|
+
logger.warn(
|
|
263
|
+
`${errorPrefix} Could not find model named '${modelName}' for modular block '${blockUID}' at field path ${entryFieldPath.join('.')}.`
|
|
264
|
+
);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
type: 'model',
|
|
269
|
+
modelName: modelName,
|
|
270
|
+
fields: convertFields({
|
|
271
|
+
entry: nestedEntry,
|
|
272
|
+
modelFields: nestedModel.fields ?? [],
|
|
273
|
+
rootEntry,
|
|
274
|
+
rootModel: nestedModel,
|
|
275
|
+
entryFieldPath: entryFieldPath.concat(blockUID),
|
|
276
|
+
modelFieldPath: [],
|
|
277
|
+
getModelByName,
|
|
278
|
+
logger
|
|
279
|
+
})
|
|
280
|
+
};
|
|
281
|
+
} else {
|
|
282
|
+
// this is as a regular global field (model) with a single model or as a CNTSTK_LINK_MODEL
|
|
283
|
+
if (modelField.models.length !== 1) {
|
|
284
|
+
logger.warn(`${errorPrefix} The global field at field path ${entryFieldPath.join('.')} has more than one model name.`);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const modelName = modelField.models[0]!;
|
|
288
|
+
const nestedModel = getModelByName(modelName);
|
|
289
|
+
if (!nestedModel) {
|
|
290
|
+
logger.warn(`${errorPrefix} Could not find model named '${modelName}' for global field at field path ${entryFieldPath.join('.')}.`);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (!isObject(fieldValue)) {
|
|
294
|
+
logger.warn(`${errorPrefix} The value of a global field at field path ${entryFieldPath.join('.')} is not an object.`);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
type: 'model',
|
|
299
|
+
modelName: modelName,
|
|
300
|
+
fields: convertFields({
|
|
301
|
+
entry: fieldValue,
|
|
302
|
+
modelFields: nestedModel.fields ?? [],
|
|
303
|
+
rootEntry,
|
|
304
|
+
rootModel: nestedModel,
|
|
305
|
+
entryFieldPath: entryFieldPath,
|
|
306
|
+
modelFieldPath: [],
|
|
307
|
+
getModelByName,
|
|
308
|
+
logger
|
|
309
|
+
})
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
case 'list': {
|
|
314
|
+
if (!Array.isArray(fieldValue)) {
|
|
315
|
+
logger.warn(`${errorPrefix} The value of a list field at field path ${entryFieldPath.join('.')} is not an array.`);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
type: 'list',
|
|
320
|
+
items: _.reduce(
|
|
321
|
+
fieldValue,
|
|
322
|
+
(documentListFieldItems: StackbitTypes.DocumentListFieldItems[], value, index) => {
|
|
323
|
+
const documentListFieldItem = convertField({
|
|
324
|
+
fieldValue: value,
|
|
325
|
+
modelField: modelField.items,
|
|
326
|
+
rootEntry,
|
|
327
|
+
rootModel,
|
|
328
|
+
entryFieldPath: entryFieldPath.concat(index),
|
|
329
|
+
modelFieldPath,
|
|
330
|
+
getModelByName,
|
|
331
|
+
logger
|
|
332
|
+
});
|
|
333
|
+
if (!documentListFieldItem) {
|
|
334
|
+
logger.debug(
|
|
335
|
+
`${errorPrefix} One of the items of a list at field path ${entryFieldPath.join('.')} ` +
|
|
336
|
+
`could not be converted, skipping the whole list field.`
|
|
337
|
+
);
|
|
338
|
+
return documentListFieldItems;
|
|
339
|
+
}
|
|
340
|
+
return documentListFieldItems.concat(documentListFieldItem);
|
|
341
|
+
},
|
|
342
|
+
[]
|
|
343
|
+
)
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
case 'cross-reference':
|
|
347
|
+
case 'style':
|
|
348
|
+
logger.warn(`${errorPrefix} Field type ${modelField.type} at field path ${entryFieldPath.join('.')}.`);
|
|
349
|
+
return;
|
|
350
|
+
default: {
|
|
351
|
+
const _exhaustiveCheck: never = modelField;
|
|
352
|
+
return _exhaustiveCheck;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export function convertAssets(options: {
|
|
358
|
+
assets: Asset[];
|
|
359
|
+
apiKey: string;
|
|
360
|
+
usersById: Record<string, User>;
|
|
361
|
+
publishEnvironment: Environment;
|
|
362
|
+
}): AssetWithContext[] {
|
|
363
|
+
const { assets, ...rest } = options;
|
|
364
|
+
return assets.map((asset) => convertAsset({ asset, ...rest }));
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export function convertAsset({
|
|
368
|
+
asset,
|
|
369
|
+
apiKey,
|
|
370
|
+
usersById,
|
|
371
|
+
publishEnvironment
|
|
372
|
+
}: {
|
|
373
|
+
asset: Asset;
|
|
374
|
+
apiKey: string;
|
|
375
|
+
usersById: Record<string, User>;
|
|
376
|
+
publishEnvironment: Environment;
|
|
377
|
+
}): AssetWithContext {
|
|
378
|
+
return {
|
|
379
|
+
type: 'asset',
|
|
380
|
+
id: asset.uid,
|
|
381
|
+
manageUrl: getAssetUrl({ apiKey, asset }),
|
|
382
|
+
status: getAssetPublishStatus(asset, publishEnvironment),
|
|
383
|
+
createdAt: asset.created_at,
|
|
384
|
+
updatedAt: asset.updated_at,
|
|
385
|
+
...getEntityCreatedAndUpdatedBy(usersById, asset),
|
|
386
|
+
context: {},
|
|
387
|
+
fields: {
|
|
388
|
+
title: {
|
|
389
|
+
type: 'string',
|
|
390
|
+
value: asset.title ?? asset.filename ?? ''
|
|
391
|
+
},
|
|
392
|
+
file: {
|
|
393
|
+
type: 'assetFile',
|
|
394
|
+
url: asset.url!,
|
|
395
|
+
fileName: asset.filename,
|
|
396
|
+
contentType: asset.content_type,
|
|
397
|
+
size: Number(asset.file_size)
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function getEntryPublishStatus(entry: Entry, publishEnvironment: Environment): StackbitTypes.DocumentStatus {
|
|
404
|
+
// Get the publish that matches the publish environment and the entry's locale
|
|
405
|
+
const publishDetailsForEnv = _.filter(entry.publish_details, _.matchesProperty('environment', publishEnvironment.uid));
|
|
406
|
+
const publishForLocale = _.find(publishDetailsForEnv, _.matchesProperty('locale', entry.locale));
|
|
407
|
+
if (publishForLocale) {
|
|
408
|
+
return entry._version === publishForLocale.version ? 'published' : 'modified';
|
|
409
|
+
}
|
|
410
|
+
return 'added';
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function getAssetPublishStatus(asset: Asset, publishEnvironment: Environment): StackbitTypes.DocumentStatus {
|
|
414
|
+
// Get the publish that matches the publish environment and the asset's locale
|
|
415
|
+
const publishDetailsForEnv = _.filter(asset.publish_details, _.matchesProperty('environment', publishEnvironment.uid));
|
|
416
|
+
if (publishDetailsForEnv?.length === 1) {
|
|
417
|
+
const publish = publishDetailsForEnv[0]!;
|
|
418
|
+
return asset._version === publish.version ? 'published' : 'modified';
|
|
419
|
+
}
|
|
420
|
+
return 'added';
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function getEntityCreatedAndUpdatedBy(usersById: Record<string, User>, entity: Entry | Asset) {
|
|
424
|
+
const result: { createdBy?: string; updatedBy?: string[] } = {};
|
|
425
|
+
const createdBy = usersById[entity.created_by];
|
|
426
|
+
if (createdBy && createdBy.email) {
|
|
427
|
+
result.createdBy = createdBy.email;
|
|
428
|
+
}
|
|
429
|
+
const updatedBy = usersById[entity.updated_by];
|
|
430
|
+
if (updatedBy && updatedBy.email) {
|
|
431
|
+
result.updatedBy = [updatedBy.email];
|
|
432
|
+
}
|
|
433
|
+
return result;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function isObject(value: unknown): value is Record<string, unknown> {
|
|
437
|
+
return _.isPlainObject(value);
|
|
438
|
+
}
|