|
const dotenv = require('dotenv'); |
|
const { upload } = require('@contentful/app-scripts'); |
|
const { createClient } = require('contentful-management') |
|
const fs = require('fs') |
|
const path = require('path') |
|
const mkdirp = require('mkdirp') |
|
const chalk = require('chalk') |
|
const HTMLParser = require('node-html-parser') |
|
|
|
const log = { |
|
debug: (message, ...args) => console.log(`${chalk.bgGray.black(' debug ')} ${message}`, ...args.map(i => chalk.gray.underline(i))), |
|
info: (message, ...args) => console.log(`${chalk.bgBlue.black(' info ')} ${message}`, ...args.map(i => chalk.blueBright.underline(i))), |
|
error: (message, ...args) => console.log(`${chalk.bgRed.black(' error ')} ${message}`, ...args.map(i => chalk.redBright.underline(i))), |
|
success: (message, ...args) => console.log(`${chalk.bgGreen.black(' success ')} ${message}`, ...args.map(i => chalk.greenBright.underline(i))) |
|
} |
|
|
|
const requiredEnvVar = (environment, variable) => { |
|
if (!environment[variable]) { |
|
log.error('Variable %s is required. Add it to your environment or to the .env file.', variable) |
|
process.exit(1) |
|
} |
|
|
|
return environment[variable] |
|
} |
|
|
|
const getConfig = () => { |
|
dotenv.config() |
|
|
|
return { |
|
accessToken: requiredEnvVar(process.env, 'CONTENTFUL_MANAGEMENT_TOKEN'), |
|
spaceId: requiredEnvVar(process.env, 'CONTENTFUL_SPACE_ID'), |
|
environmentId: requiredEnvVar(process.env, 'CONTENTFUL_ENVIRONMENT_ID'), |
|
extensionId: requiredEnvVar(process.env, 'CONTENTFUL_EXTENSION_ID'), |
|
organizationId: requiredEnvVar(process.env, 'CONTENTFUL_ORGANIZATION_ID'), |
|
buildUrl: path.join(__dirname, './build') |
|
} |
|
} |
|
|
|
/** |
|
* Takes an extension body and converts (best effort) to an app body |
|
* |
|
* @param {string} srcDoc |
|
*/ |
|
const appizeSrcDocs = (srcDoc) => { |
|
const tree = HTMLParser.parse(srcDoc) |
|
|
|
const uieSDKScriptNode = tree |
|
.querySelectorAll('script') |
|
.find(i => /contentful-ui-extensions-sdk/.test(i.getAttribute('src'))) |
|
|
|
uieSDKScriptNode.setAttribute('src', 'https://unpkg.com/@contentful/app-sdk@3') |
|
|
|
return tree.toString().replace('window.contentfulExtension.init', 'window.contentfulApp.init') |
|
} |
|
|
|
;(async function main () { |
|
console.log(` |
|
|
|
This script will convert an existing Contentful-Hosted UI Extension |
|
to a Contentful-Hosted App. |
|
|
|
`) |
|
const {accessToken, spaceId, environmentId, extensionId, buildUrl, organizationId } = getConfig(); |
|
|
|
log.info('Utilizing space %s, environment %s', spaceId, environmentId); |
|
const client = createClient({ accessToken }, { type: 'plain', |
|
defaults: { |
|
spaceId, |
|
environmentId, |
|
organizationId, |
|
} |
|
}) |
|
|
|
log.info('Getting extension with id %s', extensionId); |
|
const {extension} = await client.extension.get({ extensionId }); |
|
|
|
if (!extension.srcdoc) { |
|
log.error('Extension %s does not have a %s attribute', extensionId, 'srcdoc') |
|
process.exit(1); |
|
} |
|
|
|
log.success('Got extension %s', extension.name); |
|
|
|
log.info('Converting extension to app in %s', buildUrl) |
|
const index = appizeSrcDocs(extension.srcdoc) |
|
|
|
mkdirp.sync(buildUrl); |
|
fs.writeFileSync(path.join(buildUrl, 'index.html'), index); |
|
|
|
log.success('Successfully converted app') |
|
|
|
log.info('Creating an app definition for extension %s', extension.name) |
|
const definition = await client.appDefinition.create({organizationId}, { |
|
name: extension.name, |
|
src: 'http://localhost:3000', |
|
locations: [ |
|
{ |
|
location: 'entry-field', |
|
fieldTypes: extension.fieldTypes |
|
} |
|
], |
|
parameters: extension.parameters |
|
}) |
|
|
|
log.success('Created app %s', definition.sys.id) |
|
|
|
log.info('Hosting your app in Contentful') |
|
await upload.nonInteractive({ |
|
organizationId, |
|
definitionId: definition.sys.id, |
|
token: accessToken, |
|
bundleDir: buildUrl, |
|
comment: 'Autogenerated', |
|
skipActivation: false, |
|
}) |
|
log.success('Your %s extension is now a Contentful-hosted App! 🎉', extension.name) |
|
})(); |