@shgysk8zer0/importmap 1.5.0 → 1.5.1

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 CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [v1.5.1] - 2025-12-04
11
+
12
+ ### Added
13
+ - Add `Importmap` methods to set local imports using `package.json`
14
+ - Add static `Importmap.importFromFile()` to import from a local JSON file
15
+
16
+ ### Changed
17
+ - Update package & module `exports`
18
+
10
19
  ## [v1.5.0] - 2025-12-03
11
20
 
12
21
  ### Added
package/cli.cjs CHANGED
@@ -4,7 +4,7 @@ var json_js = require('@shgysk8zer0/npm-utils/json.js');
4
4
  var yaml_js = require('@shgysk8zer0/npm-utils/yaml.js');
5
5
  var commander = require('commander');
6
6
  var node_path = require('node:path');
7
- require('node:fs/promises');
7
+ var promises = require('node:fs/promises');
8
8
  require('@shgysk8zer0/polyfills');
9
9
  require('@shgysk8zer0/npm-utils/path.js');
10
10
 
@@ -98,11 +98,11 @@ const imports$1 = {
98
98
  "firebase/storage": "https://www.gstatic.com/firebasejs/10.12.1/firebase-storage.js",
99
99
  "firebase/analytics": "https://www.gstatic.com/firebasejs/10.12.1/firebase-analytics.js"
100
100
  };
101
- const scope$1 = {
101
+ const scopes$1 = {
102
102
  };
103
103
  var json = {
104
104
  imports: imports$1,
105
- scope: scope$1
105
+ scopes: scopes$1
106
106
  };
107
107
 
108
108
  const SHA256 = 'SHA-256';
@@ -112,15 +112,23 @@ const DEFAULT_ALGO = SHA384;
112
112
 
113
113
  const BASE64 = 'base64';
114
114
 
115
- const { imports, scope } = json;
115
+ const { imports, scopes } = json;
116
116
 
117
117
  class Importmap {
118
118
  #imports = {};
119
- #scope = {};
119
+ #scopes = {};
120
120
 
121
- constructor({ imports: i = imports, scope: s = scope } = {}) {
121
+ constructor({ imports: i = imports, scopes: s = scopes } = {}) {
122
122
  this.#imports = i;
123
- this.#scope = s;
123
+ this.#scopes = s;
124
+ }
125
+
126
+ get imports() {
127
+ return structuredClone(this.#imports);
128
+ }
129
+
130
+ get scopes() {
131
+ return structuredClone(this.#scopes);
124
132
  }
125
133
 
126
134
  delete(key) {
@@ -140,13 +148,56 @@ class Importmap {
140
148
  }
141
149
 
142
150
  toJSON() {
143
- return { imports: this.#imports, scope: this.#scope };
151
+ return { imports: this.#imports, scopes: this.#scopes };
144
152
  }
145
153
 
146
154
  toString() {
147
155
  return JSON.stringify(this);
148
156
  }
149
157
 
158
+ async importLocalPackage(name = 'package.json', { signal } = {}) {
159
+ const path = node_path.join(process.cwd(), name);
160
+ const pkg = await promises.readFile(path, { encoding: 'utf8', signal });
161
+
162
+ return this.setLocalPackage(JSON.parse(pkg));
163
+ }
164
+
165
+ setLocalPackage({ name, module, exports = {} }) {
166
+ if (typeof name !== 'string') {
167
+ return false;
168
+ } else if (typeof exports === 'string' ) {
169
+ this.set(name, exports);
170
+ return true;
171
+ } else if (typeof exports === 'object') {
172
+ Object.entries(exports).forEach(([key, value]) => {
173
+ if (key.startsWith('.')) {
174
+ const importKey = key === '.' ? name : `${name}${key.substring(1)}`;
175
+ const resolved = typeof value === 'string' ? value : value.import ?? value.default;
176
+
177
+ if (typeof resolved === 'string' && resolved.startsWith('./')) {
178
+ if (importKey.includes('*') && resolved.includes('*')) {
179
+ const [prefix, suffix] = importKey.split('*');
180
+
181
+ if (resolved.endsWith('*' + suffix)) {
182
+ this.set(prefix, resolved.substring(1).replace('*' + suffix, ''));
183
+ }
184
+ } else {
185
+ this.set(importKey, resolved.substring(1));
186
+ }
187
+ }
188
+ }
189
+ });
190
+
191
+ return true;
192
+ } else if (typeof module === 'string') {
193
+ this.set(name, module);
194
+ return true;
195
+ } else {
196
+ this.set(name, '/');
197
+ return true;
198
+ }
199
+ }
200
+
150
201
  async getScript({ algo = DEFAULT_ALGO, alphabet = BASE64, signal } = {}) {
151
202
  const integrity = await this.getIntegrity({ algo, alphabet, signal });
152
203
 
@@ -176,18 +227,16 @@ class Importmap {
176
227
  static get SHA512() {
177
228
  return SHA512;
178
229
  }
179
- }
180
230
 
181
- const importmap = new Importmap({ imports, scope });
231
+ static async importFromFile(path = 'importmap.json', { signal } = {}) {
232
+ const fullPath = node_path.join(process.cwd(), path);
233
+ const importmap = await promises.readFile(fullPath, { encoding: 'utf8', signal });
182
234
 
183
- var importmap$1 = /*#__PURE__*/Object.freeze({
184
- __proto__: null,
185
- Importmap: Importmap,
186
- default: importmap,
187
- importmap: importmap,
188
- imports: imports,
189
- scope: scope
190
- });
235
+ return new Importmap(JSON.parse(importmap));
236
+ }
237
+ }
238
+
239
+ const importmap = new Importmap({ imports, scopes });
191
240
 
192
241
  /* eslint-env node */
193
242
 
@@ -244,12 +293,12 @@ async function init() {
244
293
 
245
294
  init().then(async ({ opts: { input, encoding, format, output }}) => {
246
295
  const mod = typeof input === 'string'
247
- ? await parse(input, { encoding }).then(({ imports: imports$1, scope: scope$1 = {}, ...rest }) => ({
296
+ ? await parse(input, { encoding }).then(({ imports, scope = {}, ...rest }) => ({
248
297
  ...rest,
249
- imports: { ...imports$1, ...imports },
250
- scope: { ...scope$1, ...scope },
298
+ imports: { ...imports, ...importmap.imports },
299
+ scope: { ...scope, ...importmap.scope },
251
300
  }))
252
- : importmap$1;
301
+ : importmap;
253
302
 
254
303
  console.log(mod);
255
304
 
package/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { writeJSONFile, readJSONFile } from '@shgysk8zer0/npm-utils/json.js';
2
2
  import { writeYAMLFile, readYAMLFile } from '@shgysk8zer0/npm-utils/yaml.js';
3
3
  import { program } from 'commander';
4
- import { extname } from 'node:path';
5
- import 'node:fs/promises';
4
+ import { join, extname } from 'node:path';
5
+ import { readFile } from 'node:fs/promises';
6
6
  import '@shgysk8zer0/polyfills';
7
7
  import '@shgysk8zer0/npm-utils/path.js';
8
8
 
@@ -95,11 +95,11 @@ const imports$1 = {
95
95
  "firebase/storage": "https://www.gstatic.com/firebasejs/10.12.1/firebase-storage.js",
96
96
  "firebase/analytics": "https://www.gstatic.com/firebasejs/10.12.1/firebase-analytics.js"
97
97
  };
98
- const scope$1 = {
98
+ const scopes$1 = {
99
99
  };
100
100
  var json = {
101
101
  imports: imports$1,
102
- scope: scope$1
102
+ scopes: scopes$1
103
103
  };
104
104
 
105
105
  const SHA256 = 'SHA-256';
@@ -109,15 +109,23 @@ const DEFAULT_ALGO = SHA384;
109
109
 
110
110
  const BASE64 = 'base64';
111
111
 
112
- const { imports, scope } = json;
112
+ const { imports, scopes } = json;
113
113
 
114
114
  class Importmap {
115
115
  #imports = {};
116
- #scope = {};
116
+ #scopes = {};
117
117
 
118
- constructor({ imports: i = imports, scope: s = scope } = {}) {
118
+ constructor({ imports: i = imports, scopes: s = scopes } = {}) {
119
119
  this.#imports = i;
120
- this.#scope = s;
120
+ this.#scopes = s;
121
+ }
122
+
123
+ get imports() {
124
+ return structuredClone(this.#imports);
125
+ }
126
+
127
+ get scopes() {
128
+ return structuredClone(this.#scopes);
121
129
  }
122
130
 
123
131
  delete(key) {
@@ -137,13 +145,56 @@ class Importmap {
137
145
  }
138
146
 
139
147
  toJSON() {
140
- return { imports: this.#imports, scope: this.#scope };
148
+ return { imports: this.#imports, scopes: this.#scopes };
141
149
  }
142
150
 
143
151
  toString() {
144
152
  return JSON.stringify(this);
145
153
  }
146
154
 
155
+ async importLocalPackage(name = 'package.json', { signal } = {}) {
156
+ const path = join(process.cwd(), name);
157
+ const pkg = await readFile(path, { encoding: 'utf8', signal });
158
+
159
+ return this.setLocalPackage(JSON.parse(pkg));
160
+ }
161
+
162
+ setLocalPackage({ name, module, exports = {} }) {
163
+ if (typeof name !== 'string') {
164
+ return false;
165
+ } else if (typeof exports === 'string' ) {
166
+ this.set(name, exports);
167
+ return true;
168
+ } else if (typeof exports === 'object') {
169
+ Object.entries(exports).forEach(([key, value]) => {
170
+ if (key.startsWith('.')) {
171
+ const importKey = key === '.' ? name : `${name}${key.substring(1)}`;
172
+ const resolved = typeof value === 'string' ? value : value.import ?? value.default;
173
+
174
+ if (typeof resolved === 'string' && resolved.startsWith('./')) {
175
+ if (importKey.includes('*') && resolved.includes('*')) {
176
+ const [prefix, suffix] = importKey.split('*');
177
+
178
+ if (resolved.endsWith('*' + suffix)) {
179
+ this.set(prefix, resolved.substring(1).replace('*' + suffix, ''));
180
+ }
181
+ } else {
182
+ this.set(importKey, resolved.substring(1));
183
+ }
184
+ }
185
+ }
186
+ });
187
+
188
+ return true;
189
+ } else if (typeof module === 'string') {
190
+ this.set(name, module);
191
+ return true;
192
+ } else {
193
+ this.set(name, '/');
194
+ return true;
195
+ }
196
+ }
197
+
147
198
  async getScript({ algo = DEFAULT_ALGO, alphabet = BASE64, signal } = {}) {
148
199
  const integrity = await this.getIntegrity({ algo, alphabet, signal });
149
200
 
@@ -173,18 +224,16 @@ class Importmap {
173
224
  static get SHA512() {
174
225
  return SHA512;
175
226
  }
176
- }
177
227
 
178
- const importmap = new Importmap({ imports, scope });
228
+ static async importFromFile(path = 'importmap.json', { signal } = {}) {
229
+ const fullPath = join(process.cwd(), path);
230
+ const importmap = await readFile(fullPath, { encoding: 'utf8', signal });
179
231
 
180
- var importmap$1 = /*#__PURE__*/Object.freeze({
181
- __proto__: null,
182
- Importmap: Importmap,
183
- default: importmap,
184
- importmap: importmap,
185
- imports: imports,
186
- scope: scope
187
- });
232
+ return new Importmap(JSON.parse(importmap));
233
+ }
234
+ }
235
+
236
+ const importmap = new Importmap({ imports, scopes });
188
237
 
189
238
  /* eslint-env node */
190
239
 
@@ -241,12 +290,12 @@ async function init() {
241
290
 
242
291
  init().then(async ({ opts: { input, encoding, format, output }}) => {
243
292
  const mod = typeof input === 'string'
244
- ? await parse(input, { encoding }).then(({ imports: imports$1, scope: scope$1 = {}, ...rest }) => ({
293
+ ? await parse(input, { encoding }).then(({ imports, scope = {}, ...rest }) => ({
245
294
  ...rest,
246
- imports: { ...imports$1, ...imports },
247
- scope: { ...scope$1, ...scope },
295
+ imports: { ...imports, ...importmap.imports },
296
+ scope: { ...scope, ...importmap.scope },
248
297
  }))
249
- : importmap$1;
298
+ : importmap;
250
299
 
251
300
  console.log(mod);
252
301
 
package/importmap.cjs CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var node_path = require('node:path');
6
+ var promises = require('node:fs/promises');
5
7
  require('@shgysk8zer0/polyfills');
6
8
 
7
9
  const imports$1 = {
@@ -93,11 +95,11 @@ const imports$1 = {
93
95
  "firebase/storage": "https://www.gstatic.com/firebasejs/10.12.1/firebase-storage.js",
94
96
  "firebase/analytics": "https://www.gstatic.com/firebasejs/10.12.1/firebase-analytics.js"
95
97
  };
96
- const scope$1 = {
98
+ const scopes$1 = {
97
99
  };
98
100
  var json = {
99
101
  imports: imports$1,
100
- scope: scope$1
102
+ scopes: scopes$1
101
103
  };
102
104
 
103
105
  const SHA256 = 'SHA-256';
@@ -107,15 +109,23 @@ const DEFAULT_ALGO = SHA384;
107
109
 
108
110
  const BASE64 = 'base64';
109
111
 
110
- const { imports, scope } = json;
112
+ const { imports, scopes } = json;
111
113
 
112
114
  class Importmap {
113
115
  #imports = {};
114
- #scope = {};
116
+ #scopes = {};
115
117
 
116
- constructor({ imports: i = imports, scope: s = scope } = {}) {
118
+ constructor({ imports: i = imports, scopes: s = scopes } = {}) {
117
119
  this.#imports = i;
118
- this.#scope = s;
120
+ this.#scopes = s;
121
+ }
122
+
123
+ get imports() {
124
+ return structuredClone(this.#imports);
125
+ }
126
+
127
+ get scopes() {
128
+ return structuredClone(this.#scopes);
119
129
  }
120
130
 
121
131
  delete(key) {
@@ -135,13 +145,56 @@ class Importmap {
135
145
  }
136
146
 
137
147
  toJSON() {
138
- return { imports: this.#imports, scope: this.#scope };
148
+ return { imports: this.#imports, scopes: this.#scopes };
139
149
  }
140
150
 
141
151
  toString() {
142
152
  return JSON.stringify(this);
143
153
  }
144
154
 
155
+ async importLocalPackage(name = 'package.json', { signal } = {}) {
156
+ const path = node_path.join(process.cwd(), name);
157
+ const pkg = await promises.readFile(path, { encoding: 'utf8', signal });
158
+
159
+ return this.setLocalPackage(JSON.parse(pkg));
160
+ }
161
+
162
+ setLocalPackage({ name, module, exports = {} }) {
163
+ if (typeof name !== 'string') {
164
+ return false;
165
+ } else if (typeof exports === 'string' ) {
166
+ this.set(name, exports);
167
+ return true;
168
+ } else if (typeof exports === 'object') {
169
+ Object.entries(exports).forEach(([key, value]) => {
170
+ if (key.startsWith('.')) {
171
+ const importKey = key === '.' ? name : `${name}${key.substring(1)}`;
172
+ const resolved = typeof value === 'string' ? value : value.import ?? value.default;
173
+
174
+ if (typeof resolved === 'string' && resolved.startsWith('./')) {
175
+ if (importKey.includes('*') && resolved.includes('*')) {
176
+ const [prefix, suffix] = importKey.split('*');
177
+
178
+ if (resolved.endsWith('*' + suffix)) {
179
+ this.set(prefix, resolved.substring(1).replace('*' + suffix, ''));
180
+ }
181
+ } else {
182
+ this.set(importKey, resolved.substring(1));
183
+ }
184
+ }
185
+ }
186
+ });
187
+
188
+ return true;
189
+ } else if (typeof module === 'string') {
190
+ this.set(name, module);
191
+ return true;
192
+ } else {
193
+ this.set(name, '/');
194
+ return true;
195
+ }
196
+ }
197
+
145
198
  async getScript({ algo = DEFAULT_ALGO, alphabet = BASE64, signal } = {}) {
146
199
  const integrity = await this.getIntegrity({ algo, alphabet, signal });
147
200
 
@@ -171,12 +224,20 @@ class Importmap {
171
224
  static get SHA512() {
172
225
  return SHA512;
173
226
  }
227
+
228
+ static async importFromFile(path = 'importmap.json', { signal } = {}) {
229
+ const fullPath = node_path.join(process.cwd(), path);
230
+ const importmap = await promises.readFile(fullPath, { encoding: 'utf8', signal });
231
+
232
+ return new Importmap(JSON.parse(importmap));
233
+ }
174
234
  }
175
235
 
176
- const importmap = new Importmap({ imports, scope });
236
+ const importmap = new Importmap({ imports, scopes });
237
+ var importmap$1 = { imports, scopes };
177
238
 
178
239
  exports.Importmap = Importmap;
179
- exports.default = importmap;
240
+ exports.default = importmap$1;
180
241
  exports.importmap = importmap;
181
242
  exports.imports = imports;
182
- exports.scope = scope;
243
+ exports.scopes = scopes;
package/importmap.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { join } from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
1
3
  import '@shgysk8zer0/polyfills';
2
4
 
3
5
  const imports$1 = {
@@ -89,11 +91,11 @@ const imports$1 = {
89
91
  "firebase/storage": "https://www.gstatic.com/firebasejs/10.12.1/firebase-storage.js",
90
92
  "firebase/analytics": "https://www.gstatic.com/firebasejs/10.12.1/firebase-analytics.js"
91
93
  };
92
- const scope$1 = {
94
+ const scopes$1 = {
93
95
  };
94
96
  var json = {
95
97
  imports: imports$1,
96
- scope: scope$1
98
+ scopes: scopes$1
97
99
  };
98
100
 
99
101
  const SHA256 = 'SHA-256';
@@ -103,15 +105,23 @@ const DEFAULT_ALGO = SHA384;
103
105
 
104
106
  const BASE64 = 'base64';
105
107
 
106
- const { imports, scope } = json;
108
+ const { imports, scopes } = json;
107
109
 
108
110
  class Importmap {
109
111
  #imports = {};
110
- #scope = {};
112
+ #scopes = {};
111
113
 
112
- constructor({ imports: i = imports, scope: s = scope } = {}) {
114
+ constructor({ imports: i = imports, scopes: s = scopes } = {}) {
113
115
  this.#imports = i;
114
- this.#scope = s;
116
+ this.#scopes = s;
117
+ }
118
+
119
+ get imports() {
120
+ return structuredClone(this.#imports);
121
+ }
122
+
123
+ get scopes() {
124
+ return structuredClone(this.#scopes);
115
125
  }
116
126
 
117
127
  delete(key) {
@@ -131,13 +141,56 @@ class Importmap {
131
141
  }
132
142
 
133
143
  toJSON() {
134
- return { imports: this.#imports, scope: this.#scope };
144
+ return { imports: this.#imports, scopes: this.#scopes };
135
145
  }
136
146
 
137
147
  toString() {
138
148
  return JSON.stringify(this);
139
149
  }
140
150
 
151
+ async importLocalPackage(name = 'package.json', { signal } = {}) {
152
+ const path = join(process.cwd(), name);
153
+ const pkg = await readFile(path, { encoding: 'utf8', signal });
154
+
155
+ return this.setLocalPackage(JSON.parse(pkg));
156
+ }
157
+
158
+ setLocalPackage({ name, module, exports = {} }) {
159
+ if (typeof name !== 'string') {
160
+ return false;
161
+ } else if (typeof exports === 'string' ) {
162
+ this.set(name, exports);
163
+ return true;
164
+ } else if (typeof exports === 'object') {
165
+ Object.entries(exports).forEach(([key, value]) => {
166
+ if (key.startsWith('.')) {
167
+ const importKey = key === '.' ? name : `${name}${key.substring(1)}`;
168
+ const resolved = typeof value === 'string' ? value : value.import ?? value.default;
169
+
170
+ if (typeof resolved === 'string' && resolved.startsWith('./')) {
171
+ if (importKey.includes('*') && resolved.includes('*')) {
172
+ const [prefix, suffix] = importKey.split('*');
173
+
174
+ if (resolved.endsWith('*' + suffix)) {
175
+ this.set(prefix, resolved.substring(1).replace('*' + suffix, ''));
176
+ }
177
+ } else {
178
+ this.set(importKey, resolved.substring(1));
179
+ }
180
+ }
181
+ }
182
+ });
183
+
184
+ return true;
185
+ } else if (typeof module === 'string') {
186
+ this.set(name, module);
187
+ return true;
188
+ } else {
189
+ this.set(name, '/');
190
+ return true;
191
+ }
192
+ }
193
+
141
194
  async getScript({ algo = DEFAULT_ALGO, alphabet = BASE64, signal } = {}) {
142
195
  const integrity = await this.getIntegrity({ algo, alphabet, signal });
143
196
 
@@ -167,8 +220,16 @@ class Importmap {
167
220
  static get SHA512() {
168
221
  return SHA512;
169
222
  }
223
+
224
+ static async importFromFile(path = 'importmap.json', { signal } = {}) {
225
+ const fullPath = join(process.cwd(), path);
226
+ const importmap = await readFile(fullPath, { encoding: 'utf8', signal });
227
+
228
+ return new Importmap(JSON.parse(importmap));
229
+ }
170
230
  }
171
231
 
172
- const importmap = new Importmap({ imports, scope });
232
+ const importmap = new Importmap({ imports, scopes });
233
+ var importmap$1 = { imports, scopes };
173
234
 
174
- export { Importmap, importmap as default, importmap, imports, scope };
235
+ export { Importmap, importmap$1 as default, importmap, imports, scopes };
package/importmap.json CHANGED
@@ -88,5 +88,5 @@
88
88
  "firebase/storage": "https://www.gstatic.com/firebasejs/10.12.1/firebase-storage.js",
89
89
  "firebase/analytics": "https://www.gstatic.com/firebasejs/10.12.1/firebase-analytics.js"
90
90
  },
91
- "scope": {}
91
+ "scopes": {}
92
92
  }
package/index.cjs CHANGED
@@ -1,12 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  var promises = require('node:fs/promises');
4
+ var node_path = require('node:path');
4
5
  require('@shgysk8zer0/polyfills');
5
6
  var yaml_js = require('@shgysk8zer0/npm-utils/yaml.js');
6
7
  var json_js = require('@shgysk8zer0/npm-utils/json.js');
7
8
  var path_js = require('@shgysk8zer0/npm-utils/path.js');
8
9
 
9
- const imports$2 = {
10
+ const imports$1 = {
10
11
  "@node/": "/node_modules/",
11
12
  "@shgysk8zer0/kazoo/": "https://unpkg.com/@shgysk8zer0/kazoo@1.0.10/",
12
13
  "@shgysk8zer0/konami": "https://unpkg.com/@shgysk8zer0/konami@1.1.1/konami.js",
@@ -95,11 +96,11 @@ const imports$2 = {
95
96
  "firebase/storage": "https://www.gstatic.com/firebasejs/10.12.1/firebase-storage.js",
96
97
  "firebase/analytics": "https://www.gstatic.com/firebasejs/10.12.1/firebase-analytics.js"
97
98
  };
98
- const scope$2 = {
99
+ const scopes$1 = {
99
100
  };
100
101
  var json = {
101
- imports: imports$2,
102
- scope: scope$2
102
+ imports: imports$1,
103
+ scopes: scopes$1
103
104
  };
104
105
 
105
106
  const SHA256 = 'SHA-256';
@@ -141,15 +142,23 @@ async function hash(data, { algo = DEFAULT_ALGO, output = BUFFER } = {}) {
141
142
 
142
143
  const sri = async(data, { algo = SHA384 } = {}) => hash(data, { algo, output: SRI });
143
144
 
144
- const { imports: imports$1, scope: scope$1 } = json;
145
+ const { imports, scopes } = json;
145
146
 
146
147
  class Importmap {
147
148
  #imports = {};
148
- #scope = {};
149
+ #scopes = {};
149
150
 
150
- constructor({ imports: i = imports$1, scope: s = scope$1 } = {}) {
151
+ constructor({ imports: i = imports, scopes: s = scopes } = {}) {
151
152
  this.#imports = i;
152
- this.#scope = s;
153
+ this.#scopes = s;
154
+ }
155
+
156
+ get imports() {
157
+ return structuredClone(this.#imports);
158
+ }
159
+
160
+ get scopes() {
161
+ return structuredClone(this.#scopes);
153
162
  }
154
163
 
155
164
  delete(key) {
@@ -169,13 +178,56 @@ class Importmap {
169
178
  }
170
179
 
171
180
  toJSON() {
172
- return { imports: this.#imports, scope: this.#scope };
181
+ return { imports: this.#imports, scopes: this.#scopes };
173
182
  }
174
183
 
175
184
  toString() {
176
185
  return JSON.stringify(this);
177
186
  }
178
187
 
188
+ async importLocalPackage(name = 'package.json', { signal } = {}) {
189
+ const path = node_path.join(process.cwd(), name);
190
+ const pkg = await promises.readFile(path, { encoding: 'utf8', signal });
191
+
192
+ return this.setLocalPackage(JSON.parse(pkg));
193
+ }
194
+
195
+ setLocalPackage({ name, module, exports = {} }) {
196
+ if (typeof name !== 'string') {
197
+ return false;
198
+ } else if (typeof exports === 'string' ) {
199
+ this.set(name, exports);
200
+ return true;
201
+ } else if (typeof exports === 'object') {
202
+ Object.entries(exports).forEach(([key, value]) => {
203
+ if (key.startsWith('.')) {
204
+ const importKey = key === '.' ? name : `${name}${key.substring(1)}`;
205
+ const resolved = typeof value === 'string' ? value : value.import ?? value.default;
206
+
207
+ if (typeof resolved === 'string' && resolved.startsWith('./')) {
208
+ if (importKey.includes('*') && resolved.includes('*')) {
209
+ const [prefix, suffix] = importKey.split('*');
210
+
211
+ if (resolved.endsWith('*' + suffix)) {
212
+ this.set(prefix, resolved.substring(1).replace('*' + suffix, ''));
213
+ }
214
+ } else {
215
+ this.set(importKey, resolved.substring(1));
216
+ }
217
+ }
218
+ }
219
+ });
220
+
221
+ return true;
222
+ } else if (typeof module === 'string') {
223
+ this.set(name, module);
224
+ return true;
225
+ } else {
226
+ this.set(name, '/');
227
+ return true;
228
+ }
229
+ }
230
+
179
231
  async getScript({ algo = DEFAULT_ALGO, alphabet = BASE64, signal } = {}) {
180
232
  const integrity = await this.getIntegrity({ algo, alphabet, signal });
181
233
 
@@ -205,18 +257,16 @@ class Importmap {
205
257
  static get SHA512() {
206
258
  return SHA512;
207
259
  }
208
- }
209
260
 
210
- const importmap = new Importmap({ imports: imports$1, scope: scope$1 });
261
+ static async importFromFile(path = 'importmap.json', { signal } = {}) {
262
+ const fullPath = node_path.join(process.cwd(), path);
263
+ const importmap = await promises.readFile(fullPath, { encoding: 'utf8', signal });
211
264
 
212
- var importmap$1 = /*#__PURE__*/Object.freeze({
213
- __proto__: null,
214
- Importmap: Importmap,
215
- default: importmap,
216
- importmap: importmap,
217
- imports: imports$1,
218
- scope: scope$1
219
- });
265
+ return new Importmap(JSON.parse(importmap));
266
+ }
267
+ }
268
+
269
+ const importmap = new Importmap({ imports, scopes });
220
270
 
221
271
  const UNPKG = 'https://unpkg.com/';
222
272
 
@@ -343,18 +393,17 @@ var unpkg = /*#__PURE__*/Object.freeze({
343
393
  updateYAML: updateYAML
344
394
  });
345
395
 
346
- const { imports, scope } = importmap$1;
347
396
  const ENCODING = 'utf8';
348
397
 
349
- function mergeWithImportmap({ imports = {}, scope = {}}) {
398
+ function mergeWithImportmap({ imports = {}, scopes = {}}) {
350
399
  return {
351
- imports: { ...imports$1, ...imports },
352
- scope: { ...scope$1, ...scope },
400
+ imports: { ...importmap.imports, ...imports },
401
+ scopes: { ...importmap.scope, ...scopes },
353
402
  };
354
403
  }
355
404
 
356
405
  async function createImportmapJSON(path = 'importmap.json', {
357
- importmap = { imports, scope },
406
+ importmap = { imports, scopes },
358
407
  spaces = 2,
359
408
  signal,
360
409
  } = {}) {
@@ -362,14 +411,14 @@ async function createImportmapJSON(path = 'importmap.json', {
362
411
  }
363
412
 
364
413
  async function getImportmapIntegrity({
365
- importmap = { imports, scope },
414
+ importmap = { imports, scopes },
366
415
  algo = DEFAULT_ALGO,
367
416
  } = {}) {
368
417
  return await sri(JSON.stringify(importmap), { algo });
369
418
  }
370
419
 
371
420
  async function getImportmapScript({
372
- importmap = { imports, scope },
421
+ importmap = { imports, scopes },
373
422
  algo = DEFAULT_ALGO,
374
423
  } = {}) {
375
424
  const integrity = await getImportmapIntegrity({ importmap, algo });
@@ -377,11 +426,12 @@ async function getImportmapScript({
377
426
  }
378
427
 
379
428
  exports.ENCODING = ENCODING;
429
+ exports.Importmap = Importmap;
380
430
  exports.createImportmapJSON = createImportmapJSON;
381
431
  exports.getImportmapIntegrity = getImportmapIntegrity;
382
432
  exports.getImportmapScript = getImportmapScript;
383
- exports.importmap = importmap$1;
433
+ exports.importmap = importmap;
384
434
  exports.imports = imports;
385
435
  exports.mergeWithImportmap = mergeWithImportmap;
386
- exports.scope = scope;
436
+ exports.scopes = scopes;
387
437
  exports.unpkg = unpkg;
package/index.js CHANGED
@@ -1,10 +1,11 @@
1
- import { writeFile } from 'node:fs/promises';
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
2
3
  import '@shgysk8zer0/polyfills';
3
4
  import { readYAMLFile, writeYAMLFile } from '@shgysk8zer0/npm-utils/yaml.js';
4
5
  import { readJSONFile, writeJSONFile } from '@shgysk8zer0/npm-utils/json.js';
5
6
  import { getFileURL } from '@shgysk8zer0/npm-utils/path.js';
6
7
 
7
- const imports$2 = {
8
+ const imports$1 = {
8
9
  "@node/": "/node_modules/",
9
10
  "@shgysk8zer0/kazoo/": "https://unpkg.com/@shgysk8zer0/kazoo@1.0.10/",
10
11
  "@shgysk8zer0/konami": "https://unpkg.com/@shgysk8zer0/konami@1.1.1/konami.js",
@@ -93,11 +94,11 @@ const imports$2 = {
93
94
  "firebase/storage": "https://www.gstatic.com/firebasejs/10.12.1/firebase-storage.js",
94
95
  "firebase/analytics": "https://www.gstatic.com/firebasejs/10.12.1/firebase-analytics.js"
95
96
  };
96
- const scope$2 = {
97
+ const scopes$1 = {
97
98
  };
98
99
  var json = {
99
- imports: imports$2,
100
- scope: scope$2
100
+ imports: imports$1,
101
+ scopes: scopes$1
101
102
  };
102
103
 
103
104
  const SHA256 = 'SHA-256';
@@ -139,15 +140,23 @@ async function hash(data, { algo = DEFAULT_ALGO, output = BUFFER } = {}) {
139
140
 
140
141
  const sri = async(data, { algo = SHA384 } = {}) => hash(data, { algo, output: SRI });
141
142
 
142
- const { imports: imports$1, scope: scope$1 } = json;
143
+ const { imports, scopes } = json;
143
144
 
144
145
  class Importmap {
145
146
  #imports = {};
146
- #scope = {};
147
+ #scopes = {};
147
148
 
148
- constructor({ imports: i = imports$1, scope: s = scope$1 } = {}) {
149
+ constructor({ imports: i = imports, scopes: s = scopes } = {}) {
149
150
  this.#imports = i;
150
- this.#scope = s;
151
+ this.#scopes = s;
152
+ }
153
+
154
+ get imports() {
155
+ return structuredClone(this.#imports);
156
+ }
157
+
158
+ get scopes() {
159
+ return structuredClone(this.#scopes);
151
160
  }
152
161
 
153
162
  delete(key) {
@@ -167,13 +176,56 @@ class Importmap {
167
176
  }
168
177
 
169
178
  toJSON() {
170
- return { imports: this.#imports, scope: this.#scope };
179
+ return { imports: this.#imports, scopes: this.#scopes };
171
180
  }
172
181
 
173
182
  toString() {
174
183
  return JSON.stringify(this);
175
184
  }
176
185
 
186
+ async importLocalPackage(name = 'package.json', { signal } = {}) {
187
+ const path = join(process.cwd(), name);
188
+ const pkg = await readFile(path, { encoding: 'utf8', signal });
189
+
190
+ return this.setLocalPackage(JSON.parse(pkg));
191
+ }
192
+
193
+ setLocalPackage({ name, module, exports = {} }) {
194
+ if (typeof name !== 'string') {
195
+ return false;
196
+ } else if (typeof exports === 'string' ) {
197
+ this.set(name, exports);
198
+ return true;
199
+ } else if (typeof exports === 'object') {
200
+ Object.entries(exports).forEach(([key, value]) => {
201
+ if (key.startsWith('.')) {
202
+ const importKey = key === '.' ? name : `${name}${key.substring(1)}`;
203
+ const resolved = typeof value === 'string' ? value : value.import ?? value.default;
204
+
205
+ if (typeof resolved === 'string' && resolved.startsWith('./')) {
206
+ if (importKey.includes('*') && resolved.includes('*')) {
207
+ const [prefix, suffix] = importKey.split('*');
208
+
209
+ if (resolved.endsWith('*' + suffix)) {
210
+ this.set(prefix, resolved.substring(1).replace('*' + suffix, ''));
211
+ }
212
+ } else {
213
+ this.set(importKey, resolved.substring(1));
214
+ }
215
+ }
216
+ }
217
+ });
218
+
219
+ return true;
220
+ } else if (typeof module === 'string') {
221
+ this.set(name, module);
222
+ return true;
223
+ } else {
224
+ this.set(name, '/');
225
+ return true;
226
+ }
227
+ }
228
+
177
229
  async getScript({ algo = DEFAULT_ALGO, alphabet = BASE64, signal } = {}) {
178
230
  const integrity = await this.getIntegrity({ algo, alphabet, signal });
179
231
 
@@ -203,18 +255,16 @@ class Importmap {
203
255
  static get SHA512() {
204
256
  return SHA512;
205
257
  }
206
- }
207
258
 
208
- const importmap = new Importmap({ imports: imports$1, scope: scope$1 });
259
+ static async importFromFile(path = 'importmap.json', { signal } = {}) {
260
+ const fullPath = join(process.cwd(), path);
261
+ const importmap = await readFile(fullPath, { encoding: 'utf8', signal });
209
262
 
210
- var importmap$1 = /*#__PURE__*/Object.freeze({
211
- __proto__: null,
212
- Importmap: Importmap,
213
- default: importmap,
214
- importmap: importmap,
215
- imports: imports$1,
216
- scope: scope$1
217
- });
263
+ return new Importmap(JSON.parse(importmap));
264
+ }
265
+ }
266
+
267
+ const importmap = new Importmap({ imports, scopes });
218
268
 
219
269
  const UNPKG = 'https://unpkg.com/';
220
270
 
@@ -341,18 +391,17 @@ var unpkg = /*#__PURE__*/Object.freeze({
341
391
  updateYAML: updateYAML
342
392
  });
343
393
 
344
- const { imports, scope } = importmap$1;
345
394
  const ENCODING = 'utf8';
346
395
 
347
- function mergeWithImportmap({ imports = {}, scope = {}}) {
396
+ function mergeWithImportmap({ imports = {}, scopes = {}}) {
348
397
  return {
349
- imports: { ...imports$1, ...imports },
350
- scope: { ...scope$1, ...scope },
398
+ imports: { ...importmap.imports, ...imports },
399
+ scopes: { ...importmap.scope, ...scopes },
351
400
  };
352
401
  }
353
402
 
354
403
  async function createImportmapJSON(path = 'importmap.json', {
355
- importmap = { imports, scope },
404
+ importmap = { imports, scopes },
356
405
  spaces = 2,
357
406
  signal,
358
407
  } = {}) {
@@ -360,18 +409,18 @@ async function createImportmapJSON(path = 'importmap.json', {
360
409
  }
361
410
 
362
411
  async function getImportmapIntegrity({
363
- importmap = { imports, scope },
412
+ importmap = { imports, scopes },
364
413
  algo = DEFAULT_ALGO,
365
414
  } = {}) {
366
415
  return await sri(JSON.stringify(importmap), { algo });
367
416
  }
368
417
 
369
418
  async function getImportmapScript({
370
- importmap = { imports, scope },
419
+ importmap = { imports, scopes },
371
420
  algo = DEFAULT_ALGO,
372
421
  } = {}) {
373
422
  const integrity = await getImportmapIntegrity({ importmap, algo });
374
423
  return `<script type="importmap" integrity="${integrity}">${JSON.stringify(importmap)}</script>`;
375
424
  }
376
425
 
377
- export { ENCODING, createImportmapJSON, getImportmapIntegrity, getImportmapScript, importmap$1 as importmap, imports, mergeWithImportmap, scope, unpkg };
426
+ export { ENCODING, Importmap, createImportmapJSON, getImportmapIntegrity, getImportmapScript, importmap, imports, mergeWithImportmap, scopes, unpkg };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@shgysk8zer0/importmap",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "engines": {
5
- "node": ">=18.0.0"
5
+ "node": ">=20.10.0"
6
6
  },
7
7
  "description": "Front-End dependencies based on `<script type=\"importmap\">`",
8
8
  "type": "module",
@@ -14,6 +14,9 @@
14
14
  "import": "./index.js",
15
15
  "require": "./index.cjs"
16
16
  },
17
+ "./importmap": {
18
+ "import": "./importmap.js"
19
+ },
17
20
  "./*.js": {
18
21
  "import": "./*.js",
19
22
  "require": "./*.cjs"