@shgysk8zer0/importmap 1.2.5 → 1.3.0
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/CHANGELOG.md +12 -0
- package/cli.mjs +10 -3
- package/importmap.json +25 -0
- package/index.cjs +140 -42
- package/index.mjs +182 -0
- package/package.json +23 -9
- package/unpkg.js +47 -0
- package/update.js +3 -0
- package/utils.js +55 -0
- package/index.js +0 -66
- package/versions.js +0 -17
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [v1.3.0] - 2023-10-31
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Auto-update from `unpkg.com` (no Firebase updates) by running `update.js`
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Importmap is now stored in `importmap.json`
|
|
16
|
+
- Update `exports`, etc.
|
|
17
|
+
|
|
18
|
+
### Removed
|
|
19
|
+
- No more `versions.js` - It is directly in the JSON
|
|
20
|
+
|
|
9
21
|
## [v1.2.5] - 2023-09-08
|
|
10
22
|
|
|
11
23
|
### Fixed
|
package/cli.mjs
CHANGED
|
@@ -5,7 +5,8 @@ import { readJSONFile, writeJSONFile } from '@shgysk8zer0/npm-utils/json';
|
|
|
5
5
|
import { readYAMLFile, writeYAMLFile } from '@shgysk8zer0/npm-utils/yaml';
|
|
6
6
|
import { program } from 'commander';
|
|
7
7
|
import { extname } from 'node:path';
|
|
8
|
-
import { importmap } from './index.
|
|
8
|
+
import { importmap } from './index.mjs';
|
|
9
|
+
import { updateImportMap } from './html.js';
|
|
9
10
|
|
|
10
11
|
function guessFileType(file) {
|
|
11
12
|
const ext = extname(file).toLowerCase();
|
|
@@ -18,6 +19,9 @@ function guessFileType(file) {
|
|
|
18
19
|
case '.json':
|
|
19
20
|
return 'json';
|
|
20
21
|
|
|
22
|
+
case '.html':
|
|
23
|
+
return 'html';
|
|
24
|
+
|
|
21
25
|
default:
|
|
22
26
|
throw new TypeError(`"${ext}" is not a supported file extension for file ${file}.`);
|
|
23
27
|
}
|
|
@@ -35,7 +39,7 @@ async function parse(file, { encoding, signal } = {}) {
|
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
async function init() {
|
|
38
|
-
const { version: VERSION } = await readJSONFile(new URL('./package.json', import.meta.url)
|
|
42
|
+
const { version: VERSION } = await readJSONFile(new URL('./package.json', import.meta.url));
|
|
39
43
|
|
|
40
44
|
program
|
|
41
45
|
.name('importmap-utils')
|
|
@@ -54,7 +58,6 @@ async function init() {
|
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
init().then(async ({ opts: { input, encoding, format, output }}) => {
|
|
57
|
-
console.log({ input, encoding, format, output });
|
|
58
61
|
const mod = typeof input === 'string'
|
|
59
62
|
? await parse(input, { encoding }).then(({ imports, scope = {}, ...rest }) => ({
|
|
60
63
|
...rest,
|
|
@@ -73,5 +76,9 @@ init().then(async ({ opts: { input, encoding, format, output }}) => {
|
|
|
73
76
|
case 'yaml':
|
|
74
77
|
await writeYAMLFile(output, mod, { encoding });
|
|
75
78
|
break;
|
|
79
|
+
|
|
80
|
+
case 'html':
|
|
81
|
+
await updateImportMap(output, { spaces: null });
|
|
82
|
+
break;
|
|
76
83
|
}
|
|
77
84
|
});
|
package/importmap.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"imports": {
|
|
3
|
+
"@shgysk8zer0/kazoo/": "https://unpkg.com/@shgysk8zer0/kazoo@0.2.5/",
|
|
4
|
+
"@shgysk8zer0/konami": "https://unpkg.com/@shgysk8zer0/konami@1.1.1/konami.js",
|
|
5
|
+
"@shgysk8zer0/polyfills": "https://unpkg.com/@shgysk8zer0/polyfills@0.2.6/all.min.js",
|
|
6
|
+
"@shgysk8zer0/polyfills/": "https://unpkg.com/@shgysk8zer0/polyfills@0.2.6/",
|
|
7
|
+
"@shgysk8zer0/jswaggersheets": "https://unpkg.com/@shgysk8zer0/jswaggersheets@1.1.0/swagger.js",
|
|
8
|
+
"@shgysk8zer0/jswaggersheets/": "https://unpkg.com/@shgysk8zer0/jswaggersheets@1.1.0/",
|
|
9
|
+
"@shgysk8zer0/jss/": "https://unpkg.com/@shgysk8zer0/jss@1.0.1/",
|
|
10
|
+
"@shgysk8zer0/consts/": "https://unpkg.com/@shgysk8zer0/consts@1.0.7/",
|
|
11
|
+
"@shgysk8zer0/http/": "https://unpkg.com/@shgysk8zer0/http@1.0.5/",
|
|
12
|
+
"@shgysk8zer0/http-status": "https://unpkg.com/@shgysk8zer0/http-status@1.1.1/http-status.js",
|
|
13
|
+
"@shgysk8zer0/components/": "https://unpkg.com/@shgysk8zer0/components@0.1.5/",
|
|
14
|
+
"@kernvalley/components/": "https://unpkg.com/@kernvalley/components@1.1.0/",
|
|
15
|
+
"@webcomponents/custom-elements": "https://unpkg.com/@webcomponents/custom-elements@1.6.0/custom-elements.min.js",
|
|
16
|
+
"leaflet": "https://unpkg.com/leaflet@1.9.4/dist/leaflet-src.esm.js",
|
|
17
|
+
"urlpattern-polyfill": "https://unpkg.com/urlpattern-polyfill@9.0.0/index.js",
|
|
18
|
+
"highlight.js": "https://unpkg.com/@highlightjs/cdn-assets@11.9.0/es/highlight.min.js",
|
|
19
|
+
"highlight.js/": "https://unpkg.com/@highlightjs/cdn-assets@11.9.0/",
|
|
20
|
+
"marked": "https://unpkg.com/marked@9.1.4/lib/marked.esm.js",
|
|
21
|
+
"marked-highlight": "https://unpkg.com/marked-highlight@2.0.6/src/index.js",
|
|
22
|
+
"firebase/": "https://www.gstatic.com/firebasejs/9.23.0/"
|
|
23
|
+
},
|
|
24
|
+
"scope": {}
|
|
25
|
+
}
|
package/index.cjs
CHANGED
|
@@ -2,48 +2,147 @@
|
|
|
2
2
|
|
|
3
3
|
var promises = require('node:fs/promises');
|
|
4
4
|
var node_crypto = require('node:crypto');
|
|
5
|
+
var yaml_js = require('@shgysk8zer0/npm-utils/yaml.js');
|
|
6
|
+
var json_js = require('@shgysk8zer0/npm-utils/json.js');
|
|
5
7
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
const imports$1 = {
|
|
9
|
+
"@shgysk8zer0/kazoo/": "https://unpkg.com/@shgysk8zer0/kazoo@0.2.5/",
|
|
10
|
+
"@shgysk8zer0/konami": "https://unpkg.com/@shgysk8zer0/konami@1.1.1/konami.js",
|
|
11
|
+
"@shgysk8zer0/polyfills": "https://unpkg.com/@shgysk8zer0/polyfills@0.2.6/all.min.js",
|
|
12
|
+
"@shgysk8zer0/polyfills/": "https://unpkg.com/@shgysk8zer0/polyfills@0.2.6/",
|
|
13
|
+
"@shgysk8zer0/jswaggersheets": "https://unpkg.com/@shgysk8zer0/jswaggersheets@1.1.0/swagger.js",
|
|
14
|
+
"@shgysk8zer0/jswaggersheets/": "https://unpkg.com/@shgysk8zer0/jswaggersheets@1.1.0/",
|
|
15
|
+
"@shgysk8zer0/jss/": "https://unpkg.com/@shgysk8zer0/jss@1.0.1/",
|
|
16
|
+
"@shgysk8zer0/consts/": "https://unpkg.com/@shgysk8zer0/consts@1.0.7/",
|
|
17
|
+
"@shgysk8zer0/http/": "https://unpkg.com/@shgysk8zer0/http@1.0.5/",
|
|
18
|
+
"@shgysk8zer0/http-status": "https://unpkg.com/@shgysk8zer0/http-status@1.1.1/http-status.js",
|
|
19
|
+
"@shgysk8zer0/components/": "https://unpkg.com/@shgysk8zer0/components@0.1.5/",
|
|
20
|
+
"@kernvalley/components/": "https://unpkg.com/@kernvalley/components@1.1.0/",
|
|
21
|
+
"@webcomponents/custom-elements": "https://unpkg.com/@webcomponents/custom-elements@1.6.0/custom-elements.min.js",
|
|
22
|
+
leaflet: "https://unpkg.com/leaflet@1.9.4/dist/leaflet-src.esm.js",
|
|
23
|
+
"urlpattern-polyfill": "https://unpkg.com/urlpattern-polyfill@9.0.0/index.js",
|
|
24
|
+
"highlight.js": "https://unpkg.com/@highlightjs/cdn-assets@11.9.0/es/highlight.min.js",
|
|
25
|
+
"highlight.js/": "https://unpkg.com/@highlightjs/cdn-assets@11.9.0/",
|
|
26
|
+
marked: "https://unpkg.com/marked@9.1.4/lib/marked.esm.js",
|
|
27
|
+
"marked-highlight": "https://unpkg.com/marked-highlight@2.0.6/src/index.js",
|
|
28
|
+
"firebase/": "https://www.gstatic.com/firebasejs/9.23.0/"
|
|
22
29
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'@shgysk8zer0/polyfills/': `https://unpkg.com/@shgysk8zer0/polyfills@${versions['@shgysk8zer0/polyfills']}/`,
|
|
29
|
-
'@shgysk8zer0/jswaggersheets': `https://unpkg.com/@shgysk8zer0/jswaggersheets@${versions['@shgysk8zer0/jswaggersheets']}/swagger.js`,
|
|
30
|
-
'@shgysk8zer0/jswaggersheets/': `https://unpkg.com/@shgysk8zer0/jswaggersheets@${versions['@shgysk8zer0/jswaggersheets']}/`,
|
|
31
|
-
'@shgysk8zer0/jss/': `https://unpkg.com/@shgysk8zer0/jss@${versions['@shgysk8zer0/jss']}/`,
|
|
32
|
-
'@shgysk8zer0/http-status': `https://unpkg.com/@shgysk8zer0/http-status@${versions['@shgysk8zer0/http-status']}/http-status.js`,
|
|
33
|
-
'@shgysk8zer0/components/': `https://unpkg.com/@shgysk8zer0/components@${versions['@shgysk8zer0/components']}/`,
|
|
34
|
-
'@kernvalley/components/': `https://unpkg.com/@kernvalley/components@${versions['@kernvalley/components']}/`,
|
|
35
|
-
'@webcomponents/custom-elements': `https://unpkg.com/@webcomponents/custom-elements@${versions['@webcomponents/custom-elements']}/custom-elements.min.js`,
|
|
36
|
-
'leaflet': `https://unpkg.com/leaflet@${versions.leaflet}/dist/leaflet-src.esm.js`,
|
|
37
|
-
'firebase/': `https://www.gstatic.com/firebasejs/${versions.firebase}/`,
|
|
38
|
-
'urlpattern-polyfill': `https://unpkg.com/urlpattern-polyfill@${versions['urlpattern-polyfill']}/index.js`,
|
|
39
|
-
'highlight.js': `https://unpkg.com/@highlightjs/cdn-assets@${versions['highlight.js']}/es/highlight.min.js`,
|
|
40
|
-
'highlight.js/': `https://unpkg.com/@highlightjs/cdn-assets@${versions['highlight.js']}/`,
|
|
41
|
-
'marked': `https://unpkg.com/marked@${versions.marked}/src/marked.js`,
|
|
42
|
-
'marked-highlight': `https://unpkg.com/marked-highlight@${versions['marked-highlight']}/src/index.js`
|
|
30
|
+
const scope$1 = {
|
|
31
|
+
};
|
|
32
|
+
var importmap = {
|
|
33
|
+
imports: imports$1,
|
|
34
|
+
scope: scope$1
|
|
43
35
|
};
|
|
44
36
|
|
|
45
|
-
const
|
|
46
|
-
|
|
37
|
+
const UNPKG = 'https://unpkg.com/';
|
|
38
|
+
|
|
39
|
+
const cache = new Map();
|
|
40
|
+
|
|
41
|
+
function parseUnpkgURL(src) {
|
|
42
|
+
const url = new URL(src, UNPKG);
|
|
43
|
+
|
|
44
|
+
if (! url.hostname === UNPKG || url.pathname.length === 1 || url.pathname === '/[object%20Object]') {
|
|
45
|
+
throw new Error(`${src} is not an unpkg URL.`);
|
|
46
|
+
} else {
|
|
47
|
+
const path = url.pathname.substr(1).split('/');
|
|
48
|
+
|
|
49
|
+
if (path.length === 0) {
|
|
50
|
+
throw new Error(`Invalid unpkg URL: ${src}`);
|
|
51
|
+
} else if (path.length !== 1 && path[0].startsWith('@')) {
|
|
52
|
+
const [pkg, version = null] = path[1].split('@');
|
|
53
|
+
return { scope: path[0], pkg, version, module: path.splice(2).join('/') };
|
|
54
|
+
} else {
|
|
55
|
+
const [pkg, version = null] = path[0].split('@');
|
|
56
|
+
return { scope: null, pkg, version, module: path.splice(1).join('/') };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getUnpkgURL({ scope, pkg, version, module = '' }) {
|
|
62
|
+
// console.log({ scope, pkg, version });
|
|
63
|
+
if (typeof pkg !== 'string' || pkg.length === 0) {
|
|
64
|
+
throw new TypeError('Package name must be a non-empty string.');
|
|
65
|
+
} else if (typeof version !== 'string' || version.length === 0) {
|
|
66
|
+
throw new TypeError('Version must be a non-empty string.');
|
|
67
|
+
} else if (typeof scope === 'string' && scope.length !== 0) {
|
|
68
|
+
return new URL(`/${scope}/${pkg}@${version}/${module}`, UNPKG).href;
|
|
69
|
+
} else {
|
|
70
|
+
return new URL(`/${pkg}@${version}/${module}`, UNPKG).href;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function getLatestVersion({ scope, pkg, signal } = {}) {
|
|
75
|
+
const path = typeof scope === 'string' ? `/${scope}/${pkg}/` : `/${pkg}/`;
|
|
76
|
+
|
|
77
|
+
if (cache.has(path)) {
|
|
78
|
+
return await cache.get(path);
|
|
79
|
+
} else {
|
|
80
|
+
const url = new URL(path, 'https://unpkg.com/');
|
|
81
|
+
url.searchParams.set('meta', '');
|
|
82
|
+
|
|
83
|
+
const promise = fetch(url, { method: 'HEAD', signal }).then(resp => {
|
|
84
|
+
const { version } = parseUnpkgURL(resp.url);
|
|
85
|
+
return version;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
cache.set(path, promise);
|
|
89
|
+
return promise;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function update(imports) {
|
|
94
|
+
let updated = false;
|
|
95
|
+
|
|
96
|
+
const entries = await Promise.all(Object.entries(imports)
|
|
97
|
+
.filter(([,val]) => val.startsWith(UNPKG))
|
|
98
|
+
.map(async ([key, val]) => {
|
|
99
|
+
const { scope, pkg, version: oldVersion, module } = parseUnpkgURL(val);
|
|
100
|
+
const version = await getLatestVersion({ scope, pkg });
|
|
101
|
+
|
|
102
|
+
if (! updated && version > oldVersion) {
|
|
103
|
+
updated = true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return [key, getUnpkgURL({ scope, pkg, version, module })];
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return { imports: Object.fromEntries(entries), updated };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function updateYAML(file) {
|
|
114
|
+
const importmap = await yaml_js.readYAMLFile(file);
|
|
115
|
+
const { updated, imports } = await update(importmap.imports);
|
|
116
|
+
|
|
117
|
+
if (updated) {
|
|
118
|
+
await yaml_js.writeYAMLFile(file, { ...importmap, imports: { ...importmap.imports, ...imports }});
|
|
119
|
+
return true;
|
|
120
|
+
} else {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function updateJSON(file) {
|
|
126
|
+
const importmap = await json_js.readJSONFile(file);
|
|
127
|
+
const { updated, imports } = await update(importmap.imports);
|
|
128
|
+
|
|
129
|
+
if (updated) {
|
|
130
|
+
await json_js.writeJSONFile(file, { ...importmap, imports: { ...importmap.imports, ...imports }});
|
|
131
|
+
return true;
|
|
132
|
+
} else {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
var unpkg = /*#__PURE__*/Object.freeze({
|
|
138
|
+
__proto__: null,
|
|
139
|
+
update: update,
|
|
140
|
+
updateJSON: updateJSON,
|
|
141
|
+
updateYAML: updateYAML
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const { imports, scope } = importmap;
|
|
145
|
+
|
|
47
146
|
const ENCODING = 'utf8';
|
|
48
147
|
const ALGO = 'sha384';
|
|
49
148
|
|
|
@@ -76,12 +175,10 @@ function getImportmapIntegrity({
|
|
|
76
175
|
function getImportMapScript({
|
|
77
176
|
importmap = { imports, scope },
|
|
78
177
|
algo = ALGO,
|
|
79
|
-
encoding = ENCODING,
|
|
80
178
|
spaces = 2,
|
|
81
179
|
} = {}) {
|
|
82
|
-
const integrity = getImportmapIntegrity({ importmap, algo,
|
|
83
|
-
|
|
84
|
-
return `<script type="importmap" integrity="${integrity}">${json}</script>`;
|
|
180
|
+
const integrity = getImportmapIntegrity({ importmap, algo, spaces });
|
|
181
|
+
return `<script type="importmap" integrity="${integrity}">${JSON.stringify(importmap, null, spaces)}</script>`;
|
|
85
182
|
}
|
|
86
183
|
|
|
87
184
|
exports.ALGO = ALGO;
|
|
@@ -93,3 +190,4 @@ exports.importmap = importmap;
|
|
|
93
190
|
exports.imports = imports;
|
|
94
191
|
exports.mergeWithImportmap = mergeWithImportmap;
|
|
95
192
|
exports.scope = scope;
|
|
193
|
+
exports.unpkg = unpkg;
|
package/index.mjs
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { readYAMLFile, writeYAMLFile } from '@shgysk8zer0/npm-utils/yaml.js';
|
|
4
|
+
import { readJSONFile, writeJSONFile } from '@shgysk8zer0/npm-utils/json.js';
|
|
5
|
+
|
|
6
|
+
const imports$1 = {
|
|
7
|
+
"@shgysk8zer0/kazoo/": "https://unpkg.com/@shgysk8zer0/kazoo@0.2.5/",
|
|
8
|
+
"@shgysk8zer0/konami": "https://unpkg.com/@shgysk8zer0/konami@1.1.1/konami.js",
|
|
9
|
+
"@shgysk8zer0/polyfills": "https://unpkg.com/@shgysk8zer0/polyfills@0.2.6/all.min.js",
|
|
10
|
+
"@shgysk8zer0/polyfills/": "https://unpkg.com/@shgysk8zer0/polyfills@0.2.6/",
|
|
11
|
+
"@shgysk8zer0/jswaggersheets": "https://unpkg.com/@shgysk8zer0/jswaggersheets@1.1.0/swagger.js",
|
|
12
|
+
"@shgysk8zer0/jswaggersheets/": "https://unpkg.com/@shgysk8zer0/jswaggersheets@1.1.0/",
|
|
13
|
+
"@shgysk8zer0/jss/": "https://unpkg.com/@shgysk8zer0/jss@1.0.1/",
|
|
14
|
+
"@shgysk8zer0/consts/": "https://unpkg.com/@shgysk8zer0/consts@1.0.7/",
|
|
15
|
+
"@shgysk8zer0/http/": "https://unpkg.com/@shgysk8zer0/http@1.0.5/",
|
|
16
|
+
"@shgysk8zer0/http-status": "https://unpkg.com/@shgysk8zer0/http-status@1.1.1/http-status.js",
|
|
17
|
+
"@shgysk8zer0/components/": "https://unpkg.com/@shgysk8zer0/components@0.1.5/",
|
|
18
|
+
"@kernvalley/components/": "https://unpkg.com/@kernvalley/components@1.1.0/",
|
|
19
|
+
"@webcomponents/custom-elements": "https://unpkg.com/@webcomponents/custom-elements@1.6.0/custom-elements.min.js",
|
|
20
|
+
leaflet: "https://unpkg.com/leaflet@1.9.4/dist/leaflet-src.esm.js",
|
|
21
|
+
"urlpattern-polyfill": "https://unpkg.com/urlpattern-polyfill@9.0.0/index.js",
|
|
22
|
+
"highlight.js": "https://unpkg.com/@highlightjs/cdn-assets@11.9.0/es/highlight.min.js",
|
|
23
|
+
"highlight.js/": "https://unpkg.com/@highlightjs/cdn-assets@11.9.0/",
|
|
24
|
+
marked: "https://unpkg.com/marked@9.1.4/lib/marked.esm.js",
|
|
25
|
+
"marked-highlight": "https://unpkg.com/marked-highlight@2.0.6/src/index.js",
|
|
26
|
+
"firebase/": "https://www.gstatic.com/firebasejs/9.23.0/"
|
|
27
|
+
};
|
|
28
|
+
const scope$1 = {
|
|
29
|
+
};
|
|
30
|
+
var importmap = {
|
|
31
|
+
imports: imports$1,
|
|
32
|
+
scope: scope$1
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const UNPKG = 'https://unpkg.com/';
|
|
36
|
+
|
|
37
|
+
const cache = new Map();
|
|
38
|
+
|
|
39
|
+
function parseUnpkgURL(src) {
|
|
40
|
+
const url = new URL(src, UNPKG);
|
|
41
|
+
|
|
42
|
+
if (! url.hostname === UNPKG || url.pathname.length === 1 || url.pathname === '/[object%20Object]') {
|
|
43
|
+
throw new Error(`${src} is not an unpkg URL.`);
|
|
44
|
+
} else {
|
|
45
|
+
const path = url.pathname.substr(1).split('/');
|
|
46
|
+
|
|
47
|
+
if (path.length === 0) {
|
|
48
|
+
throw new Error(`Invalid unpkg URL: ${src}`);
|
|
49
|
+
} else if (path.length !== 1 && path[0].startsWith('@')) {
|
|
50
|
+
const [pkg, version = null] = path[1].split('@');
|
|
51
|
+
return { scope: path[0], pkg, version, module: path.splice(2).join('/') };
|
|
52
|
+
} else {
|
|
53
|
+
const [pkg, version = null] = path[0].split('@');
|
|
54
|
+
return { scope: null, pkg, version, module: path.splice(1).join('/') };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getUnpkgURL({ scope, pkg, version, module = '' }) {
|
|
60
|
+
// console.log({ scope, pkg, version });
|
|
61
|
+
if (typeof pkg !== 'string' || pkg.length === 0) {
|
|
62
|
+
throw new TypeError('Package name must be a non-empty string.');
|
|
63
|
+
} else if (typeof version !== 'string' || version.length === 0) {
|
|
64
|
+
throw new TypeError('Version must be a non-empty string.');
|
|
65
|
+
} else if (typeof scope === 'string' && scope.length !== 0) {
|
|
66
|
+
return new URL(`/${scope}/${pkg}@${version}/${module}`, UNPKG).href;
|
|
67
|
+
} else {
|
|
68
|
+
return new URL(`/${pkg}@${version}/${module}`, UNPKG).href;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function getLatestVersion({ scope, pkg, signal } = {}) {
|
|
73
|
+
const path = typeof scope === 'string' ? `/${scope}/${pkg}/` : `/${pkg}/`;
|
|
74
|
+
|
|
75
|
+
if (cache.has(path)) {
|
|
76
|
+
return await cache.get(path);
|
|
77
|
+
} else {
|
|
78
|
+
const url = new URL(path, 'https://unpkg.com/');
|
|
79
|
+
url.searchParams.set('meta', '');
|
|
80
|
+
|
|
81
|
+
const promise = fetch(url, { method: 'HEAD', signal }).then(resp => {
|
|
82
|
+
const { version } = parseUnpkgURL(resp.url);
|
|
83
|
+
return version;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
cache.set(path, promise);
|
|
87
|
+
return promise;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function update(imports) {
|
|
92
|
+
let updated = false;
|
|
93
|
+
|
|
94
|
+
const entries = await Promise.all(Object.entries(imports)
|
|
95
|
+
.filter(([,val]) => val.startsWith(UNPKG))
|
|
96
|
+
.map(async ([key, val]) => {
|
|
97
|
+
const { scope, pkg, version: oldVersion, module } = parseUnpkgURL(val);
|
|
98
|
+
const version = await getLatestVersion({ scope, pkg });
|
|
99
|
+
|
|
100
|
+
if (! updated && version > oldVersion) {
|
|
101
|
+
updated = true;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return [key, getUnpkgURL({ scope, pkg, version, module })];
|
|
105
|
+
})
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
return { imports: Object.fromEntries(entries), updated };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function updateYAML(file) {
|
|
112
|
+
const importmap = await readYAMLFile(file);
|
|
113
|
+
const { updated, imports } = await update(importmap.imports);
|
|
114
|
+
|
|
115
|
+
if (updated) {
|
|
116
|
+
await writeYAMLFile(file, { ...importmap, imports: { ...importmap.imports, ...imports }});
|
|
117
|
+
return true;
|
|
118
|
+
} else {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function updateJSON(file) {
|
|
124
|
+
const importmap = await readJSONFile(file);
|
|
125
|
+
const { updated, imports } = await update(importmap.imports);
|
|
126
|
+
|
|
127
|
+
if (updated) {
|
|
128
|
+
await writeJSONFile(file, { ...importmap, imports: { ...importmap.imports, ...imports }});
|
|
129
|
+
return true;
|
|
130
|
+
} else {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var unpkg = /*#__PURE__*/Object.freeze({
|
|
136
|
+
__proto__: null,
|
|
137
|
+
update: update,
|
|
138
|
+
updateJSON: updateJSON,
|
|
139
|
+
updateYAML: updateYAML
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const { imports, scope } = importmap;
|
|
143
|
+
|
|
144
|
+
const ENCODING = 'utf8';
|
|
145
|
+
const ALGO = 'sha384';
|
|
146
|
+
|
|
147
|
+
function mergeWithImportmap({ imports = {}, scope = {}}) {
|
|
148
|
+
return {
|
|
149
|
+
imports: { ...importmap.imports, ...imports },
|
|
150
|
+
scope: { ...importmap.scope, ...scope },
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function createImportmapJSON(path = 'importmap.json', {
|
|
155
|
+
importmap = { imports, scope },
|
|
156
|
+
spaces = 2,
|
|
157
|
+
signal,
|
|
158
|
+
} = {}) {
|
|
159
|
+
await writeFile(path, JSON.stringify(importmap, null, spaces), { encoding: ENCODING, signal });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function getImportmapIntegrity({
|
|
163
|
+
importmap = { imports, scope },
|
|
164
|
+
algo = ALGO,
|
|
165
|
+
encoding = ENCODING,
|
|
166
|
+
spaces = 2,
|
|
167
|
+
} = {}) {
|
|
168
|
+
const hash = createHash(algo);
|
|
169
|
+
hash.update(JSON.stringify(importmap, null, spaces), encoding);
|
|
170
|
+
return `${algo}-${hash.digest('base64')}`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function getImportMapScript({
|
|
174
|
+
importmap = { imports, scope },
|
|
175
|
+
algo = ALGO,
|
|
176
|
+
spaces = 2,
|
|
177
|
+
} = {}) {
|
|
178
|
+
const integrity = getImportmapIntegrity({ importmap, algo, spaces });
|
|
179
|
+
return `<script type="importmap" integrity="${integrity}">${JSON.stringify(importmap, null, spaces)}</script>`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export { ALGO, ENCODING, createImportmapJSON, getImportMapScript, getImportmapIntegrity, importmap, imports, mergeWithImportmap, scope, unpkg };
|
package/package.json
CHANGED
|
@@ -1,21 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgysk8zer0/importmap",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=18.0.0"
|
|
6
6
|
},
|
|
7
7
|
"description": "Front-End dependencies based on `<script type=\"importmap\">`",
|
|
8
8
|
"type": "module",
|
|
9
|
-
"module": "./index.
|
|
9
|
+
"module": "./index.mjs",
|
|
10
10
|
"main": "./index.cjs",
|
|
11
|
-
"unpkg": "./index.
|
|
11
|
+
"unpkg": "./index.mjs",
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"import": "./index.
|
|
14
|
+
"import": "./index.mjs",
|
|
15
15
|
"require": "./index.cjs"
|
|
16
16
|
},
|
|
17
|
+
"./*.js": {
|
|
18
|
+
"import": "./*.mjs",
|
|
19
|
+
"require": "./*.cjs"
|
|
20
|
+
},
|
|
21
|
+
"./*.mjs": {
|
|
22
|
+
"import": "./*.mjs"
|
|
23
|
+
},
|
|
24
|
+
"./*.cjs": {
|
|
25
|
+
"require": "./*.cjs"
|
|
26
|
+
},
|
|
17
27
|
"./*": {
|
|
18
|
-
"import": "./*.
|
|
28
|
+
"import": "./*.mjs",
|
|
19
29
|
"require": "./*.cjs"
|
|
20
30
|
}
|
|
21
31
|
},
|
|
@@ -27,7 +37,7 @@
|
|
|
27
37
|
"preversion": "npm test",
|
|
28
38
|
"prepare": "npm run build",
|
|
29
39
|
"lint:js": "eslint .",
|
|
30
|
-
"fix:js": "eslint. --fix",
|
|
40
|
+
"fix:js": "eslint . --fix",
|
|
31
41
|
"build": "npm run build:js",
|
|
32
42
|
"build:js": "rollup -c",
|
|
33
43
|
"test:imports": "rollup -c rollup.test.config.js",
|
|
@@ -48,11 +58,15 @@
|
|
|
48
58
|
},
|
|
49
59
|
"homepage": "https://github.com/shgysk8zer0/importmap#readme",
|
|
50
60
|
"devDependencies": {
|
|
61
|
+
"@babel/eslint-parser": "^7.22.15",
|
|
62
|
+
"@babel/eslint-plugin": "^7.22.10",
|
|
63
|
+
"@babel/plugin-syntax-import-assertions": "^7.22.5",
|
|
64
|
+
"@rollup/plugin-json": "^6.0.1",
|
|
51
65
|
"@shgysk8zer0/js-utils": "^1.0.1",
|
|
52
|
-
"@shgysk8zer0/rollup-import": "^1.2.
|
|
66
|
+
"@shgysk8zer0/rollup-import": "^1.2.2"
|
|
53
67
|
},
|
|
54
68
|
"dependencies": {
|
|
55
|
-
"@shgysk8zer0/npm-utils": "^1.1.
|
|
56
|
-
"commander": "^11.
|
|
69
|
+
"@shgysk8zer0/npm-utils": "^1.1.2",
|
|
70
|
+
"commander": "^11.1.0"
|
|
57
71
|
}
|
|
58
72
|
}
|
package/unpkg.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { readYAMLFile, writeYAMLFile } from '@shgysk8zer0/npm-utils/yaml.js';
|
|
2
|
+
import { readJSONFile, writeJSONFile } from '@shgysk8zer0/npm-utils/json.js';
|
|
3
|
+
import { parseUnpkgURL, getUnpkgURL, getLatestVersion, UNPKG } from './utils.js';
|
|
4
|
+
|
|
5
|
+
export async function update(imports) {
|
|
6
|
+
let updated = false;
|
|
7
|
+
|
|
8
|
+
const entries = await Promise.all(Object.entries(imports)
|
|
9
|
+
.filter(([,val]) => val.startsWith(UNPKG))
|
|
10
|
+
.map(async ([key, val]) => {
|
|
11
|
+
const { scope, pkg, version: oldVersion, module } = parseUnpkgURL(val);
|
|
12
|
+
const version = await getLatestVersion({ scope, pkg });
|
|
13
|
+
|
|
14
|
+
if (! updated && version > oldVersion) {
|
|
15
|
+
updated = true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return [key, getUnpkgURL({ scope, pkg, version, module })];
|
|
19
|
+
})
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
return { imports: Object.fromEntries(entries), updated };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function updateYAML(file) {
|
|
26
|
+
const importmap = await readYAMLFile(file);
|
|
27
|
+
const { updated, imports } = await update(importmap.imports);
|
|
28
|
+
|
|
29
|
+
if (updated) {
|
|
30
|
+
await writeYAMLFile(file, { ...importmap, imports: { ...importmap.imports, ...imports }});
|
|
31
|
+
return true;
|
|
32
|
+
} else {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function updateJSON(file) {
|
|
38
|
+
const importmap = await readJSONFile(file);
|
|
39
|
+
const { updated, imports } = await update(importmap.imports);
|
|
40
|
+
|
|
41
|
+
if (updated) {
|
|
42
|
+
await writeJSONFile(file, { ...importmap, imports: { ...importmap.imports, ...imports }});
|
|
43
|
+
return true;
|
|
44
|
+
} else {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
package/update.js
ADDED
package/utils.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const UNPKG = 'https://unpkg.com/';
|
|
2
|
+
|
|
3
|
+
const cache = new Map();
|
|
4
|
+
|
|
5
|
+
export function parseUnpkgURL(src) {
|
|
6
|
+
const url = new URL(src, UNPKG);
|
|
7
|
+
|
|
8
|
+
if (! url.hostname === UNPKG || url.pathname.length === 1 || url.pathname === '/[object%20Object]') {
|
|
9
|
+
throw new Error(`${src} is not an unpkg URL.`);
|
|
10
|
+
} else {
|
|
11
|
+
const path = url.pathname.substr(1).split('/');
|
|
12
|
+
|
|
13
|
+
if (path.length === 0) {
|
|
14
|
+
throw new Error(`Invalid unpkg URL: ${src}`);
|
|
15
|
+
} else if (path.length !== 1 && path[0].startsWith('@')) {
|
|
16
|
+
const [pkg, version = null] = path[1].split('@');
|
|
17
|
+
return { scope: path[0], pkg, version, module: path.splice(2).join('/') };
|
|
18
|
+
} else {
|
|
19
|
+
const [pkg, version = null] = path[0].split('@');
|
|
20
|
+
return { scope: null, pkg, version, module: path.splice(1).join('/') };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getUnpkgURL({ scope, pkg, version, module = '' }) {
|
|
26
|
+
// console.log({ scope, pkg, version });
|
|
27
|
+
if (typeof pkg !== 'string' || pkg.length === 0) {
|
|
28
|
+
throw new TypeError('Package name must be a non-empty string.');
|
|
29
|
+
} else if (typeof version !== 'string' || version.length === 0) {
|
|
30
|
+
throw new TypeError('Version must be a non-empty string.');
|
|
31
|
+
} else if (typeof scope === 'string' && scope.length !== 0) {
|
|
32
|
+
return new URL(`/${scope}/${pkg}@${version}/${module}`, UNPKG).href;
|
|
33
|
+
} else {
|
|
34
|
+
return new URL(`/${pkg}@${version}/${module}`, UNPKG).href;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function getLatestVersion({ scope, pkg, signal } = {}) {
|
|
39
|
+
const path = typeof scope === 'string' ? `/${scope}/${pkg}/` : `/${pkg}/`;
|
|
40
|
+
|
|
41
|
+
if (cache.has(path)) {
|
|
42
|
+
return await cache.get(path);
|
|
43
|
+
} else {
|
|
44
|
+
const url = new URL(path, 'https://unpkg.com/');
|
|
45
|
+
url.searchParams.set('meta', '');
|
|
46
|
+
|
|
47
|
+
const promise = fetch(url, { method: 'HEAD', signal }).then(resp => {
|
|
48
|
+
const { version } = parseUnpkgURL(resp.url);
|
|
49
|
+
return version;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
cache.set(path, promise);
|
|
53
|
+
return promise;
|
|
54
|
+
}
|
|
55
|
+
}
|
package/index.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { writeFile } from 'node:fs/promises';
|
|
2
|
-
import { createHash } from 'node:crypto';
|
|
3
|
-
import { versions } from './versions.js';
|
|
4
|
-
|
|
5
|
-
export const imports = {
|
|
6
|
-
'@shgysk8zer0/kazoo/': `https://unpkg.com/@shgysk8zer0/kazoo@${versions['@shgysk8zer0/kazoo']}/`,
|
|
7
|
-
'@shgysk8zer0/konami': `https://unpkg.com/@shgysk8zer0/konami@${versions['@shgysk8zer0/konami']}/konami.js`,
|
|
8
|
-
'@shgysk8zer0/polyfills': `https://unpkg.com/@shgysk8zer0/polyfills@${versions['@shgysk8zer0/polyfills']}/all.min.js`,
|
|
9
|
-
'@shgysk8zer0/polyfills/': `https://unpkg.com/@shgysk8zer0/polyfills@${versions['@shgysk8zer0/polyfills']}/`,
|
|
10
|
-
'@shgysk8zer0/jswaggersheets': `https://unpkg.com/@shgysk8zer0/jswaggersheets@${versions['@shgysk8zer0/jswaggersheets']}/swagger.js`,
|
|
11
|
-
'@shgysk8zer0/jswaggersheets/': `https://unpkg.com/@shgysk8zer0/jswaggersheets@${versions['@shgysk8zer0/jswaggersheets']}/`,
|
|
12
|
-
'@shgysk8zer0/jss/': `https://unpkg.com/@shgysk8zer0/jss@${versions['@shgysk8zer0/jss']}/`,
|
|
13
|
-
'@shgysk8zer0/http-status': `https://unpkg.com/@shgysk8zer0/http-status@${versions['@shgysk8zer0/http-status']}/http-status.js`,
|
|
14
|
-
'@shgysk8zer0/components/': `https://unpkg.com/@shgysk8zer0/components@${versions['@shgysk8zer0/components']}/`,
|
|
15
|
-
'@kernvalley/components/': `https://unpkg.com/@kernvalley/components@${versions['@kernvalley/components']}/`,
|
|
16
|
-
'@webcomponents/custom-elements': `https://unpkg.com/@webcomponents/custom-elements@${versions['@webcomponents/custom-elements']}/custom-elements.min.js`,
|
|
17
|
-
'leaflet': `https://unpkg.com/leaflet@${versions.leaflet}/dist/leaflet-src.esm.js`,
|
|
18
|
-
'firebase/': `https://www.gstatic.com/firebasejs/${versions.firebase}/`,
|
|
19
|
-
'urlpattern-polyfill': `https://unpkg.com/urlpattern-polyfill@${versions['urlpattern-polyfill']}/index.js`,
|
|
20
|
-
'highlight.js': `https://unpkg.com/@highlightjs/cdn-assets@${versions['highlight.js']}/es/highlight.min.js`,
|
|
21
|
-
'highlight.js/': `https://unpkg.com/@highlightjs/cdn-assets@${versions['highlight.js']}/`,
|
|
22
|
-
'marked': `https://unpkg.com/marked@${versions.marked}/src/marked.js`,
|
|
23
|
-
'marked-highlight': `https://unpkg.com/marked-highlight@${versions['marked-highlight']}/src/index.js`
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const scope = {};
|
|
27
|
-
export const importmap = { imports, scope };
|
|
28
|
-
export const ENCODING = 'utf8';
|
|
29
|
-
export const ALGO = 'sha384';
|
|
30
|
-
|
|
31
|
-
export function mergeWithImportmap({ imports = {}, scope = {}}) {
|
|
32
|
-
return {
|
|
33
|
-
imports: { ...importmap.imports, ...imports },
|
|
34
|
-
scope: { ...importmap.scope, ...scope },
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export async function createImportmapJSON(path = 'importmap.json', {
|
|
39
|
-
importmap = { imports, scope },
|
|
40
|
-
spaces = 2,
|
|
41
|
-
signal,
|
|
42
|
-
} = {}) {
|
|
43
|
-
await writeFile(path, JSON.stringify(importmap, null, spaces), { encoding: ENCODING, signal });
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function getImportmapIntegrity({
|
|
47
|
-
importmap = { imports, scope },
|
|
48
|
-
algo = ALGO,
|
|
49
|
-
encoding = ENCODING,
|
|
50
|
-
spaces = 2,
|
|
51
|
-
} = {}) {
|
|
52
|
-
const hash = createHash(algo);
|
|
53
|
-
hash.update(JSON.stringify(importmap, null, spaces), encoding);
|
|
54
|
-
return `${algo}-${hash.digest('base64')}`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function getImportMapScript({
|
|
58
|
-
importmap = { imports, scope },
|
|
59
|
-
algo = ALGO,
|
|
60
|
-
encoding = ENCODING,
|
|
61
|
-
spaces = 2,
|
|
62
|
-
} = {}) {
|
|
63
|
-
const integrity = getImportmapIntegrity({ importmap, algo, encoding, spaces });
|
|
64
|
-
const json = JSON.stringify(importmap, null, spaces);
|
|
65
|
-
return `<script type="importmap" integrity="${integrity}">${json}</script>`;
|
|
66
|
-
}
|
package/versions.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const versions = {
|
|
2
|
-
'@shgysk8zer0/kazoo': '0.2.3',
|
|
3
|
-
'@shgysk8zer0/konami': '1.1.0',
|
|
4
|
-
'@shgysk8zer0/polyfills': '0.2.4',
|
|
5
|
-
'@shgysk8zer0/components': '0.1.3',
|
|
6
|
-
'@shgysk8zer0/http-status': '1.1.1',
|
|
7
|
-
'@shgysk8zer0/jswaggersheets': '1.1.0',
|
|
8
|
-
'@shgysk8zer0/jss': '1.0.1',
|
|
9
|
-
'@kernvalley/components': '1.1.0',
|
|
10
|
-
'@webcomponents/custom-elements': '1.6.0',
|
|
11
|
-
'leaflet': '1.9.4',
|
|
12
|
-
'firebase': '9.23.0',
|
|
13
|
-
'urlpattern-polyfill': '9.0.0',
|
|
14
|
-
'highlight.js': '11.8.0',
|
|
15
|
-
'marked': '5.1.0',
|
|
16
|
-
'marked-highlight': '2.0.1',
|
|
17
|
-
};
|