diff --git a/bin/commands/build.js b/bin/commands/build.js new file mode 100644 index 0000000..fc1e7b4 --- /dev/null +++ b/bin/commands/build.js @@ -0,0 +1,70 @@ +const { mkdirSync, rmdirSync, existsSync, readFileSync, writeFileSync, cpSync } = require('node:fs'); +const { join } = require('node:path'); +const { execSync } = require('node:child_process'); + +exports.command = 'build'; +exports.desc = 'build from static.json'; +exports.builder = function (yargs) { + yargs + .option('out-directory', { + alias: 'out', + type: 'string', + default: './out', + describe: 'path the "out" directory will be saved to' + }) + .option('next-base-path', { + type: 'string', + describe: 'Next.js basePath option' + }) +} +exports.handler = function (argv) { + const staticExists = existsSync(argv.path); + if (!staticExists) { + throw Error(`Unable to locate ${argv.path}`); + } + + const STATIC = JSON.parse(readFileSync(argv.path)); + + const workspace = join(__dirname, '..', 'workspace'); + + const exists = existsSync(workspace); + if (exists) { + rmdirSync(workspace, { + recursive: true + }); + } + + mkdirSync(workspace); + + const { + application, + version + } = STATIC['_static']; + + execSync(`cd ${workspace} && git clone ${application} . && npm ci`); + + writeFileSync(join(workspace, 'static.json'), JSON.stringify(STATIC)); + + const nextConfiguration = { + output: 'export' + } + + if (argv.nextBasePath) { + nextConfiguration.basePath = argv.nextBasePath + } + + writeFileSync( + join(workspace, 'next.config.js'), + `module.exports = ${JSON.stringify(nextConfiguration)}` + ) + + execSync(`cd ${workspace} && npm run build`); + + cpSync(join(workspace, 'out'), argv.out, { + recursive: true + }); + + rmdirSync(workspace, { + recursive: true + }); +} diff --git a/bin/commands/lint.js b/bin/commands/lint.js new file mode 100644 index 0000000..d7e42f2 --- /dev/null +++ b/bin/commands/lint.js @@ -0,0 +1,54 @@ +const { existsSync, readFileSync } = require('node:fs'); + +const Ajv = require("ajv"); +const ajv = new Ajv(); + +exports.command = 'lint'; +exports.desc = 'lint a static.json file'; +exports.handler = function (argv) { + const staticExists = existsSync(argv.path); + if (!staticExists) { + throw Error(`Unable to locate ${argv.path}`); + } + let STATIC; + try { + STATIC = JSON.parse(readFileSync(argv.path)); + } catch (e) { + throw Error(`Unable to parse ${argv.path} as JSON`); + } + + const schema = { + type: "object", + properties: { + _static: { + type: "object", + properties: { + application: { type: "string"}, + version: { type: "string" } + }, + required: ["application"], + additionalProperties: false + }, + metadata: { + type: "object", + properties: { + title: { type: "string" }, + description: { type: "string" } + } + }, + contents: { + type: "object" + } + }, + required: ["_static"], + additionalProperties: false + } + + + const validate = ajv.compile(schema); + + const valid = validate(STATIC); + if (!valid) { + console.error(validate.errors); + } +} diff --git a/bin/index.js b/bin/index.js index b74236b..acd4181 100755 --- a/bin/index.js +++ b/bin/index.js @@ -5,76 +5,15 @@ const { join } = require('node:path'); const { execSync } = require('node:child_process'); require('yargs/yargs')(process.argv.slice(2)) - .command('build', 'build from static.json', (yargs) => { - yargs - .option('path', { - type: 'string', - default: 'static.json', - describe: 'path to the static.json file to processs' - }) - .option('out-directory', { - alias: 'out', - type: 'string', - default: './out', - describe: 'path the "out" directory will be saved to' - }) - .option('next-base-path', { - type: 'string', - describe: 'Next.js basePath option' - }) - }, (argv) => { - const staticExists = existsSync(argv.path); - if (!staticExists) { - throw Error(`Unable to locate ${argv.path}`); - } - - const STATIC = JSON.parse(readFileSync(argv.path)); - - const workspace = join(__dirname, '..', 'workspace'); - - const exists = existsSync(workspace); - if (exists) { - rmdirSync(workspace, { - recursive: true - }); - } - - mkdirSync(workspace); - - const { - application, - version - } = STATIC['_static']; - - execSync(`cd ${workspace} && git clone ${application} . && npm ci`); - - writeFileSync(join(workspace, 'static.json'), JSON.stringify(STATIC)); - - const nextConfiguration = { - output: 'export' - } - - if (argv.nextBasePath) { - nextConfiguration.basePath = argv.nextBasePath - } - - writeFileSync( - join(workspace, 'next.config.js'), - `module.exports = ${JSON.stringify(nextConfiguration)}` - ) - - execSync(`cd ${workspace} && npm run build`); - - cpSync(join(workspace, 'out'), argv.out, { - recursive: true - }); - - rmdirSync(workspace, { - recursive: true - }); + .option('path', { + type: 'string', + default: 'static.json', + describe: 'path to the static.json file to processs' }) + .commandDir('commands') .help() .argv + diff --git a/package-lock.json b/package-lock.json index c1a3f70..b376d8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,28 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "ajv": "^8.12.0", "yargs": "^17.7.2" }, "bin": { "static": "bin/index.js" } }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -79,6 +95,11 @@ "node": ">=6" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -95,6 +116,19 @@ "node": ">=8" } }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -103,6 +137,14 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -127,6 +169,14 @@ "node": ">=8" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 2face63..ed76652 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "author": "", "license": "ISC", "dependencies": { + "ajv": "^8.12.0", "yargs": "^17.7.2" } }