diff --git a/.eslintrc.js b/.eslintrc.js index ccf951ca..9d2e7f8e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,12 +6,16 @@ module.exports = { }, 'parser': 'babel-eslint', 'parserOptions': { - ecmaVersion: 7, - sourceType: 'module' + 'ecmaVersion': 7, + 'sourceType': 'module' }, 'plugins': ['import'], - 'extends': 'eslint:recommended', - 'rules':{ + 'extends': [ + 'plugin:prettier/recommended', + 'eslint:recommended', + ], + 'rules': { + 'prettier/prettier': 'error', 'no-console': 0, } }; diff --git a/.travis.yml b/.travis.yml index a474bb33..4faad0fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: node_js node_js: +- '10' - '8' -- '7' - '6' cache: diff --git a/package.json b/package.json index 15f208b0..07aa28ab 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,11 @@ "babel-preset-es2015": "^6.24.0", "babel-preset-stage-0": "^6.22.0", "eslint": "^3.18.0", + "eslint-config-prettier": "^2.9.0", "eslint-plugin-import": "^2.2.0", + "eslint-plugin-prettier": "^2.6.0", "jest": "^23", + "prettier": "^1.13.2", "tmp": "^0.0.31" }, "dependencies": { @@ -43,6 +46,8 @@ "scripts": { "test": "jest", "lint": "eslint src", + "fix": "eslint --fix src", + "eslint-check": "eslint --print-config .eslintrc.js | eslint-config-prettier-check", "build": "babel src -d lib --ignore '*.test.js'", "watch": "babel --watch src -d lib --ignore '*.test.js'", "test-gen": "rm -rf ./tmp && npm run build && ./lib/index.js https://demo.api-platform.com ./tmp/react && ./lib/index.js https://demo.api-platform.com ./tmp/react-native -g react-native && ./lib/index.js https://demo.api-platform.com ./tmp/vue -g vue && ./lib/index.js https://demo.api-platform.com ./tmp/admin-on-rest -g admin-on-rest", diff --git a/src/generators.js b/src/generators.js index d2212eaa..1c332cb0 100644 --- a/src/generators.js +++ b/src/generators.js @@ -1,24 +1,25 @@ -import AdminOnRestGenerator from './generators/AdminOnRestGenerator'; -import ReactGenerator from './generators/ReactGenerator'; -import ReactNativeGenerator from './generators/ReactNativeGenerator'; -import TypescriptInterfaceGenerator from './generators/TypescriptInterfaceGenerator'; -import VueGenerator from './generators/VueGenerator'; +import AdminOnRestGenerator from "./generators/AdminOnRestGenerator"; +import ReactGenerator from "./generators/ReactGenerator"; +import ReactNativeGenerator from "./generators/ReactNativeGenerator"; +import TypescriptInterfaceGenerator from "./generators/TypescriptInterfaceGenerator"; +import VueGenerator from "./generators/VueGenerator"; -function wrap (cl) { - return ({hydraPrefix, templateDirectory}) => new cl({hydraPrefix, templateDirectory}) +function wrap(cl) { + return ({ hydraPrefix, templateDirectory }) => + new cl({ hydraPrefix, templateDirectory }); } -export default function generators (generator = 'react') { +export default function generators(generator = "react") { switch (generator) { - case 'admin-on-rest': + case "admin-on-rest": return wrap(AdminOnRestGenerator); - case 'react': + case "react": return wrap(ReactGenerator); - case 'react-native': + case "react-native": return wrap(ReactNativeGenerator); - case 'typescript': + case "typescript": return wrap(TypescriptInterfaceGenerator); - case 'vue': - return wrap(VueGenerator) + case "vue": + return wrap(VueGenerator); } } diff --git a/src/generators/AdminOnRestGenerator.js b/src/generators/AdminOnRestGenerator.js index 61188223..1258af8a 100644 --- a/src/generators/AdminOnRestGenerator.js +++ b/src/generators/AdminOnRestGenerator.js @@ -1,33 +1,37 @@ -import fs from 'fs'; -import BaseGenerator from './BaseGenerator'; -import handlebars from 'handlebars'; -import hbh_comparison from 'handlebars-helpers/lib/comparison'; +import fs from "fs"; +import BaseGenerator from "./BaseGenerator"; +import handlebars from "handlebars"; +import hbh_comparison from "handlebars-helpers/lib/comparison"; export default class extends BaseGenerator { constructor(params) { super(params); this.registerTemplates(`admin-on-rest/`, [ - 'components/foo.js', - 'config/foo.js', - 'resources/foo.js', - 'resource-import.js', + "components/foo.js", + "config/foo.js", + "resources/foo.js", + "resource-import.js" ]); - handlebars.registerHelper('compare', hbh_comparison.compare); + handlebars.registerHelper("compare", hbh_comparison.compare); } help(resource) { - console.log('Code for the "%s" resource type has been generated!', resource.title); + console.log( + 'Code for the "%s" resource type has been generated!', + resource.title + ); } appendFile(template, dest, context = {}) { - fs.appendFileSync(dest, this.templates[template](context)); + fs.appendFileSync(dest, this.templates[template](context)); } generate(api, resource, dir) { const lc = resource.title.toLowerCase(); - const titleUcFirst = resource.title.charAt(0).toUpperCase() + resource.title.slice(1); + const titleUcFirst = + resource.title.charAt(0).toUpperCase() + resource.title.slice(1); const context = { title: resource.title, @@ -37,25 +41,29 @@ export default class extends BaseGenerator { fields: resource.readableFields, formFields: this.buildFields(resource.writableFields), hydraPrefix: this.hydraPrefix, - titleUcFirst, + titleUcFirst }; // Create directories // These directories may already exist - for (let dir of [`${dir}/config`, `${dir}/resources`, `${dir}/components/`]) { + for (let dir of [ + `${dir}/config`, + `${dir}/resources`, + `${dir}/components/` + ]) { this.createDir(dir, false); } for (let pattern of [ - 'components/%s.js', - 'config/%s.js', - 'resources/%s.js', + "components/%s.js", + "config/%s.js", + "resources/%s.js" ]) { - this.createFileFromPattern(pattern, dir, lc, context) + this.createFileFromPattern(pattern, dir, lc, context); } - this.appendFile('resource-import.js', `${dir}/resource-import.js`, context); + this.appendFile("resource-import.js", `${dir}/resource-import.js`, context); - this.createEntrypoint(api.entrypoint, `${dir}/config/_entrypoint.js`) + this.createEntrypoint(api.entrypoint, `${dir}/config/_entrypoint.js`); } } diff --git a/src/generators/AdminOnRestGenerator.test.js b/src/generators/AdminOnRestGenerator.test.js index a27dc907..b469ec82 100644 --- a/src/generators/AdminOnRestGenerator.test.js +++ b/src/generators/AdminOnRestGenerator.test.js @@ -1,46 +1,48 @@ -import Api from '@api-platform/api-doc-parser/lib/Api'; -import Resource from '@api-platform/api-doc-parser/lib/Resource'; -import Field from '@api-platform/api-doc-parser/lib/Field'; -import fs from 'fs'; -import tmp from 'tmp'; -import AdminOnRestGenerator from './AdminOnRestGenerator'; +import Api from "@api-platform/api-doc-parser/lib/Api"; +import Resource from "@api-platform/api-doc-parser/lib/Resource"; +import Field from "@api-platform/api-doc-parser/lib/Field"; +import fs from "fs"; +import tmp from "tmp"; +import AdminOnRestGenerator from "./AdminOnRestGenerator"; -test('Generate a Admin On Rest app', () => { - const generator = new AdminOnRestGenerator({hydraPrefix: 'hydra:', templateDirectory: `${__dirname}/../../templates`}); - const tmpobj = tmp.dirSync({unsafeCleanup: true}); +test("Generate a Admin On Rest app", () => { + const generator = new AdminOnRestGenerator({ + hydraPrefix: "hydra:", + templateDirectory: `${__dirname}/../../templates` + }); + const tmpobj = tmp.dirSync({ unsafeCleanup: true }); - const fields = [new Field('bar', { - id: 'http://schema.org/url', - range: 'http://www.w3.org/2001/XMLSchema#string', - reference: null, - required: true, - description: 'An URL' - })]; - const resource = new Resource('abc', 'http://example.com/foos', { - id: 'abc', - title: 'abc', + const fields = [ + new Field("bar", { + id: "http://schema.org/url", + range: "http://www.w3.org/2001/XMLSchema#string", + reference: null, + required: true, + description: "An URL" + }) + ]; + const resource = new Resource("abc", "http://example.com/foos", { + id: "abc", + title: "abc", readableFields: fields, writableFields: fields }); - const api = new Api('http://example.com', { - entrypoint: 'http://example.com:8080', - title: 'My API', + const api = new Api("http://example.com", { + entrypoint: "http://example.com:8080", + title: "My API", resources: [resource] }); generator.generate(api, resource, tmpobj.name); [ - '/config/_entrypoint.js', - '/resources/abc.js', - '/resource-import.js', - ].forEach(file => expect(fs.existsSync(tmpobj.name+file)).toBe(true)); + "/config/_entrypoint.js", + "/resources/abc.js", + "/resource-import.js" + ].forEach(file => expect(fs.existsSync(tmpobj.name + file)).toBe(true)); - [ - '/components/abc.js', - '/config/abc.js', - ].forEach(file => { - expect(fs.existsSync(tmpobj.name+file)).toBe(true) - expect(fs.readFileSync(tmpobj.name+file, 'utf8')).toMatch(/bar/); + ["/components/abc.js", "/config/abc.js"].forEach(file => { + expect(fs.existsSync(tmpobj.name + file)).toBe(true); + expect(fs.readFileSync(tmpobj.name + file, "utf8")).toMatch(/bar/); }); tmpobj.removeCallback(); diff --git a/src/generators/BaseGenerator.js b/src/generators/BaseGenerator.js index f7b93840..7f843007 100644 --- a/src/generators/BaseGenerator.js +++ b/src/generators/BaseGenerator.js @@ -1,22 +1,26 @@ -import fs from 'fs'; -import handlebars from 'handlebars'; -import mkdirp from 'mkdirp'; -import { sprintf } from 'sprintf-js'; -import urlapi from 'url'; +import fs from "fs"; +import handlebars from "handlebars"; +import mkdirp from "mkdirp"; +import { sprintf } from "sprintf-js"; +import urlapi from "url"; export default class { templates = {}; - constructor({hydraPrefix, templateDirectory}) { + constructor({ hydraPrefix, templateDirectory }) { this.hydraPrefix = hydraPrefix; this.templateDirectory = templateDirectory; - this.registerTemplates('', ['_entrypoint.js']); + this.registerTemplates("", ["_entrypoint.js"]); } registerTemplates(basePath, paths) { for (let path of paths) { - this.templates[path] = handlebars.compile(fs.readFileSync(`${this.templateDirectory}/${basePath}${path}`).toString()); + this.templates[path] = handlebars.compile( + fs + .readFileSync(`${this.templateDirectory}/${basePath}${path}`) + .toString() + ); } } @@ -31,7 +35,11 @@ export default class { } createFileFromPattern(pattern, dir, lc, context) { - this.createFile(sprintf(pattern, 'foo'), sprintf(`${dir}/${pattern}`, lc), context); + this.createFile( + sprintf(pattern, "foo"), + sprintf(`${dir}/${pattern}`, lc), + context + ); } createFile(template, dest, context = {}, warn = true) { @@ -46,41 +54,46 @@ export default class { createEntrypoint(apiEntry, dest) { const url = urlapi.parse(apiEntry); - const {protocol, host, pathname} = url; - - this.createFile('_entrypoint.js', dest, {host: `${protocol}//${host}`, path: pathname}, false); + const { protocol, host, pathname } = url; + + this.createFile( + "_entrypoint.js", + dest, + { host: `${protocol}//${host}`, path: pathname }, + false + ); } getHtmlInputTypeFromField(field) { switch (field.id) { - case 'http://schema.org/email': - return {type: 'email'}; + case "http://schema.org/email": + return { type: "email" }; - case 'http://schema.org/url': - return {type: 'url'}; + case "http://schema.org/url": + return { type: "url" }; } switch (field.range) { - case 'http://www.w3.org/2001/XMLSchema#integer': - return {type: 'number'}; + case "http://www.w3.org/2001/XMLSchema#integer": + return { type: "number" }; - case 'http://www.w3.org/2001/XMLSchema#decimal': - return {type: 'number', step: '0.1'}; + case "http://www.w3.org/2001/XMLSchema#decimal": + return { type: "number", step: "0.1" }; - case 'http://www.w3.org/2001/XMLSchema#boolean': - return {type: 'checkbox'}; + case "http://www.w3.org/2001/XMLSchema#boolean": + return { type: "checkbox" }; - case 'http://www.w3.org/2001/XMLSchema#date': - return {type: 'date'}; + case "http://www.w3.org/2001/XMLSchema#date": + return { type: "date" }; - case 'http://www.w3.org/2001/XMLSchema#time': - return {type: 'time'}; + case "http://www.w3.org/2001/XMLSchema#time": + return { type: "time" }; - case 'http://www.w3.org/2001/XMLSchema#dateTime': - return {type: 'dateTime'}; + case "http://www.w3.org/2001/XMLSchema#dateTime": + return { type: "dateTime" }; default: - return {type: 'text'}; + return { type: "text" }; } } @@ -92,7 +105,7 @@ export default class { field.name = apiField.name; field.description = apiField.description.replace(/"/g, "'"); // fix for Form placeholder description - fields.push(field) + fields.push(field); } return fields; diff --git a/src/generators/ReactGenerator.js b/src/generators/ReactGenerator.js index 70c930d7..b8fa5dbc 100644 --- a/src/generators/ReactGenerator.js +++ b/src/generators/ReactGenerator.js @@ -1,5 +1,5 @@ -import chalk from 'chalk'; -import BaseGenerator from './BaseGenerator'; +import chalk from "chalk"; +import BaseGenerator from "./BaseGenerator"; export default class extends BaseGenerator { constructor(params) { @@ -7,47 +7,53 @@ export default class extends BaseGenerator { this.registerTemplates(`react-common/`, [ // actions - 'actions/foo/create.js', - 'actions/foo/delete.js', - 'actions/foo/list.js', - 'actions/foo/update.js', - 'actions/foo/show.js', + "actions/foo/create.js", + "actions/foo/delete.js", + "actions/foo/list.js", + "actions/foo/update.js", + "actions/foo/show.js", // utils - 'utils/fetch.js', + "utils/fetch.js", // reducers - 'reducers/foo/create.js', - 'reducers/foo/delete.js', - 'reducers/foo/index.js', - 'reducers/foo/list.js', - 'reducers/foo/update.js', - 'reducers/foo/show.js', + "reducers/foo/create.js", + "reducers/foo/delete.js", + "reducers/foo/index.js", + "reducers/foo/list.js", + "reducers/foo/update.js", + "reducers/foo/show.js" ]); this.registerTemplates(`react/`, [ // components - 'components/foo/Create.js', - 'components/foo/Form.js', - 'components/foo/index.js', - 'components/foo/List.js', - 'components/foo/Update.js', - 'components/foo/Show.js', + "components/foo/Create.js", + "components/foo/Form.js", + "components/foo/index.js", + "components/foo/List.js", + "components/foo/Update.js", + "components/foo/Show.js", // routes - 'routes/foo.js', + "routes/foo.js", // utils - 'utils/helpers.js', + "utils/helpers.js" ]); } help(resource) { const titleLc = resource.title.toLowerCase(); - console.log('Code for the "%s" resource type has been generated!', resource.title); - console.log('Paste the following definitions in your application configuration:'); - console.log(chalk.green(` + console.log( + 'Code for the "%s" resource type has been generated!', + resource.title + ); + console.log( + "Paste the following definitions in your application configuration:" + ); + console.log( + chalk.green(` // import reducers import ${titleLc} from './reducers/${titleLc}/'; @@ -59,12 +65,14 @@ combineReducers(${titleLc},{/* ... */}), // Add routes to { ${titleLc}Routes } -`)); +`) + ); } generate(api, resource, dir) { const lc = resource.title.toLowerCase(); - const titleUcFirst = resource.title.charAt(0).toUpperCase() + resource.title.slice(1); + const titleUcFirst = + resource.title.charAt(0).toUpperCase() + resource.title.slice(1); const context = { title: resource.title, @@ -74,7 +82,7 @@ combineReducers(${titleLc},{/* ... */}), fields: resource.readableFields, formFields: this.buildFields(resource.writableFields), hydraPrefix: this.hydraPrefix, - titleUcFirst, + titleUcFirst }; // Create directories @@ -83,45 +91,49 @@ combineReducers(${titleLc},{/* ... */}), this.createDir(dir, false); } - for (let dir of [`${dir}/actions/${lc}`, `${dir}/components/${lc}`, `${dir}/reducers/${lc}`]) { + for (let dir of [ + `${dir}/actions/${lc}`, + `${dir}/components/${lc}`, + `${dir}/reducers/${lc}` + ]) { this.createDir(dir); } for (let pattern of [ // actions - 'actions/%s/create.js', - 'actions/%s/delete.js', - 'actions/%s/list.js', - 'actions/%s/update.js', - 'actions/%s/show.js', + "actions/%s/create.js", + "actions/%s/delete.js", + "actions/%s/list.js", + "actions/%s/update.js", + "actions/%s/show.js", // components - 'components/%s/Create.js', - 'components/%s/Form.js', - 'components/%s/index.js', - 'components/%s/List.js', - 'components/%s/Update.js', - 'components/%s/Show.js', + "components/%s/Create.js", + "components/%s/Form.js", + "components/%s/index.js", + "components/%s/List.js", + "components/%s/Update.js", + "components/%s/Show.js", // reducers - 'reducers/%s/create.js', - 'reducers/%s/delete.js', - 'reducers/%s/index.js', - 'reducers/%s/list.js', - 'reducers/%s/update.js', - 'reducers/%s/show.js', + "reducers/%s/create.js", + "reducers/%s/delete.js", + "reducers/%s/index.js", + "reducers/%s/list.js", + "reducers/%s/update.js", + "reducers/%s/show.js", // routes - 'routes/%s.js' + "routes/%s.js" ]) { - this.createFileFromPattern(pattern, dir, lc, context) + this.createFileFromPattern(pattern, dir, lc, context); } // utils - for (let file of ['utils/helpers.js', 'utils/fetch.js']) { + for (let file of ["utils/helpers.js", "utils/fetch.js"]) { this.createFile(file, `${dir}/${file}`, context, false); } - this.createEntrypoint(api.entrypoint, `${dir}/config/_entrypoint.js`) + this.createEntrypoint(api.entrypoint, `${dir}/config/_entrypoint.js`); } } diff --git a/src/generators/ReactGenerator.test.js b/src/generators/ReactGenerator.test.js index 08a2ce74..1a29326f 100644 --- a/src/generators/ReactGenerator.test.js +++ b/src/generators/ReactGenerator.test.js @@ -1,68 +1,71 @@ -import Api from '@api-platform/api-doc-parser/lib/Api'; -import Resource from '@api-platform/api-doc-parser/lib/Resource'; -import Field from '@api-platform/api-doc-parser/lib/Field'; -import fs from 'fs'; -import tmp from 'tmp'; -import ReactGenerator from './ReactGenerator'; +import Api from "@api-platform/api-doc-parser/lib/Api"; +import Resource from "@api-platform/api-doc-parser/lib/Resource"; +import Field from "@api-platform/api-doc-parser/lib/Field"; +import fs from "fs"; +import tmp from "tmp"; +import ReactGenerator from "./ReactGenerator"; -test('Generate a React app', () => { - const generator = new ReactGenerator({hydraPrefix: 'hydra:', templateDirectory: `${__dirname}/../../templates`}); - const tmpobj = tmp.dirSync({unsafeCleanup: true}); +test("Generate a React app", () => { + const generator = new ReactGenerator({ + hydraPrefix: "hydra:", + templateDirectory: `${__dirname}/../../templates` + }); + const tmpobj = tmp.dirSync({ unsafeCleanup: true }); const fields = [ - new Field('bar', { - id: 'http://schema.org/url', - range: 'http://www.w3.org/2001/XMLSchema#string', - reference: null, - required: true, - description: 'An URL' - }), + new Field("bar", { + id: "http://schema.org/url", + range: "http://www.w3.org/2001/XMLSchema#string", + reference: null, + required: true, + description: "An URL" + }) ]; - const resource = new Resource('abc', 'http://example.com/foos', { - id: 'abc', - title: 'abc', + const resource = new Resource("abc", "http://example.com/foos", { + id: "abc", + title: "abc", readableFields: fields, writableFields: fields }); - const api = new Api('http://example.com', { - entrypoint: 'http://example.com:8080', - title: 'My API', + const api = new Api("http://example.com", { + entrypoint: "http://example.com:8080", + title: "My API", resources: [resource] }); generator.generate(api, resource, tmpobj.name); [ - '/utils/fetch.js', - '/utils/helpers.js', - '/config/_entrypoint.js', + "/utils/fetch.js", + "/utils/helpers.js", + "/config/_entrypoint.js", - '/actions/abc/create.js', - '/actions/abc/delete.js', - '/actions/abc/list.js', - '/actions/abc/show.js', - '/actions/abc/update.js', + "/actions/abc/create.js", + "/actions/abc/delete.js", + "/actions/abc/list.js", + "/actions/abc/show.js", + "/actions/abc/update.js", - '/components/abc/index.js', - '/components/abc/Create.js', - '/components/abc/Update.js', + "/components/abc/index.js", + "/components/abc/Create.js", + "/components/abc/Update.js", - '/routes/abc.js', + "/routes/abc.js", - '/reducers/abc/create.js', - '/reducers/abc/delete.js', - '/reducers/abc/index.js', - '/reducers/abc/list.js', - '/reducers/abc/show.js', - '/reducers/abc/update.js', - ].forEach(file => expect(fs.existsSync(tmpobj.name+file)).toBe(true)); + "/reducers/abc/create.js", + "/reducers/abc/delete.js", + "/reducers/abc/index.js", + "/reducers/abc/list.js", + "/reducers/abc/show.js", + "/reducers/abc/update.js" + ].forEach(file => expect(fs.existsSync(tmpobj.name + file)).toBe(true)); [ - '/components/abc/Form.js', - '/components/abc/List.js', - '/components/abc/Show.js', + "/components/abc/Form.js", + "/components/abc/List.js", + "/components/abc/Show.js" ].forEach(file => { - expect(fs.existsSync(tmpobj.name+file)).toBe(true); - expect(fs.readFileSync(tmpobj.name+file, 'utf8')).toMatch(/bar/); + expect(fs.existsSync(tmpobj.name + file)).toBe(true); + expect(fs.readFileSync(tmpobj.name + file, "utf8")).toMatch(/bar/); }); tmpobj.removeCallback(); diff --git a/src/generators/ReactNativeGenerator.js b/src/generators/ReactNativeGenerator.js index 7d964546..ab0da877 100644 --- a/src/generators/ReactNativeGenerator.js +++ b/src/generators/ReactNativeGenerator.js @@ -1,5 +1,5 @@ -import chalk from 'chalk'; -import BaseGenerator from './BaseGenerator'; +import chalk from "chalk"; +import BaseGenerator from "./BaseGenerator"; export default class extends BaseGenerator { constructor(params) { @@ -7,52 +7,60 @@ export default class extends BaseGenerator { this.registerTemplates(`react-common/`, [ // actions - 'actions/foo/create.js', - 'actions/foo/delete.js', - 'actions/foo/list.js', - 'actions/foo/update.js', - 'actions/foo/show.js', + "actions/foo/create.js", + "actions/foo/delete.js", + "actions/foo/list.js", + "actions/foo/update.js", + "actions/foo/show.js", // utils - 'utils/fetch.js', + "utils/fetch.js", // reducers - 'reducers/foo/create.js', - 'reducers/foo/delete.js', - 'reducers/foo/index.js', - 'reducers/foo/list.js', - 'reducers/foo/update.js', - 'reducers/foo/show.js', + "reducers/foo/create.js", + "reducers/foo/delete.js", + "reducers/foo/index.js", + "reducers/foo/list.js", + "reducers/foo/update.js", + "reducers/foo/show.js" ]); this.registerTemplates(`react/`, [ // components - 'components/foo/Create.js', - 'components/foo/Form.js', - 'components/foo/index.js', - 'components/foo/List.js', - 'components/foo/Update.js', - 'components/foo/Show.js', + "components/foo/Create.js", + "components/foo/Form.js", + "components/foo/index.js", + "components/foo/List.js", + "components/foo/Update.js", + "components/foo/Show.js" ]); } help(resource) { const titleLc = resource.title.toLowerCase(); - console.log('Code for the "%s" resource type has been generated!', resource.title); - console.log('Paste the following definitions in your application configuration:'); - console.log(chalk.green(` + console.log( + 'Code for the "%s" resource type has been generated!', + resource.title + ); + console.log( + "Paste the following definitions in your application configuration:" + ); + console.log( + chalk.green(` // import reducers import ${titleLc} from './reducers/${titleLc}/'; // Add the reducer combineReducers(${titleLc},{/* ... */}), -`)); +`) + ); } generate(api, resource, dir) { const lc = resource.title.toLowerCase(); - const titleUcFirst = resource.title.charAt(0).toUpperCase() + resource.title.slice(1); + const titleUcFirst = + resource.title.charAt(0).toUpperCase() + resource.title.slice(1); const context = { title: resource.title, @@ -71,38 +79,42 @@ combineReducers(${titleLc},{/* ... */}), this.createDir(dir, false); } - for (let dir of [`${dir}/actions/${lc}`, `${dir}/components/${lc}`, `${dir}/reducers/${lc}`]) { + for (let dir of [ + `${dir}/actions/${lc}`, + `${dir}/components/${lc}`, + `${dir}/reducers/${lc}` + ]) { this.createDir(dir); } for (let pattern of [ // actions - 'actions/%s/create.js', - 'actions/%s/delete.js', - 'actions/%s/list.js', - 'actions/%s/update.js', - 'actions/%s/show.js', + "actions/%s/create.js", + "actions/%s/delete.js", + "actions/%s/list.js", + "actions/%s/update.js", + "actions/%s/show.js", // components - 'components/%s/Create.js', - 'components/%s/Form.js', - 'components/%s/index.js', - 'components/%s/List.js', - 'components/%s/Update.js', - 'components/%s/Show.js', + "components/%s/Create.js", + "components/%s/Form.js", + "components/%s/index.js", + "components/%s/List.js", + "components/%s/Update.js", + "components/%s/Show.js", // reducers - 'reducers/%s/create.js', - 'reducers/%s/delete.js', - 'reducers/%s/index.js', - 'reducers/%s/list.js', - 'reducers/%s/update.js', - 'reducers/%s/show.js', + "reducers/%s/create.js", + "reducers/%s/delete.js", + "reducers/%s/index.js", + "reducers/%s/list.js", + "reducers/%s/update.js", + "reducers/%s/show.js" ]) { this.createFileFromPattern(pattern, dir, lc, context); } - this.createFile('utils/fetch.js', `${dir}/utils/fetch.js`, context, false); - this.createEntrypoint(api.entrypoint, `${dir}/config/_entrypoint.js`) + this.createFile("utils/fetch.js", `${dir}/utils/fetch.js`, context, false); + this.createEntrypoint(api.entrypoint, `${dir}/config/_entrypoint.js`); } } diff --git a/src/generators/ReactNativeGenerator.test.js b/src/generators/ReactNativeGenerator.test.js index 62c3982f..8f8e289d 100644 --- a/src/generators/ReactNativeGenerator.test.js +++ b/src/generators/ReactNativeGenerator.test.js @@ -1,63 +1,67 @@ -import Api from '@api-platform/api-doc-parser/lib/Api'; -import Resource from '@api-platform/api-doc-parser/lib/Resource'; -import Field from '@api-platform/api-doc-parser/lib/Field'; -import fs from 'fs'; -import tmp from 'tmp'; -import ReactNativeGenerator from './ReactNativeGenerator'; +import Api from "@api-platform/api-doc-parser/lib/Api"; +import Resource from "@api-platform/api-doc-parser/lib/Resource"; +import Field from "@api-platform/api-doc-parser/lib/Field"; +import fs from "fs"; +import tmp from "tmp"; +import ReactNativeGenerator from "./ReactNativeGenerator"; +test("Generate a React app", () => { + const generator = new ReactNativeGenerator({ + hydraPrefix: "hydra:", + templateDirectory: `${__dirname}/../../templates` + }); + const tmpobj = tmp.dirSync({ unsafeCleanup: true }); -test('Generate a React app', () => { - const generator = new ReactNativeGenerator({hydraPrefix: 'hydra:', templateDirectory: `${__dirname}/../../templates`}); - const tmpobj = tmp.dirSync({unsafeCleanup: true}); - - const fields = [new Field('bar', { - id: 'http://schema.org/url', - range: 'http://www.w3.org/2001/XMLSchema#string', - reference: null, - required: true, - description: 'An URL' - })]; - const resource = new Resource('abc', 'http://example.com/foos', { - id: 'abc', - title: 'abc', + const fields = [ + new Field("bar", { + id: "http://schema.org/url", + range: "http://www.w3.org/2001/XMLSchema#string", + reference: null, + required: true, + description: "An URL" + }) + ]; + const resource = new Resource("abc", "http://example.com/foos", { + id: "abc", + title: "abc", readableFields: fields, writableFields: fields }); - const api = new Api('http://example.com', { - entrypoint: 'http://example.com:8080', - title: 'My API', + const api = new Api("http://example.com", { + entrypoint: "http://example.com:8080", + title: "My API", resources: [resource] }); generator.generate(api, resource, tmpobj.name); [ - '/utils/fetch.js', - '/config/_entrypoint.js', + "/utils/fetch.js", + "/config/_entrypoint.js", - '/actions/abc/create.js', - '/actions/abc/delete.js', - '/actions/abc/list.js', - '/actions/abc/show.js', - '/actions/abc/update.js', + "/actions/abc/create.js", + "/actions/abc/delete.js", + "/actions/abc/list.js", + "/actions/abc/show.js", + "/actions/abc/update.js", - '/components/abc/Create.js', - '/components/abc/Update.js', + "/components/abc/Create.js", + "/components/abc/Update.js", - '/reducers/abc/create.js', - '/reducers/abc/delete.js', - '/reducers/abc/index.js', - '/reducers/abc/list.js', - '/reducers/abc/show.js', - '/reducers/abc/update.js', - ].forEach(file => expect(fs.existsSync(tmpobj.name+file)).toBe(true)); + "/reducers/abc/create.js", + "/reducers/abc/delete.js", + "/reducers/abc/index.js", + "/reducers/abc/list.js", + "/reducers/abc/show.js", + "/reducers/abc/update.js" + ].forEach(file => expect(fs.existsSync(tmpobj.name + file)).toBe(true)); [ - '/components/abc/Form.js', - '/components/abc/List.js', - '/components/abc/Show.js', + "/components/abc/Form.js", + "/components/abc/List.js", + "/components/abc/Show.js" ].forEach(file => { - expect(fs.existsSync(tmpobj.name+file)).toBe(true); - expect(fs.readFileSync(tmpobj.name+file, 'utf8')).toMatch(/bar/); + expect(fs.existsSync(tmpobj.name + file)).toBe(true); + expect(fs.readFileSync(tmpobj.name + file, "utf8")).toMatch(/bar/); }); tmpobj.removeCallback(); diff --git a/src/generators/TypescriptInterfaceGenerator.js b/src/generators/TypescriptInterfaceGenerator.js index 4a8fdb36..a35524c9 100644 --- a/src/generators/TypescriptInterfaceGenerator.js +++ b/src/generators/TypescriptInterfaceGenerator.js @@ -1,24 +1,31 @@ -import BaseGenerator from './BaseGenerator'; +import BaseGenerator from "./BaseGenerator"; export default class TypescriptInterfaceGenerator extends BaseGenerator { constructor(params) { super(params); - this.registerTemplates(`typescript/`, ['interface.ts']); + this.registerTemplates(`typescript/`, ["interface.ts"]); } help(resource) { - console.log('Interface for the "%s" resource type has been generated!', resource.title); + console.log( + 'Interface for the "%s" resource type has been generated!', + resource.title + ); } generate(api, resource, dir) { const dest = `${dir}/interfaces`; this.createDir(dest, false); - this.createFile('interface.ts', `${dest}/${resource.title.toLowerCase()}.ts`, { - fields: this.parseFields(resource), - name: resource.title - }); + this.createFile( + "interface.ts", + `${dest}/${resource.title.toLowerCase()}.ts`, + { + fields: this.parseFields(resource), + name: resource.title + } + ); } getType(field) { @@ -27,28 +34,28 @@ export default class TypescriptInterfaceGenerator extends BaseGenerator { } switch (field.range) { - case 'http://www.w3.org/2001/XMLSchema#integer': - case 'http://www.w3.org/2001/XMLSchema#decimal': - return 'number'; - case 'http://www.w3.org/2001/XMLSchema#boolean': - return 'boolean'; - case 'http://www.w3.org/2001/XMLSchema#date': - case 'http://www.w3.org/2001/XMLSchema#dateTime': - case 'http://www.w3.org/2001/XMLSchema#time': - return 'Date'; - case 'http://www.w3.org/2001/XMLSchema#string': - return 'string'; + case "http://www.w3.org/2001/XMLSchema#integer": + case "http://www.w3.org/2001/XMLSchema#decimal": + return "number"; + case "http://www.w3.org/2001/XMLSchema#boolean": + return "boolean"; + case "http://www.w3.org/2001/XMLSchema#date": + case "http://www.w3.org/2001/XMLSchema#dateTime": + case "http://www.w3.org/2001/XMLSchema#time": + return "Date"; + case "http://www.w3.org/2001/XMLSchema#string": + return "string"; } - return 'any'; + return "any"; } getDescription(field) { - return field.description ? field.description.replace(/"/g, "'") : '' + return field.description ? field.description.replace(/"/g, "'") : ""; } parseFields(resource) { - const fields = {} + const fields = {}; for (let field of resource.writableFields) { fields[field.name] = { @@ -57,7 +64,7 @@ export default class TypescriptInterfaceGenerator extends BaseGenerator { type: this.getType(field), description: this.getDescription(field), readonly: false - } + }; } for (let field of resource.readableFields) { @@ -71,9 +78,9 @@ export default class TypescriptInterfaceGenerator extends BaseGenerator { type: this.getType(field), description: this.getDescription(field), readonly: true - } + }; } - return Object.keys(fields).map((e) => fields[e]); + return Object.keys(fields).map(e => fields[e]); } } diff --git a/src/generators/TypescriptInterfaceGenerator.test.js b/src/generators/TypescriptInterfaceGenerator.test.js index db714586..7f260476 100644 --- a/src/generators/TypescriptInterfaceGenerator.test.js +++ b/src/generators/TypescriptInterfaceGenerator.test.js @@ -1,45 +1,54 @@ -import Api from '@api-platform/api-doc-parser/lib/Api'; -import Resource from '@api-platform/api-doc-parser/lib/Resource'; -import Field from '@api-platform/api-doc-parser/lib/Field'; -import fs from 'fs'; -import tmp from 'tmp'; -import TypescriptInterfaceGenerator from './TypescriptInterfaceGenerator'; +import Api from "@api-platform/api-doc-parser/lib/Api"; +import Resource from "@api-platform/api-doc-parser/lib/Resource"; +import Field from "@api-platform/api-doc-parser/lib/Field"; +import fs from "fs"; +import tmp from "tmp"; +import TypescriptInterfaceGenerator from "./TypescriptInterfaceGenerator"; -test('Generate a typescript interface', () => { - const generator = new TypescriptInterfaceGenerator({templateDirectory: `${__dirname}/../../templates`}); - const tmpobj = tmp.dirSync({unsafeCleanup: true}); +test("Generate a typescript interface", () => { + const generator = new TypescriptInterfaceGenerator({ + templateDirectory: `${__dirname}/../../templates` + }); + const tmpobj = tmp.dirSync({ unsafeCleanup: true }); - const resource = new Resource('abc', 'http://example.com/foos', { - id: 'foo', - title: 'Foo', - readableFields: [new Field('bar', { - id: 'http://schema.org/url', - range: 'http://www.w3.org/2001/XMLSchema#string', - reference: null, - required: true, - description: 'An URL' - })], - writableFields: [new Field('foo', { - id: 'http://schema.org/url', - range: 'http://www.w3.org/2001/XMLSchema#datetime', - reference: null, - required: true, - description: 'An URL' - }), new Field('foobar', { - id: 'http://schema.org/url', - range: undefined, - reference: new Resource('foobar', 'http://example.com/FooBar', {title: 'FooBar'}), - required: false - })] + const resource = new Resource("abc", "http://example.com/foos", { + id: "foo", + title: "Foo", + readableFields: [ + new Field("bar", { + id: "http://schema.org/url", + range: "http://www.w3.org/2001/XMLSchema#string", + reference: null, + required: true, + description: "An URL" + }) + ], + writableFields: [ + new Field("foo", { + id: "http://schema.org/url", + range: "http://www.w3.org/2001/XMLSchema#datetime", + reference: null, + required: true, + description: "An URL" + }), + new Field("foobar", { + id: "http://schema.org/url", + range: undefined, + reference: new Resource("foobar", "http://example.com/FooBar", { + title: "FooBar" + }), + required: false + }) + ] }); - const api = new Api('http://example.com', { - entrypoint: 'http://example.com:8080', - title: 'My API', + const api = new Api("http://example.com", { + entrypoint: "http://example.com:8080", + title: "My API", resources: [resource] }); generator.generate(api, resource, tmpobj.name); - expect(fs.existsSync(tmpobj.name+'/interfaces/foo.ts')).toBe(true); + expect(fs.existsSync(tmpobj.name + "/interfaces/foo.ts")).toBe(true); const res = `interface Foo { '@id'?: string; @@ -48,8 +57,10 @@ test('Generate a typescript interface', () => { foobar?: FooBar; readonly bar: string; } -` - expect(fs.readFileSync(tmpobj.name+'/interfaces/foo.ts').toString()).toEqual(res) +`; + expect( + fs.readFileSync(tmpobj.name + "/interfaces/foo.ts").toString() + ).toEqual(res); tmpobj.removeCallback(); }); diff --git a/src/generators/VueGenerator.js b/src/generators/VueGenerator.js index 3c7efd69..0e9ab333 100644 --- a/src/generators/VueGenerator.js +++ b/src/generators/VueGenerator.js @@ -1,5 +1,5 @@ -import chalk from 'chalk'; -import BaseGenerator from './BaseGenerator'; +import chalk from "chalk"; +import BaseGenerator from "./BaseGenerator"; export default class extends BaseGenerator { constructor(params) { @@ -7,57 +7,63 @@ export default class extends BaseGenerator { this.registerTemplates(`vue/`, [ // modules - 'store/modules/foo/index.js', - 'store/modules/foo/create/actions.js', - 'store/modules/foo/create/getters.js', - 'store/modules/foo/create/index.js', - 'store/modules/foo/create/mutation_types.js', - 'store/modules/foo/create/mutations.js', - 'store/modules/foo/delete/actions.js', - 'store/modules/foo/delete/getters.js', - 'store/modules/foo/delete/index.js', - 'store/modules/foo/delete/mutation_types.js', - 'store/modules/foo/delete/mutations.js', - 'store/modules/foo/list/actions.js', - 'store/modules/foo/list/getters.js', - 'store/modules/foo/list/index.js', - 'store/modules/foo/list/mutation_types.js', - 'store/modules/foo/list/mutations.js', - 'store/modules/foo/show/actions.js', - 'store/modules/foo/show/getters.js', - 'store/modules/foo/show/index.js', - 'store/modules/foo/show/mutation_types.js', - 'store/modules/foo/show/mutations.js', - 'store/modules/foo/update/actions.js', - 'store/modules/foo/update/getters.js', - 'store/modules/foo/update/index.js', - 'store/modules/foo/update/mutation_types.js', - 'store/modules/foo/update/mutations.js', + "store/modules/foo/index.js", + "store/modules/foo/create/actions.js", + "store/modules/foo/create/getters.js", + "store/modules/foo/create/index.js", + "store/modules/foo/create/mutation_types.js", + "store/modules/foo/create/mutations.js", + "store/modules/foo/delete/actions.js", + "store/modules/foo/delete/getters.js", + "store/modules/foo/delete/index.js", + "store/modules/foo/delete/mutation_types.js", + "store/modules/foo/delete/mutations.js", + "store/modules/foo/list/actions.js", + "store/modules/foo/list/getters.js", + "store/modules/foo/list/index.js", + "store/modules/foo/list/mutation_types.js", + "store/modules/foo/list/mutations.js", + "store/modules/foo/show/actions.js", + "store/modules/foo/show/getters.js", + "store/modules/foo/show/index.js", + "store/modules/foo/show/mutation_types.js", + "store/modules/foo/show/mutations.js", + "store/modules/foo/update/actions.js", + "store/modules/foo/update/getters.js", + "store/modules/foo/update/index.js", + "store/modules/foo/update/mutation_types.js", + "store/modules/foo/update/mutations.js", // components - 'components/foo/Create.vue', - 'components/foo/Form.vue', - 'components/foo/List.vue', - 'components/foo/Update.vue', - 'components/foo/Show.vue', + "components/foo/Create.vue", + "components/foo/Form.vue", + "components/foo/List.vue", + "components/foo/Update.vue", + "components/foo/Show.vue", // routes - 'router/foo.js', + "router/foo.js", // error - 'error/SubmissionError.js', + "error/SubmissionError.js", // utils - 'utils/fetch.js', + "utils/fetch.js" ]); } help(resource) { const titleLc = resource.title.toLowerCase(); - console.log('Code for the "%s" resource type has been generated!', resource.title); - console.log('Paste the following definitions in your application configuration:'); - console.log(chalk.green(` + console.log( + 'Code for the "%s" resource type has been generated!', + resource.title + ); + console.log( + "Paste the following definitions in your application configuration:" + ); + console.log( + chalk.green(` //import routes import ${titleLc}Routes from './router/${titleLc}'; @@ -78,12 +84,14 @@ export const store = new Vuex.Store({ ${titleLc} } }); -`)); +`) + ); } generate(api, resource, dir) { const lc = resource.title.toLowerCase(); - const titleUcFirst = resource.title.charAt(0).toUpperCase() + resource.title.slice(1); + const titleUcFirst = + resource.title.charAt(0).toUpperCase() + resource.title.slice(1); const context = { title: resource.title, @@ -98,7 +106,12 @@ export const store = new Vuex.Store({ // Create directories // These directories may already exist - for (let dir of [`${dir}/config`, `${dir}/error`, `${dir}/router`, `${dir}/utils`]) { + for (let dir of [ + `${dir}/config`, + `${dir}/error`, + `${dir}/router`, + `${dir}/utils` + ]) { this.createDir(dir, false); } @@ -116,50 +129,60 @@ export const store = new Vuex.Store({ for (let pattern of [ // modules - 'store/modules/%s/index.js', - 'store/modules/%s/create/actions.js', - 'store/modules/%s/create/getters.js', - 'store/modules/%s/create/index.js', - 'store/modules/%s/create/mutation_types.js', - 'store/modules/%s/create/mutations.js', - 'store/modules/%s/delete/actions.js', - 'store/modules/%s/delete/getters.js', - 'store/modules/%s/delete/index.js', - 'store/modules/%s/delete/mutation_types.js', - 'store/modules/%s/delete/mutations.js', - 'store/modules/%s/list/actions.js', - 'store/modules/%s/list/getters.js', - 'store/modules/%s/list/index.js', - 'store/modules/%s/list/mutation_types.js', - 'store/modules/%s/list/mutations.js', - 'store/modules/%s/show/actions.js', - 'store/modules/%s/show/getters.js', - 'store/modules/%s/show/index.js', - 'store/modules/%s/show/mutation_types.js', - 'store/modules/%s/show/mutations.js', - 'store/modules/%s/update/actions.js', - 'store/modules/%s/update/getters.js', - 'store/modules/%s/update/index.js', - 'store/modules/%s/update/mutation_types.js', - 'store/modules/%s/update/mutations.js', + "store/modules/%s/index.js", + "store/modules/%s/create/actions.js", + "store/modules/%s/create/getters.js", + "store/modules/%s/create/index.js", + "store/modules/%s/create/mutation_types.js", + "store/modules/%s/create/mutations.js", + "store/modules/%s/delete/actions.js", + "store/modules/%s/delete/getters.js", + "store/modules/%s/delete/index.js", + "store/modules/%s/delete/mutation_types.js", + "store/modules/%s/delete/mutations.js", + "store/modules/%s/list/actions.js", + "store/modules/%s/list/getters.js", + "store/modules/%s/list/index.js", + "store/modules/%s/list/mutation_types.js", + "store/modules/%s/list/mutations.js", + "store/modules/%s/show/actions.js", + "store/modules/%s/show/getters.js", + "store/modules/%s/show/index.js", + "store/modules/%s/show/mutation_types.js", + "store/modules/%s/show/mutations.js", + "store/modules/%s/update/actions.js", + "store/modules/%s/update/getters.js", + "store/modules/%s/update/index.js", + "store/modules/%s/update/mutation_types.js", + "store/modules/%s/update/mutations.js", // components - 'components/%s/Create.vue', - 'components/%s/Form.vue', - 'components/%s/List.vue', - 'components/%s/Update.vue', - 'components/%s/Show.vue', + "components/%s/Create.vue", + "components/%s/Form.vue", + "components/%s/List.vue", + "components/%s/Update.vue", + "components/%s/Show.vue", // routes - 'router/%s.js', + "router/%s.js" ]) { this.createFileFromPattern(pattern, dir, lc, context); } // error - this.createFile('error/SubmissionError.js', `${dir}/error/SubmissionError.js`, context, false); + this.createFile( + "error/SubmissionError.js", + `${dir}/error/SubmissionError.js`, + context, + false + ); this.createEntrypoint(api.entrypoint, `${dir}/config/_entrypoint.js`); - this.createFile('utils/fetch.js', `${dir}/utils/fetch.js`, {hydraPrefix: this.hydraPrefix}, false); + this.createFile( + "utils/fetch.js", + `${dir}/utils/fetch.js`, + { hydraPrefix: this.hydraPrefix }, + false + ); } } diff --git a/src/generators/VueGenerator.test.js b/src/generators/VueGenerator.test.js index 4f01f98c..890e895d 100644 --- a/src/generators/VueGenerator.test.js +++ b/src/generators/VueGenerator.test.js @@ -1,57 +1,74 @@ -import Api from '@api-platform/api-doc-parser/lib/Api'; -import Resource from '@api-platform/api-doc-parser/lib/Resource'; -import Field from '@api-platform/api-doc-parser/lib/Field'; -import fs from 'fs'; -import tmp from 'tmp'; -import VueGenerator from './VueGenerator'; - -test('Generate a Vue app', () => { - const generator = new VueGenerator({hydraPrefix: 'hydra:', templateDirectory: `${__dirname}/../../templates`}); - const tmpobj = tmp.dirSync({unsafeCleanup: true}); - - const fields = [new Field('bar', { - id: 'http://schema.org/url', - range: 'http://www.w3.org/2001/XMLSchema#string', - reference: null, - required: true, - description: 'An URL' - })]; - const resource = new Resource('abc', 'http://example.com/foos', { - id: 'foo', - title: 'Foo', +import Api from "@api-platform/api-doc-parser/lib/Api"; +import Resource from "@api-platform/api-doc-parser/lib/Resource"; +import Field from "@api-platform/api-doc-parser/lib/Field"; +import fs from "fs"; +import tmp from "tmp"; +import VueGenerator from "./VueGenerator"; + +test("Generate a Vue app", () => { + const generator = new VueGenerator({ + hydraPrefix: "hydra:", + templateDirectory: `${__dirname}/../../templates` + }); + const tmpobj = tmp.dirSync({ unsafeCleanup: true }); + + const fields = [ + new Field("bar", { + id: "http://schema.org/url", + range: "http://www.w3.org/2001/XMLSchema#string", + reference: null, + required: true, + description: "An URL" + }) + ]; + const resource = new Resource("abc", "http://example.com/foos", { + id: "foo", + title: "Foo", readableFields: fields, writableFields: fields }); - const api = new Api('http://example.com', { - entrypoint: 'http://example.com:8080', - title: 'My API', + const api = new Api("http://example.com", { + entrypoint: "http://example.com:8080", + title: "My API", resources: [resource] }); generator.generate(api, resource, tmpobj.name); - expect(fs.existsSync(tmpobj.name+'/components/foo/Create.vue')).toBe(true); - expect(fs.existsSync(tmpobj.name+'/components/foo/Form.vue')).toBe(true); - expect(fs.existsSync(tmpobj.name+'/components/foo/List.vue')).toBe(true); - expect(fs.existsSync(tmpobj.name+'/components/foo/Show.vue')).toBe(true); - expect(fs.existsSync(tmpobj.name+'/components/foo/Update.vue')).toBe(true); + expect(fs.existsSync(tmpobj.name + "/components/foo/Create.vue")).toBe(true); + expect(fs.existsSync(tmpobj.name + "/components/foo/Form.vue")).toBe(true); + expect(fs.existsSync(tmpobj.name + "/components/foo/List.vue")).toBe(true); + expect(fs.existsSync(tmpobj.name + "/components/foo/Show.vue")).toBe(true); + expect(fs.existsSync(tmpobj.name + "/components/foo/Update.vue")).toBe(true); - expect(fs.existsSync(tmpobj.name+'/config/_entrypoint.js')).toBe(true); + expect(fs.existsSync(tmpobj.name + "/config/_entrypoint.js")).toBe(true); - expect(fs.existsSync(tmpobj.name+'/error/SubmissionError.js')).toBe(true); + expect(fs.existsSync(tmpobj.name + "/error/SubmissionError.js")).toBe(true); - expect(fs.existsSync(tmpobj.name+'/router/foo.js')).toBe(true); + expect(fs.existsSync(tmpobj.name + "/router/foo.js")).toBe(true); - expect(fs.existsSync(tmpobj.name+'/store/modules/foo/index.js')).toBe(true); + expect(fs.existsSync(tmpobj.name + "/store/modules/foo/index.js")).toBe(true); - ['create', 'delete', 'list', 'show', 'update'].forEach((action) => { - expect(fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/actions.js`)).toBe(true); - expect(fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/getters.js`)).toBe(true); - expect(fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/index.js`)).toBe(true); - expect(fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/mutation_types.js`)).toBe(true); - expect(fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/mutations.js`)).toBe(true); + ["create", "delete", "list", "show", "update"].forEach(action => { + expect( + fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/actions.js`) + ).toBe(true); + expect( + fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/getters.js`) + ).toBe(true); + expect( + fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/index.js`) + ).toBe(true); + expect( + fs.existsSync( + `${tmpobj.name}/store/modules/foo/${action}/mutation_types.js` + ) + ).toBe(true); + expect( + fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/mutations.js`) + ).toBe(true); }); - expect(fs.existsSync(tmpobj.name+'/utils/fetch.js')).toBe(true); + expect(fs.existsSync(tmpobj.name + "/utils/fetch.js")).toBe(true); tmpobj.removeCallback(); }); diff --git a/src/index.js b/src/index.js index 96b571ee..f7ddcd84 100755 --- a/src/index.js +++ b/src/index.js @@ -1,48 +1,87 @@ #!/usr/bin/env node -import 'isomorphic-fetch'; -import program from 'commander'; -import parseHydraDocumentation from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation'; -import {version} from '../package.json'; -import generators from './generators'; +import "isomorphic-fetch"; +import program from "commander"; +import parseHydraDocumentation from "@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation"; +import { version } from "../package.json"; +import generators from "./generators"; program .version(version) - .description('Generate a CRUD application built with React, Redux and React Router from an Hydra-enabled API') - .usage('entrypoint outputDirectory') - .option('-r, --resource [resourceName]', 'Generate CRUD for the given resource') - .option('-p, --hydra-prefix [hydraPrefix]', 'The hydra prefix used by the API', 'hydra:') - .option('-g, --generator [generator]', 'The generator to use, one of "react", "react-native", "vue", "admin-on-rest"', 'react') - .option('-t, --template-directory [templateDirectory]', 'The templates directory base to use. Final directory will be ${templateDirectory}/${generator}', `${__dirname}/../templates/`) + .description( + "Generate a CRUD application built with React, Redux and React Router from an Hydra-enabled API" + ) + .usage("entrypoint outputDirectory") + .option( + "-r, --resource [resourceName]", + "Generate CRUD for the given resource" + ) + .option( + "-p, --hydra-prefix [hydraPrefix]", + "The hydra prefix used by the API", + "hydra:" + ) + .option( + "-g, --generator [generator]", + 'The generator to use, one of "react", "react-native", "vue", "admin-on-rest"', + "react" + ) + .option( + "-t, --template-directory [templateDirectory]", + "The templates directory base to use. Final directory will be ${templateDirectory}/${generator}", + `${__dirname}/../templates/` + ) .parse(process.argv); -if (2 !== program.args.length && (!process.env.API_PLATFORM_CLIENT_GENERATOR_ENTRYPOINT || !process.env.API_PLATFORM_CLIENT_GENERATOR_OUTPUT)) { +if ( + 2 !== program.args.length && + (!process.env.API_PLATFORM_CLIENT_GENERATOR_ENTRYPOINT || + !process.env.API_PLATFORM_CLIENT_GENERATOR_OUTPUT) +) { program.help(); } -const entrypoint = program.args[0] || process.env.API_PLATFORM_CLIENT_GENERATOR_ENTRYPOINT; -const outputDirectory = program.args[1] || process.env.API_PLATFORM_CLIENT_GENERATOR_OUTPUT; +const entrypoint = + program.args[0] || process.env.API_PLATFORM_CLIENT_GENERATOR_ENTRYPOINT; +const outputDirectory = + program.args[1] || process.env.API_PLATFORM_CLIENT_GENERATOR_OUTPUT; const generator = generators(program.generator)({ hydraPrefix: program.hydraPrefix, templateDirectory: program.templateDirectory }); -const resourceToGenerate = program.resource ? program.resource.toLowerCase() : null; +const resourceToGenerate = program.resource + ? program.resource.toLowerCase() + : null; -parseHydraDocumentation(entrypoint).then(ret => { - ret.api.resources.filter(({deprecated}) => !deprecated).forEach(resource => { - const nameLc = resource.name.toLowerCase(); - const titleLc = resource.title.toLowerCase(); +parseHydraDocumentation(entrypoint) + .then(ret => { + ret.api.resources + .filter(({ deprecated }) => !deprecated) + .forEach(resource => { + const nameLc = resource.name.toLowerCase(); + const titleLc = resource.title.toLowerCase(); - if (null === resourceToGenerate || nameLc === resourceToGenerate || titleLc === resourceToGenerate) { - resource.fields = resource.fields.filter(({deprecated}) => !deprecated); - resource.readableFields = resource.readableFields.filter(({deprecated}) => !deprecated); - resource.writableFields = resource.writableFields.filter(({deprecated}) => !deprecated); + if ( + null === resourceToGenerate || + nameLc === resourceToGenerate || + titleLc === resourceToGenerate + ) { + resource.fields = resource.fields.filter( + ({ deprecated }) => !deprecated + ); + resource.readableFields = resource.readableFields.filter( + ({ deprecated }) => !deprecated + ); + resource.writableFields = resource.writableFields.filter( + ({ deprecated }) => !deprecated + ); - generator.generate(ret.api, resource, outputDirectory); - generator.help(resource) - } + generator.generate(ret.api, resource, outputDirectory); + generator.help(resource); + } + }); }) -}).catch((e) => { - console.log(e); -}); + .catch(e => { + console.log(e); + }); diff --git a/yarn.lock b/yarn.lock index 364d8f75..b524fb23 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1749,6 +1749,12 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-config-prettier@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3" + dependencies: + get-stdin "^5.0.1" + eslint-import-resolver-node@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" @@ -1778,6 +1784,13 @@ eslint-plugin-import@^2.2.0: read-pkg-up "^2.0.0" resolve "^1.6.0" +eslint-plugin-prettier@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.0.tgz#33e4e228bdb06142d03c560ce04ec23f6c767dd7" + dependencies: + fast-diff "^1.1.1" + jest-docblock "^21.0.0" + eslint@^3.18.0: version "3.19.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" @@ -1975,6 +1988,10 @@ fast-deep-equal@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" +fast-diff@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -2156,6 +2173,10 @@ get-object@^0.2.0: is-number "^2.0.2" isobject "^0.2.0" +get-stdin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -2890,6 +2911,10 @@ jest-diff@^23.0.1: jest-get-type "^22.1.0" pretty-format "^23.0.1" +jest-docblock@^21.0.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" + jest-docblock@^23.0.1: version "23.0.1" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.0.1.tgz#deddd18333be5dc2415260a04ef3fce9276b5725" @@ -3836,6 +3861,10 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" +prettier@^1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.2.tgz#412b87bc561cb11074d2877a33a38f78c2303cda" + pretty-format@^23.0.1: version "23.0.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.0.1.tgz#d61d065268e4c759083bccbca27a01ad7c7601f4"