create-graphql-yoga
Version:
102 lines (101 loc) • 4.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createGraphQLYoga = exports.spinner = void 0;
const tslib_1 = require("tslib");
const ora_1 = tslib_1.__importDefault(require("ora"));
const node_util_1 = require("node:util");
const tar_1 = tslib_1.__importDefault(require("tar"));
const node_path_1 = require("node:path");
const node_stream_1 = require("node:stream");
const node_fs_1 = require("node:fs");
const node_readline_1 = require("node:readline");
const get_npm_tarball_url_1 = tslib_1.__importDefault(require("get-npm-tarball-url"));
exports.spinner = (0, ora_1.default)();
const options = {
template: {
type: 'string',
short: 't',
},
};
function getRegistryAPIUrl(packageName, version) {
return `https://registry.npmjs.org/${packageName}/${version}`;
}
async function getVersionByTag(packageName, tag, fetchFn) {
const url = getRegistryAPIUrl(packageName, tag);
const response = await fetchFn(url);
if (response.status === 404) {
throw new Error(`Package not found: ${packageName}`);
}
if (!response.ok) {
throw new Error(`Failed to fetch package ${packageName} with ${response.status}: ${await response.text()}`);
}
const { version } = await response.json();
return version;
}
function getPackageNameAndTagForTemplate(template) {
const [suffix, tag] = template.split('@');
return {
packageName: `@graphql-yoga/template-${suffix}`,
tag: tag ?? 'latest',
};
}
async function createGraphQLYoga({ argv, input, output, fetchFn, }) {
const args = [...argv];
while (args[0].startsWith('/') || args[0] === '--') {
args.shift();
}
const rl = (0, node_readline_1.createInterface)({
input,
output,
});
const projectName = await new Promise((resolve) => {
rl.question('What is the name of your project? ', (answer) => {
resolve(answer);
});
});
const { values: { template = 'node-ts' }, } = (0, node_util_1.parseArgs)({ args, options, allowPositionals: true });
exports.spinner.start(`Fetching template ${template}...`);
const { packageName, tag } = getPackageNameAndTagForTemplate(template);
const version = await getVersionByTag(packageName, tag, fetchFn);
const url = (0, get_npm_tarball_url_1.default)(packageName, version);
const response = await fetchFn(url);
if (response.status === 404) {
throw new Error(`Template not found: ${template}`);
}
if (!response.ok) {
throw new Error(`Failed to fetch template ${template} with ${response.status}: ${await response.text()}`);
}
if (!response.body) {
throw new Error(`Failed to fetch template ${template} with empty body`);
}
const nodeStream = node_stream_1.Readable.from(response.body);
const targetDir = (0, node_path_1.join)(process.cwd(), projectName);
if ((0, node_fs_1.existsSync)(targetDir)) {
throw new Error(`Target directory ${targetDir} already exists.`);
}
(0, node_fs_1.mkdirSync)(targetDir, { recursive: true });
await new Promise((resolve, reject) => {
const extractedTarStream = tar_1.default.extract({
strip: 1,
cwd: targetDir,
});
nodeStream
.pipe(extractedTarStream)
.once('error', (err) => {
reject(new Error(`Failed to extract template ${template} with ${err}`));
})
.once('close', () => {
resolve();
});
});
const packageJsonPath = (0, node_path_1.join)(targetDir, 'package.json');
const packageJsonContent = (0, node_fs_1.readFileSync)(packageJsonPath, 'utf-8');
const packageJson = JSON.parse(packageJsonContent);
packageJson.name = projectName;
delete packageJson.version;
packageJson.private = true;
const newPackageJsonContent = JSON.stringify(packageJson, null, 2);
(0, node_fs_1.writeFileSync)(packageJsonPath, newPackageJsonContent);
exports.spinner.succeed(`Project ${projectName} created on ${targetDir}.`);
}
exports.createGraphQLYoga = createGraphQLYoga;