@stackbit/cms-core 0.1.3-alpha.2 → 0.1.3
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/content-source-interface.d.ts +14 -9
- package/dist/content-source-interface.d.ts.map +1 -1
- package/dist/content-source-interface.js.map +1 -1
- package/dist/content-store-types.d.ts +24 -25
- package/dist/content-store-types.d.ts.map +1 -1
- package/dist/content-store.d.ts +4 -17
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +949 -147
- package/dist/content-store.js.map +1 -1
- package/dist/encoder.d.ts.map +1 -1
- package/dist/encoder.js +5 -1
- package/dist/encoder.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/package.json +5 -6
- package/src/content-source-interface.ts +15 -6
- package/src/content-store-types.ts +10 -23
- package/src/content-store.ts +1079 -137
- package/src/encoder.ts +6 -2
- package/src/index.ts +1 -3
- package/dist/content-store-utils.d.ts +0 -9
- package/dist/content-store-utils.d.ts.map +0 -1
- package/dist/content-store-utils.js +0 -139
- package/dist/content-store-utils.js.map +0 -1
- package/dist/types/search-filter.d.ts +0 -42
- package/dist/types/search-filter.d.ts.map +0 -1
- package/dist/types/search-filter.js +0 -3
- package/dist/types/search-filter.js.map +0 -1
- package/dist/utils/create-update-csi-docs.d.ts +0 -68
- package/dist/utils/create-update-csi-docs.d.ts.map +0 -1
- package/dist/utils/create-update-csi-docs.js +0 -376
- package/dist/utils/create-update-csi-docs.js.map +0 -1
- package/dist/utils/csi-to-store-docs-converter.d.ts +0 -15
- package/dist/utils/csi-to-store-docs-converter.d.ts.map +0 -1
- package/dist/utils/csi-to-store-docs-converter.js +0 -287
- package/dist/utils/csi-to-store-docs-converter.js.map +0 -1
- package/dist/utils/search-utils.d.ts +0 -21
- package/dist/utils/search-utils.d.ts.map +0 -1
- package/dist/utils/search-utils.js +0 -323
- package/dist/utils/search-utils.js.map +0 -1
- package/dist/utils/store-to-api-docs-converter.d.ts +0 -5
- package/dist/utils/store-to-api-docs-converter.d.ts.map +0 -1
- package/dist/utils/store-to-api-docs-converter.js +0 -247
- package/dist/utils/store-to-api-docs-converter.js.map +0 -1
- package/src/content-store-utils.ts +0 -149
- package/src/types/search-filter.ts +0 -53
- package/src/utils/create-update-csi-docs.ts +0 -440
- package/src/utils/csi-to-store-docs-converter.ts +0 -365
- package/src/utils/search-utils.ts +0 -436
- package/src/utils/store-to-api-docs-converter.ts +0 -246
|
@@ -1,440 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import slugify from 'slugify';
|
|
3
|
-
|
|
4
|
-
import { Field, FieldObjectProps, FieldSpecificProps, Model } from '@stackbit/sdk';
|
|
5
|
-
import { mapPromise } from '@stackbit/utils';
|
|
6
|
-
|
|
7
|
-
import * as CSITypes from '../content-source-interface';
|
|
8
|
-
import * as ContentStoreTypes from '../content-store-types';
|
|
9
|
-
|
|
10
|
-
export type CreateDocumentCallback = ({
|
|
11
|
-
updateOperationFields,
|
|
12
|
-
modelName
|
|
13
|
-
}: {
|
|
14
|
-
updateOperationFields: Record<string, CSITypes.UpdateOperationField>;
|
|
15
|
-
modelName: string;
|
|
16
|
-
}) => Promise<CSITypes.Document>;
|
|
17
|
-
|
|
18
|
-
export function getCreateDocumentThunk({
|
|
19
|
-
csiModelMap,
|
|
20
|
-
locale,
|
|
21
|
-
userContext,
|
|
22
|
-
contentSourceInstance
|
|
23
|
-
}: {
|
|
24
|
-
csiModelMap: Record<string, Model>;
|
|
25
|
-
locale?: string;
|
|
26
|
-
userContext: unknown;
|
|
27
|
-
contentSourceInstance: CSITypes.ContentSourceInterface;
|
|
28
|
-
}): CreateDocumentCallback {
|
|
29
|
-
return async ({ updateOperationFields, modelName }) => {
|
|
30
|
-
// When passing model and modelMap to contentSourceInstance, we have to pass
|
|
31
|
-
// the original models (i.e., csiModel and csiModelMap) that we've received
|
|
32
|
-
// from that contentSourceInstance. We can't pass internal models as they
|
|
33
|
-
// might
|
|
34
|
-
const csiModel = csiModelMap[modelName];
|
|
35
|
-
if (!csiModel) {
|
|
36
|
-
throw new Error(`no model with name '${modelName}' was found`);
|
|
37
|
-
}
|
|
38
|
-
return await contentSourceInstance.createDocument({
|
|
39
|
-
updateOperationFields: updateOperationFields,
|
|
40
|
-
model: csiModel,
|
|
41
|
-
modelMap: csiModelMap,
|
|
42
|
-
locale,
|
|
43
|
-
userContext
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Receives a plain `object`, and creates a map of `CSITypes.UpdateOperationField`
|
|
50
|
-
* by recursively iterating the `object` fields. Then invokes the `createDocument`
|
|
51
|
-
* callback to delegate the creation if CSI document.
|
|
52
|
-
*
|
|
53
|
-
* If the `object` has fields of type `reference` or `model` with the special
|
|
54
|
-
* `$$type` property holding the model name of the nested object, this function
|
|
55
|
-
* will recursively create new documents and nested objects for these fields.
|
|
56
|
-
* Other fields of will be used to populate the fields of the new document or
|
|
57
|
-
* nested object.
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* {
|
|
61
|
-
* title: 'hello world',
|
|
62
|
-
* button: {
|
|
63
|
-
* $$type: 'Button', // a new nested object of type Button will be
|
|
64
|
-
* label: 'Click me' // created with 'label' field set to 'Click me'
|
|
65
|
-
* }
|
|
66
|
-
* }
|
|
67
|
-
*
|
|
68
|
-
* If the `object` has fields of type `reference` or `image` with the special
|
|
69
|
-
* `$$ref` property holding an ID of an existing document, this function will
|
|
70
|
-
* link an existing documents or assets with that ID.
|
|
71
|
-
*
|
|
72
|
-
* @example
|
|
73
|
-
* {
|
|
74
|
-
* title: 'hello world',
|
|
75
|
-
* author: {
|
|
76
|
-
* $$ref: 'xyz' // the 'author' field will be linked to a document
|
|
77
|
-
* // with ID 'xyz'
|
|
78
|
-
* }
|
|
79
|
-
* }
|
|
80
|
-
*
|
|
81
|
-
* Returns an object with two fields:
|
|
82
|
-
* 1. `document` holding the created CSITypes.Document for the passed object.
|
|
83
|
-
* 2. `newRefDocuments` holding list of created CSITypes.Document that were
|
|
84
|
-
* created recursively for `reference` fields having the `$$type` property.
|
|
85
|
-
*/
|
|
86
|
-
export async function createDocumentRecursively({
|
|
87
|
-
object,
|
|
88
|
-
modelName,
|
|
89
|
-
modelMap,
|
|
90
|
-
createDocument
|
|
91
|
-
}: {
|
|
92
|
-
object?: Record<string, any>;
|
|
93
|
-
modelName: string;
|
|
94
|
-
modelMap: Record<string, Model>;
|
|
95
|
-
createDocument: CreateDocumentCallback;
|
|
96
|
-
}): Promise<{ document: CSITypes.Document; newRefDocuments: CSITypes.Document[] }> {
|
|
97
|
-
const model = modelMap[modelName];
|
|
98
|
-
if (!model) {
|
|
99
|
-
throw new Error(`no model with name '${modelName}' was found`);
|
|
100
|
-
}
|
|
101
|
-
if (model.type === 'page') {
|
|
102
|
-
const tokens = extractTokensFromString(String(model.urlPath));
|
|
103
|
-
const slugField = _.last(tokens);
|
|
104
|
-
if (object && slugField && slugField in object) {
|
|
105
|
-
const slugFieldValue = object[slugField];
|
|
106
|
-
object[slugField] = sanitizeSlug(slugFieldValue);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const nestedResult = await createNestedObjectRecursively({
|
|
111
|
-
object,
|
|
112
|
-
modelFields: model.fields ?? [],
|
|
113
|
-
fieldPath: [],
|
|
114
|
-
modelMap,
|
|
115
|
-
createDocument
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
const document = await createDocument({
|
|
119
|
-
updateOperationFields: nestedResult.fields,
|
|
120
|
-
modelName: modelName
|
|
121
|
-
});
|
|
122
|
-
return {
|
|
123
|
-
document: document,
|
|
124
|
-
newRefDocuments: nestedResult.newRefDocuments
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function extractTokensFromString(input: string): string[] {
|
|
129
|
-
return input.match(/(?<={)[^}]+(?=})/g) || [];
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function sanitizeSlug(slug: string) {
|
|
133
|
-
return slug
|
|
134
|
-
.split('/')
|
|
135
|
-
.map((part) => slugify(part, { lower: true }))
|
|
136
|
-
.join('/');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async function createNestedObjectRecursively({
|
|
140
|
-
object,
|
|
141
|
-
modelFields,
|
|
142
|
-
fieldPath,
|
|
143
|
-
modelMap,
|
|
144
|
-
createDocument
|
|
145
|
-
}: {
|
|
146
|
-
object?: Record<string, any>;
|
|
147
|
-
modelFields: Field[];
|
|
148
|
-
fieldPath: (string | number)[];
|
|
149
|
-
modelMap: Record<string, Model>;
|
|
150
|
-
createDocument: CreateDocumentCallback;
|
|
151
|
-
}): Promise<{
|
|
152
|
-
fields: Record<string, CSITypes.UpdateOperationField>;
|
|
153
|
-
newRefDocuments: CSITypes.Document[];
|
|
154
|
-
}> {
|
|
155
|
-
object = object ?? {};
|
|
156
|
-
const result: {
|
|
157
|
-
fields: Record<string, CSITypes.UpdateOperationField>;
|
|
158
|
-
newRefDocuments: CSITypes.Document[];
|
|
159
|
-
} = {
|
|
160
|
-
fields: {},
|
|
161
|
-
newRefDocuments: []
|
|
162
|
-
};
|
|
163
|
-
const objectFieldNames = Object.keys(object);
|
|
164
|
-
for (const modelField of modelFields) {
|
|
165
|
-
const fieldName = modelField.name;
|
|
166
|
-
let value;
|
|
167
|
-
if (fieldName in object) {
|
|
168
|
-
value = object[fieldName];
|
|
169
|
-
_.pull(objectFieldNames, fieldName);
|
|
170
|
-
} else if (modelField.const) {
|
|
171
|
-
value = modelField.const;
|
|
172
|
-
} else if (!_.isNil(modelField.default)) {
|
|
173
|
-
value = modelField.default;
|
|
174
|
-
}
|
|
175
|
-
if (!_.isNil(value)) {
|
|
176
|
-
const fieldResult = await createNestedField({
|
|
177
|
-
value,
|
|
178
|
-
modelField,
|
|
179
|
-
fieldPath: fieldPath.concat(fieldName),
|
|
180
|
-
modelMap,
|
|
181
|
-
createDocument
|
|
182
|
-
});
|
|
183
|
-
result.fields[fieldName] = fieldResult.field;
|
|
184
|
-
result.newRefDocuments = result.newRefDocuments.concat(fieldResult.newRefDocuments);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
if (objectFieldNames.length > 0) {
|
|
188
|
-
throw new Error(`no model fields found when creating a document with fields: '${objectFieldNames.join(', ')}'`);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return result;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
async function createNestedField({
|
|
195
|
-
value,
|
|
196
|
-
modelField,
|
|
197
|
-
fieldPath,
|
|
198
|
-
modelMap,
|
|
199
|
-
createDocument
|
|
200
|
-
}: {
|
|
201
|
-
value: any;
|
|
202
|
-
modelField: FieldSpecificProps;
|
|
203
|
-
fieldPath: (string | number)[];
|
|
204
|
-
modelMap: Record<string, Model>;
|
|
205
|
-
createDocument: CreateDocumentCallback;
|
|
206
|
-
}): Promise<{ field: CSITypes.UpdateOperationField; newRefDocuments: CSITypes.Document[] }> {
|
|
207
|
-
if (modelField.type === 'object') {
|
|
208
|
-
const result = await createNestedObjectRecursively({
|
|
209
|
-
object: value,
|
|
210
|
-
modelFields: modelField.fields,
|
|
211
|
-
fieldPath,
|
|
212
|
-
modelMap,
|
|
213
|
-
createDocument
|
|
214
|
-
});
|
|
215
|
-
return {
|
|
216
|
-
field: {
|
|
217
|
-
type: 'object',
|
|
218
|
-
fields: result.fields
|
|
219
|
-
},
|
|
220
|
-
newRefDocuments: result.newRefDocuments
|
|
221
|
-
};
|
|
222
|
-
} else if (modelField.type === 'model') {
|
|
223
|
-
let { $$type, ...rest } = value;
|
|
224
|
-
const modelNames = modelField.models;
|
|
225
|
-
// for backward compatibility check if the object has 'type' instead of '$$type' because older projects use
|
|
226
|
-
// the 'type' property in default values
|
|
227
|
-
if (!$$type && 'type' in rest) {
|
|
228
|
-
$$type = rest.type;
|
|
229
|
-
rest = _.omit(rest, 'type');
|
|
230
|
-
}
|
|
231
|
-
const modelName = $$type ?? (modelNames.length === 1 ? modelNames[0] : null);
|
|
232
|
-
if (!modelName) {
|
|
233
|
-
throw new Error(`no $$type was specified for nested model`);
|
|
234
|
-
}
|
|
235
|
-
const model = modelMap[modelName];
|
|
236
|
-
if (!model) {
|
|
237
|
-
throw new Error(`no model with name '${modelName}' was found`);
|
|
238
|
-
}
|
|
239
|
-
const result = await createNestedObjectRecursively({
|
|
240
|
-
object: rest,
|
|
241
|
-
modelFields: model.fields ?? [],
|
|
242
|
-
fieldPath,
|
|
243
|
-
modelMap,
|
|
244
|
-
createDocument
|
|
245
|
-
});
|
|
246
|
-
return {
|
|
247
|
-
field: {
|
|
248
|
-
type: 'model',
|
|
249
|
-
modelName: modelName,
|
|
250
|
-
fields: result.fields
|
|
251
|
-
},
|
|
252
|
-
newRefDocuments: result.newRefDocuments
|
|
253
|
-
};
|
|
254
|
-
} else if (modelField.type === 'image') {
|
|
255
|
-
let refId: string | undefined;
|
|
256
|
-
if (_.isPlainObject(value)) {
|
|
257
|
-
refId = value.$$ref;
|
|
258
|
-
} else {
|
|
259
|
-
refId = value;
|
|
260
|
-
}
|
|
261
|
-
if (!refId) {
|
|
262
|
-
throw new Error(`reference field must specify a value`);
|
|
263
|
-
}
|
|
264
|
-
return {
|
|
265
|
-
field: {
|
|
266
|
-
type: 'reference',
|
|
267
|
-
refType: 'asset',
|
|
268
|
-
refId: refId
|
|
269
|
-
},
|
|
270
|
-
newRefDocuments: []
|
|
271
|
-
};
|
|
272
|
-
} else if (modelField.type === 'reference') {
|
|
273
|
-
let { $$ref: refId = null, $$type: modelName = null, ...rest } = _.isPlainObject(value) ? value : { $$ref: value };
|
|
274
|
-
if (refId) {
|
|
275
|
-
return {
|
|
276
|
-
field: {
|
|
277
|
-
type: 'reference',
|
|
278
|
-
refType: 'document',
|
|
279
|
-
refId: refId
|
|
280
|
-
},
|
|
281
|
-
newRefDocuments: []
|
|
282
|
-
};
|
|
283
|
-
} else {
|
|
284
|
-
const modelNames = modelField.models;
|
|
285
|
-
if (!modelName) {
|
|
286
|
-
// for backward compatibility check if the object has 'type' instead of '$$type' because older projects use
|
|
287
|
-
// the 'type' property in default values
|
|
288
|
-
if ('type' in rest) {
|
|
289
|
-
modelName = rest.type;
|
|
290
|
-
rest = _.omit(rest, 'type');
|
|
291
|
-
} else if (modelNames.length === 1) {
|
|
292
|
-
modelName = modelNames[0];
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
const { document, newRefDocuments } = await createDocumentRecursively({
|
|
296
|
-
object: rest,
|
|
297
|
-
modelName,
|
|
298
|
-
modelMap,
|
|
299
|
-
createDocument
|
|
300
|
-
});
|
|
301
|
-
return {
|
|
302
|
-
field: {
|
|
303
|
-
type: 'reference',
|
|
304
|
-
refType: 'document',
|
|
305
|
-
refId: document.id
|
|
306
|
-
},
|
|
307
|
-
newRefDocuments: [document, ...newRefDocuments]
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
} else if (modelField.type === 'list') {
|
|
311
|
-
if (!Array.isArray(value)) {
|
|
312
|
-
throw new Error(`value for list field must be array`);
|
|
313
|
-
}
|
|
314
|
-
const itemsField = modelField.items;
|
|
315
|
-
if (!itemsField) {
|
|
316
|
-
throw new Error(`list field does not define items`);
|
|
317
|
-
}
|
|
318
|
-
const arrayResult = await mapPromise(value, async (item, index) => {
|
|
319
|
-
return createNestedField({
|
|
320
|
-
value: item,
|
|
321
|
-
modelField: itemsField,
|
|
322
|
-
fieldPath: fieldPath.concat(index),
|
|
323
|
-
modelMap,
|
|
324
|
-
createDocument
|
|
325
|
-
});
|
|
326
|
-
});
|
|
327
|
-
return {
|
|
328
|
-
field: {
|
|
329
|
-
type: 'list',
|
|
330
|
-
items: arrayResult.map((result) => result.field)
|
|
331
|
-
},
|
|
332
|
-
newRefDocuments: arrayResult.reduce((result: CSITypes.Document[], { newRefDocuments }) => result.concat(newRefDocuments), [])
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
return {
|
|
336
|
-
field: {
|
|
337
|
-
type: modelField.type,
|
|
338
|
-
value: value
|
|
339
|
-
},
|
|
340
|
-
newRefDocuments: []
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
export async function convertOperationField({
|
|
345
|
-
operationField,
|
|
346
|
-
fieldPath,
|
|
347
|
-
modelField,
|
|
348
|
-
modelMap,
|
|
349
|
-
createDocument
|
|
350
|
-
}: {
|
|
351
|
-
operationField: ContentStoreTypes.UpdateOperationField;
|
|
352
|
-
fieldPath: (string | number)[];
|
|
353
|
-
modelField: Field;
|
|
354
|
-
modelMap: Record<string, Model>;
|
|
355
|
-
createDocument: CreateDocumentCallback;
|
|
356
|
-
}): Promise<CSITypes.UpdateOperationField> {
|
|
357
|
-
// for insert operations, the modelField will be of the list, so get the modelField of the list items
|
|
358
|
-
const modelFieldOrListItems: FieldSpecificProps = modelField.type === 'list' ? modelField.items! : modelField;
|
|
359
|
-
switch (operationField.type) {
|
|
360
|
-
case 'object': {
|
|
361
|
-
const result = await createNestedObjectRecursively({
|
|
362
|
-
object: operationField.object,
|
|
363
|
-
modelFields: (modelFieldOrListItems as FieldObjectProps).fields,
|
|
364
|
-
fieldPath: fieldPath,
|
|
365
|
-
modelMap,
|
|
366
|
-
createDocument
|
|
367
|
-
});
|
|
368
|
-
return {
|
|
369
|
-
type: operationField.type,
|
|
370
|
-
fields: result.fields
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
case 'model': {
|
|
374
|
-
const model = modelMap[operationField.modelName];
|
|
375
|
-
if (!model) {
|
|
376
|
-
throw new Error(`error updating document, could not find document model: '${operationField.modelName}'`);
|
|
377
|
-
}
|
|
378
|
-
const result = await createNestedObjectRecursively({
|
|
379
|
-
object: operationField.object,
|
|
380
|
-
modelFields: model.fields!,
|
|
381
|
-
fieldPath,
|
|
382
|
-
modelMap,
|
|
383
|
-
createDocument
|
|
384
|
-
});
|
|
385
|
-
return {
|
|
386
|
-
type: operationField.type,
|
|
387
|
-
modelName: operationField.modelName,
|
|
388
|
-
fields: result.fields
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
case 'list': {
|
|
392
|
-
if (modelField.type !== 'list') {
|
|
393
|
-
throw new Error(`'the operation field type '${operationField.type}' does not match the model field type '${modelField.type}'`);
|
|
394
|
-
}
|
|
395
|
-
const result = await mapPromise(operationField.items, async (item) => {
|
|
396
|
-
const result = await createNestedField({
|
|
397
|
-
value: item,
|
|
398
|
-
modelField: modelField.items!,
|
|
399
|
-
fieldPath,
|
|
400
|
-
modelMap,
|
|
401
|
-
createDocument
|
|
402
|
-
});
|
|
403
|
-
return result.field;
|
|
404
|
-
});
|
|
405
|
-
return {
|
|
406
|
-
type: operationField.type,
|
|
407
|
-
items: result
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
case 'string':
|
|
411
|
-
// When inserting new string value into a list, the client does not
|
|
412
|
-
// send value. Set an empty string value.
|
|
413
|
-
if (typeof operationField.value !== 'string') {
|
|
414
|
-
return {
|
|
415
|
-
type: operationField.type,
|
|
416
|
-
value: ''
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
return operationField as CSITypes.UpdateOperationField;
|
|
420
|
-
case 'enum':
|
|
421
|
-
// When inserting new enum value into a list, the client does not
|
|
422
|
-
// send value. Set first option as the value.
|
|
423
|
-
if (typeof operationField.value !== 'string') {
|
|
424
|
-
if (modelFieldOrListItems.type !== 'enum') {
|
|
425
|
-
throw new Error(`'the operation field type 'enum' does not match the model field type '${modelFieldOrListItems.type}'`);
|
|
426
|
-
}
|
|
427
|
-
const option = modelFieldOrListItems.options[0]!;
|
|
428
|
-
const optionValue = typeof option === 'object' ? option.value : option;
|
|
429
|
-
return {
|
|
430
|
-
type: operationField.type,
|
|
431
|
-
value: optionValue
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
return operationField as CSITypes.UpdateOperationField;
|
|
435
|
-
case 'image':
|
|
436
|
-
return operationField as CSITypes.UpdateOperationField;
|
|
437
|
-
default:
|
|
438
|
-
return operationField as CSITypes.UpdateOperationField;
|
|
439
|
-
}
|
|
440
|
-
}
|