@rxdi/parcel-plugin-shebang 0.7.118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +166 -0
- package/package.json +28 -0
package/README.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
declare const fs: any;
|
|
2
|
+
declare const escapeStringRegexp: any;
|
|
3
|
+
declare const path: any;
|
|
4
|
+
declare const CWD: string;
|
|
5
|
+
declare const yn: any;
|
|
6
|
+
declare const processAccordingFoundShebangs: (bundles: any) => void;
|
|
7
|
+
declare const processAccordingConfiguration: (bundles: any, conf: any) => void;
|
|
8
|
+
declare const validate: (obj: any) => any;
|
|
9
|
+
declare const loadConfigFromPackageJson: () => any;
|
|
10
|
+
declare const loadConfigFromShebangRc: () => any[];
|
|
11
|
+
declare const toAbsolutePath: (files: any) => any;
|
|
12
|
+
declare const getConfig: (dynamicConfig: any) => any[];
|
|
13
|
+
declare const SHEBANG_REGEX: RegExp;
|
|
14
|
+
declare const BLANK_LINE_REGEX: RegExp;
|
|
15
|
+
declare const existsFile: (path: any) => any;
|
|
16
|
+
declare const readFile: (path: any) => any;
|
|
17
|
+
declare const writeFile: (path: any, content: any) => void;
|
|
18
|
+
declare const hasShebang: (content: any) => boolean;
|
|
19
|
+
declare const getShebang: (content: any) => string;
|
|
20
|
+
declare const buildShebangLine: (interpreter: any) => string;
|
|
21
|
+
declare const rewriteShebang: (path: any) => void;
|
|
22
|
+
declare const writeShebang: (path: any, interpreter: any) => void;
|
|
23
|
+
declare const removeBlankLines: (content: any) => any;
|
|
24
|
+
declare const newBundle: (name: any, path: any) => {
|
|
25
|
+
name: any;
|
|
26
|
+
path: any;
|
|
27
|
+
};
|
|
28
|
+
declare const getBundles: (bundle: any) => any[];
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const escapeStringRegexp = require('escape-string-regexp');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const CWD = process.cwd();
|
|
5
|
+
const yn = require('yn');
|
|
6
|
+
const processAccordingFoundShebangs = bundles => {
|
|
7
|
+
bundles.forEach(({ path }) => rewriteShebang(path));
|
|
8
|
+
};
|
|
9
|
+
const processAccordingConfiguration = (bundles, conf) => {
|
|
10
|
+
conf.forEach(elem => {
|
|
11
|
+
const { interpreter, files } = elem;
|
|
12
|
+
files.forEach(file => {
|
|
13
|
+
const bundle = bundles.find(({ name }) => name === file);
|
|
14
|
+
if (bundle) {
|
|
15
|
+
const { path } = bundle;
|
|
16
|
+
writeShebang(path, interpreter);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
const validate = obj => {
|
|
22
|
+
return ('interpreter' in obj &&
|
|
23
|
+
typeof obj.interpreter === 'string' &&
|
|
24
|
+
obj.interpreter !== '' &&
|
|
25
|
+
'files' in obj &&
|
|
26
|
+
Array.isArray(obj.files) &&
|
|
27
|
+
obj.files.length &&
|
|
28
|
+
obj.files.filter(file => fs.existsSync(path.join(CWD, file))).length);
|
|
29
|
+
};
|
|
30
|
+
const loadConfigFromPackageJson = () => {
|
|
31
|
+
const packageJsonPath = path.join(CWD, 'package.json');
|
|
32
|
+
if (existsFile(packageJsonPath)) {
|
|
33
|
+
const packageJson = JSON.parse(readFile(packageJsonPath));
|
|
34
|
+
if (packageJson &&
|
|
35
|
+
'shebang' in packageJson &&
|
|
36
|
+
Array.isArray(packageJson.shebang) &&
|
|
37
|
+
packageJson.shebang.length) {
|
|
38
|
+
return packageJson.shebang;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return [];
|
|
42
|
+
};
|
|
43
|
+
const loadConfigFromShebangRc = () => {
|
|
44
|
+
const shebangRcPath = path.join(CWD, '.shebangrc');
|
|
45
|
+
if (existsFile(shebangRcPath)) {
|
|
46
|
+
const shebangRc = JSON.parse(readFile(shebangRcPath));
|
|
47
|
+
if (shebangRc && Array.isArray(shebangRc) && shebangRc.length) {
|
|
48
|
+
return shebangRc;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return [];
|
|
52
|
+
};
|
|
53
|
+
const toAbsolutePath = files => files.map(file => path.join(CWD, file));
|
|
54
|
+
const getConfig = dynamicConfig => {
|
|
55
|
+
const conf = [];
|
|
56
|
+
const configData = dynamicConfig
|
|
57
|
+
? dynamicConfig
|
|
58
|
+
: [...loadConfigFromPackageJson(), ...loadConfigFromShebangRc()];
|
|
59
|
+
if (Array.isArray(configData) && configData.length) {
|
|
60
|
+
configData
|
|
61
|
+
.filter(elem => validate(elem))
|
|
62
|
+
.forEach(elem => {
|
|
63
|
+
elem.files = toAbsolutePath(elem.files);
|
|
64
|
+
conf.push(elem);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return conf;
|
|
68
|
+
};
|
|
69
|
+
const SHEBANG_REGEX = /#!(.*) (.*)\n/;
|
|
70
|
+
const BLANK_LINE_REGEX = /^(?=\n)$|^\s*|\s*$|\n\n+/gm;
|
|
71
|
+
const existsFile = path => {
|
|
72
|
+
return fs.existsSync(path);
|
|
73
|
+
};
|
|
74
|
+
const readFile = path => {
|
|
75
|
+
return fs.readFileSync(path, 'utf8');
|
|
76
|
+
};
|
|
77
|
+
const writeFile = (path, content) => {
|
|
78
|
+
fs.writeFileSync(path, content);
|
|
79
|
+
};
|
|
80
|
+
const hasShebang = content => {
|
|
81
|
+
return SHEBANG_REGEX.test(content);
|
|
82
|
+
};
|
|
83
|
+
const getShebang = content => {
|
|
84
|
+
return SHEBANG_REGEX.exec(content)[0].replace(/\n/g, '');
|
|
85
|
+
};
|
|
86
|
+
const buildShebangLine = interpreter => {
|
|
87
|
+
return `#!/usr/bin/env ${interpreter}`;
|
|
88
|
+
};
|
|
89
|
+
const rewriteShebang = path => {
|
|
90
|
+
if (existsFile(path)) {
|
|
91
|
+
const content = readFile(path);
|
|
92
|
+
if (hasShebang(content)) {
|
|
93
|
+
const shebang = getShebang(content);
|
|
94
|
+
const re = new RegExp(escapeStringRegexp(shebang), 'gi');
|
|
95
|
+
writeFile(path, `${shebang}\n${removeBlankLines(content.replace(re, ''))}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const writeShebang = (path, interpreter) => {
|
|
100
|
+
if (existsFile(path)) {
|
|
101
|
+
const content = readFile(path);
|
|
102
|
+
if (!hasShebang(content)) {
|
|
103
|
+
const shebang = buildShebangLine(interpreter);
|
|
104
|
+
writeFile(path, `${shebang}\n${removeBlankLines(content)}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const removeBlankLines = content => {
|
|
109
|
+
return content.replace(BLANK_LINE_REGEX, '');
|
|
110
|
+
};
|
|
111
|
+
const newBundle = (name, path) => ({
|
|
112
|
+
name,
|
|
113
|
+
path
|
|
114
|
+
});
|
|
115
|
+
const getBundles = bundle => {
|
|
116
|
+
const { name: path, assets, childBundles } = bundle;
|
|
117
|
+
const bundles = [];
|
|
118
|
+
if (childBundles && childBundles.size) {
|
|
119
|
+
childBundles.forEach(({ name: path, assets, type }) => {
|
|
120
|
+
if (assets && assets.size && type !== 'map') {
|
|
121
|
+
assets.forEach(({ name }) => {
|
|
122
|
+
if (!bundles.find(b => b.name === name)) {
|
|
123
|
+
bundles.push(newBundle(name, path));
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (path && assets) {
|
|
130
|
+
if (assets && assets.size) {
|
|
131
|
+
assets.forEach(({ name, type }) => {
|
|
132
|
+
if (!bundles.find(b => b.name === name) && type !== 'map') {
|
|
133
|
+
bundles.push(newBundle(name, path));
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return bundles;
|
|
139
|
+
};
|
|
140
|
+
// export { processAccordingFoundShebangs,
|
|
141
|
+
// processAccordingConfiguration, getConfig,
|
|
142
|
+
// existsFile,
|
|
143
|
+
// readFile,
|
|
144
|
+
// hasShebang,
|
|
145
|
+
// buildShebangLine,
|
|
146
|
+
// rewriteShebang,
|
|
147
|
+
// writeShebang,
|
|
148
|
+
// getBundles
|
|
149
|
+
// };
|
|
150
|
+
module.exports = (bundler, dynamicConfig = null) => {
|
|
151
|
+
if ('PARCEL_PLUGIN_SHEBANG' in process.env &&
|
|
152
|
+
!yn(process.env.PARCEL_PLUGIN_SHEBANG)) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
bundler.on('bundled', bundle => {
|
|
156
|
+
const bundles = getBundles(bundle);
|
|
157
|
+
const conf = getConfig(dynamicConfig);
|
|
158
|
+
if (bundles.length) {
|
|
159
|
+
processAccordingFoundShebangs(bundles);
|
|
160
|
+
if (conf.length) {
|
|
161
|
+
processAccordingConfiguration(bundles, conf);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return true;
|
|
166
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rxdi/parcel-plugin-shebang",
|
|
3
|
+
"version": "0.7.118",
|
|
4
|
+
"description": "Shebang for ParcelJS",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc || true",
|
|
8
|
+
"test": "echo \"Error: no test specified\""
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/rxdi/parcel-plugin-shebang.git"
|
|
13
|
+
},
|
|
14
|
+
"author": "Kristiyan Tachev (@Stradivario)",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/rxdi/parcel-plugin-shebang/issues"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/rxdi/parcel-plugin-shebang#readme",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"yn": "^3.1.0",
|
|
22
|
+
"escape-string-regexp": "^2.0.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^12.0.10",
|
|
26
|
+
"typescript": "^3.9.3"
|
|
27
|
+
}
|
|
28
|
+
}
|