· 6 years ago · Mar 24, 2019, 08:24 PM
1const StoryblokClient = require('storyblok-js-client')
2
3const Storyblok = new StoryblokClient({
4 oauthToken: PROTECTED_VAR
5})
6
7const sourceSpaceId = SOURCE_SPACE_ID
8const targetSpaceId = TARGET_SPACE_ID
9
10const Sync = {
11 targetComponents: [],
12 sourceComponents: [],
13 existingFolders: [],
14 componentsCount: 0,
15 componentsSynced: 0,
16
17 async syncFolders() {
18 let sourceFolders = await Storyblok.get(`spaces/${sourceSpaceId}/stories`, {
19 folder_only: 1,
20 per_page: 1000,
21 sort_by: 'slug:asc'
22 })
23 let syncedFolders = {}
24
25 for (var i = 0; i < sourceFolders.data.stories.length; i++) {
26 let folder = sourceFolders.data.stories[i]
27 let folderId = folder.id
28 delete folder.id
29 delete folder.created_at
30
31 if (folder.parent_id) {
32 // Parent child resolving
33 if (!syncedFolders[folderId]) {
34 let folderSlug = folder.full_slug.split('/')
35 let parentFolderSlug = folderSlug.splice(0, folderSlug.length - 1).join('/')
36
37 let existingFolders = await Storyblok.get(`spaces/${targetSpaceId}/stories`, {
38 with_slug: parentFolderSlug
39 })
40
41 if (existingFolders.data.stories.length) {
42 folder.parent_id = existingFolders.data.stories[0].id
43 } else {
44 folder.parent_id = 0
45 }
46 } else {
47 folder.parent_id = syncedFolders[folderId]
48 }
49 }
50
51 try {
52 let newFolder = await Storyblok.post(`spaces/${targetSpaceId}/stories`, {
53 story: folder
54 })
55
56 syncedFolders[folderId] = newFolder.data.story.id
57 console.log(`Folder ${newFolder.data.story.name} created`)
58 } catch(e) {
59 console.log(`Folder ${folder.name} already exists`)
60 // console.log(e.response.data)
61 }
62 }
63
64 this.existingFolders = await Storyblok.get(`spaces/${targetSpaceId}/stories`, {
65 folder_only: 1,
66 per_page: 1000,
67 sort_by: 'slug:asc'
68 })
69 },
70
71 async syncRoles() {
72 let roles = await Storyblok.get(`spaces/${sourceSpaceId}/space_roles`)
73 let existingRoles = await Storyblok.get(`spaces/${targetSpaceId}/space_roles`)
74
75 for (var i = 0; i < roles.data.space_roles.length; i++) {
76 let space_role = roles.data.space_roles[i]
77 delete space_role.id
78 delete space_role.created_at
79
80 space_role.allowed_paths = []
81
82 space_role.resolved_allowed_paths.forEach((path) => {
83 let folders = this.existingFolders.data.stories.filter((story) => {
84 return story.full_slug + '/' == path
85 })
86
87 if (folders.length) {
88 space_role.allowed_paths.push(folders[0].id)
89 }
90 })
91
92 let existingRole = existingRoles.data.space_roles.filter((role) => {
93 return role.role == space_role.role
94 })
95 if (existingRole.length) {
96 await Storyblok.put(`spaces/${targetSpaceId}/space_roles/${existingRole[0].id}`, {
97 space_role: space_role
98 })
99 } else {
100 await Storyblok.post(`spaces/${targetSpaceId}/space_roles`, {
101 space_role: space_role
102 })
103 }
104 console.log(`Role ${space_role.role} synced`)
105 }
106 },
107
108 async syncComponents() {
109 this.targetComponents = await Storyblok.get(`spaces/${targetSpaceId}/components`)
110 this.sourceComponents = await Storyblok.get(`spaces/${sourceSpaceId}/components`)
111
112 for (var i = 0; i < this.sourceComponents.data.components.length; i++) {
113 let component = this.sourceComponents.data.components[i]
114
115 delete component.id
116 delete component.created_at
117
118 // Create new component on target space
119 try {
120 await Storyblok.post(`spaces/${targetSpaceId}/components`, {
121 component: component
122 })
123 console.log(`Component ${component.name} synced`)
124 } catch(e) {
125 if (e.response.status == 422) {
126 await Storyblok.put(`spaces/${targetSpaceId}/components/${this.getTargetComponentId(component.name)}`, {
127 component: component
128 })
129 console.log(`Component ${component.name} synced`)
130 } else {
131 console.log(`Component ${component.name} sync failed`)
132 }
133 }
134 }
135 },
136
137 getTargetComponentId(name) {
138 let comps = this.targetComponents.data.components.filter((comp) => {
139 return comp.name == name
140 })
141
142 return comps[0].id
143 }
144}
145
146exports.handler = async function (event, context) {
147 await Sync.syncFolders()
148 await Sync.syncRoles()
149
150 return {
151 statusCode: '200',
152 body: JSON.stringify({success: 'Folders and roles synced.'})
153 }
154}