@webiny/api-headless-cms 5.19.0-beta.1 → 5.19.0-beta.5
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/content/plugins/crud/contentEntry/referenceFieldsMapping.d.ts +1 -0
- package/content/plugins/crud/contentEntry/referenceFieldsMapping.js +58 -19
- package/content/plugins/crud/contentEntry.crud.js +84 -3
- package/content/plugins/crud/contentModel/beforeDelete.js +2 -1
- package/content/plugins/schema/createManageResolvers.js +5 -0
- package/content/plugins/schema/createManageSDL.js +2 -0
- package/content/plugins/schema/resolvers/manage/resolveRepublish.d.ts +2 -0
- package/content/plugins/schema/resolvers/manage/resolveRepublish.js +21 -0
- package/package.json +23 -23
- package/plugins/crud/system.crud.js +24 -7
- package/types.d.ts +5 -0
|
@@ -7,6 +7,7 @@ interface Params {
|
|
|
7
7
|
context: CmsContext;
|
|
8
8
|
model: CmsModel;
|
|
9
9
|
input: Record<string, ReferenceObject | ReferenceObject[]>;
|
|
10
|
+
validateEntries?: boolean;
|
|
10
11
|
}
|
|
11
12
|
export declare const referenceFieldsMapping: (params: Params) => Promise<Record<string, any>>;
|
|
12
13
|
export {};
|
|
@@ -13,6 +13,8 @@ var _error = _interopRequireDefault(require("@webiny/error"));
|
|
|
13
13
|
|
|
14
14
|
var _dotProp = _interopRequireDefault(require("dot-prop"));
|
|
15
15
|
|
|
16
|
+
var _utils = require("@webiny/utils");
|
|
17
|
+
|
|
16
18
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
17
19
|
|
|
18
20
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
@@ -116,11 +118,26 @@ const buildReferenceFieldPaths = params => {
|
|
|
116
118
|
}, []);
|
|
117
119
|
};
|
|
118
120
|
|
|
121
|
+
const getReferenceFieldValue = ref => {
|
|
122
|
+
if (!ref) {
|
|
123
|
+
return {
|
|
124
|
+
id: null,
|
|
125
|
+
modelId: null
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
id: (ref.id || ref.entryId || "").trim() || null,
|
|
131
|
+
modelId: (ref.modelId || "").trim() || null
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
|
|
119
135
|
const referenceFieldsMapping = async params => {
|
|
120
136
|
const {
|
|
121
137
|
context,
|
|
122
138
|
model,
|
|
123
|
-
input
|
|
139
|
+
input,
|
|
140
|
+
validateEntries = false
|
|
124
141
|
} = params;
|
|
125
142
|
|
|
126
143
|
let output = _objectSpread({}, input);
|
|
@@ -141,21 +158,26 @@ const referenceFieldsMapping = async params => {
|
|
|
141
158
|
for (const path of referenceFieldPaths) {
|
|
142
159
|
const ref = _dotProp.default.get(output, path);
|
|
143
160
|
|
|
144
|
-
|
|
161
|
+
const {
|
|
162
|
+
id,
|
|
163
|
+
modelId
|
|
164
|
+
} = getReferenceFieldValue(ref);
|
|
165
|
+
|
|
166
|
+
if (!id || !modelId) {
|
|
145
167
|
continue;
|
|
146
168
|
}
|
|
147
169
|
|
|
148
|
-
if (!referencesByModel[
|
|
149
|
-
referencesByModel[
|
|
170
|
+
if (!referencesByModel[modelId]) {
|
|
171
|
+
referencesByModel[modelId] = [];
|
|
150
172
|
}
|
|
151
173
|
|
|
152
|
-
referencesByModel[
|
|
174
|
+
referencesByModel[modelId].push(id);
|
|
153
175
|
|
|
154
|
-
if (!pathsByReferenceId[
|
|
155
|
-
pathsByReferenceId[
|
|
176
|
+
if (!pathsByReferenceId[id]) {
|
|
177
|
+
pathsByReferenceId[id] = [];
|
|
156
178
|
}
|
|
157
179
|
|
|
158
|
-
pathsByReferenceId[
|
|
180
|
+
pathsByReferenceId[id].push(path);
|
|
159
181
|
}
|
|
160
182
|
/**
|
|
161
183
|
* Again, no point in going further.
|
|
@@ -197,7 +219,11 @@ const referenceFieldsMapping = async params => {
|
|
|
197
219
|
const results = await Promise.all(promises);
|
|
198
220
|
const records = results.reduce((collection, entries) => {
|
|
199
221
|
for (const entry of entries) {
|
|
200
|
-
collection[entry.id] =
|
|
222
|
+
collection[entry.id] = {
|
|
223
|
+
id: entry.id,
|
|
224
|
+
entryId: entry.entryId,
|
|
225
|
+
modelId: entry.modelId
|
|
226
|
+
};
|
|
201
227
|
}
|
|
202
228
|
|
|
203
229
|
return collection;
|
|
@@ -209,15 +235,24 @@ const referenceFieldsMapping = async params => {
|
|
|
209
235
|
for (const modelId in referencesByModel) {
|
|
210
236
|
const entries = referencesByModel[modelId];
|
|
211
237
|
|
|
212
|
-
for (const
|
|
213
|
-
if (records[
|
|
238
|
+
for (const id of entries) {
|
|
239
|
+
if (records[id]) {
|
|
214
240
|
continue;
|
|
241
|
+
} else if (validateEntries === true) {
|
|
242
|
+
throw new _error.default(`Missing referenced entry with id "${id}" in model "${modelId}".`, "ENTRY_NOT_FOUND", {
|
|
243
|
+
id,
|
|
244
|
+
model: modelId
|
|
245
|
+
});
|
|
215
246
|
}
|
|
216
247
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
248
|
+
const {
|
|
249
|
+
id: entryId
|
|
250
|
+
} = (0, _utils.parseIdentifier)(id);
|
|
251
|
+
records[id] = {
|
|
252
|
+
id,
|
|
253
|
+
entryId,
|
|
254
|
+
modelId
|
|
255
|
+
};
|
|
221
256
|
}
|
|
222
257
|
}
|
|
223
258
|
/**
|
|
@@ -230,10 +265,14 @@ const referenceFieldsMapping = async params => {
|
|
|
230
265
|
const paths = pathsByReferenceId[id];
|
|
231
266
|
|
|
232
267
|
if (!entry) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
268
|
+
if (validateEntries === true) {
|
|
269
|
+
throw new _error.default("Missing entry in records.", "ENTRY_ERROR", {
|
|
270
|
+
id,
|
|
271
|
+
paths
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
continue;
|
|
237
276
|
}
|
|
238
277
|
|
|
239
278
|
for (const path of paths) {
|
|
@@ -380,7 +380,8 @@ const createContentEntryCrud = params => {
|
|
|
380
380
|
const input = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
381
381
|
context,
|
|
382
382
|
model,
|
|
383
|
-
input: initialInput
|
|
383
|
+
input: initialInput,
|
|
384
|
+
validateEntries: true
|
|
384
385
|
});
|
|
385
386
|
const identity = context.security.getIdentity();
|
|
386
387
|
const locale = context.cms.getLocale();
|
|
@@ -480,7 +481,8 @@ const createContentEntryCrud = params => {
|
|
|
480
481
|
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
481
482
|
context,
|
|
482
483
|
model,
|
|
483
|
-
input: initialValues
|
|
484
|
+
input: initialValues,
|
|
485
|
+
validateEntries: false
|
|
484
486
|
});
|
|
485
487
|
utils.checkOwnership(context, permission, originalEntry);
|
|
486
488
|
const latestEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, latestStorageEntry);
|
|
@@ -578,7 +580,8 @@ const createContentEntryCrud = params => {
|
|
|
578
580
|
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
579
581
|
context,
|
|
580
582
|
model,
|
|
581
|
-
input: initialValues
|
|
583
|
+
input: initialValues,
|
|
584
|
+
validateEntries: false
|
|
582
585
|
});
|
|
583
586
|
/**
|
|
584
587
|
* We always send the full entry to the hooks and storage operations update.
|
|
@@ -624,6 +627,84 @@ const createContentEntryCrud = params => {
|
|
|
624
627
|
});
|
|
625
628
|
}
|
|
626
629
|
},
|
|
630
|
+
republishEntry: async (model, id) => {
|
|
631
|
+
await checkEntryPermissions({
|
|
632
|
+
rwd: "w"
|
|
633
|
+
});
|
|
634
|
+
await utils.checkModelAccess(context, model);
|
|
635
|
+
/**
|
|
636
|
+
* Fetch the entry from the storage.
|
|
637
|
+
*/
|
|
638
|
+
|
|
639
|
+
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
640
|
+
id
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
if (!originalStorageEntry) {
|
|
644
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${id}" was not found!`);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
648
|
+
/**
|
|
649
|
+
* We can only process published entries.
|
|
650
|
+
*/
|
|
651
|
+
|
|
652
|
+
if (originalEntry.status !== "published") {
|
|
653
|
+
throw new _error.default("Entry with given ID is not published!", "NOT_PUBLISHED_ERROR", {
|
|
654
|
+
id,
|
|
655
|
+
original: originalEntry
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
660
|
+
context,
|
|
661
|
+
model,
|
|
662
|
+
input: originalEntry.values,
|
|
663
|
+
validateEntries: false
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
const entry = _objectSpread(_objectSpread({}, originalEntry), {}, {
|
|
667
|
+
savedOn: new Date().toISOString(),
|
|
668
|
+
webinyVersion: context.WEBINY_VERSION,
|
|
669
|
+
values
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
const storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
673
|
+
/**
|
|
674
|
+
* First we need to update existing entry.
|
|
675
|
+
*/
|
|
676
|
+
|
|
677
|
+
try {
|
|
678
|
+
await storageOperations.entries.update(model, {
|
|
679
|
+
originalEntry,
|
|
680
|
+
originalStorageEntry,
|
|
681
|
+
entry,
|
|
682
|
+
storageEntry,
|
|
683
|
+
input: {}
|
|
684
|
+
});
|
|
685
|
+
} catch (ex) {
|
|
686
|
+
throw new _error.default("Could not update existing entry with new data while re-publishing.", "REPUBLISH_UPDATE_ERROR", {
|
|
687
|
+
entry
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Then we move onto publishing it again.
|
|
692
|
+
*/
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
try {
|
|
696
|
+
return await storageOperations.entries.publish(model, {
|
|
697
|
+
originalEntry,
|
|
698
|
+
originalStorageEntry,
|
|
699
|
+
entry,
|
|
700
|
+
storageEntry
|
|
701
|
+
});
|
|
702
|
+
} catch (ex) {
|
|
703
|
+
throw new _error.default("Could not publish existing entry while re-publishing.", "REPUBLISH_PUBLISH_ERROR", {
|
|
704
|
+
entry
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
},
|
|
627
708
|
deleteEntryRevision: async (model, revisionId) => {
|
|
628
709
|
const permission = await checkEntryPermissions({
|
|
629
710
|
rwd: "d"
|
|
@@ -31,6 +31,8 @@ var _resolveDelete = require("./resolvers/manage/resolveDelete");
|
|
|
31
31
|
|
|
32
32
|
var _resolvePublish = require("./resolvers/manage/resolvePublish");
|
|
33
33
|
|
|
34
|
+
var _resolveRepublish = require("./resolvers/manage/resolveRepublish");
|
|
35
|
+
|
|
34
36
|
var _resolveUnpublish = require("./resolvers/manage/resolveUnpublish");
|
|
35
37
|
|
|
36
38
|
var _resolveCreateFrom = require("./resolvers/manage/resolveCreateFrom");
|
|
@@ -88,6 +90,9 @@ const createManageResolvers = ({
|
|
|
88
90
|
[`publish${typeName}`]: (0, _resolvePublish.resolvePublish)({
|
|
89
91
|
model
|
|
90
92
|
}),
|
|
93
|
+
[`republish${typeName}`]: (0, _resolveRepublish.resolveRepublish)({
|
|
94
|
+
model
|
|
95
|
+
}),
|
|
91
96
|
[`unpublish${typeName}`]: (0, _resolveUnpublish.resolveUnpublish)({
|
|
92
97
|
model
|
|
93
98
|
}),
|
|
@@ -139,6 +139,8 @@ const createManageSDL = ({
|
|
|
139
139
|
delete${typeName}(revision: ID!): CmsDeleteResponse
|
|
140
140
|
|
|
141
141
|
publish${typeName}(revision: ID!): ${mTypeName}Response
|
|
142
|
+
|
|
143
|
+
republish${typeName}(revision: ID!): ${mTypeName}Response
|
|
142
144
|
|
|
143
145
|
unpublish${typeName}(revision: ID!): ${mTypeName}Response
|
|
144
146
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.resolveRepublish = void 0;
|
|
7
|
+
|
|
8
|
+
var _responses = require("@webiny/handler-graphql/responses");
|
|
9
|
+
|
|
10
|
+
const resolveRepublish = ({
|
|
11
|
+
model
|
|
12
|
+
}) => async (_, args, context) => {
|
|
13
|
+
try {
|
|
14
|
+
const entry = await context.cms.republishEntry(model, args.revision);
|
|
15
|
+
return new _responses.Response(entry);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return new _responses.ErrorResponse(e);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
exports.resolveRepublish = resolveRepublish;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/api-headless-cms",
|
|
3
|
-
"version": "5.19.0-beta.
|
|
3
|
+
"version": "5.19.0-beta.5",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms:base"
|
|
@@ -21,23 +21,23 @@
|
|
|
21
21
|
"@babel/runtime": "7.16.3",
|
|
22
22
|
"@commodo/fields": "1.1.2-beta.20",
|
|
23
23
|
"@graphql-tools/schema": "7.1.5",
|
|
24
|
-
"@webiny/api-file-manager": "5.19.0-beta.
|
|
25
|
-
"@webiny/api-i18n": "5.19.0-beta.
|
|
26
|
-
"@webiny/api-i18n-content": "5.19.0-beta.
|
|
27
|
-
"@webiny/api-i18n-ddb": "5.19.0-beta.
|
|
28
|
-
"@webiny/api-security": "5.19.0-beta.
|
|
29
|
-
"@webiny/api-tenancy": "5.19.0-beta.
|
|
30
|
-
"@webiny/api-upgrade": "5.19.0-beta.
|
|
31
|
-
"@webiny/error": "5.19.0-beta.
|
|
32
|
-
"@webiny/handler": "5.19.0-beta.
|
|
33
|
-
"@webiny/handler-aws": "5.19.0-beta.
|
|
34
|
-
"@webiny/handler-db": "5.19.0-beta.
|
|
35
|
-
"@webiny/handler-graphql": "5.19.0-beta.
|
|
36
|
-
"@webiny/handler-http": "5.19.0-beta.
|
|
37
|
-
"@webiny/plugins": "5.19.0-beta.
|
|
38
|
-
"@webiny/pubsub": "5.19.0-beta.
|
|
39
|
-
"@webiny/utils": "5.19.0-beta.
|
|
40
|
-
"@webiny/validation": "5.19.0-beta.
|
|
24
|
+
"@webiny/api-file-manager": "5.19.0-beta.5",
|
|
25
|
+
"@webiny/api-i18n": "5.19.0-beta.5",
|
|
26
|
+
"@webiny/api-i18n-content": "5.19.0-beta.5",
|
|
27
|
+
"@webiny/api-i18n-ddb": "5.19.0-beta.5",
|
|
28
|
+
"@webiny/api-security": "5.19.0-beta.5",
|
|
29
|
+
"@webiny/api-tenancy": "5.19.0-beta.5",
|
|
30
|
+
"@webiny/api-upgrade": "5.19.0-beta.5",
|
|
31
|
+
"@webiny/error": "5.19.0-beta.5",
|
|
32
|
+
"@webiny/handler": "5.19.0-beta.5",
|
|
33
|
+
"@webiny/handler-aws": "5.19.0-beta.5",
|
|
34
|
+
"@webiny/handler-db": "5.19.0-beta.5",
|
|
35
|
+
"@webiny/handler-graphql": "5.19.0-beta.5",
|
|
36
|
+
"@webiny/handler-http": "5.19.0-beta.5",
|
|
37
|
+
"@webiny/plugins": "5.19.0-beta.5",
|
|
38
|
+
"@webiny/pubsub": "5.19.0-beta.5",
|
|
39
|
+
"@webiny/utils": "5.19.0-beta.5",
|
|
40
|
+
"@webiny/validation": "5.19.0-beta.5",
|
|
41
41
|
"boolean": "3.1.4",
|
|
42
42
|
"commodo-fields-object": "1.0.6",
|
|
43
43
|
"dataloader": "2.0.0",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"@babel/core": "^7.5.5",
|
|
55
55
|
"@babel/preset-env": "^7.5.5",
|
|
56
56
|
"@babel/preset-flow": "^7.0.0",
|
|
57
|
-
"@webiny/api-security-so-ddb": "^5.19.0-beta.
|
|
58
|
-
"@webiny/api-tenancy-so-ddb": "^5.19.0-beta.
|
|
59
|
-
"@webiny/cli": "^5.19.0-beta.
|
|
60
|
-
"@webiny/project-utils": "^5.19.0-beta.
|
|
57
|
+
"@webiny/api-security-so-ddb": "^5.19.0-beta.5",
|
|
58
|
+
"@webiny/api-tenancy-so-ddb": "^5.19.0-beta.5",
|
|
59
|
+
"@webiny/cli": "^5.19.0-beta.5",
|
|
60
|
+
"@webiny/project-utils": "^5.19.0-beta.5",
|
|
61
61
|
"apollo-graphql": "^0.4.1",
|
|
62
62
|
"get-yarn-workspaces": "^1.0.2",
|
|
63
63
|
"graphql": "^14.6.0",
|
|
@@ -77,5 +77,5 @@
|
|
|
77
77
|
"build": "yarn webiny run build",
|
|
78
78
|
"watch": "yarn webiny run watch"
|
|
79
79
|
},
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "839188911bbaee4a596724c729c0a78f681fa614"
|
|
81
81
|
}
|
|
@@ -162,17 +162,34 @@ const createSystemCrud = params => {
|
|
|
162
162
|
|
|
163
163
|
const upgradePlugins = context.plugins.byType("api-upgrade").filter(pl => pl.app === "headless-cms");
|
|
164
164
|
const installedAppVersion = await this.getSystemVersion();
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
165
|
+
let plugin;
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
plugin = (0, _apiUpgrade.getApplicablePlugin)({
|
|
169
|
+
deployedVersion: context.WEBINY_VERSION,
|
|
170
|
+
installedAppVersion,
|
|
171
|
+
upgradePlugins,
|
|
172
|
+
upgradeToVersion: version
|
|
173
|
+
});
|
|
174
|
+
} catch (ex) {
|
|
175
|
+
/**
|
|
176
|
+
* We just let the error disappear if is UPGRADE_NOT_AVAILABLE code
|
|
177
|
+
* and rethrow if is not.
|
|
178
|
+
* This is because we want upgrade to pass if there is no plugin available.
|
|
179
|
+
*/
|
|
180
|
+
if (ex.code !== _apiUpgrade.ErrorCode.UPGRADE_NOT_AVAILABLE) {
|
|
181
|
+
throw ex;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (plugin) {
|
|
186
|
+
await plugin.apply(context);
|
|
187
|
+
}
|
|
172
188
|
/**
|
|
173
189
|
* Store new app version.
|
|
174
190
|
*/
|
|
175
191
|
|
|
192
|
+
|
|
176
193
|
await setVersion(version);
|
|
177
194
|
return true;
|
|
178
195
|
}
|
package/types.d.ts
CHANGED
|
@@ -1525,6 +1525,11 @@ export interface CmsEntryContext {
|
|
|
1525
1525
|
* Update existing entry.
|
|
1526
1526
|
*/
|
|
1527
1527
|
updateEntry: (model: CmsModel, id: string, data?: Record<string, any>) => Promise<CmsEntry>;
|
|
1528
|
+
/**
|
|
1529
|
+
* Method that republishes entry with given identifier.
|
|
1530
|
+
* @internal
|
|
1531
|
+
*/
|
|
1532
|
+
republishEntry: (model: CmsModel, id: string) => Promise<CmsEntry>;
|
|
1528
1533
|
/**
|
|
1529
1534
|
* Delete only a certain revision of the entry.
|
|
1530
1535
|
*/
|