UNPKG

5.74 kBPlain TextView Raw
1#!/usr/bin/env node
2
3const { execSync } = require('child_process');
4const program = require('commander');
5const fs = require('fs');
6const { resolve } = require('path');
7
8function patchJson(path, ...patches) {
9 console.log(`Patching ${path}...`);
10 const json = fs.existsSync(path)
11 ? JSON.parse(
12 fs.readFileSync(path).toString() || '{}',
13 )
14 : {};
15
16 for (const patch of patches) {
17 patch(json);
18 }
19
20 fs.writeFileSync(
21 path,
22 JSON.stringify(json, null, 2) + '\n',
23 'utf-8',
24 );
25}
26
27program
28 .command('init')
29 .option('-l, --lib-only', 'Only install library helpers')
30 .action((cmd) => {
31 const destination = process.cwd();
32 const packageOriginal = JSON.parse(fs.readFileSync(resolve(destination, 'package.json')));
33 const libOnly = cmd.libOnly || packageOriginal.libOnly;
34 const source = resolve(__dirname, '..');
35
36 if (source === destination) {
37 console.log('Cannot install into itself.');
38 return;
39 }
40
41 console.log(`Init ${source} -> ${destination}`);
42
43 function copy(file) {
44 const toFile = file.endsWith('_publish') ? file.slice(0, -8) : file;
45 console.log(`Copying ${toFile}...`);
46 fs.copyFileSync(resolve(source, file), resolve(destination, toFile));
47 }
48
49 function copyOnce(file) {
50 const toFile = file.endsWith('_publish') ? file.slice(0, -8) : file;
51 if (fs.existsSync(toFile)) return;
52
53 console.log(`Copying ${toFile}...`);
54 fs.copyFileSync(resolve(source, file), resolve(destination, toFile));
55 }
56
57 try {
58 fs.mkdirSync(resolve(destination, 'src'));
59 } catch { }
60 try {
61 fs.mkdirSync(resolve(destination, '.vscode'));
62 } catch { }
63
64 copy('.editorconfig');
65 copy('.eslintignore');
66 copy('.eslintrc.js');
67 copy('.dockerignore');
68 copy('.gitignore_publish');
69 copy('.npmignore_publish');
70 copy('jest.config.js');
71 if (!libOnly) {
72 copy('nodemon.json');
73 copyOnce('.vscode/launch.json');
74 } else {
75 if (fs.existsSync(resolve(destination, 'nodemon.json'))) {
76 fs.unlinkSync(resolve(destination, 'nodemon.json'));
77 }
78 }
79 copy('tsconfig.json');
80
81 patchJson(resolve(destination, 'package.json'),
82 (package) => {
83 Object.assign(package, {
84 main: './dist/index.js',
85 types: './src/index.ts',
86 });
87 package.scripts = Object.assign(package.scripts || {}, {
88 build: 'rm -rf dist && npx tsc --outDir dist --sourceMap',
89 lint: './node_modules/.bin/eslint src/ --ext .ts,.tsx',
90 postpublish: 'git push',
91 prepublishOnly: 'npm run lint && npm run build && npm version patch',
92 test: './node_modules/.bin/jest --coverage',
93 });
94 package.libOnly = libOnly;
95 if (!libOnly) {
96 package.scripts = Object.assign(package.scripts || {}, {
97 start: 'node -r ts-node/register src/index.ts',
98 watch: 'npx nodemon',
99 });
100 delete package.nodemonConfig;
101 }
102 delete package.jest;
103 },
104 );
105
106 patchJson(resolve(destination, '.vscode/settings.json'),
107 (json) => {
108 const spelling = Array.from([
109 'asynciterable',
110 'camelcase',
111 'eqeqeq',
112 'esnext',
113 'geeebe',
114 'isnan',
115 'postpublish',
116 ].reduce(
117 (acc, word) => acc.add(word),
118 new Set(json['cSpell.words'] || []),
119 ));
120 spelling.sort();
121
122 Object.assign(json, {
123 'cSpell.words': spelling,
124 'editor.codeActionsOnSave': {
125 'source.fixAll': true,
126 'source.organizeImports': true,
127 },
128 'editor.formatOnSave': true,
129 'editor.tabSize': 2,
130 'eslint.enable': true,
131 'files.eol': '\n',
132 'files.exclude': {
133 ...json['files.exclude'],
134 '**/*.js': {
135 when: '$(basename).ts',
136 },
137 '**/*.js.map': true,
138 '**/.DS_Store': true,
139 '**/.git': true,
140 '**/.idea': true,
141 '**/node_modules': true,
142 },
143 'files.insertFinalNewline': true,
144 'files.trimTrailingWhitespace': true,
145 'tslint.enable': false,
146 'typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces': true,
147 });
148 },
149 );
150
151 patchJson(resolve(destination, '.vscode/extensions.json'),
152 (json) => {
153 const original = json.recommendations || [];
154 const set = {};
155 original.forEach((rec) => {
156 set[rec] = true;
157 });
158 set['ms-vscode.vscode-typescript-tslint-plugin'] = false;
159 set['steoates.autoimport'] = true;
160 set['editorconfig.editorconfig'] = true;
161 set['christian-kohler.path-intellisense'] = true;
162 set['dbaeumer.vscode-eslint'] = true;
163 set['waderyan.gitblame'] = true;
164 set['codezombiech.gitignore'] = true;
165
166 const recommendations = [];
167 Object.keys(set).forEach((key) => {
168 if (!set.hasOwnProperty(key) || !set[key]) return;
169 recommendations.push(key);
170 });
171 json.recommendations = recommendations;
172 },
173 );
174
175 console.log('Installing packages...');
176 const packages = [
177 '@types/jest',
178 '@types/node',
179 '@typescript-eslint/eslint-plugin',
180 '@typescript-eslint/eslint-plugin-tslint',
181 '@typescript-eslint/parser',
182 'eslint',
183 'eslint-plugin-prefer-arrow',
184 'jest',
185 'typescript',
186 'ts-node',
187 'ts-jest',
188 'tslint',
189 ];
190 if (!libOnly) {
191 packages.push('nodemon');
192 }
193 execSync('npm i -D ' + packages.join(' '));
194
195 console.log('. Done');
196 });
197
198program.parse(process.argv);