@cooperco/cooper-component-library 0.1.71 → 0.1.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cms/0062-create-new-article.cjs +231 -0
- package/dist/cms/contentful/migrations/scripts/0062-create-new-article.cjs +231 -0
- package/dist/cms/contentful/migrations/scripts-entries/migrate-legacy-articles.cjs +275 -0
- package/dist/cms/migrate-legacy-articles.cjs +275 -0
- package/dist/cms/migrations/scripts/0062-create-new-article.cjs +231 -0
- package/dist/cms/migrations/scripts-entries/migrate-legacy-articles.cjs +275 -0
- package/dist/cms/scripts/0062-create-new-article.cjs +231 -0
- package/dist/cms/scripts-entries/migrate-legacy-articles.cjs +275 -0
- package/package.json +3 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
// @ts-check
|
|
3
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
4
|
+
up: function (migration) {
|
|
5
|
+
const article = migration.createContentType('blog-article', {
|
|
6
|
+
name: 'Blog Article',
|
|
7
|
+
description: 'Article content',
|
|
8
|
+
displayField: 'slug',
|
|
9
|
+
})
|
|
10
|
+
// Add slug field
|
|
11
|
+
article.createField('slug', {
|
|
12
|
+
name: 'Slug',
|
|
13
|
+
type: 'Symbol',
|
|
14
|
+
required: true,
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
// Add heading field
|
|
18
|
+
article.createField('heading', {
|
|
19
|
+
name: 'Heading',
|
|
20
|
+
type: 'Symbol',
|
|
21
|
+
required: true,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// Add image field
|
|
25
|
+
article.createField('image',{
|
|
26
|
+
name: 'Image',
|
|
27
|
+
type: 'Link',
|
|
28
|
+
linkType: 'Asset',
|
|
29
|
+
required: false
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// Add summary field
|
|
33
|
+
article.createField('summary', {
|
|
34
|
+
name: 'Summary',
|
|
35
|
+
type: 'RichText',
|
|
36
|
+
required: false,
|
|
37
|
+
validations: [
|
|
38
|
+
{
|
|
39
|
+
enabledMarks: [
|
|
40
|
+
'bold',
|
|
41
|
+
'italic',
|
|
42
|
+
'underline',
|
|
43
|
+
'code',
|
|
44
|
+
'superscript',
|
|
45
|
+
'subscript',
|
|
46
|
+
'strikethrough',
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
enabledNodeTypes: [
|
|
51
|
+
'heading-1',
|
|
52
|
+
'heading-2',
|
|
53
|
+
'heading-3',
|
|
54
|
+
'heading-4',
|
|
55
|
+
'heading-5',
|
|
56
|
+
'heading-6',
|
|
57
|
+
'ordered-list',
|
|
58
|
+
'unordered-list',
|
|
59
|
+
'blockquote',
|
|
60
|
+
'hr',
|
|
61
|
+
'embedded-entry-block',
|
|
62
|
+
'embedded-asset-block',
|
|
63
|
+
'embedded-entry-inline',
|
|
64
|
+
'hyperlink',
|
|
65
|
+
'entry-hyperlink',
|
|
66
|
+
'asset-hyperlink',
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// Add content field
|
|
73
|
+
article.createField('content', {
|
|
74
|
+
name: 'Content',
|
|
75
|
+
type: 'RichText',
|
|
76
|
+
required: false,
|
|
77
|
+
validations: [
|
|
78
|
+
{
|
|
79
|
+
enabledMarks: [
|
|
80
|
+
'bold',
|
|
81
|
+
'italic',
|
|
82
|
+
'underline',
|
|
83
|
+
'code',
|
|
84
|
+
'superscript',
|
|
85
|
+
'subscript',
|
|
86
|
+
'strikethrough',
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
enabledNodeTypes: [
|
|
91
|
+
'heading-1',
|
|
92
|
+
'heading-2',
|
|
93
|
+
'heading-3',
|
|
94
|
+
'heading-4',
|
|
95
|
+
'heading-5',
|
|
96
|
+
'heading-6',
|
|
97
|
+
'ordered-list',
|
|
98
|
+
'unordered-list',
|
|
99
|
+
'blockquote',
|
|
100
|
+
'hr',
|
|
101
|
+
'embedded-entry-block',
|
|
102
|
+
'embedded-asset-block',
|
|
103
|
+
'embedded-entry-inline',
|
|
104
|
+
'hyperlink',
|
|
105
|
+
'entry-hyperlink',
|
|
106
|
+
'asset-hyperlink',
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// Add footnote field
|
|
113
|
+
article.createField('footnote', {
|
|
114
|
+
name: 'Footnote',
|
|
115
|
+
type: 'RichText',
|
|
116
|
+
required: false,
|
|
117
|
+
validations: [
|
|
118
|
+
{
|
|
119
|
+
enabledMarks: [
|
|
120
|
+
'bold',
|
|
121
|
+
'italic',
|
|
122
|
+
'underline',
|
|
123
|
+
'code',
|
|
124
|
+
'superscript',
|
|
125
|
+
'subscript',
|
|
126
|
+
'strikethrough',
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
enabledNodeTypes: [
|
|
131
|
+
'heading-1',
|
|
132
|
+
'heading-2',
|
|
133
|
+
'heading-3',
|
|
134
|
+
'heading-4',
|
|
135
|
+
'heading-5',
|
|
136
|
+
'heading-6',
|
|
137
|
+
'ordered-list',
|
|
138
|
+
'unordered-list',
|
|
139
|
+
'blockquote',
|
|
140
|
+
'hr',
|
|
141
|
+
'embedded-entry-block',
|
|
142
|
+
'embedded-asset-block',
|
|
143
|
+
'embedded-entry-inline',
|
|
144
|
+
'hyperlink',
|
|
145
|
+
'entry-hyperlink',
|
|
146
|
+
'asset-hyperlink',
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// Add heading field
|
|
153
|
+
article.createField('author', {
|
|
154
|
+
name: 'Author',
|
|
155
|
+
type: 'Symbol',
|
|
156
|
+
required: false,
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
//Add top field
|
|
160
|
+
article.createField('top', {
|
|
161
|
+
name: 'Top',
|
|
162
|
+
type: 'Boolean',
|
|
163
|
+
required: false,
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// Add heading field
|
|
167
|
+
article.createField('instagram', {
|
|
168
|
+
name: 'Instagram',
|
|
169
|
+
type: 'Symbol',
|
|
170
|
+
required: false,
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
// Add categories field
|
|
174
|
+
article.createField('categories', {
|
|
175
|
+
name: 'Categories',
|
|
176
|
+
type: 'Array',
|
|
177
|
+
items: {
|
|
178
|
+
type: 'Symbol',
|
|
179
|
+
validations: [],
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
//Add top field
|
|
184
|
+
article.createField('active', {
|
|
185
|
+
name: 'Active',
|
|
186
|
+
type: 'Boolean',
|
|
187
|
+
required: false,
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
//Add date field
|
|
191
|
+
article.createField('date', {
|
|
192
|
+
name: 'Date',
|
|
193
|
+
type: 'Date',
|
|
194
|
+
required: false,
|
|
195
|
+
})
|
|
196
|
+
article.changeFieldControl('date', 'builtin', 'datePicker', {
|
|
197
|
+
format: 'dateAndTime',
|
|
198
|
+
ampm: '24',
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
//Add comments field
|
|
202
|
+
article.createField('comments', {
|
|
203
|
+
name: 'Comments',
|
|
204
|
+
type: 'Array',
|
|
205
|
+
items: {
|
|
206
|
+
type: 'Link',
|
|
207
|
+
linkType: 'Entry',
|
|
208
|
+
validations: [],
|
|
209
|
+
},
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
//Add article type field
|
|
213
|
+
article.createField('articleType', {
|
|
214
|
+
name: 'Article Type',
|
|
215
|
+
type: 'Symbol',
|
|
216
|
+
required: false,
|
|
217
|
+
validations: [
|
|
218
|
+
{
|
|
219
|
+
in: ['Default', 'HCP'],
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
})
|
|
223
|
+
article.changeFieldControl('articleType', 'builtin', 'dropdown', {
|
|
224
|
+
helpText: 'Select the type of article',
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
},
|
|
228
|
+
down: function (migration) {
|
|
229
|
+
migration.deleteContentType('blog-article')
|
|
230
|
+
},
|
|
231
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
const { createClient } = require('contentful-management')
|
|
2
|
+
const readline = require('readline')
|
|
3
|
+
const dotenv = require('dotenv')
|
|
4
|
+
dotenv.config()
|
|
5
|
+
|
|
6
|
+
const args = process.argv.slice(2)
|
|
7
|
+
const getArg = (name) => {
|
|
8
|
+
const index = args.indexOf(`--${name}`)
|
|
9
|
+
return index !== -1 && args[index + 1] ? args[index + 1] : null
|
|
10
|
+
}
|
|
11
|
+
const hasFlag = (name) => args.includes(`--${name}`)
|
|
12
|
+
|
|
13
|
+
function confirm(message) {
|
|
14
|
+
const rl = readline.createInterface({
|
|
15
|
+
input: process.stdin,
|
|
16
|
+
output: process.stdout,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
rl.question(message, (answer) => {
|
|
21
|
+
rl.close()
|
|
22
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes')
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const SPACE_ID = getArg('space-id') || process.env.CONTENTFUL_SPACE_ID
|
|
28
|
+
const ENVIRONMENT_ID = getArg('environment-id') || process.env.CONTENTFUL_ENVIRONMENT_ID || 'master'
|
|
29
|
+
const MANAGEMENT_TOKEN = getArg('management-token') || process.env.CONTENTFUL_MANAGEMENT_TOKEN
|
|
30
|
+
|
|
31
|
+
if (!SPACE_ID || !MANAGEMENT_TOKEN) {
|
|
32
|
+
process.stderr.write('Error: SPACE_ID and MANAGEMENT_TOKEN are required\n')
|
|
33
|
+
process.stderr.write('Use: node migrate-legacy-articles.cjs --space-id <ID> --management-token <TOKEN> [--environment-id <ENV>]\n')
|
|
34
|
+
process.exit(1)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const fieldMapping = {
|
|
38
|
+
slug: 'slug',
|
|
39
|
+
heading: 'heading',
|
|
40
|
+
image: 'image',
|
|
41
|
+
summary: 'summary',
|
|
42
|
+
content: 'content',
|
|
43
|
+
footnote: 'footnote',
|
|
44
|
+
author: 'author',
|
|
45
|
+
top: 'top',
|
|
46
|
+
instagram: 'instagram',
|
|
47
|
+
categories: 'categories',
|
|
48
|
+
active: 'active',
|
|
49
|
+
date: 'date',
|
|
50
|
+
comments: 'comments',
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function mapLegacyEntryToArticle(legacyEntry, sourceContentType) {
|
|
54
|
+
const fields = legacyEntry.fields
|
|
55
|
+
const mappedFields = {}
|
|
56
|
+
|
|
57
|
+
Object.keys(fieldMapping).forEach(newField => {
|
|
58
|
+
const legacyField = fieldMapping[newField]
|
|
59
|
+
|
|
60
|
+
if (fields[legacyField]) {
|
|
61
|
+
mappedFields[newField] = fields[legacyField]
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
if (sourceContentType === 'hcpArticle') {
|
|
66
|
+
Object.keys(mappedFields.slug || {}).forEach(locale => {
|
|
67
|
+
if (!mappedFields.articleType) {
|
|
68
|
+
mappedFields.articleType = {}
|
|
69
|
+
}
|
|
70
|
+
mappedFields.articleType[locale] = 'HCP'
|
|
71
|
+
})
|
|
72
|
+
} else {
|
|
73
|
+
Object.keys(mappedFields.slug || {}).forEach(locale => {
|
|
74
|
+
if (!mappedFields.articleType) {
|
|
75
|
+
mappedFields.articleType = {}
|
|
76
|
+
}
|
|
77
|
+
mappedFields.articleType[locale] = 'Default'
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return mappedFields
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function getAllEntries(environment, contentTypeId) {
|
|
85
|
+
const entries = []
|
|
86
|
+
let skip = 0
|
|
87
|
+
const limit = 1000
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
let hasMore = true
|
|
91
|
+
while (hasMore) {
|
|
92
|
+
const response = await environment.getEntries({
|
|
93
|
+
content_type: contentTypeId,
|
|
94
|
+
skip,
|
|
95
|
+
limit,
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
entries.push(...response.items)
|
|
99
|
+
|
|
100
|
+
if (response.items.length < limit) {
|
|
101
|
+
hasMore = false
|
|
102
|
+
} else {
|
|
103
|
+
skip += limit
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
// If content type doesn't exist, return empty array
|
|
108
|
+
if (error.name === 'InvalidQuery' ||
|
|
109
|
+
(error.details && error.details.errors &&
|
|
110
|
+
error.details.errors.some(e => e.name === 'unknownContentType'))) {
|
|
111
|
+
return []
|
|
112
|
+
}
|
|
113
|
+
throw error
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return entries
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function migrateContentType(environment, legacyContentTypeId) {
|
|
120
|
+
const legacyEntries = await getAllEntries(environment, legacyContentTypeId)
|
|
121
|
+
|
|
122
|
+
if (legacyEntries.length === 0) {
|
|
123
|
+
return { successCount: 0, errorCount: 0 }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let successCount = 0
|
|
127
|
+
let errorCount = 0
|
|
128
|
+
|
|
129
|
+
for (const legacyEntry of legacyEntries) {
|
|
130
|
+
const entryId = legacyEntry.sys.id
|
|
131
|
+
const slug = legacyEntry.fields.slug?.['en-US'] || entryId
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const mappedFields = mapLegacyEntryToArticle(legacyEntry, legacyContentTypeId)
|
|
135
|
+
|
|
136
|
+
if (!mappedFields.slug || Object.keys(mappedFields.slug).length === 0) {
|
|
137
|
+
process.stderr.write(` Skipped "${slug}" (${entryId}): missing required slug field\n`)
|
|
138
|
+
errorCount++
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const isPublished = legacyEntry.isPublished()
|
|
143
|
+
const isArchived = legacyEntry.isArchived()
|
|
144
|
+
const isUpdated = legacyEntry.isUpdated()
|
|
145
|
+
const isDraft = !isPublished && !isArchived
|
|
146
|
+
|
|
147
|
+
const newEntry = await environment.createEntry('blog-article', {
|
|
148
|
+
fields: mappedFields,
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
if (isPublished) {
|
|
152
|
+
await newEntry.publish()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (isArchived) {
|
|
156
|
+
await newEntry.archive()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (isPublished && isUpdated && !isArchived) {
|
|
160
|
+
const reloadedEntry = await environment.getEntry(newEntry.sys.id)
|
|
161
|
+
|
|
162
|
+
let fieldUpdated = false
|
|
163
|
+
|
|
164
|
+
if (reloadedEntry.fields.active) {
|
|
165
|
+
const firstLocale = Object.keys(reloadedEntry.fields.active)[0]
|
|
166
|
+
if (firstLocale !== undefined) {
|
|
167
|
+
const originalValue = reloadedEntry.fields.active[firstLocale]
|
|
168
|
+
reloadedEntry.fields.active[firstLocale] = !originalValue
|
|
169
|
+
await reloadedEntry.update()
|
|
170
|
+
const toggledEntry = await environment.getEntry(newEntry.sys.id)
|
|
171
|
+
toggledEntry.fields.active[firstLocale] = originalValue
|
|
172
|
+
await toggledEntry.update()
|
|
173
|
+
fieldUpdated = true
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!fieldUpdated && reloadedEntry.fields.heading) {
|
|
178
|
+
const firstLocale = Object.keys(reloadedEntry.fields.heading)[0]
|
|
179
|
+
if (firstLocale) {
|
|
180
|
+
const currentHeading = reloadedEntry.fields.heading[firstLocale]
|
|
181
|
+
reloadedEntry.fields.heading[firstLocale] = currentHeading + ' '
|
|
182
|
+
await reloadedEntry.update()
|
|
183
|
+
const fixedEntry = await environment.getEntry(newEntry.sys.id)
|
|
184
|
+
fixedEntry.fields.heading[firstLocale] = currentHeading
|
|
185
|
+
await fixedEntry.update()
|
|
186
|
+
fieldUpdated = true
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (!fieldUpdated) {
|
|
191
|
+
await reloadedEntry.update()
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const statusInfo = []
|
|
196
|
+
if (isDraft) statusInfo.push('draft')
|
|
197
|
+
if (isPublished && !isUpdated) statusInfo.push('published')
|
|
198
|
+
if (isPublished && isUpdated) statusInfo.push('changed')
|
|
199
|
+
if (isArchived) statusInfo.push('archived')
|
|
200
|
+
const statusText = statusInfo.length > 0 ? ` [${statusInfo.join(', ')}]` : ''
|
|
201
|
+
|
|
202
|
+
process.stdout.write(` Migrated: "${slug}" (${entryId})${statusText}\n`)
|
|
203
|
+
successCount++
|
|
204
|
+
} catch (error) {
|
|
205
|
+
const errorMessage = error.message || 'Unknown error'
|
|
206
|
+
const errorDetails = error.details?.errors?.[0]?.details || ''
|
|
207
|
+
process.stderr.write(` Failed "${slug}" (${entryId}): ${errorMessage} ${errorDetails}\n`)
|
|
208
|
+
errorCount++
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return { successCount, errorCount }
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function main() {
|
|
216
|
+
const client = createClient({
|
|
217
|
+
accessToken: MANAGEMENT_TOKEN,
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
const space = await client.getSpace(SPACE_ID)
|
|
221
|
+
const environment = await space.getEnvironment(ENVIRONMENT_ID)
|
|
222
|
+
|
|
223
|
+
// Pre-check: show environment info and confirm
|
|
224
|
+
const articleCount = (await getAllEntries(environment, 'article')).length
|
|
225
|
+
const hcpArticleCount = (await getAllEntries(environment, 'hcpArticle')).length
|
|
226
|
+
|
|
227
|
+
process.stdout.write('\n=== Migration Preview ===\n')
|
|
228
|
+
process.stdout.write(`Space ID: ${SPACE_ID}\n`)
|
|
229
|
+
process.stdout.write(`Environment: ${ENVIRONMENT_ID}\n`)
|
|
230
|
+
process.stdout.write(`Space Name: ${space.name}\n`)
|
|
231
|
+
process.stdout.write(`\nEntries to migrate:\n`)
|
|
232
|
+
process.stdout.write(` - article: ${articleCount} entries\n`)
|
|
233
|
+
process.stdout.write(` - hcpArticle: ${hcpArticleCount} entries\n`)
|
|
234
|
+
process.stdout.write(` - Total: ${articleCount + hcpArticleCount} entries\n\n`)
|
|
235
|
+
|
|
236
|
+
if (!hasFlag('yes') && !hasFlag('y')) {
|
|
237
|
+
const confirmed = await confirm('Proceed with migration? (y/N): ')
|
|
238
|
+
if (!confirmed) {
|
|
239
|
+
process.stdout.write('Migration cancelled.\n')
|
|
240
|
+
process.exit(0)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
await environment.getContentType('blog-article')
|
|
246
|
+
} catch (error) {
|
|
247
|
+
process.stderr.write('Error: Content type "blog-article" does not exist.\n')
|
|
248
|
+
process.stderr.write(' Run migration 0061-create-new-article.cjs first.\n')
|
|
249
|
+
process.exit(1)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Migrate entries from article
|
|
253
|
+
process.stdout.write('\nMigrating "article" entries...\n')
|
|
254
|
+
const articleResults = await migrateContentType(environment, 'article')
|
|
255
|
+
process.stdout.write(`Done: ${articleResults.successCount} success, ${articleResults.errorCount} errors\n`)
|
|
256
|
+
|
|
257
|
+
// Migrate entries from hcpArticle
|
|
258
|
+
process.stdout.write('\nMigrating "hcpArticle" entries...\n')
|
|
259
|
+
const hcpResults = await migrateContentType(environment, 'hcpArticle')
|
|
260
|
+
process.stdout.write(`Done: ${hcpResults.successCount} success, ${hcpResults.errorCount} errors\n`)
|
|
261
|
+
|
|
262
|
+
// Final summary
|
|
263
|
+
const totalSuccess = articleResults.successCount + hcpResults.successCount
|
|
264
|
+
const totalErrors = articleResults.errorCount + hcpResults.errorCount
|
|
265
|
+
process.stdout.write(`\nMigration complete: ${totalSuccess} migrated, ${totalErrors} failed\n`)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
main().catch(error => {
|
|
269
|
+
process.stderr.write(`\n❌ Fatal error: ${error.message}\n`)
|
|
270
|
+
if (error.stack) {
|
|
271
|
+
process.stderr.write(`${error.stack}\n`)
|
|
272
|
+
}
|
|
273
|
+
process.exit(1)
|
|
274
|
+
})
|
|
275
|
+
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cooperco/cooper-component-library",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.72",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
"@primevue/themes": "^4.0.0",
|
|
33
33
|
"@vueuse/components": "^11.1.0",
|
|
34
34
|
"@vueuse/core": "^11.1.0",
|
|
35
|
+
"contentful-management": "^11.68.0",
|
|
35
36
|
"contentful-migration": "^4.23.2",
|
|
37
|
+
"dotenv": "^17.2.3",
|
|
36
38
|
"graphql": "^16.9.0",
|
|
37
39
|
"graphql-tag": "^2.12.6",
|
|
38
40
|
"primeicons": "^7.0.0",
|