Skip to content

Instantly share code, notes, and snippets.

@TimBeyer
Last active December 11, 2017 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TimBeyer/89238eeadb358d1641cfedcaf670a8c8 to your computer and use it in GitHub Desktop.
Save TimBeyer/89238eeadb358d1641cfedcaf670a8c8 to your computer and use it in GitHub Desktop.
Generate a migration from a content type
{
"name": "What is a collection",
"description": null,
"displayField": "plainText",
"fields": [
{
"id": "plainText",
"name": "plainText",
"type": "Text",
"localized": false,
"required": false,
"validations": [],
"disabled": false,
"omitted": false
},
{
"id": "markdown",
"name": "markdown",
"type": "Text",
"localized": false,
"required": false,
"validations": [],
"disabled": false,
"omitted": false
},
{
"id": "number",
"name": "number",
"type": "Number",
"localized": false,
"required": false,
"validations": [],
"disabled": false,
"omitted": false
},
{
"id": "date",
"name": "date",
"type": "Date",
"localized": false,
"required": false,
"validations": [],
"disabled": false,
"omitted": false
},
{
"id": "switch",
"name": "switch",
"type": "Boolean",
"localized": false,
"required": false,
"validations": [],
"disabled": false,
"omitted": false
}
],
"sys": {
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "zd2pt2bc3cts"
}
},
"id": "what-is-a-collection",
"type": "ContentType",
"createdAt": "2017-09-12T08:51:02.797Z",
"updatedAt": "2017-09-12T12:15:07.715Z",
"createdBy": {
"sys": {
"type": "Link",
"linkType": "User",
"id": "2T4JQZGOuHn2xzFE3Nht1J"
}
},
"updatedBy": {
"sys": {
"type": "Link",
"linkType": "User",
"id": "6c10tlsIDlE3qvnNoTwYa5"
}
},
"publishedCounter": 2,
"version": 4,
"publishedBy": {
"sys": {
"type": "Link",
"linkType": "User",
"id": "6c10tlsIDlE3qvnNoTwYa5"
}
},
"publishedVersion": 3,
"firstPublishedAt": "2017-09-12T08:51:03.261Z",
"publishedAt": "2017-09-12T12:15:07.715Z"
}
}
'use strict';
const contentType = require('./content-type.json');
// const { namedTypes: n, builders: b } = require('ast-types');
const recast = require('recast');
const camelCase = require('camelcase');
const b = recast.types.builders;
const _ = require('lodash');
const toAst = require('to-ast');
const prettier = require('prettier');
const wrapMigrationWithBase = function (blockStatement) {
const migration = b.program([
b.expressionStatement(
b.assignmentExpression(
'=',
b.memberExpression(
b.identifier('module'),
b.identifier('exports')
),
b.functionExpression(
null,
[b.identifier('migration')],
blockStatement
)
)
)
])
return migration
}
const createCallChain = function (base, chain) {
if (chain.length === 0) {
return base;
}
const [identifier, value] = chain[0];
const rest = chain.slice(1);
return createCallChain(b.callExpression(
b.memberExpression(
base,
b.identifier(identifier)
),
[toAst(value)]
), rest)
};
const createContentType = function (ct) {
const id = ct.sys.id;
const { name, description, displayField } = ct;
const chain = [
['name', name],
['description', description],
['displayField', displayField]
].filter(([id, value]) => value !== null);
const variableName = camelCase(id);
const createCallExpression = b.callExpression(
b.memberExpression(
b.identifier('migration'),
b.identifier('createContentType')
),
[b.literal(id)]
);
const callChain = createCallChain(createCallExpression, chain);
const withDeclaration = b.variableDeclaration(
'const',
[
b.variableDeclarator(
b.identifier(variableName),
callChain
)
]
)
return withDeclaration
}
const createField = function (ctId, field) {
const fieldId = field.id;
const ctVariable = camelCase(ctId);
const chain = Object.keys(_.omit(field, 'id')).map((key) => {
return [key, field[key]];
});
return createCallChain(
b.callExpression(
b.memberExpression(
b.identifier(ctVariable),
b.identifier('createField')
),
[b.literal(fieldId)]
),
chain
)
}
const fieldCreators = contentType.fields.map((field) => {
return b.expressionStatement(createField(contentType.sys.id, field));
})
const blockContents = [createContentType(contentType)].concat(fieldCreators);
const migration = wrapMigrationWithBase(b.blockStatement(blockContents));
const output = recast.prettyPrint(migration, { tabWidth: 2 }).code;
console.log(prettier.format(output))
module.exports = function(migration) {
const whatIsACollection = migration
.createContentType("what-is-a-collection")
.name("What is a collection")
.displayField("plainText");
whatIsACollection
.createField("plainText")
.name("plainText")
.type("Text")
.localized(false)
.required(false)
.validations([])
.disabled(false)
.omitted(false);
whatIsACollection
.createField("markdown")
.name("markdown")
.type("Text")
.localized(false)
.required(false)
.validations([])
.disabled(false)
.omitted(false);
whatIsACollection
.createField("number")
.name("number")
.type("Number")
.localized(false)
.required(false)
.validations([])
.disabled(false)
.omitted(false);
whatIsACollection
.createField("date")
.name("date")
.type("Date")
.localized(false)
.required(false)
.validations([])
.disabled(false)
.omitted(false);
whatIsACollection
.createField("switch")
.name("switch")
.type("Boolean")
.localized(false)
.required(false)
.validations([])
.disabled(false)
.omitted(false);
};
{
"name": "content-type-to-migration",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"ast-types": "^0.9.12",
"camelcase": "^4.1.0",
"lodash": "^4.17.4",
"prettier": "^1.6.1",
"recast": "^0.12.6",
"to-ast": "^1.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment