contentful-migration 4.8.1 → 4.9.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/CHANGELOG.md +3 -3
- package/README.md +237 -140
- package/built/lib/action/content-type-annotate.js +27 -0
- package/built/lib/action/content-type-annotate.js.map +1 -0
- package/built/lib/action/editor-layout/editor-layout-change-field-group-control.js +23 -0
- package/built/lib/action/editor-layout/editor-layout-change-field-group-control.js.map +1 -0
- package/built/lib/action/editor-layout/editor-layout-create-field-group.js +26 -0
- package/built/lib/action/editor-layout/editor-layout-create-field-group.js.map +1 -0
- package/built/lib/action/editor-layout/editor-layout-create.js +18 -0
- package/built/lib/action/editor-layout/editor-layout-create.js.map +1 -0
- package/built/lib/action/editor-layout/editor-layout-delete-field-group.js +23 -0
- package/built/lib/action/editor-layout/editor-layout-delete-field-group.js.map +1 -0
- package/built/lib/action/editor-layout/editor-layout-delete.js +21 -0
- package/built/lib/action/editor-layout/editor-layout-delete.js.map +1 -0
- package/built/lib/action/editor-layout/editor-layout-move-field.js +24 -0
- package/built/lib/action/editor-layout/editor-layout-move-field.js.map +1 -0
- package/built/lib/action/editor-layout/editor-layout-update-field-group.js +41 -0
- package/built/lib/action/editor-layout/editor-layout-update-field-group.js.map +1 -0
- package/built/lib/action/field-annotate.js +28 -0
- package/built/lib/action/field-annotate.js.map +1 -0
- package/built/lib/action/field-rename.js +4 -0
- package/built/lib/action/field-rename.js.map +1 -1
- package/built/lib/entities/content-type.js +239 -11
- package/built/lib/entities/content-type.js.map +1 -1
- package/built/lib/fetcher.js +2 -1
- package/built/lib/fetcher.js.map +1 -1
- package/built/lib/intent/base-intent.js +47 -0
- package/built/lib/intent/base-intent.js.map +1 -1
- package/built/lib/intent/composed-intent.js +51 -1
- package/built/lib/intent/composed-intent.js.map +1 -1
- package/built/lib/intent/content-type-annotate.js +57 -0
- package/built/lib/intent/content-type-annotate.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-change-field-group-control.js +57 -0
- package/built/lib/intent/editor-layout/editor-layout-change-field-group-control.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-change-field-group-id.js +59 -0
- package/built/lib/intent/editor-layout/editor-layout-change-field-group-id.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-create-field-group.js +54 -0
- package/built/lib/intent/editor-layout/editor-layout-create-field-group.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-create.js +49 -0
- package/built/lib/intent/editor-layout/editor-layout-create.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-delete-field-group.js +53 -0
- package/built/lib/intent/editor-layout/editor-layout-delete-field-group.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-delete.js +45 -0
- package/built/lib/intent/editor-layout/editor-layout-delete.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-invalid-method.js +38 -0
- package/built/lib/intent/editor-layout/editor-layout-invalid-method.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-move-field.js +81 -0
- package/built/lib/intent/editor-layout/editor-layout-move-field.js.map +1 -0
- package/built/lib/intent/editor-layout/editor-layout-update-field-group.js +57 -0
- package/built/lib/intent/editor-layout/editor-layout-update-field-group.js.map +1 -0
- package/built/lib/intent/field-annotate.js +57 -0
- package/built/lib/intent/field-annotate.js.map +1 -0
- package/built/lib/intent/index.js +23 -1
- package/built/lib/intent/index.js.map +1 -1
- package/built/lib/intent-list/index.js +4 -0
- package/built/lib/intent-list/index.js.map +1 -1
- package/built/lib/interfaces/annotation.js +86 -0
- package/built/lib/interfaces/annotation.js.map +1 -0
- package/built/lib/migration-chunks/validation/editor-layout.js +305 -0
- package/built/lib/migration-chunks/validation/editor-layout.js.map +1 -0
- package/built/lib/migration-chunks/validation/errors.js +91 -0
- package/built/lib/migration-chunks/validation/errors.js.map +1 -1
- package/built/lib/migration-chunks/validation/field.js +24 -23
- package/built/lib/migration-chunks/validation/field.js.map +1 -1
- package/built/lib/migration-chunks/validation/index.js +16 -3
- package/built/lib/migration-chunks/validation/index.js.map +1 -1
- package/built/lib/migration-parser.js +1 -1
- package/built/lib/migration-parser.js.map +1 -1
- package/built/lib/migration-steps/action-creators.js +164 -0
- package/built/lib/migration-steps/action-creators.js.map +1 -1
- package/built/lib/migration-steps/index.js +111 -3
- package/built/lib/migration-steps/index.js.map +1 -1
- package/built/lib/offline-api/index.js +13 -4
- package/built/lib/offline-api/index.js.map +1 -1
- package/built/lib/offline-api/validator/annotations.js +76 -0
- package/built/lib/offline-api/validator/annotations.js.map +1 -0
- package/built/lib/offline-api/validator/editor-interface.js +16 -0
- package/built/lib/offline-api/validator/editor-interface.js.map +1 -0
- package/built/lib/offline-api/validator/errors.js +21 -0
- package/built/lib/offline-api/validator/errors.js.map +1 -1
- package/built/lib/offline-api/validator/field-groups-count.js +34 -0
- package/built/lib/offline-api/validator/field-groups-count.js.map +1 -0
- package/built/lib/offline-api/validator/schema/editor-layout-schema.js +46 -0
- package/built/lib/offline-api/validator/schema/editor-layout-schema.js.map +1 -0
- package/built/lib/offline-api/validator/schema/schema-validation.js +42 -1
- package/built/lib/offline-api/validator/schema/schema-validation.js.map +1 -1
- package/built/lib/utils/editor-layout.js +60 -0
- package/built/lib/utils/editor-layout.js.map +1 -0
- package/docs/validation.md +104 -0
- package/index.d.ts +87 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|

|
|
2
|
+
|
|
2
3
|
<p align="center">
|
|
3
4
|
<a href="https://www.contentful.com/slack/">
|
|
4
5
|
<img src="https://img.shields.io/badge/-Join%20Community%20Slack-2AB27B.svg?logo=slack&maxAge=31557600" alt="Join Contentful Community Slack">
|
|
@@ -25,7 +26,6 @@
|
|
|
25
26
|
</a>
|
|
26
27
|
</p>
|
|
27
28
|
|
|
28
|
-
|
|
29
29
|
<p align="center">
|
|
30
30
|
<a href="https://www.npmjs.com/package/contentful-migration">
|
|
31
31
|
<img src="https://img.shields.io/npm/v/contentful-migration.svg" alt="NPM">
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
- [`deriveLinkedEntries(config)` Example](#derivelinkedentriesconfig-example)
|
|
68
68
|
- [`transformEntriesToType(config)`](#transformentriestotypeconfig)
|
|
69
69
|
- [`transformEntriesToType` Example](#transformentriestotype-example)
|
|
70
|
-
- [`createTag(id[, opts])`](#createtagid-opts)
|
|
70
|
+
- [`createTag(id[, opts, visibility])`](#createtagid-opts-visibility)
|
|
71
71
|
- [`editTag(id[, opts])`](#edittagid-opts)
|
|
72
72
|
- [`deleteTag(id)`](#deletetagid)
|
|
73
73
|
- [`setTagsForEntries(config)`](#settagsforentriesconfig)
|
|
@@ -92,11 +92,24 @@
|
|
|
92
92
|
- [`configureEntryEditor (widgetNamespace, widgetId[, settings])` : void](#configureentryeditor-widgetnamespace-widgetid-settings--void)
|
|
93
93
|
- [`configureEntryEditors (EntryEditor[])` : void](#configureentryeditors-entryeditor--void)
|
|
94
94
|
- [`resetEntryEditorToDefault ()` : void](#resetentryeditortodefault---void)
|
|
95
|
+
- [`createEditorLayout ()` : EditorLayout](#createeditorlayout---editorlayout)
|
|
96
|
+
- [`editEditorLayout ()` : EditorLayout](#editeditorlayout---editorlayout)
|
|
97
|
+
- [`deleteEditorLayout ()` : void](#deleteeditorlayout---void)
|
|
95
98
|
- [Field](#field)
|
|
99
|
+
- [Editor Layout](#editor-layout)
|
|
100
|
+
- [`moveField(id)` : MovableEditorLayoutItem](#movefieldid--movableeditorlayoutitem)
|
|
101
|
+
- [`createFieldGroup(id[, opts])` : EditorLayoutFieldGroup](#createfieldgroupid-opts--editorlayoutfieldgroup)
|
|
102
|
+
- [`deleteFieldGroup (id)` : void](#deletefieldgroup-id--void)
|
|
103
|
+
- [`changeFieldGroupId (currentId, newId)`](#changefieldgroupid-currentid-newid)
|
|
104
|
+
- [`editFieldGroup (id[, opts])` : EditorLayoutFieldGroup](#editfieldgroup-id-opts--editorlayoutfieldgroup)
|
|
105
|
+
- [Editor Layout Field Group](#editor-layout-field-group)
|
|
106
|
+
- [`createFieldGroup (id[, opts])` : EditorLayoutFieldGroup](#createfieldgroup-id-opts--editorlayoutfieldgroup)
|
|
107
|
+
- [`changeFieldGroupControl (id, widgetNamespace, widgetId[, settings])` : void](#changefieldgroupcontrol-id-widgetnamespace-widgetid-settings--void)
|
|
96
108
|
- [Validation errors](#validation-errors)
|
|
97
109
|
- [Example migrations](#example-migrations)
|
|
98
110
|
- [Writing Migrations in Typescript](#writing-migrations-in-typescript)
|
|
99
111
|
- [Troubleshooting](#troubleshooting)
|
|
112
|
+
- [Updating Integration tests fixtures](#updating-integration-tests-fixtures)
|
|
100
113
|
- [Reach out to us](#reach-out-to-us)
|
|
101
114
|
- [You have questions about how to use this library?](#you-have-questions-about-how-to-use-this-library)
|
|
102
115
|
- [You found a bug or want to propose a feature?](#you-found-a-bug-or-want-to-propose-a-feature)
|
|
@@ -150,6 +163,7 @@ npm install contentful-migration
|
|
|
150
163
|
> We moved the CLI version of this tool into our [Contentful CLI](https://github.com/contentful/contentful-cli). This allows our users to use and install only one single CLI tool to get the full Contentful experience.
|
|
151
164
|
>
|
|
152
165
|
> Please have a look at the [Contentful CLI migration command documentation](https://github.com/contentful/contentful-cli/tree/master/docs/space/migration) to learn more about how to use this as command line tool.
|
|
166
|
+
|
|
153
167
|
### Usage as a library
|
|
154
168
|
|
|
155
169
|
```javascript
|
|
@@ -168,10 +182,10 @@ In your migration description file, export a function that accepts the `migratio
|
|
|
168
182
|
|
|
169
183
|
```javascript
|
|
170
184
|
module.exports = function (migration, context) {
|
|
171
|
-
const dog = migration.createContentType('dog')
|
|
172
|
-
const name = dog.createField('name')
|
|
173
|
-
name.type('Symbol').required(true)
|
|
174
|
-
}
|
|
185
|
+
const dog = migration.createContentType('dog')
|
|
186
|
+
const name = dog.createField('name')
|
|
187
|
+
name.type('Symbol').required(true)
|
|
188
|
+
}
|
|
175
189
|
```
|
|
176
190
|
|
|
177
191
|
You can also pass the function directly. For example:
|
|
@@ -179,10 +193,10 @@ You can also pass the function directly. For example:
|
|
|
179
193
|
```javascript
|
|
180
194
|
const { runMigration } = require('contentful-migration')
|
|
181
195
|
|
|
182
|
-
function migrationFunction
|
|
183
|
-
const dog = migration.createContentType('dog')
|
|
184
|
-
const name = dog.createField('name')
|
|
185
|
-
name.type('Symbol').required(true)
|
|
196
|
+
function migrationFunction(migration, context) {
|
|
197
|
+
const dog = migration.createContentType('dog')
|
|
198
|
+
const name = dog.createField('name')
|
|
199
|
+
name.type('Symbol').required(true)
|
|
186
200
|
}
|
|
187
201
|
|
|
188
202
|
const options = {
|
|
@@ -192,39 +206,40 @@ const options = {
|
|
|
192
206
|
}
|
|
193
207
|
|
|
194
208
|
runMigration(options)
|
|
195
|
-
|
|
196
|
-
|
|
209
|
+
.then(() => console.log('Migration Done!'))
|
|
210
|
+
.catch((e) => console.error(e))
|
|
197
211
|
```
|
|
198
212
|
|
|
199
213
|
## Documentation & References
|
|
200
214
|
|
|
201
215
|
### Configuration
|
|
202
216
|
|
|
203
|
-
| Name | Default | Type
|
|
204
|
-
|
|
205
|
-
| filePath | | string
|
|
206
|
-
| migrationFunction | | function| Specify the migration function directly. See the [expected signature](https://github.com/contentful/contentful-migration/blob/4b9dcae0e7616da9153d0fa481871978595049e7/index.d.ts#L506).
|
|
207
|
-
| spaceId | | string
|
|
208
|
-
| environmentId | `'master'` | string
|
|
209
|
-
| accessToken | | string
|
|
210
|
-
| yes | false | boolean
|
|
211
|
-
| retryLimit | 5 | number
|
|
212
|
-
| requestBatchSize | 100 | number
|
|
213
|
-
| headers | | object
|
|
217
|
+
| Name | Default | Type | Description | Required |
|
|
218
|
+
| ----------------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
|
|
219
|
+
| filePath | | string | The path to the migration file | if `migrationFunction` is not supplied |
|
|
220
|
+
| migrationFunction | | function | Specify the migration function directly. See the [expected signature](https://github.com/contentful/contentful-migration/blob/4b9dcae0e7616da9153d0fa481871978595049e7/index.d.ts#L506). | if `filePath` is not supplied |
|
|
221
|
+
| spaceId | | string | ID of the space to run the migration script on | true |
|
|
222
|
+
| environmentId | `'master'` | string | ID of the environment within the space to run the | false |
|
|
223
|
+
| accessToken | | string | The access token to use | true |
|
|
224
|
+
| yes | false | boolean | Skips any confirmation before applying the migration,script | false |
|
|
225
|
+
| retryLimit | 5 | number | Number of retries before failure (every subsequent retry will increase the timeout to the previous retry by about 1.5 seconds) | false |
|
|
226
|
+
| requestBatchSize | 100 | number | Limit for every single request | false |
|
|
227
|
+
| headers | | object | Additional headers to attach to the requests | false |
|
|
214
228
|
|
|
215
229
|
### Chaining vs Object notation
|
|
216
230
|
|
|
217
231
|
All methods described below can be used in two flavors:
|
|
218
232
|
|
|
219
|
-
|
|
233
|
+
1. The chained approach:
|
|
220
234
|
|
|
221
235
|
```javascript
|
|
222
|
-
const author = migration
|
|
236
|
+
const author = migration
|
|
237
|
+
.createContentType('author')
|
|
223
238
|
.name('Author')
|
|
224
239
|
.description('Author of blog posts or pages')
|
|
225
240
|
```
|
|
226
241
|
|
|
227
|
-
|
|
242
|
+
1. The object approach:
|
|
228
243
|
|
|
229
244
|
```javascript
|
|
230
245
|
const author = migration.createContentType('author', {
|
|
@@ -247,7 +262,7 @@ Creates a content type with provided `id` and returns a reference to the newly c
|
|
|
247
262
|
|
|
248
263
|
**`opts : Object`** – Content type definition, with the following options:
|
|
249
264
|
|
|
250
|
-
- **`name : string`** –
|
|
265
|
+
- **`name : string`** – Name of the content type.
|
|
251
266
|
- **`description : string`** – Description of the content type.
|
|
252
267
|
- **`displayField : string`** – ID of the field to use as the display field for the content type. This is referred to as the "Entry title" in the web application.
|
|
253
268
|
|
|
@@ -271,27 +286,26 @@ The transform function is expected to return an object with the desired target f
|
|
|
271
286
|
- **`from : array`** _(required)_ – Array of the source field IDs
|
|
272
287
|
- **`to : array`** _(required)_ – Array of the target field IDs
|
|
273
288
|
- **`transformEntryForLocale : function (fields, locale): object`** _(required)_ – Transformation function to be applied.
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
289
|
+
- `fields` is an object containing each of the `from` fields. Each field will contain their current localized values (i.e. `fields == {myField: {'en-US': 'my field value'}}`)
|
|
290
|
+
- `locale` one of the locales in the space being transformed
|
|
291
|
+
The return value must be an object with the same keys as specified in `to`. Their values will be written to the respective entry fields for the current locale (i.e. `{nameField: 'myNewValue'}`). If it returns `undefined`, this the values for this locale on the entry will be left untouched.
|
|
277
292
|
- **`shouldPublish : bool | 'preserve'`** _(optional)_ – Flag that specifies publishing of target entries, `preserve` will keep current states of the source entries (default `'preserve'`)
|
|
278
293
|
|
|
279
|
-
|
|
280
294
|
##### `transformEntries` Example
|
|
281
295
|
|
|
282
296
|
```javascript
|
|
283
297
|
migration.transformEntries({
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
const newByline = `${fromFields.author[currentLocale]} ${fromFields.authorCity[currentLocale]}`;
|
|
292
|
-
return { byline: newByline };
|
|
298
|
+
contentType: 'newsArticle',
|
|
299
|
+
from: ['author', 'authorCity'],
|
|
300
|
+
to: ['byline'],
|
|
301
|
+
transformEntryForLocale: function (fromFields, currentLocale) {
|
|
302
|
+
if (currentLocale === 'de-DE') {
|
|
303
|
+
return
|
|
293
304
|
}
|
|
294
|
-
|
|
305
|
+
const newByline = `${fromFields.author[currentLocale]} ${fromFields.authorCity[currentLocale]}`
|
|
306
|
+
return { byline: newByline }
|
|
307
|
+
}
|
|
308
|
+
})
|
|
295
309
|
```
|
|
296
310
|
|
|
297
311
|
For the complete version, please refer to [this example](./examples/12-transform-content.js).
|
|
@@ -315,9 +329,11 @@ The derive function is expected to return an object with the desired target fiel
|
|
|
315
329
|
- **`derivedFields : array`** _(required)_ – Array of the field IDs on the target content type
|
|
316
330
|
|
|
317
331
|
- **`identityKey: function (fields): string`** _(required)_ - Called once per source entry. Returns the ID used for the derived entry, which is also used for de-duplication so that multiple source entries can link to the same derived entry.
|
|
332
|
+
|
|
318
333
|
- `fields` is an object containing each of the `from` fields. Each field will contain their current localized values (i.e. `fields == {myField: {'en-US': 'my field value'}}`)
|
|
319
334
|
|
|
320
335
|
- **`deriveEntryForLocale : function (fields, locale): object`** _(required)_ – Function that generates the field values for the derived entry.
|
|
336
|
+
|
|
321
337
|
- `fields` is an object containing each of the `from` fields. Each field will contain their current localized values (i.e. `fields == {myField: {'en-US': 'my field value'}}`)
|
|
322
338
|
- `locale` one of the locales in the space being transformed
|
|
323
339
|
|
|
@@ -325,31 +341,30 @@ The derive function is expected to return an object with the desired target fiel
|
|
|
325
341
|
|
|
326
342
|
- **`shouldPublish : bool|'preserve'`** _(optional)_ – If true, both the source and the derived entries will be published. If false, both will remain in draft state. If preserve, will keep current states of the source entries (default `true`)
|
|
327
343
|
|
|
328
|
-
|
|
329
344
|
##### `deriveLinkedEntries(config)` Example
|
|
330
345
|
|
|
331
346
|
```javascript
|
|
332
347
|
migration.deriveLinkedEntries({
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
};
|
|
348
|
+
contentType: 'dog',
|
|
349
|
+
derivedContentType: 'owner',
|
|
350
|
+
from: ['owner'],
|
|
351
|
+
toReferenceField: 'ownerRef',
|
|
352
|
+
derivedFields: ['firstName', 'lastName'],
|
|
353
|
+
identityKey: async (fromFields) => {
|
|
354
|
+
return fromFields.owner['en-US'].toLowerCase().replace(' ', '-')
|
|
355
|
+
},
|
|
356
|
+
shouldPublish: true,
|
|
357
|
+
deriveEntryForLocale: async (inputFields, locale) => {
|
|
358
|
+
if (locale !== 'en-US') {
|
|
359
|
+
return
|
|
360
|
+
}
|
|
361
|
+
const [firstName, lastName] = inputFields.owner[locale].split(' ')
|
|
362
|
+
return {
|
|
363
|
+
firstName,
|
|
364
|
+
lastName
|
|
351
365
|
}
|
|
352
|
-
}
|
|
366
|
+
}
|
|
367
|
+
})
|
|
353
368
|
```
|
|
354
369
|
|
|
355
370
|
For the complete version of this migration, please refer to [this example](./examples/15-derive-entry-n-to-1.js).
|
|
@@ -368,33 +383,34 @@ For the given (source) content type, transforms all its entries according to the
|
|
|
368
383
|
- **`updateReferences : bool`** _(optional)_ – Flag that specifies if linking entries should be updated with target entries (default `false`). Note that this flag does not support Rich Text Fields references.
|
|
369
384
|
- **`removeOldEntries : bool`** _(optional)_ – Flag that specifies if source entries should be deleted (default `false`)
|
|
370
385
|
- **`transformEntryForLocale : function (fields, locale): object`** _(required)_ – Transformation function to be applied.
|
|
371
|
-
|
|
372
|
-
|
|
386
|
+
|
|
387
|
+
- `fields` is an object containing each of the `from` fields. Each field will contain their current localized values (i.e. `fields == {myField: {'en-US': 'my field value'}}`)
|
|
388
|
+
- `locale` one of the locales in the space being transformed
|
|
373
389
|
|
|
374
390
|
The return value must be an object with the same keys as specified in the `targetContentType`. Their values will be written to the respective entry fields for the current locale (i.e. `{nameField: 'myNewValue'}`). If it returns `undefined`, this the values for this locale on the entry will be left untouched.
|
|
375
391
|
|
|
376
392
|
##### `transformEntriesToType` Example
|
|
377
393
|
|
|
378
394
|
```javascript
|
|
379
|
-
const MurmurHash3 = require('imurmurhash')
|
|
395
|
+
const MurmurHash3 = require('imurmurhash')
|
|
380
396
|
|
|
381
397
|
migration.transformEntriesToType({
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
};
|
|
398
|
+
sourceContentType: 'dog',
|
|
399
|
+
targetContentType: 'copycat',
|
|
400
|
+
from: ['woofs'],
|
|
401
|
+
shouldPublish: false,
|
|
402
|
+
updateReferences: false,
|
|
403
|
+
removeOldEntries: false,
|
|
404
|
+
identityKey: function (fields) {
|
|
405
|
+
const value = fields.woofs['en-US'].toString()
|
|
406
|
+
return MurmurHash3(value).result().toString()
|
|
407
|
+
},
|
|
408
|
+
transformEntryForLocale: function (fromFields, currentLocale) {
|
|
409
|
+
return {
|
|
410
|
+
woofs: `copy - ${fromFields.woofs[currentLocale]}`
|
|
396
411
|
}
|
|
397
|
-
}
|
|
412
|
+
}
|
|
413
|
+
})
|
|
398
414
|
```
|
|
399
415
|
|
|
400
416
|
For the complete version of this migration, please refer to [this example](./examples/22-transform-entries-to-type.js).
|
|
@@ -407,7 +423,7 @@ Creates a tag with provided `id` and returns a reference to the newly created ta
|
|
|
407
423
|
|
|
408
424
|
- **`opts : Object`** – Tag definition, with the following options:
|
|
409
425
|
|
|
410
|
-
- **`name : string`** –
|
|
426
|
+
- **`name : string`** – Name of the tag.
|
|
411
427
|
|
|
412
428
|
- **`visibility : 'private' | 'public'`** Tag visibility - defaults to `private`.
|
|
413
429
|
|
|
@@ -428,22 +444,19 @@ For the given content type, updates the tags that are attached to its entries ac
|
|
|
428
444
|
|
|
429
445
|
- **`contentType : string`** _(required)_ – Content type ID
|
|
430
446
|
- **`from : array`** _(required)_ – Array of the source field IDs
|
|
431
|
-
- **`setTagsForEntry : function (entryFields, entryTags, apiTags): array`** _(required)_ – Transformation function to be applied.
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
already attached to the entry.
|
|
435
|
-
- `apiTags` is an array containing link objects of all tags
|
|
436
|
-
available in the environment.
|
|
447
|
+
- **`setTagsForEntry : function (entryFields, entryTags, apiTags): array`** _(required)_ – Transformation function to be applied. - `entryFields` is an object containing each of the `from` fields. - `entryTags` is an array containing link objects of all tags
|
|
448
|
+
already attached to the entry. - `apiTags` is an array containing link objects of all tags
|
|
449
|
+
available in the environment.
|
|
437
450
|
|
|
438
451
|
##### `setTagsForEntries` Example
|
|
439
452
|
|
|
440
|
-
```
|
|
453
|
+
```javascript
|
|
441
454
|
migration.createTag('department-sf').name('Department: San Francisco')
|
|
442
455
|
migration.createTag('department-ldn').name('Department: London')
|
|
443
456
|
|
|
444
457
|
const departmentMapping = {
|
|
445
458
|
'san-francisco': 'department-sf',
|
|
446
|
-
|
|
459
|
+
london: 'department-ldn'
|
|
447
460
|
}
|
|
448
461
|
|
|
449
462
|
migration.setTagsForEntries({
|
|
@@ -453,11 +466,7 @@ migration.setTagsForEntries({
|
|
|
453
466
|
const departmentField = entryFields.department['en-US']
|
|
454
467
|
const newTag = apiTags.find((tag) => tag.sys.id === departmentMapping[departmentField])
|
|
455
468
|
|
|
456
|
-
return [
|
|
457
|
-
...entryTags,
|
|
458
|
-
newTag,
|
|
459
|
-
]
|
|
460
|
-
|
|
469
|
+
return [...entryTags, newTag]
|
|
461
470
|
}
|
|
462
471
|
})
|
|
463
472
|
```
|
|
@@ -471,10 +480,10 @@ module.exports = async function (migration, { makeRequest, spaceId, accessToken
|
|
|
471
480
|
const contentType = await makeRequest({
|
|
472
481
|
method: 'GET',
|
|
473
482
|
url: `/content_types?sys.id[in]=foo`
|
|
474
|
-
})
|
|
483
|
+
})
|
|
475
484
|
|
|
476
485
|
const anyOtherTool = new AnyOtherTool({ spaceId, accessToken })
|
|
477
|
-
}
|
|
486
|
+
}
|
|
478
487
|
```
|
|
479
488
|
|
|
480
489
|
#### `makeRequest(config)`
|
|
@@ -482,8 +491,9 @@ module.exports = async function (migration, { makeRequest, spaceId, accessToken
|
|
|
482
491
|
The function used by the migration object to talk to the Contentful Management API. This can be useful if you want to use API features that may not be supported by the `migration` object.
|
|
483
492
|
|
|
484
493
|
`config : Object` - Configuration for the request based on [the Contentful management SDK](https://contentful.github.io/contentful-management.js/contentful-management/7.3.0/globals.html#http)
|
|
485
|
-
|
|
486
|
-
|
|
494
|
+
|
|
495
|
+
- `method` : `string` – HTTP method
|
|
496
|
+
- `url` : `string` - HTTP endpoint
|
|
487
497
|
|
|
488
498
|
```javascript
|
|
489
499
|
module.exports = async function (migration, { makeRequest }) {
|
|
@@ -491,7 +501,7 @@ module.exports = async function (migration, { makeRequest }) {
|
|
|
491
501
|
method: 'GET',
|
|
492
502
|
url: `/content_types?sys.id[in]=foo`
|
|
493
503
|
})
|
|
494
|
-
}
|
|
504
|
+
}
|
|
495
505
|
```
|
|
496
506
|
|
|
497
507
|
#### `spaceId` : `string`
|
|
@@ -502,7 +512,6 @@ The space ID that was set for the current migration.
|
|
|
502
512
|
|
|
503
513
|
The access token that was set for the current migration.
|
|
504
514
|
|
|
505
|
-
|
|
506
515
|
### Content type
|
|
507
516
|
|
|
508
517
|
For a comprehensive guide to content modelling, please refer to [this guide](https://www.contentful.com/developers/docs/concepts/data-model/).
|
|
@@ -511,7 +520,7 @@ For a comprehensive guide to content modelling, please refer to [this guide](htt
|
|
|
511
520
|
|
|
512
521
|
Creates a field with provided `id`.
|
|
513
522
|
|
|
514
|
-
**`id : string`** –
|
|
523
|
+
**`id : string`** – The ID of the field.
|
|
515
524
|
|
|
516
525
|
**`opts : Object`** – Field definition, with the following options:
|
|
517
526
|
|
|
@@ -548,19 +557,18 @@ Creates a field with provided `id`.
|
|
|
548
557
|
Example:
|
|
549
558
|
|
|
550
559
|
```javascript
|
|
551
|
-
validations: [
|
|
552
|
-
{ in: [ 'Web', 'iOS', 'Android' ] }
|
|
553
|
-
]
|
|
560
|
+
validations: [{ in: ['Web', 'iOS', 'Android'] }]
|
|
554
561
|
```
|
|
555
562
|
|
|
556
563
|
_See [The CMA documentation](https://www.contentful.com/developers/docs/references/content-management-api/#/reference/content-types/content-type) for the list of available validations._
|
|
564
|
+
|
|
557
565
|
- **`localized : boolean`** – Sets the field as localized.
|
|
558
566
|
- **`disabled : boolean`** – Sets the field as disabled, hence not editable by authors.
|
|
559
567
|
- **`omitted : boolean`** – Sets the field as omitted, hence not sent in response.
|
|
560
568
|
- **`deleted : boolean`** – Sets the field as deleted. Requires to have been `omitted` first.
|
|
561
569
|
_You may prefer using the `deleteField` method._
|
|
562
|
-
- **`defaultValue : Object`**
|
|
563
|
-
|
|
570
|
+
- **`defaultValue : Object`** – Sets the default value for the field.
|
|
571
|
+
Example:
|
|
564
572
|
|
|
565
573
|
```javascript
|
|
566
574
|
defaultValue: {
|
|
@@ -606,35 +614,26 @@ Move the field (position of the field in the web editor)
|
|
|
606
614
|
- **`.afterField(fieldId)`**
|
|
607
615
|
|
|
608
616
|
Example:
|
|
617
|
+
|
|
609
618
|
```javascript
|
|
610
619
|
module.exports = function (migration) {
|
|
611
|
-
const food = migration.editContentType('food')
|
|
620
|
+
const food = migration.editContentType('food')
|
|
612
621
|
|
|
613
|
-
food.createField('calories')
|
|
614
|
-
.type('Number')
|
|
615
|
-
.name('How many calories does it have?');
|
|
622
|
+
food.createField('calories').type('Number').name('How many calories does it have?')
|
|
616
623
|
|
|
617
|
-
food.createField('sugar')
|
|
618
|
-
.type('Number')
|
|
619
|
-
.name('Amount of sugar');
|
|
624
|
+
food.createField('sugar').type('Number').name('Amount of sugar')
|
|
620
625
|
|
|
621
|
-
food.createField('vegan')
|
|
622
|
-
.type('Boolean')
|
|
623
|
-
.name('Vegan friendly');
|
|
626
|
+
food.createField('vegan').type('Boolean').name('Vegan friendly')
|
|
624
627
|
|
|
625
|
-
food.createField('producer')
|
|
626
|
-
.type('Symbol')
|
|
627
|
-
.name('Food producer');
|
|
628
|
+
food.createField('producer').type('Symbol').name('Food producer')
|
|
628
629
|
|
|
629
|
-
food.createField('gmo')
|
|
630
|
-
.type('Boolean')
|
|
631
|
-
.name('Genetically modified food');
|
|
630
|
+
food.createField('gmo').type('Boolean').name('Genetically modified food')
|
|
632
631
|
|
|
633
|
-
food.moveField('calories').toTheTop()
|
|
634
|
-
food.moveField('sugar').toTheBottom()
|
|
635
|
-
food.moveField('producer').beforeField('vegan')
|
|
636
|
-
food.moveField('gmo').afterField('vegan')
|
|
637
|
-
}
|
|
632
|
+
food.moveField('calories').toTheTop()
|
|
633
|
+
food.moveField('sugar').toTheBottom()
|
|
634
|
+
food.moveField('producer').beforeField('vegan')
|
|
635
|
+
food.moveField('gmo').afterField('vegan')
|
|
636
|
+
}
|
|
638
637
|
```
|
|
639
638
|
|
|
640
639
|
#### `changeFieldControl (fieldId, widgetNamespace, widgetId[, settings])` : void
|
|
@@ -644,6 +643,7 @@ Changes control interface of given field's ID.
|
|
|
644
643
|
**`fieldId : string`** – The ID of the field.
|
|
645
644
|
|
|
646
645
|
**`widgetNamespace : string`** – The namespace of the widget, one of the following values:
|
|
646
|
+
|
|
647
647
|
- `builtin` (Standard widget)
|
|
648
648
|
- `app` (Custom App)
|
|
649
649
|
- `extension` (Custom UI extension)
|
|
@@ -678,6 +678,7 @@ Changes control interface of given field's ID.
|
|
|
678
678
|
Adds a builtin or custom widget to the sidebar of the content type.
|
|
679
679
|
|
|
680
680
|
**`widgetNamespace: string`** – The namespace of the widget, one of the following values:
|
|
681
|
+
|
|
681
682
|
- `sidebar-builtin` (Standard widget, default)
|
|
682
683
|
- `extension` (Custom UI extension)
|
|
683
684
|
|
|
@@ -692,6 +693,7 @@ Adds a builtin or custom widget to the sidebar of the content type.
|
|
|
692
693
|
Updates the configuration of a widget in the sidebar of the content type.
|
|
693
694
|
|
|
694
695
|
**`widgetNamespace: string`** – The namespace of the widget, one of the following values:
|
|
696
|
+
|
|
695
697
|
- `sidebar-builtin` (Standard widget, default)
|
|
696
698
|
- `extension` (Custom UI extension)
|
|
697
699
|
|
|
@@ -704,6 +706,7 @@ Updates the configuration of a widget in the sidebar of the content type.
|
|
|
704
706
|
Removes a widget from the sidebar of the content type.
|
|
705
707
|
|
|
706
708
|
**`widgetNamespace: string`** – The namespace of the widget, one of the following values:
|
|
709
|
+
|
|
707
710
|
- `sidebar-builtin` (Standard widget, default)
|
|
708
711
|
- `extension` (Custom UI extension)
|
|
709
712
|
|
|
@@ -735,10 +738,106 @@ Each `EntryEditor` has the following properties:
|
|
|
735
738
|
|
|
736
739
|
Resets the entry editor of the content type to default.
|
|
737
740
|
|
|
741
|
+
#### `createEditorLayout ()` : [EditorLayout](#editor-layout)
|
|
742
|
+
|
|
743
|
+
Creates an empty editor layout for this content type.
|
|
744
|
+
|
|
745
|
+
#### `editEditorLayout ()` : [EditorLayout](#editor-layout)
|
|
746
|
+
|
|
747
|
+
Edits the editor layout for this content type.
|
|
748
|
+
|
|
749
|
+
#### `deleteEditorLayout ()` : void
|
|
750
|
+
|
|
751
|
+
Deletes the editor layout for this content type.
|
|
752
|
+
|
|
753
|
+
#### `setAnnotations(AnnotationId[])`
|
|
754
|
+
|
|
755
|
+
Configure the annotations assigned to this content type. See [annotations documentation](https://www.contentful.com/developers/docs/references/content-management-api/#annotations) for more details on valid `AnnotationId`.
|
|
756
|
+
|
|
757
|
+
#### `clearAnnotations()`
|
|
758
|
+
|
|
759
|
+
Remove all assigned annotations from this content type
|
|
760
|
+
|
|
738
761
|
### Field
|
|
739
762
|
|
|
740
763
|
The field object has the same methods as the properties listed in the [`ContentType.createField`](#createfieldid--string-opts--object--field) method.
|
|
741
764
|
|
|
765
|
+
In addition the following methods allow to manage field annotations.
|
|
766
|
+
|
|
767
|
+
#### `setAnnotations(AnnotationId[])`
|
|
768
|
+
|
|
769
|
+
Configure the annotations assigned to this field. See [annotations documentation](https://www.contentful.com/developers/docs/references/content-management-api/#annotations) for more details on valid `AnnotationId`.
|
|
770
|
+
|
|
771
|
+
#### `clearAnnotations()`
|
|
772
|
+
|
|
773
|
+
Remove all assigned annotations from this field.
|
|
774
|
+
|
|
775
|
+
### Editor Layout
|
|
776
|
+
|
|
777
|
+
#### `moveField(id)` : MovableEditorLayoutItem
|
|
778
|
+
|
|
779
|
+
Moves the field with the provided `id`.
|
|
780
|
+
|
|
781
|
+
`moveField(id)` returns a movable editor layout item type which must be called with a direction function:
|
|
782
|
+
|
|
783
|
+
- **`.toTheTopOfFieldGroup(groupId)`**
|
|
784
|
+
- - if no `groupId` is provided, the field will be moved within its group
|
|
785
|
+
- **`.toTheBottomOfFieldGroup(groupId)`**
|
|
786
|
+
- - if no `groupId` is provided, the field will be moved within its group
|
|
787
|
+
- **`.beforeFieldGroup(groupId)`**
|
|
788
|
+
- **`.afterFieldGroup(groupId)`**
|
|
789
|
+
- **`.beforeField(fieldId)`**
|
|
790
|
+
- **`.afterField(fieldId)`**
|
|
791
|
+
|
|
792
|
+
#### `createFieldGroup(id[, opts])` : [EditorLayoutFieldGroup](#editor-layout-field-group)
|
|
793
|
+
|
|
794
|
+
Creates a tab with the provided `id`.
|
|
795
|
+
|
|
796
|
+
**`id : string`** – The ID of the group.
|
|
797
|
+
|
|
798
|
+
**`opts : Object`** – Group settings, with the following options:
|
|
799
|
+
|
|
800
|
+
- **`name : string`** _(required)_ – Group name.
|
|
801
|
+
|
|
802
|
+
#### `deleteFieldGroup (id)` : void
|
|
803
|
+
|
|
804
|
+
Deletes the group with the provided `id` from the editor layout,
|
|
805
|
+
moving its contents to the parent if the group to delete is a field set or to the default tab if it’s a tab.
|
|
806
|
+
|
|
807
|
+
#### `changeFieldGroupId (currentId, newId)`
|
|
808
|
+
|
|
809
|
+
Changes the group’s ID.
|
|
810
|
+
|
|
811
|
+
**`currentId : string`** – The current ID of the group.
|
|
812
|
+
|
|
813
|
+
**`newId : string`** – The new ID for the group.
|
|
814
|
+
|
|
815
|
+
#### `editFieldGroup (id[, opts])` : [EditorLayoutFieldGroup](#editor-layout-field-group)
|
|
816
|
+
|
|
817
|
+
### Editor Layout Field Group
|
|
818
|
+
|
|
819
|
+
#### `createFieldGroup (id[, opts])` : [EditorLayoutFieldGroup](#editor-layout-field-group)
|
|
820
|
+
|
|
821
|
+
Creates a field set with the provided `id`.
|
|
822
|
+
|
|
823
|
+
**`id : string`** – The ID of the group.
|
|
824
|
+
|
|
825
|
+
**`opts : Object`** – Group settings, with the following options:
|
|
826
|
+
|
|
827
|
+
- **`name : string`** _(required)_ – Group name.
|
|
828
|
+
|
|
829
|
+
#### `changeFieldGroupControl (id, widgetNamespace, widgetId[, settings])` : void
|
|
830
|
+
|
|
831
|
+
Sets the group control for a field group.
|
|
832
|
+
|
|
833
|
+
**`widgetNamespace : string`** – The namespace for the group control. Currently allowed: `builtin`.
|
|
834
|
+
**`widgetId : string`** - The widget ID for the group control. Allowed values: `fieldset`, `topLevelTab`.
|
|
835
|
+
**`settings : Object`** – Field set settings, with the following properties:
|
|
836
|
+
|
|
837
|
+
- **`helpText : string`** – Help text for the field set. Displayed when editing.
|
|
838
|
+
- **`collapsible : boolean`** – Whether the field set can be collapsed when editing.
|
|
839
|
+
- **`collapsedByDefault : string`** – Whether the field set is collapsed when opening the editor.
|
|
840
|
+
|
|
742
841
|
## Validation errors
|
|
743
842
|
|
|
744
843
|
You can learn more from the [possible validation errors here](./docs/validation.md).
|
|
@@ -758,22 +857,21 @@ const options = {
|
|
|
758
857
|
}
|
|
759
858
|
|
|
760
859
|
const migrations = async () => {
|
|
761
|
-
await runMigration({...options, ...{filePath: '01-angry-dog.js'}})
|
|
762
|
-
await runMigration({...options, ...{filePath: '02-friendly-dog.js'}})
|
|
763
|
-
await runMigration({...options, ...{filePath: '03-long-example.js'}})
|
|
764
|
-
await runMigration({...options, ...{filePath: '04-steps-errors.js'}})
|
|
765
|
-
await runMigration({...options, ...{filePath: '05-plan-errors.js'}})
|
|
766
|
-
await runMigration({...options, ...{filePath: '06-delete-field.js'}})
|
|
767
|
-
await runMigration({...options, ...{filePath: '07-display-field.js'}})
|
|
860
|
+
await runMigration({ ...options, ...{ filePath: '01-angry-dog.js' } })
|
|
861
|
+
await runMigration({ ...options, ...{ filePath: '02-friendly-dog.js' } })
|
|
862
|
+
await runMigration({ ...options, ...{ filePath: '03-long-example.js' } })
|
|
863
|
+
await runMigration({ ...options, ...{ filePath: '04-steps-errors.js' } })
|
|
864
|
+
await runMigration({ ...options, ...{ filePath: '05-plan-errors.js' } })
|
|
865
|
+
await runMigration({ ...options, ...{ filePath: '06-delete-field.js' } })
|
|
866
|
+
await runMigration({ ...options, ...{ filePath: '07-display-field.js' } })
|
|
768
867
|
}
|
|
769
868
|
|
|
770
869
|
migrations()
|
|
771
|
-
|
|
772
870
|
```
|
|
773
871
|
|
|
774
872
|
## Writing Migrations in Typescript
|
|
775
873
|
|
|
776
|
-
You can use Typescript to write your migration files using `ts-node`!
|
|
874
|
+
You can use Typescript to write your migration files using `ts-node`! First `npm install --save ts-node typescript`,
|
|
777
875
|
then run your migration with ts-node:
|
|
778
876
|
|
|
779
877
|
```bash
|
|
@@ -781,6 +879,7 @@ node_modules/.bin/ts-node node_modules/.bin/contentful-migration -s $CONTENTFUL_
|
|
|
781
879
|
```
|
|
782
880
|
|
|
783
881
|
An example Typescript migration:
|
|
882
|
+
|
|
784
883
|
```typescript
|
|
785
884
|
import { MigrationFunction } from 'contentful-migration'
|
|
786
885
|
|
|
@@ -791,9 +890,7 @@ export = function (migration, { makeRequest, spaceId, accessToken }) {
|
|
|
791
890
|
})
|
|
792
891
|
|
|
793
892
|
const name = dog.createField('name')
|
|
794
|
-
name.name('Name')
|
|
795
|
-
.type('Symbol')
|
|
796
|
-
.required(true)
|
|
893
|
+
name.name('Name').type('Symbol').required(true)
|
|
797
894
|
} as MigrationFunction
|
|
798
895
|
```
|
|
799
896
|
|
|
@@ -803,7 +900,7 @@ Here's how it looks inside VS Code:
|
|
|
803
900
|
|
|
804
901
|
## Troubleshooting
|
|
805
902
|
|
|
806
|
-
|
|
903
|
+
- Unable to connect to Contentful through your Proxy? Try to set the `rawProxy` option to `true`.
|
|
807
904
|
|
|
808
905
|
```javascript
|
|
809
906
|
runMigration({
|
|
@@ -814,8 +911,8 @@ runMigration({
|
|
|
814
911
|
```
|
|
815
912
|
|
|
816
913
|
## Updating Integration tests fixtures
|
|
817
|
-
* To add new/update integration tests, you need to set environment variable `NOCK_RECORD=1` which should automatically update fixtures
|
|
818
914
|
|
|
915
|
+
- To add new/update integration tests, you need to set environment variable `NOCK_RECORD=1` which should automatically update fixtures
|
|
819
916
|
|
|
820
917
|
## Reach out to us
|
|
821
918
|
|