Skip to content
This repository has been archived by the owner on Mar 20, 2023. It is now read-only.

Commit

Permalink
Copy 'build' implementation from 'graphql-js' (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov authored Jul 12, 2019
1 parent 45ff708 commit 325d159
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 939 deletions.
20 changes: 5 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"version": "0.8.0",
"description": "Production ready GraphQL HTTP middleware.",
"license": "MIT",
"private": true,
"main": "index.js",
"types": "index.d.ts",
"homepage": "https://github.com/graphql/express-graphql",
"bugs": {
"url": "https://github.com/graphql/express-graphql/issues"
Expand All @@ -23,17 +26,6 @@
"engines": {
"node": ">= 8.x"
},
"main": "dist/index.js",
"types": "types",
"directories": {
"lib": "./dist"
},
"files": [
"dist",
"types/index.d.ts",
"README.md",
"LICENSE"
],
"scripts": {
"test": "npm run prettier:check && npm run lint && npm run check && npm run testonly",
"test:ci": "yarn check --integrity && npm run prettier:check && npm run lint && npm run check && npm run testonly:cover && npm run build",
Expand All @@ -43,9 +35,8 @@
"prettier": "prettier --ignore-path .gitignore --write --list-different '**/*.{js,ts,md,json,yml}'",
"prettier:check": "prettier --ignore-path .gitignore --check '**/*.{js,md,json,yml}'",
"check": "flow check",
"build": "rm -rf dist/* && babel src --ignore '**/__tests__' --out-dir dist && npm run build:flow",
"build:flow": "find ./src -name '*.js' -not -path '*/__tests__*' | while read filepath; do cp $filepath `echo $filepath | sed 's/\\/src\\//\\/dist\\//g'`.flow; done",
"preversion": "npm test",
"build": "node resources/build.js",
"preversion": ". ./resources/checkgit.sh",
"start": "node -r @babel/register examples/index.js"
},
"dependencies": {
Expand All @@ -55,7 +46,6 @@
"raw-body": "^2.4.1"
},
"devDependencies": {
"@babel/cli": "^7.5.0",
"@babel/core": "7.5.4",
"@babel/plugin-transform-flow-strip-types": "7.4.4",
"@babel/plugin-transform-modules-commonjs": "7.5.0",
Expand Down
112 changes: 112 additions & 0 deletions resources/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// @noflow

'use strict';

const fs = require('fs');
const path = require('path');
const assert = require('assert');
const babel = require('@babel/core');
const {
copyFile,
writeFile,
rmdirRecursive,
mkdirRecursive,
readdirRecursive,
parseSemver,
} = require('./utils');

if (require.main === module) {
rmdirRecursive('./dist');
mkdirRecursive('./dist');

copyFile('./LICENSE', './dist/LICENSE');
copyFile('./README.md', './dist/README.md');
copyFile('./types/index.d.ts', './dist/index.d.ts');

const srcFiles = readdirRecursive('./src', { ignoreDir: /^__.*__$/ });
for (const filepath of srcFiles) {
if (filepath.endsWith('.js')) {
buildJSFile(filepath);
}
}

const packageJSON = buildPackageJSON();
writeFile('./dist/package.json', JSON.stringify(packageJSON, null, 2));
showStats();
}

function showStats() {
const fileTypes = {};
let totalSize = 0;

for (const filepath of readdirRecursive('./dist')) {
const name = filepath.split(path.sep).pop();
const [base, ...splitedExt] = name.split('.');
const ext = splitedExt.join('.');

const filetype = ext ? '*.' + ext : base;
fileTypes[filetype] = fileTypes[filetype] || { filepaths: [], size: 0 };

const { size } = fs.lstatSync(path.join('./dist', filepath));
totalSize += size;
fileTypes[filetype].size += size;
fileTypes[filetype].filepaths.push(filepath);
}

let stats = [];
for (const [filetype, typeStats] of Object.entries(fileTypes)) {
const numFiles = typeStats.filepaths.length;

if (numFiles > 1) {
stats.push([filetype + ' x' + numFiles, typeStats.size]);
} else {
stats.push([typeStats.filepaths[0], typeStats.size]);
}
}
stats.sort((a, b) => b[1] - a[1]);
stats = stats.map(([type, size]) => [type, (size / 1024).toFixed(2) + ' KB']);

const typeMaxLength = Math.max(...stats.map(x => x[0].length));
const sizeMaxLength = Math.max(...stats.map(x => x[1].length));
for (const [type, size] of stats) {
console.log(
type.padStart(typeMaxLength) + ' | ' + size.padStart(sizeMaxLength),
);
}

console.log('-'.repeat(typeMaxLength + 3 + sizeMaxLength));
const totalMB = (totalSize / 1024 / 1024).toFixed(2) + ' MB';
console.log(
'Total'.padStart(typeMaxLength) + ' | ' + totalMB.padStart(sizeMaxLength),
);
}

function babelBuild(srcPath, envName) {
return babel.transformFileSync(srcPath, { envName }).code + '\n';
}

function buildJSFile(filepath) {
const srcPath = path.join('./src', filepath);
const destPath = path.join('./dist', filepath);

copyFile(srcPath, destPath + '.flow');
writeFile(destPath, babelBuild(srcPath, 'cjs'));
}

function buildPackageJSON() {
const packageJSON = require('../package.json');
delete packageJSON.private;
delete packageJSON.scripts;
delete packageJSON.devDependencies;

const { preReleaseTag } = parseSemver(packageJSON.version);
if (preReleaseTag != null) {
const [tag] = preReleaseTag.split('.');
assert(tag === 'rc', 'Only "rc" tag is supported.');

assert(!packageJSON.publishConfig, 'Can not override "publishConfig".');
packageJSON.publishConfig = { tag: tag || 'latest' };
}

return packageJSON;
}
30 changes: 30 additions & 0 deletions resources/checkgit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Exit immediately if any subcommand terminated
trap "exit 1" ERR

#
# This script determines if current git state is the up to date master. If so
# it exits normally. If not it prompts for an explicit continue. This script
# intends to protect from versioning for NPM without first pushing changes
# and including any changes on master.
#

# First fetch to ensure git is up to date. Fail-fast if this fails.
git fetch;
if [[ $? -ne 0 ]]; then exit 1; fi;

# Extract useful information.
GITBRANCH=$(git branch -v 2> /dev/null | sed '/^[^*]/d');
GITBRANCHNAME=$(echo "$GITBRANCH" | sed 's/* \([A-Za-z0-9_\-]*\).*/\1/');
GITBRANCHSYNC=$(echo "$GITBRANCH" | sed 's/* [^[]*.\([^]]*\).*/\1/');

# Check if master is checked out
if [ "$GITBRANCHNAME" != "master" ]; then
read -p "Git not on master but $GITBRANCHNAME. Continue? (y|N) " yn;
if [ "$yn" != "y" ]; then exit 1; fi;
fi;

# Check if branch is synced with remote
if [ "$GITBRANCHSYNC" != "" ]; then
read -p "Git not up to date but $GITBRANCHSYNC. Continue? (y|N) " yn;
if [ "$yn" != "y" ]; then exit 1; fi;
fi;
108 changes: 108 additions & 0 deletions resources/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// @noflow

'use strict';

const fs = require('fs');
const util = require('util');
const path = require('path');
const childProcess = require('child_process');

function exec(command, options) {
const output = childProcess.execSync(command, {
maxBuffer: 10 * 1024 * 1024, // 10MB
encoding: 'utf-8',
...options,
});
return removeTrailingNewLine(output);
}

const childProcessExec = util.promisify(childProcess.exec);
async function execAsync(command, options) {
const output = await childProcessExec(command, {
maxBuffer: 10 * 1024 * 1024, // 10MB
encoding: 'utf-8',
...options,
});
return removeTrailingNewLine(output.stdout);
}

function removeTrailingNewLine(str) {
if (str == null) {
return str;
}

return str
.split('\n')
.slice(0, -1)
.join('\n');
}

function mkdirRecursive(dirPath) {
fs.mkdirSync(dirPath, { recursive: true });
}

function rmdirRecursive(dirPath) {
if (fs.existsSync(dirPath)) {
for (const dirent of fs.readdirSync(dirPath, { withFileTypes: true })) {
const fullPath = path.join(dirPath, dirent.name);
if (dirent.isDirectory()) {
rmdirRecursive(fullPath);
} else {
fs.unlinkSync(fullPath);
}
}
fs.rmdirSync(dirPath);
}
}

function readdirRecursive(dirPath, opts = {}) {
const { ignoreDir } = opts;
const result = [];
for (const dirent of fs.readdirSync(dirPath, { withFileTypes: true })) {
const name = dirent.name;
if (!dirent.isDirectory()) {
result.push(dirent.name);
continue;
}

if (ignoreDir && ignoreDir.test(name)) {
continue;
}
const list = readdirRecursive(path.join(dirPath, name), opts).map(f =>
path.join(name, f),
);
result.push(...list);
}
return result;
}

function writeFile(destPath, data) {
mkdirRecursive(path.dirname(destPath));
fs.writeFileSync(destPath, data);
}

function copyFile(srcPath, destPath) {
mkdirRecursive(path.dirname(destPath));
fs.copyFileSync(srcPath, destPath);
}

function parseSemver(version) {
const match = /^(\d+)\.(\d+)\.(\d+)-?(.*)?$/.exec(version);
if (!match) {
throw new Error('Version does not match semver spec: ' + version);
}

const [, major, minor, patch, preReleaseTag] = match;
return { major, minor, patch, preReleaseTag };
}

module.exports = {
exec,
execAsync,
copyFile,
writeFile,
rmdirRecursive,
mkdirRecursive,
readdirRecursive,
parseSemver,
};
Loading

0 comments on commit 325d159

Please sign in to comment.