From a3709d56c128653952456098d7f8114fbfd285e0 Mon Sep 17 00:00:00 2001 From: Christian Zoppi Date: Thu, 14 Mar 2024 10:38:28 +0100 Subject: [PATCH] Revert "Add command for Typescript typedefs generation" --- .eslintrc.js | 1 + .gitignore | 5 - .vscode/settings.json | 8 - README.md | 86 - __mocks__/fs-extra.js | 24 +- build.config.ts | 23 - jest.config.js | 1 - package.json | 24 +- src/cli.js | 64 +- src/cli.ts | 597 -- src/constants.js | 21 +- src/tasks/delete-component.js | 6 +- src/tasks/delete-components.js | 13 +- src/tasks/delete-datasources.js | 4 +- src/tasks/generate-typescript-typedefs.ts | 79 - src/tasks/import/import.js | 10 +- src/tasks/import/utils.js | 38 +- src/tasks/index.js | 47 +- src/tasks/list-spaces.js | 7 +- src/tasks/migrations/generate.js | 16 +- src/tasks/migrations/rollback.js | 11 +- src/tasks/migrations/run.js | 21 +- src/tasks/migrations/utils.js | 58 +- src/tasks/pull-components.js | 6 +- src/tasks/pull-languages.js | 6 +- src/tasks/push-components.js | 15 +- src/tasks/quickstart.js | 8 +- src/tasks/scaffold.js | 6 +- src/tasks/sync-commands/component-groups.js | 8 +- src/tasks/sync-commands/components.js | 15 +- src/tasks/sync-commands/datasources.js | 8 +- src/tasks/sync.js | 14 +- src/tasks/templates/migration-file.js | 2 +- src/tasks/templates/teaser.js | 2 +- src/types/generate-typescript-typedefs.ts | 95 - src/types/index.ts | 1 - src/utils/api.js | 23 +- src/utils/capitalize.js | 2 +- src/utils/creds.js | 10 +- src/utils/find-by-property.js | 2 +- src/utils/get-questions.js | 4 +- src/utils/index.js | 20 +- src/utils/last-step.js | 10 +- src/utils/parse-error.js | 2 +- src/utils/presets-lib.js | 13 +- src/utils/region.js | 8 +- src/utils/replace.js | 6 +- src/utils/save-file-factory.js | 4 +- .../typescript/generateTypesFromJSONSchema.ts | 502 -- .../storyblokProvidedPropertyTypes.ts | 296 - tests/constants.js | 37 +- tests/units/delete-component.spec.js | 5 +- tests/units/delete-components.spec.js | 24 +- tests/units/generate.spec.js | 153 +- tests/units/import.spec.js | 59 +- tests/units/is-authorized.spec.js | 42 +- tests/units/list-spaces.spec.js | 15 +- tests/units/login.spec.js | 33 +- tests/units/logout.spec.js | 6 +- tests/units/migrations/change_teaser_date.js | 2 +- .../migrations/change_teaser_headline.js | 3 +- .../migrations/change_teaser_subtitle.js | 4 +- tests/units/pull-components.spec.js | 75 +- tests/units/pull-languages.spec.js | 11 +- tests/units/push-components.spec.js | 12 +- tests/units/quickstart.spec.js | 20 +- tests/units/run-migration.spec.js | 90 +- tests/units/scaffold.spec.js | 22 +- tests/units/signup.spec.js | 38 +- tests/units/sync-components.spec.js | 77 +- tests/units/sync.spec.js | 10 +- tsconfig.json | 20 - yarn.lock | 4974 ++++++++--------- 73 files changed, 2885 insertions(+), 5099 deletions(-) delete mode 100644 .vscode/settings.json delete mode 100644 build.config.ts delete mode 100644 jest.config.js delete mode 100755 src/cli.ts delete mode 100644 src/tasks/generate-typescript-typedefs.ts delete mode 100644 src/types/generate-typescript-typedefs.ts delete mode 100644 src/types/index.ts delete mode 100644 src/utils/typescript/generateTypesFromJSONSchema.ts delete mode 100644 src/utils/typescript/storyblokProvidedPropertyTypes.ts delete mode 100644 tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index 77bb1f2..f030bfa 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,6 @@ module.exports = { env: { + commonjs: true, es6: true, node: true, 'jest/globals': true diff --git a/.gitignore b/.gitignore index 1d7923c..3ba1750 100644 --- a/.gitignore +++ b/.gitignore @@ -107,8 +107,3 @@ dist # IntelliJ .idea/ - -# CLI generated files -components.*.json -presets.*.json -storyblok-component-types.d.ts \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e283958..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "editor.formatOnSave": false, - "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - }, - "editor.defaultFormatter": "esbenp.prettier-vscode" -} diff --git a/README.md b/README.md index a76a021..5ef42a6 100644 --- a/README.md +++ b/README.md @@ -554,92 +554,6 @@ module.exports = function (block) { } ``` -## Typescript -It is possible to generate Typescript type definitions for your Storyblok components. The type definitions are based on the components' JSON Schema that can be retrieved with the [pull-components](#pull-components) command. - -### generate-typescript-typedefs - -Generate a file with the type definitions for the specified components' JSON Schemas. - -```sh -$ storyblok generate-typescript-typedefs - --sourceFilePaths - --destinationFilePath - --typeNamesPrefix - --typeNamesSuffix - --JSONSchemaToTSOptionsPath - --customFieldTypesParserPath -``` - -#### Options - -* `sourceFilePaths` (alias `source`) : Path(s) to the components JSON file(s) as comma separated values -* `destinationFilePath` (alias `target`) *optional* : Path to the Typescript file that will be generated (*default*: `storyblok-component-types.d.ts`) -* `typeNamesPrefix` (alias `titlePrefix`) *optional* : A prefix that will be prepended to all the names of the generated types -* `typeNamesSuffix` (alias `titleSuffix`) *optional* : A suffix that will be appended to all the names of the generated types (*default*: `Storyblok`) -* `JSONSchemaToTSOptionsPath` (alias `compilerOptions`) *optional* : Path to a JSON file with a list of options supported by `json-schema-to-typescript` -* `customFieldTypesParserPath` (alias `customTypeParser`) *optional* : Path to the parser file for Custom Field Types - -#### Examples - -```sh -# Generate typedefs for the components retrieved for the space `12345` via the `storyblok pull-components` command -$ storyblok generate-typescript-typedefs --sourceFilePaths ./components.12345.json - -# Generate typedefs for multiple components sources -$ storyblok generate-typescript-typedefs --sourceFilePaths ./fooComponent-12345.json,./barComponent-12345.json - -# Custom path for the typedefs file -$ storyblok generate-typescript-typedefs --sourceFilePaths ./components.12345.json --destinationFilePath ./types/my-custom-type-file.d.ts - -# Provide customized options for the JSON-schema-to-typescript lib -$ storyblok generate-typescript-typedefs --sourceFilePaths ./components.12345.json --JSONSchemaToTSOptionsPath ./PathToJSONFileWithCustomOptions.json - -# Provide a custom field types parser -$ storyblok generate-typescript-typedefs --sourceFilePaths ./components.12345.json --customFieldTypesParserPath ./customFieldTypesParser.js - -``` - -##### JSON Schema to Typescript options -This script uses the `json-schema-to-typescript` library under the hood. Values of the [JSON Schema to Typescript options](https://www.npmjs.com/package/json-schema-to-typescript#options) can be customized providing a JSON file to the `JSONSchemaToTSOptionsPath`. - -The default values used for the `storyblok generate-typescript-typedefs` command are the same defaults for the library except for two properties: -* `bannerComment` - The default value is `""` to remove noise from the generated Typedefs file -* `unknownAny` - The default value is `false` because it can help a smoother Typescript adoption on a JS project - -Example `JSONSchemaToTSOptions` JSON file to remove `additionalProperties` from the generated type definitions: - -```json -{ - "additionalProperties": false, -} -``` - -##### Custom Field Types parser -Storyblok [Custom Field Types](https://www.storyblok.com/docs/plugins/field-plugins/introduction) do not have inherent JSONSchema definitions. To overcome this issue, you can provide a path to a script exporting a parser function that should render a [JSONSchema Node](https://json-schema.org/learn/getting-started-step-by-step#define-properties) for each of your Custom Field Types. The parser function should be exported as a default export, like in the following example: -```js -export default function (key, obj) { - switch (obj.field_type) { - case 'my-custom-field-type-name': - return { - [key]: { - type: 'object', - properties: { - color: { type: 'string' } - }, - required: ['color'] - } - } - default: - return {} - } -} -``` - - - - - ## You're looking for a headstart? Check out our guides for client side apps (VueJS, Angular, React, ...), static site (Jekyll, NuxtJs, ...), dynamic site examples (Node, PHP, Python, Laravel, ...) on our [Getting Started](https://www.storyblok.com/getting-started) page. diff --git a/__mocks__/fs-extra.js b/__mocks__/fs-extra.js index 6a4db47..d608bdd 100644 --- a/__mocks__/fs-extra.js +++ b/__mocks__/fs-extra.js @@ -1,6 +1,4 @@ -import { jest } from '@jest/globals' - -const fs = jest.createMockFromModule('fs-extra') +const fs = jest.genMockFromModule('fs-extra') let mockFiles = Object.create(null) @@ -21,15 +19,15 @@ const readFile = jest.fn((path) => { mockFiles = path return Promise.resolve(JSON.stringify([ { - id: 0, - full_slug: 'another-post', - content: { - _uid: '5647c21f-8813-4f8a-ad38-b9f74e0e7c89', - text: 'Donec tortor mauris, mollis vel pretium vitae, lacinia nec sapien. Donec erat neque, ullamcorper tincidunt iaculis sit amet, pharetra bibendum ipsum. Nunc mattis risus ac ante consequat nec pulvinar neque molestie. Etiam interdum nunc at metus lacinia non varius erat dignissim. Integer elementum, felis id facilisis vulputate, ipsum tellus venenatis dui, at blandit nibh massa in dolor. Cras a ultricies sapien. Vivamus adipiscing feugiat pharetra.', - image: 'https://a.storyblok.com/f/51376/884x750/3bff01d851/international.svg', - title: 'test', - category: 'news', - component: 'Product' + "id": 0, + "full_slug": "another-post", + "content": { + "_uid": "5647c21f-8813-4f8a-ad38-b9f74e0e7c89", + "text": "Donec tortor mauris, mollis vel pretium vitae, lacinia nec sapien. Donec erat neque, ullamcorper tincidunt iaculis sit amet, pharetra bibendum ipsum. Nunc mattis risus ac ante consequat nec pulvinar neque molestie. Etiam interdum nunc at metus lacinia non varius erat dignissim. Integer elementum, felis id facilisis vulputate, ipsum tellus venenatis dui, at blandit nibh massa in dolor. Cras a ultricies sapien. Vivamus adipiscing feugiat pharetra.", + "image": "https://a.storyblok.com/f/51376/884x750/3bff01d851/international.svg", + "title": "test", + "category": "news", + "component": "Product" } } ])) @@ -62,4 +60,4 @@ fs.__clearMockFiles = __clearMockFiles fs.__setMockFiles = __setMockFiles -export default fs +module.exports = fs diff --git a/build.config.ts b/build.config.ts deleted file mode 100644 index 514613d..0000000 --- a/build.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { defineBuildConfig } from "unbuild"; - -export default defineBuildConfig({ - declaration: true, - rollup: { - inlineDependencies: true, - resolve: { - exportConditions: ["production", "node"] as any, - }, - }, - entries: ["src/cli"], - externals: [ - "@nuxt/test-utils", - "fsevents", - "node:url", - "node:buffer", - "node:path", - "node:child_process", - "node:process", - "node:path", - "node:os", - ], -}); diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 351f7ed..0000000 --- a/jest.config.js +++ /dev/null @@ -1 +0,0 @@ -export default { transform: {} } diff --git a/package.json b/package.json index a88a672..06e7b0d 100644 --- a/package.json +++ b/package.json @@ -12,21 +12,15 @@ "node", "javascript" ], - "main": "./dist/cli.mjs", - "files": [ - "dist/**" - ], + "main": "src/cli.js", "bin": { - "storyblok": "./dist/cli.mjs" + "storyblok": "src/cli.js" }, - "type": "module", "scripts": { - "build": "unbuild", - "dev": "npm run build && ./dist/cli.mjs", "lint": "eslint src/", "lint:fix": "eslint src/ --fix", - "test:unit": "node --experimental-vm-modules ./node_modules/.bin/jest --silent", - "test:coverage": "node --experimental-vm-modules ./node_modules/.bin/jest --coverage" + "test:unit": "jest --silent", + "test:coverage": "jest --coverage" }, "author": "Dominik Angerer , Alexander Feiglstorfer ", "license": "MIT", @@ -42,7 +36,6 @@ "fs-extra": "^9.0.1", "git-clone": "^0.1.0", "inquirer": "^7.3.2", - "json-schema-to-typescript": "^13.1.2", "lodash": "^4.17.21", "netrc": "0.1.4", "on-change": "^2.0.1", @@ -50,7 +43,7 @@ "p-series": "^2.1.0", "path": "^0.12.7", "simple-uuid": "^0.0.1", - "storyblok-js-client": "^6.7.1", + "storyblok-js-client": "^5.14.0", "update-notifier": "^5.1.0", "xml-js": "^1.6.11" }, @@ -66,16 +59,11 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", - "jest": "^29.7.0", - "typescript": "^5.3.3", - "unbuild": "^2.0.0" + "jest": "^26.1.0" }, "release": { "branches": [ "master" ] - }, - "prettier": { - "printWidth": 120 } } diff --git a/src/cli.js b/src/cli.js index 71a5799..0a64f77 100755 --- a/src/cli.js +++ b/src/cli.js @@ -1,20 +1,20 @@ #!/usr/bin/env node -import commander from 'commander' -import chalk from 'chalk' -import clear from 'clear' -import figlet from 'figlet' -import inquirer from 'inquirer' -import { ALL_REGIONS, EU_CODE, isRegion } from '@storyblok/region-helper' -import updateNotifier from 'update-notifier' -import fs from 'fs' -import tasks from './tasks' -import { getQuestions, lastStep, api, creds } from './utils' -import { SYNC_TYPES, COMMANDS } from './constants' - -const rawPkg = fs.readFileSync('./package.json') -const pkg = JSON.parse(rawPkg) +const commander = require('commander') const program = new commander.Command() + +const chalk = require('chalk') +const clear = require('clear') +const figlet = require('figlet') +const inquirer = require('inquirer') +const { ALL_REGIONS, EU_CODE, isRegion } = require('@storyblok/region-helper') + +const updateNotifier = require('update-notifier') +const pkg = require('../package.json') + +const tasks = require('./tasks') +const { getQuestions, lastStep, api, creds } = require('./utils') +const { SYNC_TYPES, COMMANDS } = require('./constants') const allRegionsText = ALL_REGIONS.join(', ') clear() @@ -523,42 +523,6 @@ program } }) -// Generate Typescript type definitions -program - .command(COMMANDS.GENERATE_TYPESCRIPT_TYPEDEFS) - // Providing backward-compatible flags with Storyblok Generate TS https://github.com/dohomi/storyblok-generate-ts - .requiredOption('--source, --sourceFilePaths ', 'Path(s) to the components JSON file(s) as comma separated values', (paths, _previous) => paths.split(',')) - .option('--target, --destinationFilePath ', 'Path to the Typescript file that will be generated (default: `storyblok-component-types.d.ts`)') - .option('--titlePrefix, --typeNamesPrefix ', 'A prefix that will be prepended to all the names of the generated types') - .option('--titleSuffix, --typeNamesSuffix ', 'A suffix that will be appended to all the names of the generated types (*default*: `Storyblok`)') - .option('--compilerOptions, --JSONSchemaToTSOptionsPath ', 'Path to a JSON file with a list of options supported by json-schema-to-typescript') - .option('--customTypeParser, --customFieldTypesParserPath ', 'Path to the parser file for Custom Field Types') - .action((options) => { - console.log(`${chalk.blue('-')} Executing ${COMMANDS.GENERATE_TYPESCRIPT_TYPEDEFS} task`) - - const { - sourceFilePaths, - destinationFilePath, - typeNamesPrefix, - typeNamesSuffix, - customFieldTypesParserPath, - JSONSchemaToTSOptionsPath - } = options - - try { - tasks.generateTypescriptTypedefs({ - sourceFilePaths, - destinationFilePath, - typeNamesPrefix, - typeNamesSuffix, - customFieldTypesParserPath, - JSONSchemaToTSOptionsPath - }) - } catch (e) { - errorHandler(e, COMMANDS.GENERATE_TYPESCRIPT_TYPEDEFS) - } - }) - program.parse(process.argv) if (program.rawArgs.length <= 2) { diff --git a/src/cli.ts b/src/cli.ts deleted file mode 100755 index 30bf257..0000000 --- a/src/cli.ts +++ /dev/null @@ -1,597 +0,0 @@ -#!/usr/bin/env node -//@ts-nocheck -import commander from "commander"; -import chalk from "chalk"; -import clear from "clear"; -import figlet from "figlet"; -import inquirer from "inquirer"; -import { ALL_REGIONS, EU_CODE, isRegion } from "@storyblok/region-helper"; -import updateNotifier from "update-notifier"; -import fs from "fs"; -import tasks from "./tasks"; -import { getQuestions, lastStep, api, creds } from "./utils"; -import { SYNC_TYPES, COMMANDS } from "./constants"; -export * from "./types/index"; - -const rawPkg = fs.readFileSync("./package.json"); -const pkg = JSON.parse(rawPkg); -const program = new commander.Command(); -const allRegionsText = ALL_REGIONS.join(", "); - -clear(); -console.log(chalk.cyan(figlet.textSync("storyblok"))); -console.log(); -console.log(); -console.log("Hi, welcome to the Storyblok CLI"); -console.log(); - -// non-intrusive notify users if an update available -const notifyOptions = { - isGlobal: true, -}; - -updateNotifier({ pkg }).notify(notifyOptions); - -program.version(pkg.version); - -program.option("-s, --space [value]", "space ID"); - -// login -program - .command(COMMANDS.LOGIN) - .description("Login to the Storyblok cli") - .option("-t, --token ", "Token to login directly without questions, like for CI environments") - .option( - "-r, --region ", - `The region you would like to work in. Please keep in mind that the region must match the region of your space. This region flag will be used for the other cli's commands. You can use the values: ${allRegionsText}.`, - EU_CODE - ) - .action(async (options) => { - const { token, region } = options; - - if (api.isAuthorized()) { - console.log( - chalk.green("✓") + - " The user has been already logged. If you want to change the logged user, you must logout and login again" - ); - return; - } - - if (!isRegion(region)) { - console.log( - chalk.red("X") + - `The provided region ${region} is not valid. Please use one of the following: ${allRegionsText}` - ); - return; - } - - try { - await api.processLogin(token, region); - process.exit(0); - } catch (e) { - console.log(chalk.red("X") + " An error occurred when logging the user: " + e.message); - process.exit(1); - } - }); - -// getUser -program - .command("user") - .description("Get the currently logged in user") - .action(async () => { - if (api.isAuthorized()) { - try { - const user = await api.getUser(); - console.log(chalk.green("✓") + ` Hi ${user.friendly_name}, you current logged in with: ${creds.get().email}`); - } catch (e) { - console.log(chalk.red("X") + ` Please check if your current region matches your user's region: ${e.message}.`); - } finally { - process.exit(0); - } - } - console.log(chalk.red("X") + " There is currently no user logged."); - }); - -// logout -program - .command(COMMANDS.LOGOUT) - .description("Logout from the Storyblok cli") - .action(async () => { - try { - await api.logout(); - console.log("Logged out successfully! Token has been removed from .netrc file."); - process.exit(0); - } catch (e) { - console.log(chalk.red("X") + " An error occurred when logging out the user: " + e.message); - process.exit(1); - } - }); - -// pull-languages -program - .command("pull-languages") - .description("Download your space's languages schema as json") - .action(async () => { - console.log(`${chalk.blue("-")} Executing pull-languages task`); - const space = program.space; - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID."); - process.exit(0); - } - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(space); - await tasks.pullLanguages(api, { space }); - } catch (e) { - console.log(chalk.red("X") + " An error occurred when executing the pull-languages task: " + e.message); - process.exit(1); - } - }); - -// pull-components -program - .command(COMMANDS.PULL_COMPONENTS) - .option("--sf, --separate-files [value]", "Argument to create a single file for each component") - .option("-p, --path ", "Path to save the component files") - .option("-f, --file-name ", "custom name to be used in file(s) name instead of space id") - .description("Download your space's components schema as json") - .action(async (options) => { - console.log(`${chalk.blue("-")} Executing pull-components task`); - const space = program.space; - const { separateFiles, path } = options; - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID."); - process.exit(0); - } - - const fileName = options.fileName ? options.fileName : space; - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(space); - await tasks.pullComponents(api, { fileName, separateFiles, path }); - } catch (e) { - errorHandler(e, COMMANDS.PULL_COMPONENTS); - } - }); - -// push-components -program - .command(COMMANDS.PUSH_COMPONENTS + " ") - .option("-p, --presets-source ", "Path to presets file") - .description( - "Download your space's components schema as json. The source parameter can be a URL to your JSON file or a path to it" - ) - .action(async (source, options) => { - console.log(`${chalk.blue("-")} Executing push-components task`); - const space = program.space; - const presetsSource = options.presetsSource; - - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID."); - process.exit(0); - } - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(space); - await tasks.pushComponents(api, { source, presetsSource }); - } catch (e) { - errorHandler(e, COMMANDS.PUSH_COMPONENTS); - } - }); - -// delete-component -program - .command("delete-component ") - .description("Delete a single component on your space.") - .action(async (component) => { - console.log(`${chalk.blue("-")} Executing delete-component task`); - const space = program.space; - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID."); - process.exit(0); - } - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(space); - await tasks.deleteComponent(api, { comp: component }); - } catch (e) { - console.log(chalk.red("X") + " An error occurred when executing the delete-component task: " + e.message); - process.exit(1); - } - }); - -// delete-components -program - .command("delete-components ") - .description("Delete all components in your space that occur in your source file.") - .option("-r, --reverse", "Delete all components in your space that do not appear in your source.", false) - .option("--dryrun", "Does not perform any delete changes on your space.") - .action(async (source, options) => { - console.log(`${chalk.blue("-")} Executing delete-components task`); - const space = program.space; - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID."); - process.exit(0); - } - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(space); - await tasks.deleteComponents(api, { source, dryRun: !!options.dryrun, reversed: !!options.reverse }); - } catch (e) { - console.log(chalk.red("X") + " An error occurred when executing the delete-component task: " + e.message); - process.exit(1); - } - }); - -// scaffold -program - .command(COMMANDS.SCAFFOLD + " ") - .description("Scaffold component") - .action(async (name) => { - console.log(`${chalk.blue("-")} Scaffolding a component\n`); - - if (api.isAuthorized()) { - api.accessToken = creds.get().token || null; - } - - try { - await tasks.scaffold(api, name, program.space); - console.log(chalk.green("✓") + " Generated files: "); - console.log(chalk.green("✓") + " - views/components/_" + name + ".liquid"); - console.log(chalk.green("✓") + " - source/scss/components/below/_" + name + ".scss"); - process.exit(0); - } catch (e) { - console.log( - chalk.red("X") + " An error occurred when executing operations to create the component: " + e.message - ); - process.exit(1); - } - }); - -// select -program - .command(COMMANDS.SELECT) - .description("Usage to kickstart a boilerplate, fieldtype or theme") - .action(async () => { - console.log(`${chalk.blue("-")} Select a boilerplate, fieldtype or theme to initialize\n`); - - try { - const questions = getQuestions("select"); - const answers = await inquirer.prompt(questions); - - await lastStep(answers); - } catch (e) { - console.error(chalk.red("X") + " An error ocurred when execute the select command: " + e.message); - process.exit(1); - } - }); - -// sync -program - .command(COMMANDS.SYNC) - .description("Sync schemas, roles, folders and stories between spaces") - .requiredOption( - "--type ", - "Define what will be sync. Can be components, folders, stories, datasources or roles" - ) - .requiredOption("--source ", "Source space id") - .requiredOption("--target ", "Target space id") - .option("--components-groups ", "Synchronize components based on their group UUIDs separated by commas") - .action(async (options) => { - console.log(`${chalk.blue("-")} Sync data between spaces\n`); - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - const { type, target, source, componentsGroups } = options; - - const _componentsGroups = componentsGroups ? componentsGroups.split(",") : null; - - const token = creds.get().token || null; - - const _types = type.split(",") || []; - _types.forEach((_type) => { - if (!SYNC_TYPES.includes(_type)) { - throw new Error(`The type ${_type} is not valid`); - } - }); - - await tasks.sync(_types, { - api, - token, - target, - source, - _componentsGroups, - }); - - console.log("\n" + chalk.green("✓") + " Sync data between spaces successfully completed"); - } catch (e) { - errorHandler(e, COMMANDS.SYNC); - } - }); - -// quickstart -program - .command(COMMANDS.QUICKSTART) - .description("Start a project quickly") - .action(async () => { - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - const space = program.space; - const questions = getQuestions("quickstart", { space }, api); - const answers = await inquirer.prompt(questions); - await tasks.quickstart(api, answers, space); - } catch (e) { - console.log(chalk.red("X") + " An error ocurred when execute quickstart operations: " + e.message); - process.exit(1); - } - }); - -program - .command(COMMANDS.GENERATE_MIGRATION) - .description("Generate a content migration file") - .requiredOption("-c, --component ", "Name of the component") - .requiredOption("-f, --field ", "Name of the component field") - .action(async (options) => { - const { field = "" } = options; - const { component = "" } = options; - - const space = program.space; - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID."); - process.exit(1); - } - - console.log(`${chalk.blue("-")} Creating the migration file in ./migrations/change_${component}_${field}.js\n`); - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(space); - await tasks.generateMigration(api, component, field); - } catch (e) { - console.log(chalk.red("X") + " An error ocurred when generate the migration file: " + e.message); - process.exit(1); - } - }); - -program - .command(COMMANDS.RUN_MIGRATION) - .description("Run a migration file") - .requiredOption("-c, --component ", "Name of the component") - .requiredOption("-f, --field ", "Name of the component field") - .option("--dryrun", "Do not update the story content") - .option("--publish ", "Publish the content. It can be: all, published or published-with-changes") - .option("--publish-languages ", "Publish specific languages") - .action(async (options) => { - const field = options.field || ""; - const component = options.component || ""; - const isDryrun = !!options.dryrun; - const publish = options.publish || null; - const publishLanguages = options.publishLanguages || ""; - - const space = program.space; - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID."); - process.exit(1); - } - - const publishOptionsAvailable = ["all", "published", "published-with-changes"]; - if (publish && !publishOptionsAvailable.includes(publish)) { - console.log( - chalk.red("X") + " Please provide a correct publish option: all, published, or published-with-changes" - ); - process.exit(1); - } - - console.log(`${chalk.blue("-")} Processing the migration ./migrations/change_${component}_${field}.js\n`); - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(space); - await tasks.runMigration(api, component, field, { isDryrun, publish, publishLanguages }); - } catch (e) { - console.log(chalk.red("X") + " An error ocurred when run the migration file: " + e.message); - process.exit(1); - } - }); - -program - .command(COMMANDS.ROLLBACK_MIGRATION) - .description("Rollback-migration a migration file") - .requiredOption("-c, --component ", "Name of the component") - .requiredOption("-f, --field ", "Name of the component field") - .action(async (options) => { - const field = options.field || ""; - const component = options.component || ""; - const space = program.space; - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID."); - process.exit(1); - } - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(space); - - await tasks.rollbackMigration(api, field, component); - } catch (e) { - console.log(chalk.red("X") + " An error ocurred when run rollback-migration: " + e.message); - process.exit(1); - } - }); - -// list spaces -program - .command(COMMANDS.SPACES) - .description("List all spaces of the logged account") - .action(async () => { - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - const { region } = creds.get(); - - await tasks.listSpaces(api, region); - } catch (e) { - console.log(chalk.red("X") + " An error ocurred to listing spaces: " + e.message); - process.exit(1); - } - }); - -// import data -program - .command(COMMANDS.IMPORT) - .description("Import data from other systems and relational databases.") - .requiredOption("-f, --file ", "Name of the file") - .requiredOption("-t, --type ", "Type of the content") - .option("-fr, --folder ", "(Optional) This is a Id of folder in storyblok") - .option("-d, --delimiter ", 'If you are using a csv file, put the file delimiter, the default is ";"') - .action(async (options) => { - const space = program.space; - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - if (!space) { - console.log(chalk.red("X") + " Please provide the space as argument --space ."); - return; - } - - api.setSpaceId(space); - await tasks.importFiles(api, options); - - console.log(`${chalk.green("✓")} The import process was executed with success!`); - } catch (e) { - console.log(chalk.red("X") + " An error ocurred to import data : " + e.message); - process.exit(1); - } - }); - -// delete-datasources -program - .command(COMMANDS.DELETE_DATASOURCES) - .requiredOption("--space-id ", "Space id") - .option("--by-slug ", "Delete datasources by slug") - .option("--by-name ", "Delete datasources by name") - .action(async (options) => { - console.log(`${chalk.blue("-")} Executing ${COMMANDS.DELETE_DATASOURCES} task`); - - const { spaceId, bySlug, byName } = options; - - try { - if (!api.isAuthorized()) { - await api.processLogin(); - } - - api.setSpaceId(spaceId); - - await tasks.deleteDatasources(api, { byName, bySlug }); - } catch (e) { - errorHandler(e, COMMANDS.DELETE_DATASOURCES); - } - }); - -// Generate Typescript type definitions -program - .command(COMMANDS.GENERATE_TYPESCRIPT_TYPEDEFS) - // Providing backward-compatible flags with Storyblok Generate TS https://github.com/dohomi/storyblok-generate-ts - .requiredOption( - "--source, --sourceFilePaths ", - "Path(s) to the components JSON file(s) as comma separated values", - (paths, _previous) => paths.split(",") - ) - .option( - "--target, --destinationFilePath ", - "Path to the Typescript file that will be generated (default: `storyblok-component-types.d.ts`)" - ) - .option( - "--titlePrefix, --typeNamesPrefix ", - "A prefix that will be prepended to all the names of the generated types" - ) - .option( - "--titleSuffix, --typeNamesSuffix ", - "A suffix that will be appended to all the names of the generated types (*default*: `Storyblok`)" - ) - .option( - "--compilerOptions, --JSONSchemaToTSOptionsPath ", - "Path to a JSON file with a list of options supported by json-schema-to-typescript" - ) - .option("--customTypeParser, --customFieldTypesParserPath ", "Path to the parser file for Custom Field Types") - .action((options) => { - console.log(`${chalk.blue("-")} Executing ${COMMANDS.GENERATE_TYPESCRIPT_TYPEDEFS} task`); - - const { - sourceFilePaths, - destinationFilePath, - typeNamesPrefix, - typeNamesSuffix, - customFieldTypesParserPath, - JSONSchemaToTSOptionsPath, - } = options; - - try { - tasks.generateTypescriptTypedefs({ - sourceFilePaths, - destinationFilePath, - typeNamesPrefix, - typeNamesSuffix, - customFieldTypesParserPath, - JSONSchemaToTSOptionsPath, - }); - } catch (e) { - errorHandler(e, COMMANDS.GENERATE_TYPESCRIPT_TYPEDEFS); - } - }); - -program.parse(process.argv); - -if (program.rawArgs.length <= 2) { - program.help(); -} - -function errorHandler(e, command) { - if (/404/.test(e.message)) { - const allRegionsButDefault = ALL_REGIONS.filter((region) => region !== EU_CODE).join(" ,"); - console.log( - chalk.yellow("/!\\") + - ` If your space was not created under ${EU_CODE} region, you must provide the region (${allRegionsButDefault}) upon login.` - ); - } else { - console.log(chalk.red("X") + " An error occurred when executing the " + command + " task: " + e || e.message); - } - process.exit(1); -} diff --git a/src/constants.js b/src/constants.js index e6db717..e73742b 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,12 +1,6 @@ -export const SYNC_TYPES = [ - 'folders', - 'components', - 'roles', - 'stories', - 'datasources' -] +const SYNC_TYPES = ['folders', 'components', 'roles', 'stories', 'datasources'] -export const COMMANDS = { +const COMMANDS = { GENERATE_MIGRATION: 'generate-migration', IMPORT: 'import', LOGIN: 'login', @@ -20,11 +14,16 @@ export const COMMANDS = { SELECT: 'select', SPACES: 'spaces', SYNC: 'sync', - DELETE_DATASOURCES: 'delete-datasources', - GENERATE_TYPESCRIPT_TYPEDEFS: 'generate-typescript-typedefs' + DELETE_DATASOURCES: 'delete-datasources' } -export const DEFAULT_AGENT = { +const DEFAULT_AGENT = { SB_Agent: 'SB-CLI', SB_Agent_Version: process.env.npm_package_version || '3.0.0' } + +module.exports = { + SYNC_TYPES, + COMMANDS, + DEFAULT_AGENT +} diff --git a/src/tasks/delete-component.js b/src/tasks/delete-component.js index 94410ab..98d2cd1 100644 --- a/src/tasks/delete-component.js +++ b/src/tasks/delete-component.js @@ -1,5 +1,5 @@ -import chalk from 'chalk' -import { getComponentsFromName } from './migrations/utils' +const chalk = require('chalk') +const { getComponentsFromName } = require('./migrations/utils') /** * @@ -29,4 +29,4 @@ const deleteComponent = async (api, { comp, dryrun = false }) => { return Promise.reject(new Error(e)) } } -export default deleteComponent +module.exports = deleteComponent diff --git a/src/tasks/delete-components.js b/src/tasks/delete-components.js index cda0f97..b8494a5 100644 --- a/src/tasks/delete-components.js +++ b/src/tasks/delete-components.js @@ -1,9 +1,8 @@ -import chalk from 'chalk' -import axios from 'axios' -import fs from 'fs' -import lodash from 'lodash' -import deleteComponent from './delete-component' -const { isEmpty } = lodash +const chalk = require('chalk') +const axios = require('axios') +const fs = require('fs') +const isEmpty = require('lodash/isEmpty') +const deleteComponent = require('./delete-component') const isUrl = source => source.indexOf('http') === 0 @@ -110,4 +109,4 @@ const deleteComponentAndSkip = async (api, c, dryrun) => { } } -export default deleteComponents +module.exports = deleteComponents diff --git a/src/tasks/delete-datasources.js b/src/tasks/delete-datasources.js index 080f130..4ff7c02 100644 --- a/src/tasks/delete-datasources.js +++ b/src/tasks/delete-datasources.js @@ -1,4 +1,4 @@ -import chalk from 'chalk' +const chalk = require('chalk') /** * @method deleteDatasources @@ -38,4 +38,4 @@ const deleteDatasources = async (api, options) => { } } -export default deleteDatasources +module.exports = deleteDatasources diff --git a/src/tasks/generate-typescript-typedefs.ts b/src/tasks/generate-typescript-typedefs.ts deleted file mode 100644 index d5413e7..0000000 --- a/src/tasks/generate-typescript-typedefs.ts +++ /dev/null @@ -1,79 +0,0 @@ -import chalk from "chalk"; -import fs from "fs"; -import type { GenerateTypescriptTypedefsCLIOptions, JSONSchemaToTSOptions } from "../types"; -import { GenerateTypesFromJSONSchemas } from "../utils/typescript/generateTypesFromJSONSchema"; -import type { JSONSchema } from "json-schema-to-typescript"; - -type GenerateTSTypedefs = (options: GenerateTypescriptTypedefsCLIOptions) => void; - -const generateTypescriptTypedefs: GenerateTSTypedefs = async ({ - sourceFilePaths, - destinationFilePath = "./storyblok-component-types.d.ts", - typeNamesPrefix, - typeNamesSuffix = "Storyblok", - customFieldTypesParserPath, - JSONSchemaToTSOptionsPath, -}) => { - /** - * Get JSON Schemas from files looking at all the paths provided - * @param paths An array of paths to read from - * @returns An array of components JSONSchemas - */ - const getJSONSchemasFromPaths = (paths: string[]): JSONSchema[] | null => { - try { - return paths.map((sourceFilePath) => JSON.parse(fs.readFileSync(sourceFilePath, "utf8"))); - } catch (e) { - console.error( - `${chalk.red("X")} - Could not load JSON files from the provided paths: ${paths}. Please check if those files exist.` - ); - return null; - } - }; - - /** - * Get user-provided options for json-schema-to-typescript https://www.npmjs.com/package/json-schema-to-typescript#options - * @param path Path to a JSON file with the options - * @returns A POJO with the options - */ - const getJSONSchemaToTSOptionsFromPath = (path: string): Record | null => { - try { - return JSON.parse(fs.readFileSync(path, "utf8")); - } catch (e) { - console.error( - `${chalk.red("X")} - Could not load options from the JSON file at ${path}. Please check if the file exists and if it's properly formatted.` - ); - return null; - } - }; - - const JSONSchemaToTSCustomOptions = - JSONSchemaToTSOptionsPath && getJSONSchemaToTSOptionsFromPath(JSONSchemaToTSOptionsPath); - - // Merge custom provided options to our defaults - const JSONSchemaToTSOptions: JSONSchemaToTSOptions = { - bannerComment: "", // Remove much noise from the Typedefs file - unknownAny: false, // Smoother transition from a non-TS codebase to a TS codebase - ...JSONSchemaToTSCustomOptions, - }; - - const componentsJSONSchemaArray = getJSONSchemasFromPaths(sourceFilePaths)?.flatMap( - (componentsJSONSchema) => componentsJSONSchema.components || componentsJSONSchema - ); - - if (componentsJSONSchemaArray && componentsJSONSchemaArray.length > 0) { - const generator = await GenerateTypesFromJSONSchemas.init(componentsJSONSchemaArray, { - sourceFilePaths, - destinationFilePath, - typeNamesPrefix, - typeNamesSuffix, - customFieldTypesParserPath, - JSONSchemaToTSCustomOptions: JSONSchemaToTSOptions, - }); - - return await generator.generateTSFile(); - } -}; - -export default generateTypescriptTypedefs; diff --git a/src/tasks/import/import.js b/src/tasks/import/import.js index d32f359..e622706 100644 --- a/src/tasks/import/import.js +++ b/src/tasks/import/import.js @@ -1,5 +1,9 @@ -import chalk from 'chalk' -import { convertFile, sendContent, discoverExtension } from './utils' +const chalk = require('chalk') +const { + convertFile, + sendContent, + discoverExtension +} = require('./utils') /** * @typedef {Object} ImportDataOptions @@ -33,4 +37,4 @@ const importFiles = async (api, options) => { return Promise.reject(e) } } -export default importFiles +module.exports = importFiles diff --git a/src/tasks/import/utils.js b/src/tasks/import/utils.js index 17d0927..32d8e98 100644 --- a/src/tasks/import/utils.js +++ b/src/tasks/import/utils.js @@ -1,17 +1,17 @@ -import csvReader from 'fast-csv' -import xmlConverter from 'xml-js' -import chalk from 'chalk' -import path from 'path' -import fs from 'fs' -import lodash from 'lodash' -const { isArray } = lodash +const csvReader = require('fast-csv') +const xmlConverter = require('xml-js') +const chalk = require('chalk') +const path = require('path') +const fs = require('fs') +const { isArray } = require('lodash') /** * @method discoverExtension * @param {String} fileName - Name of the file * @return {String} */ -export const discoverExtension = (fileName) => { + +const discoverExtension = (fileName) => { const extension = path.extname(fileName) if (extension !== '') { @@ -27,7 +27,7 @@ export const discoverExtension = (fileName) => { * @param {Object} contents - Object with the content * @return {Promise} */ -export const sendContent = async (api, contents) => { +const sendContent = async (api, contents) => { for (const story of contents) { try { console.log( @@ -66,7 +66,8 @@ const removeJsonTextAttribute = (value, parentElement) => { * @param {String} delimiter - Csv file delimiter, default value is ';' * @return {Promise} */ -export const csvParser = (data, typeOfContent, folderID = 0, delimiter = ';') => { + +const csvParser = (data, typeOfContent, folderID = 0, delimiter = ';') => { return new Promise((resolve, reject) => { console.log() console.log(`${chalk.blue('-')} Reading CSV file... `) @@ -130,7 +131,8 @@ const xmlFactoryOfStories = (line, typeOfContent, folderID) => { * @param {Number} folderID - Storyblok folder id, default value is 0 * @return {Promise} */ -export const xmlParser = async (data, typeOfContent, folderID = 0) => { + +const xmlParser = async (data, typeOfContent, folderID = 0) => { return new Promise((resolve, reject) => { console.log() console.log(`${chalk.blue('-')} Reading XML file... `) @@ -164,7 +166,8 @@ export const xmlParser = async (data, typeOfContent, folderID = 0) => { * @param {Number} folderID - Storyblok folder id, default value is 0 * @return {Promise} */ -export const jsonParser = async (data, typeOfContent, folderID = 0) => { + +const jsonParser = async (data, typeOfContent, folderID = 0) => { console.log() console.log(`${chalk.blue('-')} Reading JSON file... `) console.log() @@ -198,7 +201,7 @@ export const jsonParser = async (data, typeOfContent, folderID = 0) => { * @param {string} extension file extension * @param {ConvertFileOptions} options options to parser functions */ -export const convertFile = (file, extension, options) => { +const convertFile = (file, extension, options) => { const { type, folder, @@ -220,3 +223,12 @@ export const convertFile = (file, extension, options) => { return Promise.reject(new Error('This file extension is not supported. Please use .xml, .json or .csv')) } + +module.exports = { + csvParser, + xmlParser, + jsonParser, + sendContent, + convertFile, + discoverExtension +} diff --git a/src/tasks/index.js b/src/tasks/index.js index 25543f5..c6a2e27 100644 --- a/src/tasks/index.js +++ b/src/tasks/index.js @@ -1,33 +1,16 @@ -import sync from './sync' -import scaffold from './scaffold' -import quickstart from './quickstart' -import pullComponents from './pull-components' -import pullLanguages from './pull-languages' -import pushComponents from './push-components' -import generateMigration from './migrations/generate' -import runMigration from './migrations/run' -import rollbackMigration from './migrations/rollback' -import listSpaces from './list-spaces' -import importFiles from './import/import' -import deleteComponent from './delete-component' -import deleteComponents from './delete-components' -import deleteDatasources from './delete-datasources' -import generateTypescriptTypedefs from './generate-typescript-typedefs' - -export default { - sync, - scaffold, - quickstart, - pullComponents, - pullLanguages, - pushComponents, - generateMigration, - runMigration, - rollbackMigration, - listSpaces, - importFiles, - deleteComponent, - deleteComponents, - deleteDatasources, - generateTypescriptTypedefs +module.exports = { + sync: require('./sync'), + scaffold: require('./scaffold'), + quickstart: require('./quickstart'), + pullComponents: require('./pull-components'), + pullLanguages: require('./pull-languages'), + pushComponents: require('./push-components'), + generateMigration: require('./migrations/generate'), + runMigration: require('./migrations/run'), + rollbackMigration: require('./migrations/rollback'), + listSpaces: require('./list-spaces'), + importFiles: require('./import/import'), + deleteComponent: require('./delete-component'), + deleteComponents: require('./delete-components'), + deleteDatasources: require('./delete-datasources') } diff --git a/src/tasks/list-spaces.js b/src/tasks/list-spaces.js index 56f5d1b..e76a053 100644 --- a/src/tasks/list-spaces.js +++ b/src/tasks/list-spaces.js @@ -1,6 +1,5 @@ -import chalk from 'chalk' -import { ALL_REGIONS, getRegionName, CN_CODE } from '@storyblok/region-helper' - +const chalk = require('chalk') +const { ALL_REGIONS, getRegionName, CN_CODE } = require('@storyblok/region-helper') /** * @method listSpaces * @param api - Pass the api instance as a parameter @@ -61,4 +60,4 @@ const listSpaces = async (api, currentRegion) => { } } -export default listSpaces +module.exports = listSpaces diff --git a/src/tasks/migrations/generate.js b/src/tasks/migrations/generate.js index 5cd3627..1c78022 100644 --- a/src/tasks/migrations/generate.js +++ b/src/tasks/migrations/generate.js @@ -1,6 +1,14 @@ -import chalk from 'chalk' -import inquirer from 'inquirer' -import { getPathToFile, checkFileExists, getInquirerOptions, createMigrationFile, checkComponentExists, getNameOfMigrationFile } from './utils' +const chalk = require('chalk') +const inquirer = require('inquirer') + +const { + getPathToFile, + checkFileExists, + getInquirerOptions, + createMigrationFile, + checkComponentExists, + getNameOfMigrationFile +} = require('./utils') /** * @method generateMigration @@ -50,4 +58,4 @@ const generateMigration = async (api, component, field) => { } } -export default generateMigration +module.exports = generateMigration diff --git a/src/tasks/migrations/rollback.js b/src/tasks/migrations/rollback.js index 9c0771f..a80810c 100644 --- a/src/tasks/migrations/rollback.js +++ b/src/tasks/migrations/rollback.js @@ -1,7 +1,10 @@ -import chalk from 'chalk' -import fs from 'fs-extra' -import { checkExistenceFilesInRollBackDirectory, urlTofRollbackMigrationFile } from './utils' +const chalk = require('chalk') +const fs = require('fs-extra') const MIGRATIONS_ROLLBACK_DIRECTORY = `${process.cwd()}/migrations/rollback` +const { + checkExistenceFilesInRollBackDirectory, + urlTofRollbackMigrationFile +} = require('./utils') /** * @method rollbackMigration @@ -64,4 +67,4 @@ const rollbackMigration = async (api, field, component) => { } } -export default rollbackMigration +module.exports = rollbackMigration diff --git a/src/tasks/migrations/run.js b/src/tasks/migrations/run.js index f7a5237..e3113a2 100644 --- a/src/tasks/migrations/run.js +++ b/src/tasks/migrations/run.js @@ -1,9 +1,14 @@ -import chalk from 'chalk' -import lodash from 'lodash' -import { getPathToFile, checkFileExists, processMigration, getStoriesByComponent, getNameOfMigrationFile, createRollbackFile } from './utils' - -// Separate import because apparently `cloneDeep` is not exported as named export -const { isEmpty, cloneDeep, isEqual} = lodash +const chalk = require('chalk') +const { isEmpty, cloneDeep, isEqual } = require('lodash') + +const { + getPathToFile, + checkFileExists, + processMigration, + getStoriesByComponent, + getNameOfMigrationFile, + createRollbackFile +} = require('./utils') /** * @method isStoryPublishedWithoutChanges @@ -59,7 +64,7 @@ const runMigration = async (api, component, field, options = {}) => { console.log( `${chalk.blue('-')} Getting the user defined migration function` ) - const migrationFn = (await import(pathToFile)).default; + const migrationFn = require(pathToFile) if (typeof migrationFn !== 'function') { throw new Error("The migration file doesn't export a function") @@ -151,4 +156,4 @@ const runMigration = async (api, component, field, options = {}) => { } } -export default runMigration +module.exports = runMigration diff --git a/src/tasks/migrations/utils.js b/src/tasks/migrations/utils.js index 37328ef..3839f77 100644 --- a/src/tasks/migrations/utils.js +++ b/src/tasks/migrations/utils.js @@ -1,11 +1,10 @@ -import onChange from 'on-change' -import lodash from 'lodash' -import fs from 'fs-extra' -import chalk from 'chalk' -import { parseError } from '../../utils' -import migrationTemplate from '../templates/migration-file' -const { isArray, isPlainObject, has, isEmpty, template, truncate } = lodash +const onChange = require('on-change') +const { isArray, isPlainObject, has, isEmpty, template, truncate } = require('lodash') +const fs = require('fs-extra') +const chalk = require('chalk') +const { parseError } = require('../../utils') +const migrationTemplate = require('../templates/migration-file') const MIGRATIONS_DIRECTORY = `${process.cwd()}/migrations` const MIGRATIONS_ROLLBACK_DIRECTORY = `${process.cwd()}/migrations/rollback` @@ -22,7 +21,7 @@ const MIGRATIONS_ROLLBACK_DIRECTORY = `${process.cwd()}/migrations/rollback` * // ./migrations/change_teaser_subtitle.js * getPathToFile('change_teaser_subtitle.js', './migrations') */ -export const getPathToFile = (fileName, migrationPath = null) => { +const getPathToFile = (fileName, migrationPath = null) => { const pathTo = isEmpty(migrationPath) ? MIGRATIONS_DIRECTORY : migrationPath return `${pathTo}/${fileName}` @@ -37,7 +36,7 @@ export const getPathToFile = (fileName, migrationPath = null) => { * @example * getNameOfMigrationFile('product', 'price') // change_product_price */ -export const getNameOfMigrationFile = (component, field) => { +const getNameOfMigrationFile = (component, field) => { return `change_${component}_${field}.js` } @@ -47,7 +46,7 @@ export const getNameOfMigrationFile = (component, field) => { * @param {String} component name of component * @return {Promise} */ -export const getStoriesByComponent = async (api, componentName) => { +const getStoriesByComponent = async (api, componentName) => { try { const stories = await api.getStories({ contain_component: componentName @@ -68,7 +67,7 @@ export const getStoriesByComponent = async (api, componentName) => { * @param {String} component name of component * @return {Promise} */ -export const getComponentsFromName = async (api, componentName) => { +const getComponentsFromName = async (api, componentName) => { try { const components = await api.getComponents() @@ -95,7 +94,7 @@ export const getComponentsFromName = async (api, componentName) => { * @param {String} component name of component * @return {Promise} */ -export const checkComponentExists = async (api, component) => { +const checkComponentExists = async (api, component) => { try { const componentData = await getComponentsFromName(api, component) @@ -111,7 +110,7 @@ export const checkComponentExists = async (api, component) => { * @param {String} filePath * @return {Promise} */ -export const checkFileExists = async (filePath) => fs.pathExists(filePath) +const checkFileExists = async (filePath) => fs.pathExists(filePath) /** * @method createMigrationFile @@ -119,7 +118,7 @@ export const checkFileExists = async (filePath) => fs.pathExists(filePath) * @param {String} field name of the field * @return {Promise} */ -export const createMigrationFile = (fileName, field) => { +const createMigrationFile = (fileName, field) => { console.log(`${chalk.blue('-')} Creating the migration file in migrations folder`) // use lodash.template to replace the occurrences of fieldname @@ -138,7 +137,7 @@ export const createMigrationFile = (fileName, field) => { * @param {String} type * @return {Array} */ -export const getInquirerOptions = (type) => { +const getInquirerOptions = (type) => { if (type === 'file-exists') { return [{ type: 'confirm', @@ -156,7 +155,7 @@ export const getInquirerOptions = (type) => { * @param {unknown} value updated value * @param {unknown} oldValue previous value */ -export const showMigrationChanges = (path, value, oldValue) => { +const showMigrationChanges = (path, value, oldValue) => { // It was created a new field if (oldValue === undefined) { // truncate the string with more than 30 characters @@ -190,7 +189,7 @@ export const showMigrationChanges = (path, value, oldValue) => { * @param {String} storyFullSlug the full slug of the containing story * @return {Promise} */ -export const processMigration = async (content = {}, component = '', migrationFn, storyFullSlug) => { +const processMigration = async (content = {}, component = '', migrationFn, storyFullSlug) => { // I'm processing the component that I want if (content.component === component) { const watchedContent = onChange( @@ -243,7 +242,7 @@ export const processMigration = async (content = {}, component = '', migrationFn * @return {String} */ -export const urlTofRollbackMigrationFile = (component, field) => { +const urlTofRollbackMigrationFile = (component, field) => { return `${MIGRATIONS_ROLLBACK_DIRECTORY}/${getNameOfRollbackMigrationFile(component, field)}` } @@ -254,7 +253,7 @@ export const urlTofRollbackMigrationFile = (component, field) => { * @return {String} */ -export const getNameOfRollbackMigrationFile = (component, field) => { +const getNameOfRollbackMigrationFile = (component, field) => { return `rollback_${component}_${field}.json` } @@ -264,7 +263,7 @@ export const getNameOfRollbackMigrationFile = (component, field) => { * @return {Promise} */ -export const createRollbackFile = async (stories, component, field) => { +const createRollbackFile = async (stories, component, field) => { try { if (!fs.existsSync(MIGRATIONS_ROLLBACK_DIRECTORY)) { fs.mkdir(MIGRATIONS_ROLLBACK_DIRECTORY) @@ -300,7 +299,7 @@ export const createRollbackFile = async (stories, component, field) => { * @return {Promisse} */ -export const checkExistenceFilesInRollBackDirectory = (path, component, field) => { +const checkExistenceFilesInRollBackDirectory = (path, component, field) => { if (!fs.existsSync(path)) { console.log(` ${chalk.red('X')} The path for which the rollback files should be contained does not exist` @@ -318,3 +317,20 @@ export const checkExistenceFilesInRollBackDirectory = (path, component, field) = }) return Promise.resolve(file) } + +module.exports = { + getPathToFile, + checkFileExists, + processMigration, + getInquirerOptions, + createMigrationFile, + checkComponentExists, + showMigrationChanges, + getStoriesByComponent, + getComponentsFromName, + getNameOfMigrationFile, + createRollbackFile, + checkExistenceFilesInRollBackDirectory, + urlTofRollbackMigrationFile, + getNameOfRollbackMigrationFile +} diff --git a/src/tasks/pull-components.js b/src/tasks/pull-components.js index d0b9744..08153f1 100644 --- a/src/tasks/pull-components.js +++ b/src/tasks/pull-components.js @@ -1,5 +1,5 @@ -import chalk from 'chalk' -import saveFileFactory from '../utils/save-file-factory' +const chalk = require('chalk') +const saveFileFactory = require('../utils/save-file-factory') /** * @method getNameFromComponentGroups @@ -81,4 +81,4 @@ const pullComponents = async (api, options) => { } } -export default pullComponents +module.exports = pullComponents diff --git a/src/tasks/pull-languages.js b/src/tasks/pull-languages.js index c9622b5..7dead35 100644 --- a/src/tasks/pull-languages.js +++ b/src/tasks/pull-languages.js @@ -1,5 +1,5 @@ -import fs from 'fs' -import chalk from 'chalk' +const fs = require('fs') +const chalk = require('chalk') /** * @method pullLanguages @@ -36,4 +36,4 @@ const pullLanguages = async (api, options) => { } } -export default pullLanguages +module.exports = pullLanguages diff --git a/src/tasks/push-components.js b/src/tasks/push-components.js index 69875e9..6011ca3 100644 --- a/src/tasks/push-components.js +++ b/src/tasks/push-components.js @@ -1,9 +1,8 @@ -import axios from 'axios' -import fs from 'fs' -import chalk from 'chalk' -import PresetsLib from '../utils/presets-lib' -import lodash from 'lodash' -const { isEmpty } = lodash +const axios = require('axios') +const fs = require('fs') +const chalk = require('chalk') +const PresetsLib = require('../utils/presets-lib') +const isEmpty = require('lodash/isEmpty') const isUrl = source => source.indexOf('http') === 0 @@ -63,7 +62,7 @@ const createContentList = (content, key) => { else return !isEmpty(content) ? [content] : [] } -const pushComponents = async (api, { source, presetsSource }) => { +module.exports = async (api, { source, presetsSource }) => { try { const rawComponents = await getDataFromPath(source) const components = createContentList(rawComponents, 'components') @@ -206,5 +205,3 @@ const push = async (api, components, presets = []) => { return Promise.reject(e.message) } } - -export default pushComponents diff --git a/src/tasks/quickstart.js b/src/tasks/quickstart.js index 9e8bfa6..82c968c 100644 --- a/src/tasks/quickstart.js +++ b/src/tasks/quickstart.js @@ -1,6 +1,6 @@ -import open from 'open' -import chalk from 'chalk' -import lastStep from '../utils/last-step' +const open = require('open') +const chalk = require('chalk') +const lastStep = require('../utils/last-step') const hasSpaceId = spaceId => typeof spaceId !== 'undefined' @@ -88,4 +88,4 @@ const quickstart = async (api, answers, spaceId) => { } } -export default quickstart +module.exports = quickstart diff --git a/src/tasks/scaffold.js b/src/tasks/scaffold.js index 99710a1..50682e2 100644 --- a/src/tasks/scaffold.js +++ b/src/tasks/scaffold.js @@ -1,6 +1,6 @@ -import fs from 'fs' +const fs = require('fs') -export default async function (api, name, space) { +module.exports = function (api, name, space) { if (space) { if (!api.accessToken) { return Promise.reject(new Error('The user is not logged')) @@ -17,7 +17,7 @@ export default async function (api, name, space) { var liquid = './views/components/_' + name + '.liquid' console.log('Writing template file to ' + liquid) - fs.writeFileSync(liquid, await import('./templates/teaser')) + fs.writeFileSync(liquid, require('./templates/teaser')) var scss = './source/scss/components/below/_' + name + '.scss' console.log('Writing scss file to ' + scss) diff --git a/src/tasks/sync-commands/component-groups.js b/src/tasks/sync-commands/component-groups.js index acd7b56..4fcb150 100644 --- a/src/tasks/sync-commands/component-groups.js +++ b/src/tasks/sync-commands/component-groups.js @@ -1,6 +1,6 @@ -import chalk from 'chalk' -import { findByProperty } from '../../utils' -import api from '../../utils/api' +const chalk = require('chalk') +const { findByProperty } = require('../../utils') +const api = require('../../utils/api') class SyncComponentGroups { /** @@ -137,4 +137,4 @@ class SyncComponentGroups { } } -export default SyncComponentGroups +module.exports = SyncComponentGroups diff --git a/src/tasks/sync-commands/components.js b/src/tasks/sync-commands/components.js index 5c9beed..34f7758 100644 --- a/src/tasks/sync-commands/components.js +++ b/src/tasks/sync-commands/components.js @@ -1,10 +1,9 @@ -import chalk from 'chalk' -import lodash from 'lodash' -import SyncComponentGroups from './component-groups' -import { findByProperty } from '../../utils' -import PresetsLib from '../../utils/presets-lib' -import api from '../../utils/api' -const { find } = lodash +const chalk = require('chalk') +const { find } = require('lodash') +const SyncComponentGroups = require('./component-groups') +const { findByProperty } = require('../../utils') +const PresetsLib = require('../../utils/presets-lib') +const api = require('../../utils/api') class SyncComponents { /** @@ -261,4 +260,4 @@ class SyncComponents { } } -export default SyncComponents +module.exports = SyncComponents diff --git a/src/tasks/sync-commands/datasources.js b/src/tasks/sync-commands/datasources.js index 2321ddd..71d021a 100644 --- a/src/tasks/sync-commands/datasources.js +++ b/src/tasks/sync-commands/datasources.js @@ -1,6 +1,6 @@ -import chalk from 'chalk' -import UUID from 'simple-uuid' -import api from '../../utils/api' +const chalk = require('chalk') +const UUID = require('simple-uuid') +const api = require('../../utils/api') class SyncDatasources { /** @@ -302,4 +302,4 @@ class SyncDatasources { } } -export default SyncDatasources +module.exports = SyncDatasources diff --git a/src/tasks/sync.js b/src/tasks/sync.js index 3ec6b97..d0b5f33 100644 --- a/src/tasks/sync.js +++ b/src/tasks/sync.js @@ -1,8 +1,8 @@ -import pSeries from 'p-series' -import chalk from 'chalk' -import SyncComponents from './sync-commands/components' -import SyncDatasources from './sync-commands/datasources' -import { capitalize } from '../utils' +const pSeries = require('p-series') +const chalk = require('chalk') +const SyncComponents = require('./sync-commands/components') +const SyncDatasources = require('./sync-commands/datasources') +const { capitalize } = require('../utils') const SyncSpaces = { targetComponents: [], @@ -230,7 +230,7 @@ const SyncSpaces = { oauthToken: this.oauthToken, componentsGroups: this.componentsGroups }) - + try { await syncComponentsInstance.sync() } catch (e) { @@ -285,4 +285,4 @@ const sync = (types, options) => { return pSeries(tasks) } -export default sync +module.exports = sync diff --git a/src/tasks/templates/migration-file.js b/src/tasks/templates/migration-file.js index 44b2cdf..80c6bab 100644 --- a/src/tasks/templates/migration-file.js +++ b/src/tasks/templates/migration-file.js @@ -1,4 +1,4 @@ -export default `export default function (block) { +module.exports = `module.exports = function (block) { // Example to change a string to boolean // block.{{ fieldname }} = !!(block.{{ fieldname }}) diff --git a/src/tasks/templates/teaser.js b/src/tasks/templates/teaser.js index 10621f3..78889ca 100644 --- a/src/tasks/templates/teaser.js +++ b/src/tasks/templates/teaser.js @@ -1,4 +1,4 @@ -export default `
+module.exports = `