Skip to content

Commit 4c91b75

Browse files
committed
feat: add TypeScript typings and Prettier
- Add TypeScript type definitions. - Add Prettier for code formatting. - Update dependencies
1 parent b44f590 commit 4c91b75

12 files changed

+3133
-2299
lines changed

.babelrc

-3
This file was deleted.

.eslintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"extends": "airbnb-base",
2+
"extends": ["airbnb-base", "plugin:prettier/recommended"],
33
"env": {
44
"browser": true
55
},

.prettierrc.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"arrowParens": "always",
3+
"printWidth": 100,
4+
"singleQuote": true,
5+
"trailingComma": "all"
6+
}

babel.config.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module.exports = {
2+
presets: [
3+
[
4+
'@babel/preset-env',
5+
{
6+
targets: {
7+
node: 'current',
8+
},
9+
},
10+
],
11+
],
12+
};

fetch-script.d.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
declare module 'fetch-script' {
2+
interface Script {
3+
url: string;
4+
options: RequestInit;
5+
}
6+
7+
function fetchScript(scripts: Script[], promise?: Promise<void>): Promise<void>;
8+
9+
export = fetchScript;
10+
}

jest.config.js

+3-10
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,8 @@ module.exports = {
88
statements: 100,
99
},
1010
},
11-
coverageReporters: [
12-
'html',
13-
],
11+
coverageReporters: ['html'],
1412
moduleFileExtensions: ['js'],
15-
roots: [
16-
'<rootDir>/test',
17-
'<rootDir>/src',
18-
],
19-
setupFiles: [
20-
'<rootDir>/test/test-setup.js',
21-
],
13+
roots: ['<rootDir>/test', '<rootDir>/src'],
14+
setupFiles: ['<rootDir>/test/test-setup.js'],
2215
};

package.json

+24-18
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"name": "fetch-script",
3-
"version": "0.0.3",
3+
"version": "0.0.4",
44
"description": "Async loading of scripts using the Fetch API",
55
"main": "lib/fetch-script.js",
66
"unpkg": "dist/fetch-script.js",
77
"module": "es/fetch-script.js",
8+
"typings": "fetch-script.d.ts",
89
"scripts": {
910
"build:commonjs": "cross-env NODE_ENV=cjs rollup -c -o lib/fetch-script.js",
1011
"build:es": "cross-env BABEL_ENV=es NODE_ENV=es rollup -c -o es/fetch-script.js",
@@ -30,25 +31,30 @@
3031
"src"
3132
],
3233
"devDependencies": {
33-
"@babel/core": "^7.1.0",
34-
"@babel/preset-env": "^7.1.0",
34+
"@babel/core": "^7.6.0",
35+
"@babel/preset-env": "^7.6.0",
3536
"babel-core": "^7.0.0-bridge.0",
36-
"babel-jest": "^23.6.0",
37+
"babel-jest": "^24.9.0",
3738
"babel-preset-env": "^1.7.0",
38-
"babel-preset-es2015-rollup": "^3.0.0",
39-
"cross-env": "^5.2.0",
40-
"eslint": "^5.6.0",
41-
"eslint-config-airbnb-base": "^13.1.0",
42-
"eslint-plugin-import": "^2.14.0",
43-
"jest": "^23.6.0",
44-
"jest-fetch-mock": "^1.6.6",
45-
"jsdom": "^12.0.0",
46-
"regenerator-runtime": "^0.12.1",
47-
"rollup": "^0.66.2",
48-
"rollup-plugin-babel": "^4.0.3",
49-
"rollup-plugin-commonjs": "^9.1.8",
50-
"rollup-plugin-node-resolve": "^3.4.0",
51-
"rollup-plugin-uglify": "^6.0.0",
39+
"cross-env": "^6.0.0",
40+
"eslint": "^6.4.0",
41+
"eslint-config-airbnb-base": "^14.0.0",
42+
"eslint-config-prettier": "^6.3.0",
43+
"eslint-plugin-import": "^2.18.2",
44+
"eslint-plugin-prettier": "^3.1.1",
45+
"jest": "^24.9.0",
46+
"jest-fetch-mock": "1.6.6",
47+
"jsdom": "^15.1.1",
48+
"prettier": "^1.18.2",
49+
"rollup": "^1.21.4",
50+
"rollup-plugin-babel": "^4.3.3",
51+
"rollup-plugin-commonjs": "^10.1.0",
52+
"rollup-plugin-node-resolve": "^5.2.0",
53+
"rollup-plugin-terser": "^5.1.2",
5254
"whatwg-fetch": "^3.0.0"
55+
},
56+
"resolutions": {
57+
"mixin-deep": "1.3.2",
58+
"set-value": "2.0.1"
5359
}
5460
}

rollup.config.js

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import babel from 'rollup-plugin-babel';
22
import commonjs from 'rollup-plugin-commonjs';
33
import nodeResolve from 'rollup-plugin-node-resolve';
4-
import { uglify } from 'rollup-plugin-uglify';
4+
import { terser } from 'rollup-plugin-terser';
55

66
const env = process.env.NODE_ENV;
77

@@ -16,10 +16,7 @@ if (env === 'es' || env === 'cjs') {
1616
format: env,
1717
indent: false,
1818
};
19-
config.plugins.push(
20-
babel(),
21-
commonjs(),
22-
);
19+
config.plugins.push(babel(), commonjs());
2320
}
2421

2522
if (env === 'development' || env === 'production') {
@@ -41,14 +38,7 @@ if (env === 'development' || env === 'production') {
4138
}
4239

4340
if (env === 'production') {
44-
config.plugins.push(uglify({
45-
compress: {
46-
pure_getters: true,
47-
unsafe: true,
48-
unsafe_comps: true,
49-
warnings: false,
50-
},
51-
}));
41+
config.plugins.push(terser());
5242
}
5343

5444
export default config;

src/index.js

+35-14
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,21 @@ function contentLoadedEvent() {
1212
*/
1313
function fetchInject(scripts, promise) {
1414
if (!scripts) {
15-
return Promise.reject(new ReferenceError("Failed to execute 'fetchInject': 1 argument required but only 0 present."));
15+
return Promise.reject(
16+
new ReferenceError(
17+
"Failed to execute 'fetchInject': 1 argument required but only 0 present.",
18+
),
19+
);
1620
}
1721
if (scripts && !Array.isArray(scripts)) {
18-
return Promise.reject(new TypeError("Failed to execute 'fetchInject': argument 1 must be of type 'Array'."));
22+
return Promise.reject(
23+
new TypeError("Failed to execute 'fetchInject': argument 1 must be of type 'Array'."),
24+
);
1925
}
2026
if (promise && promise.constructor !== Promise) {
21-
return Promise.reject(new TypeError("Failed to execute 'fetchInject': argument 2 must be of type 'Promise'."));
27+
return Promise.reject(
28+
new TypeError("Failed to execute 'fetchInject': argument 2 must be of type 'Promise'."),
29+
);
2230
}
2331

2432
const resources = [];
@@ -33,25 +41,38 @@ function fetchInject(scripts, promise) {
3341
}
3442
if (options && options.mode === 'no-cors' && options.method === 'GET') {
3543
// can not use fetch, inject the script into the head
36-
deferreds.push(new Promise((resolve, reject) => {
37-
headCors(window, document, 'script', url, () => {
38-
contentLoadedEvent();
39-
resolve();
40-
}, () => {
41-
reject(new Error(networkError));
42-
});
43-
}));
44+
deferreds.push(
45+
new Promise((resolve, reject) => {
46+
headCors(
47+
window,
48+
document,
49+
'script',
50+
url,
51+
() => {
52+
contentLoadedEvent();
53+
resolve();
54+
},
55+
() => {
56+
reject(new Error(networkError));
57+
},
58+
);
59+
}),
60+
);
4461
} else {
4562
deferreds.push(
46-
window.fetch(url, options)
63+
window
64+
.fetch(url, options)
4765
.then((res) => {
4866
if (!res.ok) {
4967
throw Error(networkError);
5068
}
5169
return [res.clone().text(), res.blob()];
5270
})
53-
.then((promises) => Promise.all(promises)
54-
.then((resolved) => resources.push({ text: resolved[0], blob: resolved[1] }))),
71+
.then((promises) =>
72+
Promise.all(promises).then((resolved) =>
73+
resources.push({ text: resolved[0], blob: resolved[1] }),
74+
),
75+
),
5576
);
5677
}
5778
});

src/injectors.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
export const head = (function(w,d,t,o,r,c,s){c=d.createElement(t),s=d.getElementsByTagName(t)[0];c.appendChild(d.createTextNode(o.text));c.onload=r(o);s?s.parentNode.insertBefore(c,s):d.appendChild(c)}); // eslint-disable-line
1+
/* eslint-disable */
22

3-
export const headCors = (function(w,d,t,u,r,e,c,s){c=d.createElement(t),s=d.head.getElementsByTagName(t)[0];c.src=u;c.onload=r;c.onerror=e;s?s.parentNode.insertBefore(c,s):d.head.appendChild(c) // eslint-disable-line
4-
});
3+
export const head = function(w, d, t, o, r, c, s) {
4+
(c = d.createElement(t)), (s = d.getElementsByTagName(t)[0]);
5+
c.appendChild(d.createTextNode(o.text));
6+
c.onload = r(o);
7+
s ? s.parentNode.insertBefore(c, s) : d.appendChild(c);
8+
};
9+
10+
export const headCors = function(w, d, t, u, r, e, c, s) {
11+
(c = d.createElement(t)), (s = d.head.getElementsByTagName(t)[0]);
12+
c.src = u;
13+
c.onload = r;
14+
c.onerror = e;
15+
s ? s.parentNode.insertBefore(c, s) : d.head.appendChild(c);
16+
};

test/index.spec.js

+42-33
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ describe('fetchInject', () => {
2626
injectedScriptElement.dispatchEvent(loadEvent);
2727
}, 10);
2828

29-
fetchInject([{
30-
url: `//${scriptName}`,
31-
options: { method: 'GET', mode: 'no-cors' },
32-
}]).then(() => {
33-
expect(document.getElementsByTagName('script')[0].src)
34-
.toEqual(`http://${scriptName}/`);
29+
fetchInject([
30+
{
31+
url: `//${scriptName}`,
32+
options: { method: 'GET', mode: 'no-cors' },
33+
},
34+
]).then(() => {
35+
expect(document.getElementsByTagName('script')[0].src).toEqual(`http://${scriptName}/`);
3536
expect(contentloadedListener).toHaveBeenCalledWith(DOMContentLoadedEvent);
3637
done();
3738
});
@@ -48,12 +49,13 @@ describe('fetchInject', () => {
4849
injectedScriptElement.dispatchEvent(loadErrorEvent);
4950
}, 10);
5051

51-
fetchInject([{
52-
url: `//${scriptName}`,
53-
options: { method: 'GET', mode: 'no-cors' },
54-
}]).catch((err) => {
55-
expect(document.getElementsByTagName('script')[0].src)
56-
.toEqual(`http://${scriptName}/`);
52+
fetchInject([
53+
{
54+
url: `//${scriptName}`,
55+
options: { method: 'GET', mode: 'no-cors' },
56+
},
57+
]).catch((err) => {
58+
expect(document.getElementsByTagName('script')[0].src).toEqual(`http://${scriptName}/`);
5759
expect(contentloadedListener).not.toHaveBeenCalled();
5860
expect(err.message).toEqual(networkError);
5961
done();
@@ -63,10 +65,12 @@ describe('fetchInject', () => {
6365
test('should fetch a script in cors mode', async (done) => {
6466
fetch.mockResponseOnce(scriptText);
6567

66-
fetchInject([{
67-
url: `//${scriptName}`,
68-
options: { method: 'GET', mode: 'cors' },
69-
}]).then((res) => {
68+
fetchInject([
69+
{
70+
url: `//${scriptName}`,
71+
options: { method: 'GET', mode: 'cors' },
72+
},
73+
]).then((res) => {
7074
expect(res[0].text).toEqual(scriptText);
7175
expect(fetch.mock.calls.length).toEqual(1);
7276
done();
@@ -76,9 +80,11 @@ describe('fetchInject', () => {
7680
test('should fetch without any options', async (done) => {
7781
fetch.mockResponseOnce(scriptText);
7882

79-
fetchInject([{
80-
url: `//${scriptName}`,
81-
}]).then((res) => {
83+
fetchInject([
84+
{
85+
url: `//${scriptName}`,
86+
},
87+
]).then((res) => {
8288
expect(res[0].text).toEqual(scriptText);
8389
expect(fetch.mock.calls.length).toEqual(1);
8490
done();
@@ -115,33 +121,36 @@ describe('fetchInject', () => {
115121
test('should fetch css in cors mode', async (done) => {
116122
fetch.mockResponseOnce(new Blob([cssText], { type: 'text/css' }));
117123

118-
fetchInject([{
119-
url: `//${cssName}`,
120-
options: { method: 'GET', mode: 'cors' },
121-
}]).then((res) => {
124+
fetchInject([
125+
{
126+
url: `//${cssName}`,
127+
options: { method: 'GET', mode: 'cors' },
128+
},
129+
]).then((res) => {
122130
expect(res[0].text).toEqual(cssText);
123131
expect(fetch.mock.calls.length).toEqual(1);
124132
done();
125133
});
126134
});
127135

128136
test('should return an error for a failed fetch in cors mode', async (done) => {
129-
fetch.mockResponses([
130-
scriptText,
131-
{ status: 500 },
132-
]);
133-
134-
fetchInject([{
135-
url: `//${scriptName}`,
136-
options: { method: 'GET', mode: 'cors' },
137-
}]).catch((err) => {
137+
fetch.mockResponses([scriptText, { status: 500 }]);
138+
139+
fetchInject([
140+
{
141+
url: `//${scriptName}`,
142+
options: { method: 'GET', mode: 'cors' },
143+
},
144+
]).catch((err) => {
138145
expect(err.message).toEqual(networkError);
139146
done();
140147
});
141148
});
142149

143150
test('should reject promise, if no scripts are defined', () => {
144-
expect(fetchInject()).rejects.toThrow("Failed to execute 'fetchInject': 1 argument required but only 0 present.");
151+
expect(fetchInject()).rejects.toThrow(
152+
"Failed to execute 'fetchInject': 1 argument required but only 0 present.",
153+
);
145154
});
146155

147156
test('should reject promise, if scripts is not an array', () => {

0 commit comments

Comments
 (0)