@webiny/api-headless-cms 5.19.1 → 5.20.0-beta.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.
@@ -276,6 +276,12 @@ const createContentEntryCrud = params => {
276
276
  id: entryId
277
277
  });
278
278
  },
279
+
280
+ /**
281
+ * TODO determine if this method is required at all.
282
+ *
283
+ * @internal
284
+ */
279
285
  getEntry: async (model, params) => {
280
286
  await checkEntryPermissions({
281
287
  rwd: "r"
@@ -300,17 +306,40 @@ const createContentEntryCrud = params => {
300
306
 
301
307
  return items[0];
302
308
  },
309
+
310
+ /**
311
+ * @description Should not be used directly. Internal use only!
312
+ *
313
+ * @internal
314
+ */
303
315
  listEntries: async (model, params) => {
304
316
  const permission = await checkEntryPermissions({
305
317
  rwd: "r"
306
318
  });
307
319
  await utils.checkModelAccess(context, model);
308
- const where = params.where || {};
320
+ const {
321
+ where
322
+ } = params;
323
+ /**
324
+ * Where must contain either latest or published keys.
325
+ * We cannot list entries without one of those
326
+ */
327
+
328
+ if (where.latest && where.published) {
329
+ throw new _error.default("Cannot list entries that are both published and latest.", "LIST_ENTRIES_ERROR", {
330
+ where
331
+ });
332
+ } else if (!where.latest && !where.published) {
333
+ throw new _error.default("Cannot list entries if we do not have latest or published defined.", "LIST_ENTRIES_ERROR", {
334
+ where
335
+ });
336
+ }
309
337
  /**
310
338
  * Possibly only get records which are owned by current user.
311
339
  * Or if searching for the owner set that value - in the case that user can see other entries than their own.
312
340
  */
313
341
 
342
+
314
343
  const ownedBy = permission.own ? getIdentity().id : where.ownedBy;
315
344
 
316
345
  const listWhere = _objectSpread(_objectSpread({}, where), {}, {
@@ -3,7 +3,12 @@ import { Topic } from "@webiny/pubsub/types";
3
3
  import { PluginsContainer } from "@webiny/plugins";
4
4
  export interface Params {
5
5
  onBeforeCreate: Topic<BeforeModelCreateTopicParams>;
6
+ onBeforeCreateFrom: Topic<BeforeModelCreateTopicParams>;
6
7
  storageOperations: HeadlessCmsStorageOperations;
7
8
  plugins: PluginsContainer;
8
9
  }
10
+ /**
11
+ * We attach both on before create and createFrom events here.
12
+ * Callables are identical.
13
+ */
9
14
  export declare const assignBeforeModelCreate: (params: Params) => void;
@@ -103,13 +103,11 @@ const getModelId = model => {
103
103
  });
104
104
  };
105
105
 
106
- const assignBeforeModelCreate = params => {
107
- const {
108
- onBeforeCreate,
109
- storageOperations,
110
- plugins
111
- } = params;
112
- onBeforeCreate.subscribe(async params => {
106
+ const createOnBeforeCb = ({
107
+ plugins,
108
+ storageOperations
109
+ }) => {
110
+ return async params => {
113
111
  const {
114
112
  model
115
113
  } = params;
@@ -140,7 +138,28 @@ const assignBeforeModelCreate = params => {
140
138
  checkModelIdEndingAllowed(modelId);
141
139
  checkModelIdUniqueness(modelIdList, modelId);
142
140
  model.modelId = modelId;
143
- });
141
+ };
142
+ };
143
+
144
+ /**
145
+ * We attach both on before create and createFrom events here.
146
+ * Callables are identical.
147
+ */
148
+ const assignBeforeModelCreate = params => {
149
+ const {
150
+ onBeforeCreate,
151
+ onBeforeCreateFrom,
152
+ storageOperations,
153
+ plugins
154
+ } = params;
155
+ onBeforeCreate.subscribe(createOnBeforeCb({
156
+ storageOperations,
157
+ plugins
158
+ }));
159
+ onBeforeCreateFrom.subscribe(createOnBeforeCb({
160
+ storageOperations,
161
+ plugins
162
+ }));
144
163
  };
145
164
 
146
165
  exports.assignBeforeModelCreate = assignBeforeModelCreate;
@@ -185,6 +185,8 @@ const createModelsCrud = params => {
185
185
 
186
186
  const onBeforeCreate = (0, _pubsub.createTopic)();
187
187
  const onAfterCreate = (0, _pubsub.createTopic)();
188
+ const onBeforeCreateFrom = (0, _pubsub.createTopic)();
189
+ const onAfterCreateFrom = (0, _pubsub.createTopic)();
188
190
  const onBeforeUpdate = (0, _pubsub.createTopic)();
189
191
  const onAfterUpdate = (0, _pubsub.createTopic)();
190
192
  const onBeforeDelete = (0, _pubsub.createTopic)();
@@ -195,6 +197,7 @@ const createModelsCrud = params => {
195
197
 
196
198
  (0, _beforeCreate.assignBeforeModelCreate)({
197
199
  onBeforeCreate,
200
+ onBeforeCreateFrom,
198
201
  plugins: context.plugins,
199
202
  storageOperations
200
203
  });
@@ -223,6 +226,8 @@ const createModelsCrud = params => {
223
226
  return {
224
227
  onBeforeModelCreate: onBeforeCreate,
225
228
  onAfterModelCreate: onAfterCreate,
229
+ onBeforeModelCreateFrom: onBeforeCreateFrom,
230
+ onAfterModelCreateFrom: onAfterCreateFrom,
226
231
  onBeforeModelUpdate: onBeforeUpdate,
227
232
  onAfterModelUpdate: onAfterUpdate,
228
233
  onBeforeModelDelete: onBeforeDelete,
@@ -334,6 +339,69 @@ const createModelsCrud = params => {
334
339
  return resultModel;
335
340
  },
336
341
 
342
+ async createModelFrom(modelId, data) {
343
+ await checkModelPermissions("w");
344
+ /**
345
+ * Get a model record; this will also perform ownership validation.
346
+ */
347
+
348
+ const original = await get(modelId);
349
+ const createdData = new _models.CreateContentModelModel().populate({
350
+ name: data.name,
351
+ modelId: data.modelId,
352
+ description: data.description || original.description,
353
+ group: data.group
354
+ });
355
+ await createdData.validate();
356
+ const input = await createdData.toJSON();
357
+ context.security.disableAuthorization();
358
+ const group = await context.cms.getGroup(input.group);
359
+ context.security.enableAuthorization();
360
+
361
+ if (!group) {
362
+ throw new _handlerGraphql.NotFoundError(`There is no group "${input.group}".`);
363
+ }
364
+
365
+ const identity = getIdentity();
366
+
367
+ const model = _objectSpread(_objectSpread({}, original), {}, {
368
+ group: {
369
+ id: group.id,
370
+ name: group.name
371
+ },
372
+ name: input.name,
373
+ modelId: input.modelId,
374
+ description: input.description,
375
+ createdBy: {
376
+ id: identity.id,
377
+ displayName: identity.displayName,
378
+ type: identity.type
379
+ },
380
+ createdOn: new Date().toISOString(),
381
+ savedOn: new Date().toISOString(),
382
+ lockedFields: [],
383
+ webinyVersion: context.WEBINY_VERSION
384
+ });
385
+
386
+ await onBeforeCreateFrom.publish({
387
+ model,
388
+ original,
389
+ input
390
+ });
391
+ const createdModel = await storageOperations.models.create({
392
+ input,
393
+ model
394
+ });
395
+ loaders.listModels.clearAll();
396
+ await updateManager(context, model);
397
+ await onAfterCreateFrom.publish({
398
+ input,
399
+ original,
400
+ model: createdModel
401
+ });
402
+ return createdModel;
403
+ },
404
+
337
405
  async updateModel(modelId, inputData) {
338
406
  await checkModelPermissions("w"); // Get a model record; this will also perform ownership validation.
339
407
 
@@ -27,6 +27,11 @@ const typeFromField = ({
27
27
  const mTypeName = (0, _createTypeName.createManageTypeName)(typeName); // `field` is an "object" field
28
28
 
29
29
  const fields = field.settings.fields;
30
+
31
+ if (!fields || fields.length === 0) {
32
+ return null;
33
+ }
34
+
30
35
  const fieldTypeName = `${mTypeName}_${(0, _upperFirst.default)(field.fieldId)}`;
31
36
  const typeFields = [];
32
37
  const nestedTypes = []; // Once the loop below starts, we'll be executing a recursive "object" type generation.
@@ -84,16 +89,22 @@ const plugin = {
84
89
  model,
85
90
  fieldTypePlugins
86
91
  }) {
87
- const {
88
- fieldType,
89
- typeDefs
90
- } = typeFromField({
92
+ const result = typeFromField({
91
93
  typeOfType: "type",
92
94
  model,
93
95
  type: "read",
94
96
  field,
95
97
  fieldTypePlugins
96
98
  });
99
+
100
+ if (!result) {
101
+ return null;
102
+ }
103
+
104
+ const {
105
+ fieldType,
106
+ typeDefs
107
+ } = result;
97
108
  return {
98
109
  fields: `${field.fieldId}: ${field.multipleValues ? `[${fieldType}!]` : fieldType}`,
99
110
  typeDefs
@@ -105,13 +116,18 @@ const plugin = {
105
116
  createFieldResolvers,
106
117
  graphQLType
107
118
  }) {
119
+ if (!field.settings.fields || field.settings.fields.length === 0) {
120
+ return false;
121
+ }
122
+
108
123
  const fieldType = `${graphQLType}_${(0, _upperFirst.default)(field.fieldId)}`;
124
+ const typeResolvers = createFieldResolvers({
125
+ graphQLType: fieldType,
126
+ fields: field.settings.fields
127
+ });
109
128
  return {
110
129
  resolver: null,
111
- typeResolvers: createFieldResolvers({
112
- graphQLType: fieldType,
113
- fields: field.settings.fields
114
- })
130
+ typeResolvers: typeResolvers || {}
115
131
  };
116
132
  }
117
133
 
@@ -122,16 +138,22 @@ const plugin = {
122
138
  field,
123
139
  fieldTypePlugins
124
140
  }) {
125
- const {
126
- fieldType,
127
- typeDefs
128
- } = typeFromField({
141
+ const result = typeFromField({
129
142
  typeOfType: "type",
130
143
  model,
131
144
  type: "manage",
132
145
  field,
133
146
  fieldTypePlugins
134
147
  });
148
+
149
+ if (!result) {
150
+ return null;
151
+ }
152
+
153
+ const {
154
+ fieldType,
155
+ typeDefs
156
+ } = result;
135
157
  return {
136
158
  fields: `${field.fieldId}: ${field.multipleValues ? `[${fieldType}!]` : fieldType}`,
137
159
  typeDefs
@@ -143,16 +165,22 @@ const plugin = {
143
165
  field,
144
166
  fieldTypePlugins
145
167
  }) {
146
- const {
147
- fieldType,
148
- typeDefs
149
- } = typeFromField({
168
+ const result = typeFromField({
150
169
  typeOfType: "input",
151
170
  model,
152
171
  type: "manage",
153
172
  field,
154
173
  fieldTypePlugins
155
174
  });
175
+
176
+ if (!result) {
177
+ return null;
178
+ }
179
+
180
+ const {
181
+ fieldType,
182
+ typeDefs
183
+ } = result;
156
184
  return {
157
185
  fields: `${field.fieldId}: ${field.multipleValues ? `[${fieldType}!]` : fieldType}`,
158
186
  typeDefs
@@ -164,13 +192,18 @@ const plugin = {
164
192
  field,
165
193
  createFieldResolvers
166
194
  }) {
195
+ if (!field.settings.fields || field.settings.fields.length === 0) {
196
+ return false;
197
+ }
198
+
167
199
  const fieldType = `${graphQLType}_${(0, _upperFirst.default)(field.fieldId)}`;
200
+ const typeResolvers = createFieldResolvers({
201
+ graphQLType: fieldType,
202
+ fields: field.settings.fields
203
+ });
168
204
  return {
169
205
  resolver: null,
170
- typeResolvers: createFieldResolvers({
171
- graphQLType: fieldType,
172
- fields: field.settings.fields
173
- })
206
+ typeResolvers: typeResolvers || {}
174
207
  };
175
208
  }
176
209
 
@@ -1,4 +1,4 @@
1
- import { CmsModelManager, CmsModel, CmsContext } from "../../../types";
1
+ import { CmsModelManager, CmsModel, CmsContext, CmsEntryListParams } from "../../../types";
2
2
  export declare class DefaultCmsModelManager implements CmsModelManager {
3
3
  private readonly _context;
4
4
  private readonly _model;
@@ -6,9 +6,8 @@ export declare class DefaultCmsModelManager implements CmsModelManager {
6
6
  create(data: any): Promise<import("../../../types").CmsEntry>;
7
7
  delete(id: string): Promise<void>;
8
8
  get(id: string): Promise<import("../../../types").CmsEntry>;
9
- list(args: any): Promise<[import("../../../types").CmsEntry[], import("../../../types").CmsEntryMeta]>;
10
- listPublished(args: any): Promise<[import("../../../types").CmsEntry[], import("../../../types").CmsEntryMeta]>;
11
- listLatest(args: any): Promise<[import("../../../types").CmsEntry[], import("../../../types").CmsEntryMeta]>;
9
+ listPublished(params: CmsEntryListParams): Promise<[import("../../../types").CmsEntry[], import("../../../types").CmsEntryMeta]>;
10
+ listLatest(params: CmsEntryListParams): Promise<[import("../../../types").CmsEntry[], import("../../../types").CmsEntryMeta]>;
12
11
  getPublishedByIds(ids: string[]): Promise<import("../../../types").CmsEntry[]>;
13
12
  getLatestByIds(ids: string[]): Promise<import("../../../types").CmsEntry[]>;
14
13
  update(id: any, data: any): Promise<import("../../../types").CmsEntry>;
@@ -39,16 +39,12 @@ class DefaultCmsModelManager {
39
39
  return this._context.cms.getEntryById(this._model, id);
40
40
  }
41
41
 
42
- async list(args) {
43
- return this._context.cms.listEntries(this._model, args);
42
+ async listPublished(params) {
43
+ return this._context.cms.listPublishedEntries(this._model, params);
44
44
  }
45
45
 
46
- async listPublished(args) {
47
- return this._context.cms.listPublishedEntries(this._model, args);
48
- }
49
-
50
- async listLatest(args) {
51
- return this._context.cms.listLatestEntries(this._model, args);
46
+ async listLatest(params) {
47
+ return this._context.cms.listLatestEntries(this._model, params);
52
48
  }
53
49
 
54
50
  async getPublishedByIds(ids) {
@@ -76,11 +76,15 @@ const plugin = context => {
76
76
  const getters = models.filter(model => modelIds.includes(model.modelId)).map(async model => {
77
77
  const latest = query === "__latest__";
78
78
  const modelManager = await context.cms.getModelManager(model.modelId);
79
+ const where = {};
80
+
81
+ if (!latest) {
82
+ where[`${model.titleFieldId}_contains`] = query;
83
+ }
84
+
79
85
  const [items] = await modelManager.listLatest({
80
86
  limit,
81
- where: latest ? undefined : {
82
- [`${model.titleFieldId}_contains`]: query
83
- }
87
+ where
84
88
  });
85
89
  return items.map(entry => ({
86
90
  id: entry.id,
@@ -50,6 +50,14 @@ const plugin = context => {
50
50
  return new _handlerGraphql.ErrorResponse(e);
51
51
  }
52
52
  },
53
+ createContentModelFrom: async (_, args, context) => {
54
+ try {
55
+ const model = await context.cms.createModelFrom(args.modelId, args.data);
56
+ return new _handlerGraphql.Response(model);
57
+ } catch (e) {
58
+ return new _handlerGraphql.ErrorResponse(e);
59
+ }
60
+ },
53
61
  updateContentModel: async (_, args, context) => {
54
62
  const {
55
63
  modelId,
@@ -120,6 +128,13 @@ const plugin = context => {
120
128
  description: String
121
129
  }
122
130
 
131
+ input CmsContentModelCreateFromInput {
132
+ name: String!
133
+ modelId: String
134
+ group: RefInput!
135
+ description: String
136
+ }
137
+
123
138
  input CmsContentModelUpdateInput {
124
139
  name: String
125
140
  group: RefInput
@@ -132,6 +147,11 @@ const plugin = context => {
132
147
  extend type Mutation {
133
148
  createContentModel(data: CmsContentModelCreateInput!): CmsContentModelResponse
134
149
 
150
+ createContentModelFrom(
151
+ modelId: ID!
152
+ data: CmsContentModelCreateFromInput!
153
+ ): CmsContentModelResponse
154
+
135
155
  updateContentModel(
136
156
  modelId: ID!
137
157
  data: CmsContentModelUpdateInput!
@@ -55,10 +55,16 @@ function createFieldResolversFactory({
55
55
  field,
56
56
  createFieldResolvers
57
57
  }) : null;
58
+ /**
59
+ * When fieldResolver is false it will completely skip adding fieldId into the resolvers.
60
+ * This is to fix the breaking of GraphQL schema.
61
+ */
58
62
 
59
- if (typeof fieldResolver === "function") {
63
+ if (fieldResolver === false) {
64
+ continue;
65
+ } else if (typeof fieldResolver === "function") {
60
66
  resolver = fieldResolver;
61
- } else if (fieldResolver !== null) {
67
+ } else if (fieldResolver) {
62
68
  resolver = fieldResolver.resolver;
63
69
  Object.assign(typeResolvers, fieldResolver.typeResolvers);
64
70
  }
@@ -54,6 +54,13 @@ const createManageResolvers = ({
54
54
  model,
55
55
  fieldTypePlugins
56
56
  }) => {
57
+ if (model.fields.length === 0) {
58
+ return {
59
+ Query: {},
60
+ Mutation: {}
61
+ };
62
+ }
63
+
57
64
  const typeName = (0, _createTypeName.createTypeName)(model.modelId);
58
65
  const mTypeName = (0, _createTypeName.createManageTypeName)(typeName);
59
66
  const createFieldResolvers = (0, _createFieldResolvers.createFieldResolversFactory)({
@@ -62,6 +69,18 @@ const createManageResolvers = ({
62
69
  model,
63
70
  fieldTypePlugins
64
71
  });
72
+ const fieldResolvers = createFieldResolvers({
73
+ graphQLType: mTypeName,
74
+ fields: model.fields,
75
+ isRoot: true,
76
+ // These are extra fields we want to apply to field resolvers of "gqlType"
77
+ extraResolvers: _objectSpread(_objectSpread({}, (0, _commonFieldResolvers.commonFieldResolvers)()), {}, {
78
+ meta(entry) {
79
+ return entry;
80
+ }
81
+
82
+ })
83
+ });
65
84
  return _objectSpread(_objectSpread({
66
85
  Query: {
67
86
  [`get${typeName}`]: (0, _resolveGet.resolveGet)({
@@ -106,18 +125,7 @@ const createManageResolvers = ({
106
125
  model
107
126
  })
108
127
  }
109
- }, createFieldResolvers({
110
- graphQLType: mTypeName,
111
- fields: model.fields,
112
- isRoot: true,
113
- // These are extra fields we want to apply to field resolvers of "gqlType"
114
- extraResolvers: _objectSpread(_objectSpread({}, (0, _commonFieldResolvers.commonFieldResolvers)()), {}, {
115
- meta(entry) {
116
- return entry;
117
- }
118
-
119
- })
120
- })), {}, {
128
+ }, fieldResolvers), {}, {
121
129
  [`${mTypeName}Meta`]: {
122
130
  title(entry) {
123
131
  return (0, _getEntryTitle.getEntryTitle)(model, entry);
@@ -47,10 +47,15 @@ const createManageSDL = ({
47
47
  type: "manage",
48
48
  fieldTypePlugins
49
49
  });
50
+
51
+ if (inputFields.length === 0) {
52
+ return "";
53
+ }
54
+
50
55
  return (
51
56
  /* GraphQL */
52
57
  `
53
- """${model.description}"""
58
+ """${model.description || model.modelId}"""
54
59
  ${fields.map(f => f.typeDefs).filter(Boolean).join("\n")}
55
60
 
56
61
  type ${mTypeName} {
@@ -28,6 +28,12 @@ const createPreviewResolvers = ({
28
28
  model,
29
29
  fieldTypePlugins
30
30
  }) => {
31
+ if (model.fields.length === 0) {
32
+ return {
33
+ Query: {}
34
+ };
35
+ }
36
+
31
37
  const typeName = (0, _createTypeName.createTypeName)(model.modelId);
32
38
  const rTypeName = (0, _createTypeName.createReadTypeName)(typeName);
33
39
  const createFieldResolvers = (0, _createFieldResolvers.createFieldResolversFactory)({
@@ -36,6 +42,11 @@ const createPreviewResolvers = ({
36
42
  model,
37
43
  fieldTypePlugins
38
44
  });
45
+ const fieldResolvers = createFieldResolvers({
46
+ graphQLType: rTypeName,
47
+ fields: model.fields,
48
+ isRoot: true
49
+ });
39
50
  return _objectSpread({
40
51
  Query: {
41
52
  [`get${typeName}`]: (0, _resolveGet.resolveGet)({
@@ -45,11 +56,7 @@ const createPreviewResolvers = ({
45
56
  model
46
57
  })
47
58
  }
48
- }, createFieldResolvers({
49
- graphQLType: rTypeName,
50
- fields: model.fields,
51
- isRoot: true
52
- }));
59
+ }, fieldResolvers);
53
60
  };
54
61
 
55
62
  exports.createPreviewResolvers = createPreviewResolvers;
@@ -28,6 +28,12 @@ const createReadResolvers = ({
28
28
  model,
29
29
  fieldTypePlugins
30
30
  }) => {
31
+ if (model.fields.length === 0) {
32
+ return {
33
+ Query: {}
34
+ };
35
+ }
36
+
31
37
  const typeName = (0, _createTypeName.createTypeName)(model.modelId);
32
38
  const rTypeName = (0, _createTypeName.createReadTypeName)(typeName);
33
39
  const createFieldResolvers = (0, _createFieldResolvers.createFieldResolversFactory)({
@@ -36,6 +42,11 @@ const createReadResolvers = ({
36
42
  model,
37
43
  fieldTypePlugins
38
44
  });
45
+ const fieldResolvers = createFieldResolvers({
46
+ graphQLType: rTypeName,
47
+ fields: model.fields,
48
+ isRoot: true
49
+ });
39
50
  return _objectSpread({
40
51
  Query: {
41
52
  [`get${typeName}`]: (0, _resolveGet.resolveGet)({
@@ -45,11 +56,7 @@ const createReadResolvers = ({
45
56
  model
46
57
  })
47
58
  }
48
- }, createFieldResolvers({
49
- graphQLType: rTypeName,
50
- fields: model.fields,
51
- isRoot: true
52
- }));
59
+ }, fieldResolvers);
53
60
  };
54
61
 
55
62
  exports.createReadResolvers = createReadResolvers;
@@ -41,6 +41,11 @@ const createReadSDL = ({
41
41
  type: "read",
42
42
  fieldTypePlugins
43
43
  });
44
+
45
+ if (fieldsRender.length === 0) {
46
+ return "";
47
+ }
48
+
44
49
  return `
45
50
  """${model.description || ""}"""
46
51
  ${fieldsRender.map(f => f.typeDefs).filter(Boolean).join("\n")}
@@ -86,7 +86,7 @@ const generateSchemaPlugins = async context => {
86
86
  return;
87
87
  }
88
88
  });
89
- return newPlugins;
89
+ return newPlugins.filter(pl => !!pl.schema.typeDefs);
90
90
  };
91
91
 
92
92
  exports.generateSchemaPlugins = generateSchemaPlugins;
@@ -39,7 +39,9 @@ const renderField = ({
39
39
  fieldTypePlugins
40
40
  });
41
41
 
42
- if (typeof defs === "string") {
42
+ if (!defs) {
43
+ return null;
44
+ } else if (typeof defs === "string") {
43
45
  return {
44
46
  fields: defs
45
47
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/api-headless-cms",
3
- "version": "5.19.1",
3
+ "version": "5.20.0-beta.0",
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.1",
25
- "@webiny/api-i18n": "5.19.1",
26
- "@webiny/api-i18n-content": "5.19.1",
27
- "@webiny/api-i18n-ddb": "5.19.1",
28
- "@webiny/api-security": "5.19.1",
29
- "@webiny/api-tenancy": "5.19.1",
30
- "@webiny/api-upgrade": "5.19.1",
31
- "@webiny/error": "5.19.1",
32
- "@webiny/handler": "5.19.1",
33
- "@webiny/handler-aws": "5.19.1",
34
- "@webiny/handler-db": "5.19.1",
35
- "@webiny/handler-graphql": "5.19.1",
36
- "@webiny/handler-http": "5.19.1",
37
- "@webiny/plugins": "5.19.1",
38
- "@webiny/pubsub": "5.19.1",
39
- "@webiny/utils": "5.19.1",
40
- "@webiny/validation": "5.19.1",
24
+ "@webiny/api-file-manager": "5.20.0-beta.0",
25
+ "@webiny/api-i18n": "5.20.0-beta.0",
26
+ "@webiny/api-i18n-content": "5.20.0-beta.0",
27
+ "@webiny/api-i18n-ddb": "5.20.0-beta.0",
28
+ "@webiny/api-security": "5.20.0-beta.0",
29
+ "@webiny/api-tenancy": "5.20.0-beta.0",
30
+ "@webiny/api-upgrade": "5.20.0-beta.0",
31
+ "@webiny/error": "5.20.0-beta.0",
32
+ "@webiny/handler": "5.20.0-beta.0",
33
+ "@webiny/handler-aws": "5.20.0-beta.0",
34
+ "@webiny/handler-db": "5.20.0-beta.0",
35
+ "@webiny/handler-graphql": "5.20.0-beta.0",
36
+ "@webiny/handler-http": "5.20.0-beta.0",
37
+ "@webiny/plugins": "5.20.0-beta.0",
38
+ "@webiny/pubsub": "5.20.0-beta.0",
39
+ "@webiny/utils": "5.20.0-beta.0",
40
+ "@webiny/validation": "5.20.0-beta.0",
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.1",
58
- "@webiny/api-tenancy-so-ddb": "^5.19.1",
59
- "@webiny/cli": "^5.19.1",
60
- "@webiny/project-utils": "^5.19.1",
57
+ "@webiny/api-security-so-ddb": "^5.20.0-beta.0",
58
+ "@webiny/api-tenancy-so-ddb": "^5.20.0-beta.0",
59
+ "@webiny/cli": "^5.20.0-beta.0",
60
+ "@webiny/project-utils": "^5.20.0-beta.0",
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": "1424145d10add470e70fba9c44225656894e0028"
80
+ "gitHead": "2de02bc113e15e3ffa8e1d82deb9d27417787188"
81
81
  }
@@ -17,7 +17,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
17
17
 
18
18
  var _default = () => {
19
19
  return new _ContextPlugin.ContextPlugin(context => {
20
- const locale = context.i18nContent.getLocale();
20
+ const locale = context.i18nContent.getCurrentLocale();
21
21
  context.cms = _objectSpread(_objectSpread({}, context.cms || {}), {}, {
22
22
  locale: locale ? locale.code : "en-US",
23
23
 
package/types.d.ts CHANGED
@@ -364,7 +364,7 @@ export interface CmsModelFieldToGraphQLCreateResolver {
364
364
  }): GraphQLFieldResolver | {
365
365
  resolver: GraphQLFieldResolver;
366
366
  typeResolvers: Resolvers<CmsContext>;
367
- };
367
+ } | false;
368
368
  }
369
369
  /**
370
370
  * @category Plugin
@@ -455,7 +455,7 @@ export interface CmsModelFieldToGraphQLPlugin extends Plugin {
455
455
  model: CmsModel;
456
456
  field: CmsModelField;
457
457
  fieldTypePlugins: CmsFieldTypePlugins;
458
- }): CmsModelFieldDefinition | string;
458
+ }): CmsModelFieldDefinition | string | null;
459
459
  /**
460
460
  * Definition for field resolver.
461
461
  * By default it is simple return of the `instance.values[fieldId]` but if required, users can define their own.
@@ -556,7 +556,7 @@ export interface CmsModelFieldToGraphQLPlugin extends Plugin {
556
556
  model: CmsModel;
557
557
  field: CmsModelField;
558
558
  fieldTypePlugins: CmsFieldTypePlugins;
559
- }) => CmsModelFieldDefinition | string;
559
+ }) => CmsModelFieldDefinition | string | null;
560
560
  /**
561
561
  * Definition for input GraphQL field type.
562
562
  *
@@ -905,6 +905,10 @@ export interface CmsModelCreateInput {
905
905
  * Description of the content model.
906
906
  */
907
907
  description?: string;
908
+ /**
909
+ * Group where to put the content model in.
910
+ */
911
+ group: string;
908
912
  }
909
913
  /**
910
914
  * A definition for content model field received from the user.
@@ -1118,18 +1122,14 @@ export interface CmsStorageEntry extends CmsEntry {
1118
1122
  * @category CmsModel
1119
1123
  */
1120
1124
  export interface CmsModelManager {
1121
- /**
1122
- * List entries in this content model.
1123
- */
1124
- list: (params?: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;
1125
1125
  /**
1126
1126
  * List only published entries in the content model.
1127
1127
  */
1128
- listPublished: (params?: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;
1128
+ listPublished: (params: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;
1129
1129
  /**
1130
1130
  * List latest entries in the content model. Used for administration.
1131
1131
  */
1132
- listLatest: (params?: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;
1132
+ listLatest: (params: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;
1133
1133
  /**
1134
1134
  * Get a list of published entries by the ID list.
1135
1135
  */
@@ -1163,6 +1163,16 @@ export interface AfterModelCreateTopicParams {
1163
1163
  input: Partial<CmsModel>;
1164
1164
  model: CmsModel;
1165
1165
  }
1166
+ export interface BeforeModelCreateFromTopicParams {
1167
+ input: Partial<CmsModel>;
1168
+ original: CmsModel;
1169
+ model: CmsModel;
1170
+ }
1171
+ export interface AfterModelCreateFromTopicParams {
1172
+ input: Partial<CmsModel>;
1173
+ original: CmsModel;
1174
+ model: CmsModel;
1175
+ }
1166
1176
  export interface BeforeModelUpdateTopicParams {
1167
1177
  input: Partial<CmsModel>;
1168
1178
  original: CmsModel;
@@ -1211,12 +1221,12 @@ export interface CmsModelContext {
1211
1221
  * Create a content model.
1212
1222
  */
1213
1223
  createModel: (data: CmsModelCreateInput) => Promise<CmsModel>;
1224
+ /**
1225
+ * Create a content model from the given model - clone.
1226
+ */
1227
+ createModelFrom: (modelId: string, data: CmsModelCreateInput) => Promise<CmsModel>;
1214
1228
  /**
1215
1229
  * Update content model without data validation. Used internally.
1216
- *
1217
- * @param model - existing content model
1218
- * @param data - data to be updated
1219
- *
1220
1230
  * @hidden
1221
1231
  */
1222
1232
  updateModelDirect: (params: CmsModelUpdateDirectParams) => Promise<CmsModel>;
@@ -1244,6 +1254,8 @@ export interface CmsModelContext {
1244
1254
  */
1245
1255
  onBeforeModelCreate: Topic<BeforeModelCreateTopicParams>;
1246
1256
  onAfterModelCreate: Topic<AfterModelCreateTopicParams>;
1257
+ onBeforeModelCreateFrom: Topic<BeforeModelCreateFromTopicParams>;
1258
+ onAfterModelCreateFrom: Topic<AfterModelCreateFromTopicParams>;
1247
1259
  onBeforeModelUpdate: Topic<BeforeModelUpdateTopicParams>;
1248
1260
  onAfterModelUpdate: Topic<AfterModelUpdateTopicParams>;
1249
1261
  onBeforeModelDelete: Topic<BeforeModelDeleteTopicParams>;
@@ -1496,7 +1508,7 @@ export interface CmsEntryContext {
1496
1508
  /**
1497
1509
  * List entries for a model. Internal method used by get, listLatest and listPublished.
1498
1510
  */
1499
- listEntries: (model: CmsModel, params?: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;
1511
+ listEntries: (model: CmsModel, params: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;
1500
1512
  /**
1501
1513
  * Lists latest entries. Used for manage API.
1502
1514
  */