@webiny/api-headless-cms-ddb 0.0.0-mt-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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -0
  3. package/definitions/entry.d.ts +8 -0
  4. package/definitions/entry.js +97 -0
  5. package/definitions/group.d.ts +8 -0
  6. package/definitions/group.js +74 -0
  7. package/definitions/model.d.ts +8 -0
  8. package/definitions/model.js +96 -0
  9. package/definitions/settings.d.ts +8 -0
  10. package/definitions/settings.js +62 -0
  11. package/definitions/system.d.ts +8 -0
  12. package/definitions/system.js +50 -0
  13. package/definitions/table.d.ts +8 -0
  14. package/definitions/table.js +30 -0
  15. package/dynamoDb/index.d.ts +2 -0
  16. package/dynamoDb/index.js +24 -0
  17. package/dynamoDb/path/plainObject.d.ts +3 -0
  18. package/dynamoDb/path/plainObject.js +33 -0
  19. package/dynamoDb/path/ref.d.ts +3 -0
  20. package/dynamoDb/path/ref.js +27 -0
  21. package/dynamoDb/storage/date.d.ts +3 -0
  22. package/dynamoDb/storage/date.js +65 -0
  23. package/dynamoDb/storage/longText.d.ts +7 -0
  24. package/dynamoDb/storage/longText.js +83 -0
  25. package/dynamoDb/storage/richText.d.ts +8 -0
  26. package/dynamoDb/storage/richText.js +110 -0
  27. package/dynamoDb/transformValue/datetime.d.ts +3 -0
  28. package/dynamoDb/transformValue/datetime.js +47 -0
  29. package/index.d.ts +2 -0
  30. package/index.js +125 -0
  31. package/operations/entry/dataLoaders.d.ts +38 -0
  32. package/operations/entry/dataLoaders.js +303 -0
  33. package/operations/entry/index.d.ts +8 -0
  34. package/operations/entry/index.js +823 -0
  35. package/operations/entry/keys.d.ts +25 -0
  36. package/operations/entry/keys.js +62 -0
  37. package/operations/entry/systemFields.d.ts +2 -0
  38. package/operations/entry/systemFields.js +50 -0
  39. package/operations/entry/utils.d.ts +31 -0
  40. package/operations/entry/utils.js +406 -0
  41. package/operations/group/index.d.ts +8 -0
  42. package/operations/group/index.js +198 -0
  43. package/operations/model/index.d.ts +6 -0
  44. package/operations/model/index.js +161 -0
  45. package/operations/settings/index.d.ts +6 -0
  46. package/operations/settings/index.js +141 -0
  47. package/operations/system/index.d.ts +6 -0
  48. package/operations/system/index.js +105 -0
  49. package/package.json +61 -0
  50. package/types.d.ts +84 -0
  51. package/types.js +16 -0
@@ -0,0 +1,25 @@
1
+ interface BasePartitionKeyParams {
2
+ tenant: string;
3
+ locale: string;
4
+ }
5
+ export interface PartitionKeyParams extends BasePartitionKeyParams {
6
+ id: string;
7
+ }
8
+ export declare const createPartitionKey: (params: PartitionKeyParams) => string;
9
+ export interface SortKeyParams {
10
+ version: number;
11
+ }
12
+ export declare const createRevisionSortKey: (params: SortKeyParams) => string;
13
+ export declare const createLatestSortKey: () => string;
14
+ export declare const createPublishedSortKey: () => string;
15
+ export interface GSIPartitionKeyParams {
16
+ tenant: string;
17
+ locale: string;
18
+ modelId: string;
19
+ }
20
+ export declare const createGSIPartitionKey: (params: GSIPartitionKeyParams, type: "A" | "L" | "P") => string;
21
+ export interface GSISortKeyParams {
22
+ id: string;
23
+ }
24
+ export declare const createGSISortKey: (params: GSISortKeyParams) => string;
25
+ export {};
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createRevisionSortKey = exports.createPublishedSortKey = exports.createPartitionKey = exports.createLatestSortKey = exports.createGSISortKey = exports.createGSIPartitionKey = void 0;
7
+
8
+ var _utils = require("@webiny/utils");
9
+
10
+ const createBasePartitionKey = params => {
11
+ const {
12
+ tenant,
13
+ locale
14
+ } = params;
15
+ return `T#${tenant}#L#${locale}#CMS#CME`;
16
+ };
17
+
18
+ const createPartitionKey = params => {
19
+ const {
20
+ id: initialId
21
+ } = params;
22
+ const {
23
+ id
24
+ } = (0, _utils.parseIdentifier)(initialId);
25
+ return `${createBasePartitionKey(params)}#CME#${id}`;
26
+ };
27
+
28
+ exports.createPartitionKey = createPartitionKey;
29
+
30
+ const createRevisionSortKey = params => {
31
+ return `REV#${(0, _utils.zeroPad)(params.version)}`;
32
+ };
33
+
34
+ exports.createRevisionSortKey = createRevisionSortKey;
35
+
36
+ const createLatestSortKey = () => {
37
+ return "L";
38
+ };
39
+
40
+ exports.createLatestSortKey = createLatestSortKey;
41
+
42
+ const createPublishedSortKey = () => {
43
+ return "P";
44
+ };
45
+
46
+ exports.createPublishedSortKey = createPublishedSortKey;
47
+
48
+ const createGSIPartitionKey = (params, type) => {
49
+ const {
50
+ modelId
51
+ } = params;
52
+ const partitionKey = createBasePartitionKey(params);
53
+ return `${partitionKey}#M#${modelId}#${type}`;
54
+ };
55
+
56
+ exports.createGSIPartitionKey = createGSIPartitionKey;
57
+
58
+ const createGSISortKey = params => {
59
+ return params.id;
60
+ };
61
+
62
+ exports.createGSISortKey = createGSISortKey;
@@ -0,0 +1,2 @@
1
+ import { CmsModelField } from "@webiny/api-headless-cms/types";
2
+ export declare const systemFields: Record<string, CmsModelField>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.systemFields = void 0;
7
+
8
+ const createSystemField = field => {
9
+ return field;
10
+ };
11
+
12
+ const systemFields = {
13
+ id: createSystemField({
14
+ id: "id",
15
+ type: "text",
16
+ fieldId: "id"
17
+ }),
18
+ entryId: createSystemField({
19
+ id: "entryId",
20
+ type: "text",
21
+ fieldId: "entryId"
22
+ }),
23
+ createdOn: createSystemField({
24
+ id: "createdOn",
25
+ type: "datetime",
26
+ fieldId: "createdOn"
27
+ }),
28
+ savedOn: createSystemField({
29
+ id: "savedOn",
30
+ type: "datetime",
31
+ fieldId: "savedOn"
32
+ }),
33
+ createdBy: createSystemField({
34
+ id: "createdBy",
35
+ type: "plainObject",
36
+ fieldId: "createdBy",
37
+ settings: {
38
+ path: "createdBy.id"
39
+ }
40
+ }),
41
+ ownedBy: createSystemField({
42
+ id: "ownedBy",
43
+ type: "plainObject",
44
+ fieldId: "ownedBy",
45
+ settings: {
46
+ path: "ownedBy.id"
47
+ }
48
+ })
49
+ };
50
+ exports.systemFields = systemFields;
@@ -0,0 +1,31 @@
1
+ import { CmsEntry, CmsEntryListWhere, CmsModel, CmsModelField } from "@webiny/api-headless-cms/types";
2
+ import { PluginsContainer } from "@webiny/plugins";
3
+ interface ModelField {
4
+ def: CmsModelField;
5
+ valueTransformer: (value: any) => any;
6
+ valuePath: string;
7
+ isSystemField?: boolean;
8
+ }
9
+ declare type ModelFieldRecords = Record<string, ModelField>;
10
+ export interface FilterItemFromStorage {
11
+ (field: CmsModelField, value: any): Promise<any>;
12
+ }
13
+ interface FilterItemsParams {
14
+ items: CmsEntry[];
15
+ where: CmsEntryListWhere;
16
+ plugins: PluginsContainer;
17
+ fields: ModelFieldRecords;
18
+ fromStorage: FilterItemFromStorage;
19
+ }
20
+ export declare const filterItems: (params: FilterItemsParams) => Promise<CmsEntry[]>;
21
+ interface SortEntryItemsArgs {
22
+ items: CmsEntry[];
23
+ sort: string[];
24
+ fields: ModelFieldRecords;
25
+ }
26
+ export declare const sortEntryItems: (params: SortEntryItemsArgs) => CmsEntry[];
27
+ export declare const buildModelFields: ({ plugins, model }: {
28
+ plugins: PluginsContainer;
29
+ model: CmsModel;
30
+ }) => Record<string, ModelField>;
31
+ export {};
@@ -0,0 +1,406 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.sortEntryItems = exports.filterItems = exports.buildModelFields = void 0;
9
+
10
+ var _error = _interopRequireDefault(require("@webiny/error"));
11
+
12
+ var _lodash = _interopRequireDefault(require("lodash.sortby"));
13
+
14
+ var _dotProp = _interopRequireDefault(require("dot-prop"));
15
+
16
+ var _systemFields = require("./systemFields");
17
+
18
+ var _ValueFilterPlugin = require("@webiny/db-dynamodb/plugins/definitions/ValueFilterPlugin");
19
+
20
+ const VALUES_ATTRIBUTE = "values";
21
+
22
+ const extractWhereParams = key => {
23
+ const result = key.split("_");
24
+ const fieldId = result.shift();
25
+ const rawOp = result.length === 0 ? "eq" : result.join("_");
26
+ /**
27
+ * When rawOp is not, it means it is equal negated so just return that.
28
+ */
29
+
30
+ if (rawOp === "not") {
31
+ return {
32
+ fieldId,
33
+ operation: "eq",
34
+ negate: true
35
+ };
36
+ }
37
+
38
+ const negate = rawOp.match("not_") !== null;
39
+ const operation = rawOp.replace("not_", "");
40
+ return {
41
+ fieldId,
42
+ operation,
43
+ negate
44
+ };
45
+ };
46
+
47
+ const transformValue = (value, transform) => {
48
+ if (Array.isArray(value)) {
49
+ return value.map(v => transform(v));
50
+ }
51
+
52
+ return transform(value);
53
+ };
54
+
55
+ const createFilters = params => {
56
+ const {
57
+ where,
58
+ plugins,
59
+ fields
60
+ } = params;
61
+ const filterPlugins = getMappedPlugins({
62
+ plugins,
63
+ type: _ValueFilterPlugin.ValueFilterPlugin.type,
64
+ property: "operation"
65
+ });
66
+ const transformValuePlugins = getMappedPlugins({
67
+ plugins,
68
+ type: "cms-field-filter-value-transform",
69
+ property: "fieldType"
70
+ });
71
+ const valuePathPlugins = getMappedPlugins({
72
+ plugins,
73
+ type: "cms-field-filter-path",
74
+ property: "fieldType"
75
+ });
76
+ return Object.keys(where).map(key => {
77
+ const {
78
+ fieldId,
79
+ operation,
80
+ negate
81
+ } = extractWhereParams(key);
82
+ const field = fields[fieldId];
83
+
84
+ if (!field) {
85
+ throw new _error.default(`There is no field with the fieldId "${fieldId}".`, "FIELD_ERROR", {
86
+ fieldId
87
+ });
88
+ }
89
+
90
+ const transformValuePlugin = transformValuePlugins[field.def.type];
91
+ const valuePathPlugin = valuePathPlugins[field.def.type];
92
+ let targetValuePath;
93
+ /**
94
+ * add the base path if field is not a system field
95
+ * pathPlugin should not know about that
96
+ */
97
+
98
+ const basePath = _systemFields.systemFields[fieldId] ? "" : `${VALUES_ATTRIBUTE}.`;
99
+
100
+ if (valuePathPlugin) {
101
+ targetValuePath = valuePathPlugin.createPath({
102
+ field: field.def
103
+ });
104
+ } else if (_systemFields.systemFields[fieldId]) {
105
+ targetValuePath = fieldId;
106
+ } else {
107
+ targetValuePath = field.def.fieldId;
108
+ }
109
+
110
+ const valuePath = `${basePath}${targetValuePath}`;
111
+ const filterPlugin = filterPlugins[operation];
112
+
113
+ if (!filterPlugin) {
114
+ throw new _error.default(`There is no filter plugin for operation "${operation}".`, "FILTER_PLUGIN_ERROR", {
115
+ operation
116
+ });
117
+ }
118
+
119
+ const transformValueCallable = value => {
120
+ if (!transformValuePlugin) {
121
+ return value;
122
+ }
123
+
124
+ return transformValuePlugin.transform({
125
+ field: field.def,
126
+ value
127
+ });
128
+ };
129
+
130
+ return {
131
+ fieldId,
132
+ path: valuePath,
133
+ filterPlugin,
134
+ negate,
135
+ compareValue: transformValue(where[key], transformValueCallable),
136
+ transformValue: transformValueCallable
137
+ };
138
+ });
139
+ };
140
+
141
+ const filterItems = async params => {
142
+ const {
143
+ items,
144
+ where,
145
+ plugins,
146
+ fields,
147
+ fromStorage
148
+ } = params;
149
+ const filters = createFilters({
150
+ plugins,
151
+ where,
152
+ fields
153
+ });
154
+ const results = [];
155
+
156
+ for (const key in items) {
157
+ if (items.hasOwnProperty(key) === false) {
158
+ continue;
159
+ }
160
+
161
+ const item = items[key];
162
+ let passed = true;
163
+
164
+ for (const filter of filters) {
165
+ const rawValue = _dotProp.default.get(item, filter.path);
166
+
167
+ const plainValue = await fromStorage(fields[filter.fieldId].def, rawValue);
168
+ /**
169
+ * If raw value is not same as the value after the storage transform, set the value to the items being filtered.
170
+ */
171
+
172
+ if (plainValue !== rawValue) {
173
+ items[key] = _dotProp.default.set(item, filter.path, plainValue);
174
+ }
175
+
176
+ const value = transformValue(plainValue, filter.transformValue);
177
+ const matched = filter.filterPlugin.matches({
178
+ value,
179
+ compareValue: filter.compareValue
180
+ });
181
+
182
+ if ((filter.negate ? !matched : matched) === false) {
183
+ passed = false;
184
+ break;
185
+ }
186
+ }
187
+
188
+ if (!passed) {
189
+ continue;
190
+ }
191
+
192
+ results.push(item);
193
+ }
194
+
195
+ return results; // return items.filter(item => {
196
+ // for (const filter of filters) {
197
+ // const plainValue = await fromStorage(
198
+ // fields[filter.fieldId].def,
199
+ // dotProp.get(item, filter.path)
200
+ // );
201
+ //
202
+ // const value = transformValue(plainValue, filter.transformValue);
203
+ // const matched = filter.filterPlugin.matches({
204
+ // value,
205
+ // compareValue: filter.compareValue
206
+ // });
207
+ // if ((filter.negate ? !matched : matched) === false) {
208
+ // return false;
209
+ // }
210
+ // }
211
+ // return true;
212
+ // });
213
+ };
214
+
215
+ exports.filterItems = filterItems;
216
+
217
+ const extractSort = (sortBy, fields) => {
218
+ const result = sortBy.split("_");
219
+
220
+ if (result.length !== 2) {
221
+ throw new _error.default("Problem in determining the sorting for the entry items.", "SORT_ERROR", {
222
+ sortBy
223
+ });
224
+ }
225
+
226
+ const [fieldId, order] = result;
227
+ const modelField = fields[fieldId];
228
+
229
+ if (!modelField) {
230
+ throw new _error.default("Sorting field does not exist in the content model.", "SORTING_FIELD_ERROR", {
231
+ fieldId,
232
+ fields
233
+ });
234
+ }
235
+
236
+ const valuePath = modelField.valuePath;
237
+ return {
238
+ fieldId,
239
+ valuePath,
240
+ reverse: order === "DESC"
241
+ };
242
+ };
243
+
244
+ const sortEntryItems = params => {
245
+ const {
246
+ items,
247
+ sort = [],
248
+ fields
249
+ } = params;
250
+
251
+ if (items.length <= 1) {
252
+ return items;
253
+ } else if (sort.length === 0) {
254
+ sort.push("savedOn_DESC");
255
+ } else if (sort.length > 1) {
256
+ throw new _error.default("Sorting is limited to a single field.", "SORT_ERROR", {
257
+ sort: sort
258
+ });
259
+ }
260
+
261
+ const [firstSort] = sort;
262
+
263
+ if (!firstSort) {
264
+ throw new _error.default("Empty sort array item.", "SORT_ERROR", {
265
+ sort
266
+ });
267
+ }
268
+
269
+ const {
270
+ fieldId,
271
+ valuePath,
272
+ reverse
273
+ } = extractSort(firstSort, fields);
274
+ const field = fields[fieldId];
275
+ const itemsToSort = items.map(item => {
276
+ return {
277
+ id: item.id,
278
+ value: field.valueTransformer(_dotProp.default.get(item, valuePath))
279
+ };
280
+ });
281
+ const sortedItems = (0, _lodash.default)(itemsToSort, "value");
282
+ const newItems = sortedItems.map(s => {
283
+ const item = items.find(i => i.id === s.id);
284
+
285
+ if (item) {
286
+ return item;
287
+ }
288
+
289
+ throw new _error.default("Could not find item by given id after the sorting.", "SORTING_ITEMS_ERROR", {
290
+ id: s.id,
291
+ sortingBy: fieldId,
292
+ reverse
293
+ });
294
+ });
295
+
296
+ if (!reverse) {
297
+ return newItems;
298
+ }
299
+
300
+ return newItems.reverse();
301
+ };
302
+
303
+ exports.sortEntryItems = sortEntryItems;
304
+
305
+ const getMappedPlugins = params => {
306
+ const {
307
+ plugins: pluginsContainer,
308
+ type,
309
+ property
310
+ } = params;
311
+ const plugins = pluginsContainer.byType(type);
312
+
313
+ if (plugins.length === 0) {
314
+ throw new _error.default(`There are no plugins of type "${type}".`, "PLUGINS_ERROR", {
315
+ type
316
+ });
317
+ }
318
+
319
+ return plugins.reduce((collection, plugin) => {
320
+ const key = plugin[property];
321
+
322
+ if (typeof key !== "string") {
323
+ throw new _error.default("Property to map the plugins on must be a string.", "PLUGIN_PROPERTY_ERROR", {
324
+ type,
325
+ property
326
+ });
327
+ }
328
+
329
+ collection[key] = plugin;
330
+ return collection;
331
+ }, {});
332
+ };
333
+
334
+ const buildModelFields = ({
335
+ plugins,
336
+ model
337
+ }) => {
338
+ const transformValuePlugins = getMappedPlugins({
339
+ plugins,
340
+ type: "cms-field-filter-value-transform",
341
+ property: "fieldType"
342
+ });
343
+ const valuePathPlugins = getMappedPlugins({
344
+ plugins,
345
+ type: "cms-field-filter-path",
346
+ property: "fieldType"
347
+ });
348
+ const fields = Object.values(_systemFields.systemFields).reduce((collection, field) => {
349
+ const transformValuePlugin = transformValuePlugins[field.type];
350
+ const valuePathPlugin = valuePathPlugins[field.type];
351
+ let valuePath;
352
+
353
+ if (valuePathPlugin) {
354
+ valuePath = valuePathPlugin.createPath({
355
+ field
356
+ });
357
+ }
358
+
359
+ collection[field.fieldId] = {
360
+ def: field,
361
+ valueTransformer: value => {
362
+ if (!transformValuePlugin) {
363
+ return value;
364
+ }
365
+
366
+ return transformValuePlugin.transform({
367
+ field,
368
+ value
369
+ });
370
+ },
371
+ valuePath: valuePath || field.fieldId,
372
+ isSystemField: true
373
+ };
374
+ return collection;
375
+ }, {});
376
+ return model.fields.reduce((collection, field) => {
377
+ const transformValuePlugin = transformValuePlugins[field.type];
378
+ const valuePathPlugin = valuePathPlugins[field.type];
379
+ let valuePath;
380
+
381
+ if (valuePathPlugin) {
382
+ valuePath = valuePathPlugin.createPath({
383
+ field
384
+ });
385
+ }
386
+
387
+ const targetValuePath = `${VALUES_ATTRIBUTE}.${valuePath || field.fieldId}`;
388
+ collection[field.fieldId] = {
389
+ def: field,
390
+ valueTransformer: value => {
391
+ if (!transformValuePlugin) {
392
+ return value;
393
+ }
394
+
395
+ return transformValuePlugin.transform({
396
+ field,
397
+ value
398
+ });
399
+ },
400
+ valuePath: targetValuePath || field.fieldId
401
+ };
402
+ return collection;
403
+ }, fields);
404
+ };
405
+
406
+ exports.buildModelFields = buildModelFields;
@@ -0,0 +1,8 @@
1
+ import { CmsGroupStorageOperations } from "@webiny/api-headless-cms/types";
2
+ import { Entity } from "dynamodb-toolbox";
3
+ import { PluginsContainer } from "@webiny/plugins";
4
+ export interface Params {
5
+ entity: Entity<any>;
6
+ plugins: PluginsContainer;
7
+ }
8
+ export declare const createGroupsStorageOperations: (params: Params) => CmsGroupStorageOperations;