unicode-input-toolconverter 0.2.0 → 0.2.3

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.
Files changed (143) hide show
  1. package/.nyc_output/out.json +8980 -1849
  2. package/CHANGES.md +15 -1
  3. package/README.md +6 -11
  4. package/_locales/en-US/messages.json +153 -6
  5. package/_locales/hu-HU/messages.json +153 -6
  6. package/_locales/pt-BR/messages.json +153 -6
  7. package/_locales/sv-SE/messages.json +153 -6
  8. package/babel.config.json +0 -1
  9. package/browser_action/characterSelection.js +18 -11
  10. package/browser_action/charrefConverters.js +286 -79
  11. package/browser_action/chartBuild.js +97 -27
  12. package/browser_action/encodingBehaviors.js +10 -7
  13. package/browser_action/entityBehaviors.js +42 -16
  14. package/browser_action/index-es.html +13 -1
  15. package/browser_action/index-instrumented.html +13 -1
  16. package/browser_action/index-pages.html +13 -1
  17. package/browser_action/index.html +13 -1
  18. package/browser_action/index.iife.min.js +9 -1
  19. package/browser_action/index.iife.min.js.map +1 -1
  20. package/browser_action/index.instrumented.iife.min.js +1 -1
  21. package/browser_action/index.instrumented.iife.min.js.map +1 -1
  22. package/browser_action/index.js +5 -5
  23. package/browser_action/preferences/prefDefaults.js +12 -3
  24. package/browser_action/service-worker/sw-activateCallback.js +1 -2
  25. package/browser_action/service-worker/sw-resources.json +6 -4
  26. package/browser_action/templateUtils/elements.js +12 -1
  27. package/browser_action/templateUtils/fill.js +6 -0
  28. package/browser_action/templateUtils/validation.js +4 -1
  29. package/browser_action/templates/chartBuild.js +167 -102
  30. package/browser_action/templates/index.js +227 -53
  31. package/browser_action/templatesElementCustomization/widgets.js +40 -15
  32. package/browser_action/unicode/UnicodeConverter.js +99 -73
  33. package/browser_action/unicode/charrefunicodeDb.js +100 -50
  34. package/browser_action/unicode/getScriptInfoForCodePoint.js +13 -4
  35. package/browser_action/unicode/hangul.js +27 -20
  36. package/browser_action/unicode/lastScriptNames.json +1 -1
  37. package/browser_action/unicode/parseUnihanFromTextFileStrings.js +44 -25
  38. package/browser_action/unicode/unicodeFieldInfo.js +112 -90
  39. package/browser_action/unicode/unicodeScripts.js +409 -35
  40. package/browser_action/unicode/unihan.js +4 -3
  41. package/browser_action/unicode/unihanDbPopulate.js +7 -2
  42. package/browser_action/unicode/unihanFields.js +34 -0
  43. package/browser_action/unicodecharref.js +353 -190
  44. package/browser_action/utils/DOMUtils.js +95 -34
  45. package/browser_action/utils/FetchUtils.js +7 -6
  46. package/browser_action/utils/TextUtils.js +4 -4
  47. package/browser_action/utils/TypedArrayUtils.js +9 -5
  48. package/browser_action/utils/semicolonSeparatedToArray.js +3 -3
  49. package/browser_action/utils/setupServiceWorker.js +2 -2
  50. package/eslint.config.js +11 -0
  51. package/icons/openWindow16.png +0 -0
  52. package/icons/openWindow24.png +0 -0
  53. package/lib/background.html +7 -0
  54. package/lib/background.js +2 -2
  55. package/package.json +80 -70
  56. package/pnpm-workspace.yaml +8 -0
  57. package/server.js +66 -51
  58. package/sw.js +97 -56
  59. package/tools/entities-import.js +4 -1
  60. package/tools/findEsResources.js +33 -10
  61. package/tools/fix-sw-resources-vendor-paths.js +60 -0
  62. package/tools/list-locales.js +2 -2
  63. package/tools/parseUnicodeCharts.js +126 -60
  64. package/tools/ucd-import.js +1 -10
  65. package/tools/unicode-charts.html +49 -20
  66. package/tools/unihan-import.js +45 -15
  67. package/tools/write-sw-version.js +16 -0
  68. package/tsconfig.json +23 -0
  69. package/typings/__coverage__.d.ts +5 -0
  70. package/typings/apple-system-profiler.d.ts +17 -0
  71. package/typings/commands.d.ts +19 -0
  72. package/typings/json-6.d.ts +4 -0
  73. package/typings/rollup-plugin-istanbul.d.ts +3 -0
  74. package/vendor/camelcase/index.d.ts +154 -0
  75. package/vendor/camelcase/index.js +137 -23
  76. package/vendor/fflate/esm/browser.d.ts +1539 -0
  77. package/vendor/fflate/esm/browser.js +82 -55
  78. package/vendor/intl-dom/dist/Formatter.d.ts +120 -0
  79. package/vendor/intl-dom/dist/Formatter.d.ts.map +1 -0
  80. package/vendor/intl-dom/dist/collation.d.ts +42 -0
  81. package/vendor/intl-dom/dist/collation.d.ts.map +1 -0
  82. package/vendor/intl-dom/dist/defaultAllSubstitutions.d.ts +52 -0
  83. package/vendor/intl-dom/dist/defaultAllSubstitutions.d.ts.map +1 -0
  84. package/vendor/intl-dom/dist/defaultInsertNodes.d.ts +96 -0
  85. package/vendor/intl-dom/dist/defaultInsertNodes.d.ts.map +1 -0
  86. package/vendor/intl-dom/dist/defaultKeyCheckerConverter.d.ts +17 -0
  87. package/vendor/intl-dom/dist/defaultKeyCheckerConverter.d.ts.map +1 -0
  88. package/vendor/intl-dom/dist/defaultLocaleResolver.d.ts +285 -0
  89. package/vendor/intl-dom/dist/defaultLocaleResolver.d.ts.map +1 -0
  90. package/vendor/intl-dom/dist/findLocaleStrings.d.ts +88 -0
  91. package/vendor/intl-dom/dist/findLocaleStrings.d.ts.map +1 -0
  92. package/vendor/intl-dom/dist/getDOMForLocaleString.d.ts +67 -0
  93. package/vendor/intl-dom/dist/getDOMForLocaleString.d.ts.map +1 -0
  94. package/vendor/intl-dom/dist/getMessageForKeyByStyle.d.ts +73 -0
  95. package/vendor/intl-dom/dist/getMessageForKeyByStyle.d.ts.map +1 -0
  96. package/vendor/intl-dom/dist/getStringFromMessageAndDefaults.d.ts +26 -0
  97. package/vendor/intl-dom/dist/getStringFromMessageAndDefaults.d.ts.map +1 -0
  98. package/vendor/intl-dom/dist/i18n.d.ts +113 -0
  99. package/vendor/intl-dom/dist/i18n.d.ts.map +1 -0
  100. package/vendor/intl-dom/dist/index.d.ts +92 -0
  101. package/vendor/intl-dom/dist/index.d.ts.map +1 -0
  102. package/vendor/intl-dom/dist/index.esm.d.ts +34 -0
  103. package/vendor/intl-dom/dist/index.esm.js +854 -896
  104. package/vendor/intl-dom/dist/index.esm.min.js +4 -0
  105. package/vendor/intl-dom/dist/index.esm.min.js.map +1 -0
  106. package/vendor/intl-dom/dist/index.umd.js +2953 -0
  107. package/vendor/intl-dom/dist/index.umd.min.js +4 -0
  108. package/vendor/intl-dom/dist/index.umd.min.js.map +1 -0
  109. package/vendor/intl-dom/dist/promiseChainForValues.d.ts +34 -0
  110. package/vendor/intl-dom/dist/promiseChainForValues.d.ts.map +1 -0
  111. package/vendor/intl-dom/dist/shared.d.ts +20 -0
  112. package/vendor/intl-dom/dist/shared.d.ts.map +1 -0
  113. package/vendor/intl-dom/dist/utils.d.ts +53 -0
  114. package/vendor/intl-dom/dist/utils.d.ts.map +1 -0
  115. package/vendor/jamilih/dist/jml.d.mts +468 -0
  116. package/vendor/jamilih/dist/{jml-es.js → jml.mjs} +1489 -343
  117. package/vendor/jquery/dist/jquery.js +1677 -2713
  118. package/vendor/json-6/dist/index.mjs +2 -0
  119. package/vendor/miller-columns/CHANGES.md +185 -0
  120. package/vendor/miller-columns/LICENSE-MIT.txt +21 -0
  121. package/vendor/miller-columns/README.md +249 -0
  122. package/vendor/miller-columns/demos/index.html +69 -0
  123. package/vendor/miller-columns/demos/index.js +72 -0
  124. package/vendor/miller-columns/dist/index-es.js +748 -0
  125. package/vendor/miller-columns/dist/index-es.min.d.ts +25 -0
  126. package/vendor/miller-columns/dist/index-es.min.js +7 -1
  127. package/vendor/miller-columns/dist/index-umd.js +757 -0
  128. package/vendor/miller-columns/dist/index-umd.min.js +7 -0
  129. package/vendor/miller-columns/dist/index.d.ts +25 -0
  130. package/vendor/miller-columns/dist/millerColumns.d.ts +10 -0
  131. package/vendor/miller-columns/eslint.config.js +46 -0
  132. package/vendor/miller-columns/fix-declarations.js +18 -0
  133. package/vendor/miller-columns/miller-columns.css +24 -1
  134. package/vendor/miller-columns/package.json +73 -0
  135. package/vendor/miller-columns/pnpm-workspace.yaml +2 -0
  136. package/vendor/miller-columns/src/index.js +642 -0
  137. package/vendor/miller-columns/src/millerColumns.ts +12 -0
  138. package/vendor/miller-columns/tsconfig-prod.json +23 -0
  139. package/vendor/miller-columns/tsconfig.json +21 -0
  140. package/vendor/simple-prefs/dist/index.esm.d.ts +1 -0
  141. package/vendor/simple-prefs/dist/index.esm.js +164 -216
  142. package/vendor/simple-prefs/dist/simple-prefs.d.ts +117 -0
  143. package/lgtm.yml +0 -5
package/sw.js CHANGED
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable no-console -- Debugging */
2
- /* eslint-env serviceworker -- Service worker */
3
2
 
4
3
  import {getJSON} from './browser_action/utils/FetchUtils.js';
5
4
  import activateCallback from
@@ -10,20 +9,23 @@ const CURRENT_CACHES = {
10
9
  };
11
10
  const minutes = 60 * 1000;
12
11
 
12
+ // v1
13
+
13
14
  // Utilities
14
15
 
15
16
  /**
16
17
  *
17
- * @param {PlainObject} args
18
- * @param {
19
- * "log"|"error"|"beginInstall"|"finishedInstall"|"beginActivate"|
18
+ * @param {object} args
19
+ * @param {"log"|"error"|"beginInstall"|"finishedInstall"|"beginActivate"|
20
20
  * "finishedActivate"
21
21
  * } args.type
22
22
  * @param {string} [args.message]
23
23
  * @returns {Promise<void>}
24
24
  */
25
25
  async function post ({type, message = type}) {
26
- const windowClients = await self.clients.matchAll({
26
+ const windowClients = await /** @type {ServiceWorkerGlobalScope} */ (
27
+ /** @type {unknown} */ (globalThis)
28
+ ).clients.matchAll({
27
29
  // Are there any uncontrolled within activate anyways?
28
30
  includeUncontrolled: true,
29
31
  type: 'window'
@@ -31,17 +33,21 @@ async function post ({type, message = type}) {
31
33
  if (message.includes('Posting finished')) {
32
34
  message += ` (count: ${windowClients.length})`;
33
35
  }
34
- windowClients.forEach((client) => {
36
+ windowClients.forEach(/**
37
+ * @param {WindowClient} client
38
+ * @returns {void}
39
+ */ (client) => {
35
40
  // Although we only need one client to which to send
36
41
  // arguments, we want to signal phase complete to all
37
42
  // eslint-disable-next-line unicorn/require-post-message-target-origin -- Rule being reviewed: https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1396
38
- client.postMessage({message, type});
39
- });
43
+ client.postMessage({message, type});
44
+ }
45
+ );
40
46
  }
41
47
 
42
48
  /**
43
49
  * @callback Logger
44
- * @param {string[]} messages
50
+ * @param {...string[]} messages
45
51
  * @returns {Promise<void>}
46
52
  */
47
53
 
@@ -64,10 +70,21 @@ function logError (error, ...messages) {
64
70
  const message = messages.join(' ');
65
71
  console.error(error, message);
66
72
  return post({
67
- message, errorType: error.type, name: error.name, type: 'error'
73
+ message,
74
+ // errorType: error.type,
75
+ // name: error.name,
76
+ type: 'error'
68
77
  });
69
78
  }
70
79
 
80
+ /**
81
+ * @typedef {number} PositiveInteger
82
+ */
83
+
84
+ /**
85
+ * @typedef {number} Float
86
+ */
87
+
71
88
  /**
72
89
  * @callback DelayCallback
73
90
  * @param {Float} time
@@ -91,7 +108,9 @@ async function tryAndRetry (cb, timeout, errMessage, time = 0) {
91
108
  return undefined;
92
109
  } catch (err) {
93
110
  console.log('errrr', err);
94
- logError(err, err.message || errMessage);
111
+ logError(/** @type {Error} */ (err), /** @type {Error} */ (
112
+ err
113
+ ).message || errMessage);
95
114
  // eslint-disable-next-line promise/avoid-new -- Need timeout
96
115
  return new Promise((resolve) => {
97
116
  setTimeout(() => {
@@ -107,6 +126,14 @@ const pathToLocaleJSON = './browser_action/service-worker/sw-locales.json';
107
126
  const pathToUnicodeDataJSON =
108
127
  './browser_action/service-worker/sw-unicode-data.json';
109
128
 
129
+ // Auto-updated by `npm run service-worker` (see tools/write-sw-version.js).
130
+ // Keeping this in sync with `package.json`'s version ensures this file's
131
+ // own bytes change on every release, so browsers with an already-
132
+ // installed service worker actually detect the update (the update check
133
+ // is a byte-for-byte diff of this script) instead of silently continuing
134
+ // to serve a stale cache indefinitely.
135
+ const BUILD_VERSION = '0.2.2';
136
+
110
137
  console.log('sw info', pathToStaticJSON);
111
138
 
112
139
  /**
@@ -119,9 +146,8 @@ async function install (time) {
119
146
  post({type: 'beginInstall'});
120
147
  log(`Install: Trying, attempt ${time}`);
121
148
  const now = Date.now();
122
- const {version} = await getJSON('./package.json');
123
149
 
124
- const cacheKey = namespace + CURRENT_CACHES.prefetch + version;
150
+ const cacheKey = namespace + CURRENT_CACHES.prefetch + BUILD_VERSION;
125
151
 
126
152
  console.log('opening cache', cacheKey);
127
153
  const [
@@ -131,9 +157,9 @@ async function install (time) {
131
157
  unicodeDataFiles
132
158
  ] = await Promise.all([
133
159
  caches.open(cacheKey),
134
- getJSON(pathToStaticJSON),
135
- getJSON(pathToLocaleJSON),
136
- getJSON(pathToUnicodeDataJSON)
160
+ /** @type {Promise<string[]>} */ (getJSON(pathToStaticJSON)),
161
+ /** @type {Promise<string[]>} */ (getJSON(pathToLocaleJSON)),
162
+ /** @type {Promise<string[]>} */ (getJSON(pathToUnicodeDataJSON))
137
163
  ]);
138
164
  log('Install: Retrieved dependency values');
139
165
 
@@ -164,14 +190,20 @@ async function install (time) {
164
190
  }
165
191
  return cache.put(urlToPrefetch, resp);
166
192
  } catch (error) {
167
- logError(error, 'Not caching ' + urlToPrefetch + ' due to ' + error);
193
+ logError(
194
+ /** @type {Error} */ (error),
195
+ `Not caching ${urlToPrefetch} due to ${error}`
196
+ );
168
197
  throw error;
169
198
  }
170
199
  });
171
200
  await Promise.all(cachePromises);
172
201
  log('Install: Pre-fetching complete.');
173
202
  } catch (error) {
174
- logError(error, `Install: Pre-fetching failed: ${error}`);
203
+ logError(
204
+ /** @type {Error} */ (error),
205
+ `Install: Pre-fetching failed: ${error}`
206
+ );
175
207
  // Failing gives chance for a new client to re-trigger install?
176
208
  throw error;
177
209
  }
@@ -194,28 +226,24 @@ async function activate (time) {
194
226
  post({type: 'beginActivate'});
195
227
  log(`Activate: Trying, attempt ${time}`);
196
228
 
197
- const [
198
- cacheNames,
199
- {version}
200
- ] = await Promise.all([
201
- caches.keys(),
202
- getJSON('./package.json')
203
- ]);
229
+ const cacheNames = await caches.keys();
204
230
 
205
231
  const expectedCacheNames = Object.values(
206
232
  CURRENT_CACHES
207
- ).map((n) => namespace + n + version);
233
+ ).map((n) => namespace + n + BUILD_VERSION);
208
234
  cacheNames.forEach(async (cacheName) => {
209
- if (!expectedCacheNames.includes(cacheName)) {
210
- log('Activate: Deleting out of date cache:', cacheName);
211
- await caches.delete(cacheName);
235
+ if (expectedCacheNames.includes(cacheName)) {
236
+ return;
212
237
  }
238
+
239
+ log('Activate: Deleting out of date cache:', cacheName);
240
+ await caches.delete(cacheName);
213
241
  });
214
242
 
215
243
  // Todo: Use `namespace` in indexedDB db
216
244
  await activateCallback({
217
- namespace,
218
- log
245
+ namespace
246
+ // log
219
247
  });
220
248
  // log('Activate: Database changes completed');
221
249
 
@@ -224,36 +252,49 @@ async function activate (time) {
224
252
  post({type: 'finishedActivate'});
225
253
  }
226
254
 
227
- self.addEventListener('install', (e) => {
228
- self.skipWaiting();
229
- e.waitUntil(
230
- tryAndRetry(install, 5 * minutes, 'Error installing')
231
- );
232
- });
255
+ const sw = /** @type {ServiceWorkerGlobalScope} */ (
256
+ /** @type {unknown} */ (globalThis)
257
+ );
233
258
 
234
- self.addEventListener('activate', (e) => {
259
+ sw.addEventListener('install', /**
260
+ * @param {ExtendableEvent} e
261
+ * @returns {void}
262
+ */ (e) => {
263
+ sw.skipWaiting();
264
+ e.waitUntil(
265
+ tryAndRetry(install, 5 * minutes, 'Error installing')
266
+ );
267
+ });
268
+
269
+ sw.addEventListener('activate', /**
270
+ * @param {ExtendableEvent} e
271
+ * @returns {void}
272
+ */ (e) => {
235
273
  // Erring is of no present use here:
236
274
  // https://github.com/w3c/ServiceWorker/issues/659#issuecomment-384919053
237
- e.waitUntil(tryAndRetry(activate, 5 * minutes, 'Error activating'));
238
- });
275
+ e.waitUntil(tryAndRetry(activate, 5 * minutes, 'Error activating'));
276
+ });
239
277
 
240
278
  // We cannot make this async as `e.respondWith` must be called synchronously
241
- self.addEventListener('fetch', (e) => {
279
+ sw.addEventListener('fetch', /**
280
+ * @param {FetchEvent} e
281
+ * @returns {void}
282
+ */ (e) => {
242
283
  // DevTools opening will trigger these o-i-c requests
243
- const {request} = e;
244
- const {cache, mode, url} = request;
245
- if (
246
- cache === 'only-if-cached' &&
284
+ const {request} = e;
285
+ const {cache, mode, url} = request;
286
+ if (
287
+ cache === 'only-if-cached' &&
247
288
  mode !== 'same-origin'
248
- ) {
249
- return;
250
- }
251
- console.log('fetching', url);
252
- e.respondWith((async () => {
253
- const cached = await caches.match(request);
254
- if (!cached) {
255
- console.log('no cached found', url);
289
+ ) {
290
+ return;
256
291
  }
257
- return cached || fetch(request);
258
- })());
259
- });
292
+ console.log('fetching', url);
293
+ e.respondWith((async () => {
294
+ const cached = await caches.match(request);
295
+ if (!cached) {
296
+ console.log('no cached found', url);
297
+ }
298
+ return cached || fetch(request);
299
+ })());
300
+ });
@@ -2,7 +2,7 @@
2
2
  // this file for the browser, but we're keeping this file for demonstrating
3
3
  // an approach for live-obtaining the live version.
4
4
 
5
- import fs from 'fs/promises';
5
+ import fs from 'node:fs/promises';
6
6
 
7
7
  // eslint-disable-next-line no-shadow -- Clearer
8
8
  import fetch from 'node-fetch';
@@ -14,6 +14,9 @@ const args = process.argv.slice(2);
14
14
  const targetDir = `${process.cwd()}/download/entities`;
15
15
  const entityBasePath = 'https://www.w3.org/2003/entities/2007/';
16
16
 
17
+ /**
18
+ * @param {string} file
19
+ */
17
20
  const getText = async (file) => {
18
21
  return await (await fetch(
19
22
  file
@@ -1,4 +1,7 @@
1
1
  const queryModule = {
2
+ /**
3
+ * @param {import('estree').Literal} node
4
+ */
2
5
  [
3
6
  // Entity files
4
7
  'ArrayExpression > Literal[value="optgroup"] + ObjectExpression + ' +
@@ -10,19 +13,39 @@ const queryModule = {
10
13
  ];
11
14
  },
12
15
  // Dynamically imported stylesheets
16
+ /**
17
+ * @param {import('estree').Property} node
18
+ */
13
19
  'Property[key.name="stylesheets"]' (node) {
14
- return (node.value.elements || []).flatMap((element) => {
15
- if (element.type === 'Literal') {
20
+ return (
21
+ ('elements' in node.value && node.value.elements) || []
22
+ ).flatMap((element) => {
23
+ if (element?.type === 'Literal') {
16
24
  return element.value;
17
25
  }
18
- // if (element.type === 'ArrayExpression') {
19
- return element.elements.flatMap((arrayItem) => {
20
- if (arrayItem.type === 'Literal') {
21
- return arrayItem.value;
22
- }
23
- // Ignore
24
- return [];
25
- });
26
+ if (element?.type === 'ArrayExpression') {
27
+ return element.elements.flatMap((arrayItem) => {
28
+ if (arrayItem?.type === 'Literal') {
29
+ return arrayItem.value;
30
+ }
31
+ if (
32
+ arrayItem?.type === 'ConditionalExpression' &&
33
+ arrayItem.alternate.type === 'Literal'
34
+ ) {
35
+ return arrayItem.alternate.value;
36
+ }
37
+ // Ignore
38
+ return [];
39
+ });
40
+ }
41
+ if (
42
+ element?.type === 'ConditionalExpression' &&
43
+ element.alternate.type === 'Literal'
44
+ ) {
45
+ return element.alternate.value;
46
+ }
47
+
48
+ return [];
26
49
  });
27
50
  }
28
51
  };
@@ -0,0 +1,60 @@
1
+ import fs from 'node:fs/promises';
2
+
3
+ // `find-es-resources` resolves bare specifiers (e.g., `import ... from
4
+ // 'jamilih'`) via plain Node resolution, which always lands in
5
+ // `node_modules` -- it has no notion of `browser_action/index.html`'s
6
+ // `importmap`, which is what actually redirects those specifiers to
7
+ // `/vendor/...` builds in the browser. `node_modules` is gitignored, so
8
+ // any `node_modules` entry here would 404 once deployed.
9
+ const html = await fs.readFile('browser_action/index.html', 'utf8');
10
+ const importmapMatch = html.match(
11
+ /<script type="importmap">([\s\S]*?)<\/script>/v
12
+ );
13
+ if (!importmapMatch) {
14
+ throw new Error(
15
+ 'Could not find `<script type="importmap">` in browser_action/index.html'
16
+ );
17
+ }
18
+ const {imports} = JSON.parse(importmapMatch[1]);
19
+
20
+ const indexHtmlUrl = new URL(
21
+ 'https://example.invalid/browser_action/index.html'
22
+ );
23
+ const vendorPathBySpecifier = new Map(
24
+ Object.entries(imports).map(([specifier, relativePath]) => {
25
+ return [specifier, new URL(relativePath, indexHtmlUrl).pathname];
26
+ })
27
+ );
28
+
29
+ const swResourcesPath = 'browser_action/service-worker/sw-resources.json';
30
+ const resources = /** @type {string[]} */ (
31
+ JSON.parse(await fs.readFile(swResourcesPath, 'utf8'))
32
+ );
33
+
34
+ const nodeModulesPattern = /^\/node_modules\/((?:@[^\/]+\/)?[^\/]+)\//v;
35
+
36
+ const fixedResources = [...new Set(resources.flatMap((resource) => {
37
+ const nodeModulesMatch = resource.match(nodeModulesPattern);
38
+ if (!nodeModulesMatch) {
39
+ return [resource];
40
+ }
41
+ const [, packageName] = nodeModulesMatch;
42
+ const fullSpecifier = resource.replace(/^\/node_modules\//v, '');
43
+ const vendorPath = vendorPathBySpecifier.get(fullSpecifier) ||
44
+ vendorPathBySpecifier.get(packageName);
45
+ if (!vendorPath) {
46
+ // Only reachable by following a `node_modules` package's own source
47
+ // (e.g., a sub-dependency); nothing deployed actually imports it
48
+ // this way, so drop it.
49
+ // eslint-disable-next-line no-console -- CLI
50
+ console.log(`Dropping undeployable resource: ${resource}`);
51
+ return [];
52
+ }
53
+ return [vendorPath];
54
+ // eslint-disable-next-line unicorn/require-array-sort-compare -- Consistency
55
+ }))].toSorted();
56
+
57
+ await fs.writeFile(
58
+ swResourcesPath,
59
+ JSON.stringify(fixedResources, null, 2) + '\n'
60
+ );
@@ -1,4 +1,4 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
 
3
3
  const dirs = await fs.readdir('_locales');
4
4
 
@@ -6,7 +6,7 @@ const json = dirs.filter((dir) => {
6
6
  return dir !== '.DS_Store';
7
7
  }).map((dir) => {
8
8
  return `/_locales/${dir}/messages.json`;
9
- }).sort();
9
+ }).toSorted((a, b) => a.localeCompare(b));
10
10
 
11
11
  // eslint-disable-next-line no-console -- CLI
12
12
  console.log('json', json);