Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
296 changes: 168 additions & 128 deletions generate.js
Original file line number Diff line number Diff line change
@@ -1,209 +1,249 @@
'use strict'

const {
readFile,
writeFile,
existsSync
} = require('node:fs')
const path = require('node:path')
const chalk = require('chalk')
const generify = require('generify')
const argv = require('yargs-parser')
const cliPkg = require('./package')
const { execSync } = require('node:child_process')
const log = require('./log')
"use strict";

Check failure on line 1 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Extra semicolon

Check failure on line 1 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Strings must use singlequote

const { readFile, writeFile, existsSync } = require("node:fs");

Check failure on line 3 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Extra semicolon

Check failure on line 3 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Strings must use singlequote
const path = require("node:path");

Check failure on line 4 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Extra semicolon

Check failure on line 4 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Strings must use singlequote
const chalk = require("chalk");

Check failure on line 5 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Extra semicolon

Check failure on line 5 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Strings must use singlequote
const generify = require("generify");

Check failure on line 6 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Extra semicolon

Check failure on line 6 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Strings must use singlequote
const argv = require("yargs-parser");
const cliPkg = require("./package");
const { execSync } = require("node:child_process");
const log = require("./log");

const javascriptTemplate = {
dir: 'app',
main: 'app.js',
dir: "app",
main: "app.js",
scripts: {
test: 'node --test test/**/*.test.js',
start: 'fastify start -l info app.js',
dev: 'fastify start -w -l info -P app.js'
test: "node --test test/**/*.test.js",
start: "fastify start -l info app.js",
dev: "fastify start -w -l info -P app.js",
},
dependencies: {
fastify: cliPkg.dependencies.fastify,
'fastify-plugin': cliPkg.devDependencies['fastify-plugin'] || cliPkg.dependencies['fastify-plugin'],
'@fastify/autoload': cliPkg.devDependencies['@fastify/autoload'],
'@fastify/sensible': cliPkg.devDependencies['@fastify/sensible'],
'fastify-cli': '^' + cliPkg.version
"fastify-plugin":
cliPkg.devDependencies["fastify-plugin"] ||
cliPkg.dependencies["fastify-plugin"],
"@fastify/autoload": cliPkg.devDependencies["@fastify/autoload"],
"@fastify/sensible": cliPkg.devDependencies["@fastify/sensible"],
"fastify-cli": "^" + cliPkg.version,
},
devDependencies: {},
logInstructions: function (pkg) {
log('debug', 'saved package.json')
log('info', `project ${pkg.name} generated successfully`)
log('debug', `run '${chalk.bold('npm install')}' to install the dependencies`)
log('debug', `run '${chalk.bold('npm start')}' to start the application`)
log('debug', `run '${chalk.bold('npm run dev')}' to start the application with pino-pretty pretty logging (not suitable for production)`)
log('debug', `run '${chalk.bold('npm test')}' to execute the unit tests`)
log("debug", "saved package.json");
log("info", `project ${pkg.name} generated successfully`);
log(
"debug",
`run '${chalk.bold("npm install")}' to install the dependencies`,

Check warning on line 35 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);
log("debug", `run '${chalk.bold("npm start")}' to start the application`);
log(
"debug",
`run '${chalk.bold("npm run dev")}' to start the application with pino-pretty pretty logging (not suitable for production)`,

Check warning on line 40 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);
log("debug", `run '${chalk.bold("npm test")}' to execute the unit tests`);

if (pkg.scripts.lint) {
log('debug', `run '${chalk.bold('npm lint')}' to run linter and fix code style issues`)
log(
"debug",
`run '${chalk.bold("npm lint")}' to run linter and fix code style issues`,

Check warning on line 47 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);
}
}
}
},
};

const typescriptTemplate = {
dir: 'app-ts',
main: 'app.ts',
dir: "app-ts",
main: "app.ts",
scripts: {
clean:
"node -e \"require('fs').rmSync('dist', {recursive: true, force: true})\"",
test: 'npm run build:ts && tsc -p test/tsconfig.json && c8 node --test -r ts-node/register "test/**/*.ts"',
start: 'npm run build:ts && fastify start -l info dist/app.js',
'build:ts': 'tsc',
'watch:ts': 'tsc -w',
start: "npm run build:ts && fastify start -l info dist/app.js",
"build:ts": "npm run clean && tsc",
"watch:ts": "tsc -w",
dev: 'npm run build:ts && concurrently -k -p "[{name}]" -n "TypeScript,App" -c "yellow.bold,cyan.bold" "npm:watch:ts" "npm:dev:start"',
'dev:start': 'fastify start --ignore-watch=.ts$ -w -l info -P dist/app.js'
"dev:start": "fastify start --ignore-watch=.ts$ -w -l info -P dist/app.js",
},
dependencies: {
fastify: cliPkg.dependencies.fastify,
'fastify-plugin': cliPkg.devDependencies['fastify-plugin'] || cliPkg.dependencies['fastify-plugin'],
'@fastify/autoload': cliPkg.devDependencies['@fastify/autoload'],
'@fastify/sensible': cliPkg.devDependencies['@fastify/sensible'],
'fastify-cli': '^' + cliPkg.version
"fastify-plugin":
cliPkg.devDependencies["fastify-plugin"] ||
cliPkg.dependencies["fastify-plugin"],
"@fastify/autoload": cliPkg.devDependencies["@fastify/autoload"],
"@fastify/sensible": cliPkg.devDependencies["@fastify/sensible"],
"fastify-cli": "^" + cliPkg.version,
},
devDependencies: {
'@types/node': cliPkg.devDependencies['@types/node'],
"@types/node": cliPkg.devDependencies["@types/node"],
c8: cliPkg.devDependencies.c8,
'ts-node': cliPkg.devDependencies['ts-node'],
"ts-node": cliPkg.devDependencies["ts-node"],
concurrently: cliPkg.devDependencies.concurrently,
'fastify-tsconfig': cliPkg.devDependencies['fastify-tsconfig'],
typescript: cliPkg.devDependencies.typescript
"fastify-tsconfig": cliPkg.devDependencies["fastify-tsconfig"],
typescript: cliPkg.devDependencies.typescript,
},
nodemonConfig: {
watch: ['src/'],
ignore: ['dist/*']
watch: ["src/"],
ignore: ["dist/*"],
},
logInstructions: function (pkg) {
log('debug', 'saved package.json')
log('info', `project ${pkg.name} generated successfully`)
log('debug', `run '${chalk.bold('npm install')}' to install the dependencies`)
log('debug', `run '${chalk.bold('npm start')}' to start the application`)
log('debug', `run '${chalk.bold('npm build:ts')}' to compile the typescript application`)
log('debug', `run '${chalk.bold('npm run dev')}' to start the application with pino-pretty pretty logging (not suitable for production)`)
log('debug', `run '${chalk.bold('npm test')}' to execute the unit tests`)
}
}
log("debug", "saved package.json");
log("info", `project ${pkg.name} generated successfully`);
log(
"debug",
`run '${chalk.bold("npm install")}' to install the dependencies`,

Check warning on line 92 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);
log("debug", `run '${chalk.bold("npm start")}' to start the application`);
log(
"debug",
`run '${chalk.bold("npm run clean")}' to remove the compiled output directory`,

Check warning on line 97 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);
log(
"debug",
`run '${chalk.bold("npm run build:ts")}' to compile the typescript application`,

Check warning on line 101 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);
log(
"debug",
`run '${chalk.bold("npm run dev")}' to start the application with pino-pretty pretty logging (not suitable for production)`,

Check warning on line 105 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);
log("debug", `run '${chalk.bold("npm test")}' to execute the unit tests`);
},
};

function generate (dir, template) {
function generate(dir, template) {
return new Promise((resolve, reject) => {
generify(path.join(__dirname, 'templates', template.dir), dir, {}, function (file) {
log('debug', `generated ${file}`)
}, function (err) {
if (err) {
return reject(err)
}

process.chdir(dir)
execSync('npm init -y')

log('info', `reading package.json in ${dir}`)
readFile('package.json', (err, data) => {
generify(
path.join(__dirname, "templates", template.dir),
dir,
{},
function (file) {
log("debug", `generated ${file}`);
},
function (err) {
if (err) {
return reject(err)
return reject(err);
}

let pkg
try {
pkg = JSON.parse(data)
} catch (err) {
return reject(err)
}
process.chdir(dir);
execSync("npm init -y");

pkg.main = template.main
log("info", `reading package.json in ${dir}`);
readFile("package.json", (err, data) => {
if (err) {
return reject(err);
}

pkg.type = template.type
let pkg;
try {
pkg = JSON.parse(data);
} catch (err) {
return reject(err);
}

pkg.scripts = Object.assign(pkg.scripts || {}, template.scripts)
pkg.main = template.main;

pkg.dependencies = Object.assign(pkg.dependencies || {}, template.dependencies)
pkg.type = template.type;

pkg.devDependencies = Object.assign(pkg.devDependencies || {}, template.devDependencies)
pkg.scripts = Object.assign(pkg.scripts || {}, template.scripts);

log('debug', 'edited package.json, saving')
writeFile('package.json', JSON.stringify(pkg, null, 2), (err) => {
if (err) {
return reject(err)
}
pkg.dependencies = Object.assign(
pkg.dependencies || {},
template.dependencies,

Check warning on line 149 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);

pkg.devDependencies = Object.assign(
pkg.devDependencies || {},
template.devDependencies,

Check warning on line 154 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);

template.logInstructions(pkg)
resolve()
})
})
})
})
log("debug", "edited package.json, saving");
writeFile("package.json", JSON.stringify(pkg, null, 2), (err) => {
if (err) {
return reject(err);
}

template.logInstructions(pkg);
resolve();
});
});
},

Check warning on line 167 in generate.js

View workflow job for this annotation

GitHub Actions / test / quality-check / Lint Code

Unexpected trailing comma
);
});
}

function cli (args) {
const opts = argv(args)
const dir = opts._[0]
function cli(args) {
const opts = argv(args);
const dir = opts._[0];

if (dir && existsSync(dir)) {
if (dir !== '.' && dir !== './') {
log('error', 'directory ' + opts._[0] + ' already exists')
process.exit(1)
if (dir !== "." && dir !== "./") {
log("error", "directory " + opts._[0] + " already exists");
process.exit(1);
}
}
if (dir === undefined) {
log('error', 'must specify a directory to \'fastify generate\'')
process.exit(1)
log("error", "must specify a directory to 'fastify generate'");
process.exit(1);
}
if (!opts.integrate && existsSync(path.join(dir, 'package.json'))) {
log('error', 'a package.json file already exists in target directory. retry with the --integrate flag to proceed')
process.exit(1)
if (!opts.integrate && existsSync(path.join(dir, "package.json"))) {
log(
"error",
"a package.json file already exists in target directory. retry with the --integrate flag to proceed",
);
process.exit(1);
}

let template
if (opts.lang === 'ts' || opts.lang === 'typescript') {
template = { ...typescriptTemplate }
let template;
if (opts.lang === "ts" || opts.lang === "typescript") {
template = { ...typescriptTemplate };

if (opts.esm) {
template.dir = 'app-ts-esm'
template.type = 'module'
template.dir = "app-ts-esm";
template.type = "module";

template.devDependencies.c8 = cliPkg.devDependencies.c8
template.scripts.test = 'npm run build:ts && tsc -p test/tsconfig.json && FASTIFY_AUTOLOAD_TYPESCRIPT=1 node --test --experimental-test-coverage --loader ts-node/esm test/**/*.ts'
template.scripts.dev = 'fastify start -l info src/app.ts'
template.devDependencies.c8 = cliPkg.devDependencies.c8;
template.scripts.test =
"npm run build:ts && tsc -p test/tsconfig.json && FASTIFY_AUTOLOAD_TYPESCRIPT=1 node --test --experimental-test-coverage --loader ts-node/esm test/**/*.ts";
template.scripts.dev = "fastify start -l info src/app.ts";
}
} else {
template = { ...javascriptTemplate }
template = { ...javascriptTemplate };

if (opts.esm) {
template.dir = 'app-esm'
template.type = 'module'
template.dir = "app-esm";
template.type = "module";

template.devDependencies.c8 = cliPkg.devDependencies.c8
template.scripts.test = 'node --test test/**/*.test.js'
template.devDependencies.c8 = cliPkg.devDependencies.c8;
template.scripts.test = "node --test test/**/*.test.js";
}

if (opts.standardlint) {
template.scripts = {
...template.scripts,
pretest: 'standard',
lint: 'standard --fix'
}
pretest: "standard",
lint: "standard --fix",
};

template.devDependencies = {
...template.devDependencies,
standard: cliPkg.devDependencies.standard
}
standard: cliPkg.devDependencies.standard,
};
}
}

generate(dir, template).catch(function (err) {
if (err) {
log('error', err.message)
process.exit(1)
log("error", err.message);
process.exit(1);
}
})
});
}

module.exports = {
generate,
cli,
javascriptTemplate,
typescriptTemplate
}
typescriptTemplate,
};

if (require.main === module) {
cli(process.argv.slice(2))
cli(process.argv.slice(2));
}
Loading