Last active
April 3, 2019 14:08
-
-
Save samuells/a2e84e4f790cef899ad1b8433ffec812 to your computer and use it in GitHub Desktop.
Little script to swap field translation of Storyblok content
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const StoryblokClient = require('storyblok-js-client') | |
// ******* START | |
// YES&NO Prompt handler | |
// thx to https://www.npmjs.com/package/yesno | |
const options = { | |
yes: [ 'yes', 'y' ], | |
no: [ 'no', 'n' ] | |
} | |
function defaultInvalidHandler (question, defaultvalue, callback, yesvalues, novalues) { | |
process.stdout.write('\nInvalid Response.\n') | |
process.stdout.write('Answer either yes : (' + yesvalues.join(', ')+') \n') | |
process.stdout.write('Or no: (' + novalues.join(', ') + ') \n\n') | |
ask(question, defaultvalue, callback, yesvalues, novalues) | |
} | |
let invalidHandlerFunction = defaultInvalidHandler | |
function ask (question, defaultvalue, callback, yesvalues, novalues) { | |
if (!invalidHandlerFunction) { | |
invalidHandlerFunction = defaultInvalidHandler | |
} | |
yesvalues = yesvalues ? yesvalues : options.yes | |
novalues = novalues ? novalues : options.no | |
yesvalues = yesvalues.map(function (v) { return v.toLowerCase() }) | |
novalues = novalues.map(function (v) { return v.toLowerCase() }) | |
process.stdout.write(question + ' ') | |
process.stdin.setEncoding('utf8') | |
process.stdin.once('data', function (val) { | |
var result | |
var cleaned = val.trim().toLowerCase() | |
if (cleaned == '' && defaultvalue != null) { | |
result = defaultvalue | |
} | |
else if (yesvalues.indexOf(cleaned) >= 0) { | |
result = true | |
} | |
else if (novalues.indexOf(cleaned) >= 0) { | |
result = false | |
} | |
else { | |
invalidHandlerFunction(question, defaultvalue, callback, yesvalues, novalues) | |
return | |
} | |
process.stdin.unref() | |
callback(result) | |
}).resume() | |
} | |
// ******* END of YES&NO Handler | |
// Settings of script | |
let oauthToken = "" | |
let spaceId = "" // id of space where to swap content | |
let fromLang = "" // language from which will be copy content into default | |
let toLang = "" // language where will be copy content from default | |
let i18nComponentsFields = {} // translatable fields per page | |
let Storyblok | |
function addTransKeyFromComponent(component) { | |
// creates i18nComponentsFields | |
const compName = component.name | |
const compSchema = component.schema | |
const compKeys = Object.keys(compSchema) | |
let i18nKeys = [] | |
compKeys.map( key => { | |
if (compSchema[key].translatable) { | |
i18nKeys.push(key) | |
} | |
}) | |
i18nComponentsFields[compName] = i18nKeys | |
console.log(`✅ got all i18n fields of ${compName}`) | |
} | |
function swapContentOnStories(page=1) { | |
Storyblok.get(`spaces/${spaceId}/stories`, { | |
page | |
}) | |
.then(response => { | |
response.data.stories.map(story => getStoryContent(story.id)) | |
if (response.total - response.perPage * page > 0) { | |
swapContentOnStories(page + 1) // get all stories from Storyblok - response is paged!! | |
} | |
}).catch(error => { | |
console.log(error) | |
}) | |
} | |
function getStoryContent(storyId) { | |
Storyblok.get(`spaces/${spaceId}/stories/${storyId}`, {}) | |
.then(response => { | |
swapContentOfStory(response.data.story.content) | |
console.log(`✅ swapped content on ${response.data.story.name}`) | |
updateStory(storyId, response.data.story) | |
}).catch(error => { | |
console.log(error) | |
}) | |
} | |
function swapContentOfStory(content) { | |
const i18nContentKeys = i18nComponentsFields[content.component] | |
const contentKeys = Object.keys(content) | |
contentKeys.map(key => { | |
if(i18nContentKeys && i18nContentKeys.includes(key)) { | |
content[`${key}__i18n__${toLang}`] = content[key] | |
// if no translation leave the default | |
content[key] = content[`${key}__i18n__${fromLang}`] ? content[`${key}__i18n__${fromLang}`] : content[key] | |
} else if (Array.isArray(content[key])) { | |
content[key].map(component => swapContentOfStory(component)) | |
} else { | |
// Do nothing - not i18n field | |
} | |
}) | |
} | |
function updateStory(storyId, updatedStory) { | |
Storyblok.put(`spaces/${spaceId}/stories/${storyId}`, { | |
"story": updatedStory, | |
"force_update": 1 | |
}).then(response => { | |
console.log(`⬆️ successfully updated - [${response.data.story.name}] `) | |
}).catch(error => { | |
console.log(error) | |
}) | |
} | |
// Run script | |
process.stdout.write('\x1B[2J\x1B[0f\u001b[0;0H'); // clear console/terminal | |
if (process.argv.length < 7) { | |
console.log('\x1b[31m%s\x1b[0m', `Error: Expected 4 argument: | |
- "oauthToken" - Managment API Token of user (not space) from Storyblok | |
- "spaceId" - if of space, where will the swap happen | |
- "fromLang" - which language will be set as default | |
- "toLang" - as which language will be set original default content`) | |
process.exit(1) | |
} else if(process.argv.indexOf('--token') > -1) { | |
const oauthTokenIndex = process.argv.indexOf('--token') | |
if (oauthTokenIndex > -1) { | |
oauthToken = process.argv[oauthTokenIndex + 1] | |
spaceId = process.argv[oauthTokenIndex + 2] | |
fromLang = process.argv[oauthTokenIndex + 3] | |
toLang = process.argv[oauthTokenIndex + 4] | |
} | |
if (fromLang === toLang) { | |
console.log('\x1b[31m%s\x1b[0m', `Error: "fromLang" and "toLang" are equal!`) | |
process.exit(1) | |
} | |
ask(`Are you sure you want to: | |
- move default language content into '${toLang}' translation | |
- '${fromLang}' translation set as default?`, true, function (ok) { | |
if (ok) { | |
console.log("🚚 🚚 🚚 🚚 ... moving content ... "); | |
// Initialize the client with the oauth token | |
Storyblok = new StoryblokClient({ | |
oauthToken // user Auth Token from Storyblok | |
}) | |
// Get schemas of all components | |
Storyblok.get(`spaces/${spaceId}/components`, {}) | |
.then(response => { | |
response.data.components.map(component => addTransKeyFromComponent(component)) | |
// After get of all translatable fields start content swapping | |
swapContentOnStories(1) | |
}).catch(error => { | |
console.log(error) | |
}) | |
} else { | |
console.log("\x1b[34m%s\x1b[0m", "Okey, no swapping today!"); | |
process.exit(1) | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This script assume Arrays are not translatable.
eg. how to run it: