Add SRI support to Vite (#34485)

This commit is contained in:
Renaud Chaput 2025-04-23 20:32:02 +02:00
parent 8fe4bebc06
commit 8274313a71
No known key found for this signature in database
GPG Key ID: BCFC859D49B46990
15 changed files with 266 additions and 439 deletions

View File

@ -49,6 +49,7 @@ jobs:
public/assets
public/packs
public/packs-test
tmp/cache/vite
key: ${{ matrix.mode }}-assets-${{ github.head_ref || github.ref_name }}-${{ github.sha }}
restore-keys: |
${{ matrix.mode }}-assets-${{ github.head_ref || github.ref_name }}-${{ github.sha }}
@ -62,7 +63,7 @@ jobs:
- name: Archive asset artifacts
run: |
tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs*
tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs* tmp/cache/vite/last-build*.json
- uses: actions/upload-artifact@v4
if: matrix.mode == 'test'

View File

@ -18,10 +18,6 @@
!/log/.keep
/tmp
/coverage
/public/system
/public/assets
/public/packs
/public/packs-test
.env
.env.production
.env.development

View File

@ -307,6 +307,7 @@ RUN \
ldconfig; \
# Use Ruby on Rails to create Mastodon assets
SECRET_KEY_BASE_DUMMY=1 \
# Do not run `yarn` when precompiling assets, we already ran it before
bundle exec rails assets:precompile; \
# Cleanup temporary files
rm -fr /opt/mastodon/tmp;

View File

@ -1,5 +1,5 @@
import { ExpirationPlugin } from 'workbox-expiration';
import { precacheAndRoute } from 'workbox-precaching';
// import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
@ -15,7 +15,7 @@ function fetchRoot() {
return fetch('/', { credentials: 'include', redirect: 'manual' });
}
precacheAndRoute(self.__WB_MANIFEST);
// precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
/intl\/.*\.js$/,

View File

@ -393,7 +393,7 @@ code {
max-width: 100%;
height: auto;
border-radius: var(--avatar-border-radius);
background: url('images/void.png');
background: url('@/images/void.png');
&[src$='missing.png'] {
visibility: hidden;

27
bin/vite Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'vite' is installed as part of a gem, and
# this file is here to facilitate running it.
#
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
bundle_binstub = File.expand_path("bundle", __dir__)
if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end
require "rubygems"
require "bundler/setup"
load Gem.bin_path("vite_ruby", "vite")

View File

@ -52,6 +52,7 @@ require_relative '../lib/stoplight/redis_data_store_extensions'
require_relative '../lib/active_record/database_tasks_extensions'
require_relative '../lib/active_record/batches'
require_relative '../lib/simple_navigation/item_extensions'
require_relative '../lib/vite_ruby/sri_extensions'
Bundler.require(:pam_authentication) if ENV['PAM_ENABLED'] == 'true'

View File

@ -15,12 +15,7 @@ module PremailerBundledAssetStrategy
headers
).presence
else
# Read the file from filesystem
vite_path = ViteRuby.instance.manifest.path_for(url)
return unless vite_path
path = Rails.public_path.join(vite_path.delete_prefix('/'))
path = Rails.public_path.join(url.delete_prefix('/'))
return unless path.exist?
path.read

View File

@ -17,3 +17,6 @@ if Rake::Task.task_defined?('assets:precompile')
Rake::Task['assets:generate_static_pages'].invoke
end
end
# We don't want vite_ruby to run yarn, we do that in a separate step
Rake::Task['vite:install_dependencies'].clear

View File

@ -0,0 +1,99 @@
# frozen_string_literal: true
module ViteRuby::ManifestIntegrityExtension
def path_and_integrity_for(name, **)
entry = lookup!(name, **)
{ path: entry.fetch('file'), integrity: entry.fetch('integrity', nil) }
end
# Find a manifest entry by the *final* file name
def integrity_hash_for_file(file_name)
@integrity_cache ||= {}
@integrity_cache[file_name] ||= begin
entry = manifest.find { |_key, entry| entry['file'] == file_name }
entry[1].fetch('integrity', nil) if entry
end
end
def resolve_entries_with_integrity(*names, **options)
entries = names.map { |name| lookup!(name, **options) }
script_paths = entries.map do |entry|
{
file: entry.fetch('file'),
integrity: entry.fetch('integrity'),
}
end
imports = dev_server_running? ? [] : entries.flat_map { |entry| entry['imports'] }.compact
{
scripts: script_paths,
imports: imports.filter_map { |entry| { file: entry.fetch('file'), integrity: entry.fetch('integrity') } }.uniq,
stylesheets: dev_server_running? ? [] : (entries + imports).flat_map { |entry| entry['css'] }.compact.uniq,
}
end
end
ViteRuby::Manifest.prepend ViteRuby::ManifestIntegrityExtension
module ViteRails::TagHelpers::IntegrityExtension
def vite_javascript_tag(*names,
type: 'module',
asset_type: :javascript,
skip_preload_tags: false,
skip_style_tags: false,
crossorigin: 'anonymous',
media: 'screen',
**options)
entries = vite_manifest.resolve_entries_with_integrity(*names, type: asset_type)
''.html_safe.tap do |tags|
entries.fetch(:scripts).each do |script|
tags << javascript_include_tag(
script[:file],
integrity: script[:integrity],
crossorigin: crossorigin,
type: type,
extname: false,
**options
)
end
unless skip_preload_tags
entries.fetch(:imports).each do |import|
tags << vite_preload_tag(import[:file], integrity: import[:integrity], crossorigin: crossorigin, **options)
end
end
options[:extname] = false if Rails::VERSION::MAJOR >= 7
unless skip_style_tags
entries.fetch(:stylesheets).each do |stylesheet|
# This is for stylesheets imported from Javascript. The entry for the JS entrypoint only contains the final CSS file name, so we need to look it up in the manifest
tags << stylesheet_link_tag(
stylesheet,
integrity: vite_manifest.integrity_hash_for_file(stylesheet),
media: media,
**options
)
end
end
end
end
def vite_stylesheet_tag(*names, **options)
''.html_safe.tap do |tags|
names.each do |name|
entry = vite_manifest.path_and_integrity_for(name, type: :stylesheet)
options[:extname] = false if Rails::VERSION::MAJOR >= 7
tags << stylesheet_link_tag(entry[:path], integrity: entry[:integrity], **options)
end
end
end
end
ViteRails::TagHelpers.prepend ViteRails::TagHelpers::IntegrityExtension

View File

@ -47,9 +47,13 @@
"@react-spring/web": "^9.7.5",
"@reduxjs/toolkit": "^2.0.1",
"@use-gesture/react": "^10.3.1",
"@vitejs/plugin-react": "^4.2.1",
"arrow-key-navigation": "^1.2.0",
"async-mutex": "^0.5.0",
"axios": "^1.4.0",
"babel-plugin-formatjs": "^10.5.37",
"babel-plugin-preval": "^5.1.0",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"blurhash": "^2.0.5",
"classnames": "^2.3.2",
"color-blend": "^4.0.0",
@ -105,9 +109,10 @@
"vite": "^6.3.0",
"vite-bundle-analyzer": "^0.18.1",
"vite-plugin-pwa": "^1.0.0",
"vite-plugin-rails": "^0.5.0",
"vite-plugin-svgr": "^4.3.0",
"wicg-inert": "^3.1.2",
"workbox-expiration": "^7.0.0",
"workbox-precaching": "^7.0.0",
"workbox-routing": "^7.0.0",
"workbox-strategies": "^7.0.0",
"workbox-window": "^7.0.0"
@ -116,14 +121,12 @@
"@eslint/js": "^9.23.0",
"@formatjs/cli": "^6.1.1",
"@testing-library/dom": "^10.2.0",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^16.0.0",
"@types/emoji-mart": "3.0.14",
"@types/escape-html": "^1.0.2",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/http-link-header": "^1.0.3",
"@types/intl": "^1.2.0",
"@types/jest": "^29.5.14",
"@types/js-yaml": "^4.0.5",
"@types/lodash": "^4.14.195",
"@types/object-assign": "^4.0.30",
@ -142,7 +145,6 @@
"@types/react-toggle": "^4.0.3",
"@types/redux-immutable": "^4.0.3",
"@types/requestidlecallback": "^0.3.5",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^9.23.0",
"eslint-import-resolver-typescript": "^4.2.5",
"eslint-plugin-formatjs": "^5.3.1",
@ -160,11 +162,8 @@
"stylelint": "^16.11.0",
"stylelint-config-prettier-scss": "^1.0.0",
"stylelint-config-standard-scss": "^14.0.0",
"ts-jest": "^29.3.2",
"typescript": "~5.7.3",
"typescript-eslint": "^8.29.1",
"vite-plugin-rails": "^0.5.0",
"vite-plugin-svgr": "^4.3.0",
"vitest": "^3.1.2"
},
"resolutions": {

View File

@ -17,7 +17,7 @@ RSpec.describe ThemeHelper do
)
expect(html_links.last.attributes.symbolize_keys)
.to include(
href: have_attributes(value: match(/default/)),
href: have_attributes(value: match(/application/)),
media: have_attributes(value: '(prefers-color-scheme: dark)')
)
end

View File

@ -1,5 +1,3 @@
/// <reference types="vitest/config" />
import fs from 'node:fs/promises';
import path from 'node:path';
@ -11,12 +9,7 @@ import { analyzer } from 'vite-bundle-analyzer';
import RailsPlugin from 'vite-plugin-rails';
import { VitePWA } from 'vite-plugin-pwa';
import {
configDefaults,
defineConfig,
ViteUserConfig,
UserConfigFnPromise,
} from 'vitest/config';
import { defineConfig, UserConfigFnPromise, UserConfig } from 'vite';
import postcssPresetEnv from 'postcss-preset-env';
import { MastodonServiceWorkerLocales } from './config/vite/plugin-sw-locales';
@ -24,7 +17,7 @@ import { MastodonServiceWorkerLocales } from './config/vite/plugin-sw-locales';
const jsRoot = path.resolve(__dirname, 'app/javascript');
const entrypointRoot = path.resolve(jsRoot, 'entrypoints');
const config: UserConfigFnPromise = async ({ mode, command }) => {
export const config: UserConfigFnPromise = async ({ mode, command }) => {
const entrypointFiles = await fs.readdir(entrypointRoot);
const entrypoints: Record<string, string> = entrypointFiles.reduce(
(acc, file) => {
@ -66,6 +59,7 @@ const config: UserConfigFnPromise = async ({ mode, command }) => {
},
build: {
commonjsOptions: { transformMixedEsModules: true },
chunkSizeWarningLimit: 1 * 1024 * 1024, // 1MB
manifest: 'manifest.json',
sourcemap: true,
rollupOptions: {
@ -112,33 +106,29 @@ const config: UserConfigFnPromise = async ({ mode, command }) => {
RailsPlugin({
compress: mode !== 'production' && command === 'build',
}),
react(),
react({
babel: {
plugins: ['formatjs', 'transform-react-remove-prop-types'],
},
}),
MastodonServiceWorkerLocales(),
VitePWA({
srcDir: 'mastodon/service_worker',
// We need to use injectManifest because we use our own service worker
strategies: 'injectManifest',
// Force output in the prod directory so the symlink works.
outDir: path.resolve(__dirname, 'public/packs'),
manifest: false,
injectRegister: null,
injectRegister: false,
injectManifest: {
// Do not inject a manifest, we dont use precache
injectionPoint: undefined,
buildPlugins: {
vite: [
// Provide a virtual import with only the locales used in the ServiceWorker
MastodonServiceWorkerLocales(),
],
},
// Because we move the output dir, we need to scan for assets in the original output directory.
globDirectory: env.VITE_RUBY_PUBLIC_OUTPUT_DIR ?? 'public',
globIgnores: [
// Do not preload those files
'intl/*.js',
'extra_polyfills-*.js',
'polyfill-force-*.js',
'assets/mailer-*.{js,css}',
'**/*tesseract*',
],
maximumFileSizeToCacheInBytes: 2 * 1_024 * 1_024, // 2 MiB
// Force the output location, because we have a symlink in `public/sw.js`
swDest: path.resolve(__dirname, 'public/packs/sw.js'),
},
devOptions: {
enabled: true,
@ -151,24 +141,7 @@ const config: UserConfigFnPromise = async ({ mode, command }) => {
optimizeLodashImports() as PluginOption,
!!process.env.ANALYZE_BUNDLE_SIZE && analyzer({ analyzerMode: 'static' }),
],
test: {
environment: 'jsdom',
include: [
...configDefaults.include,
'**/__tests__/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
],
exclude: [
...configDefaults.exclude,
'**/node_modules/**',
'vendor/**',
'config/**',
'log/**',
'public/**',
'tmp/**',
],
globals: true,
},
} satisfies ViteUserConfig;
} satisfies UserConfig;
};
export default defineConfig(config);

26
vitest.config.mts Normal file
View File

@ -0,0 +1,26 @@
import { configDefaults, defineConfig } from 'vitest/config';
import { config as viteConfig } from './vite.config.mjs';
export default defineConfig(async (context) => {
return {
...(await viteConfig(context)),
test: {
environment: 'jsdom',
include: [
...configDefaults.include,
'**/__tests__/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
],
exclude: [
...configDefaults.exclude,
'**/node_modules/**',
'vendor/**',
'config/**',
'log/**',
'public/**',
'tmp/**',
],
globals: true,
},
};
});

456
yarn.lock
View File

@ -12,13 +12,6 @@ __metadata:
languageName: node
linkType: hard
"@adobe/css-tools@npm:^4.4.0":
version: 4.4.0
resolution: "@adobe/css-tools@npm:4.4.0"
checksum: 10c0/d65ddc719389bf469097df80fb16a8af48a973dea4b57565789d70ac8e7ab4987e6dc0095da3ed5dc16c1b6f8960214a7590312eeda8abd543d91fd0f59e6c94
languageName: node
linkType: hard
"@ampproject/remapping@npm:^2.2.0":
version: 2.2.1
resolution: "@ampproject/remapping@npm:2.2.1"
@ -55,7 +48,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.26.2":
"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.26.2":
version: 7.26.2
resolution: "@babel/code-frame@npm:7.26.2"
dependencies:
@ -73,7 +66,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/core@npm:^7.21.3, @babel/core@npm:^7.23.5, @babel/core@npm:^7.24.4":
"@babel/core@npm:^7.21.3, @babel/core@npm:^7.23.5, @babel/core@npm:^7.24.4, @babel/core@npm:^7.26.10":
version: 7.26.10
resolution: "@babel/core@npm:7.26.10"
dependencies:
@ -404,6 +397,17 @@ __metadata:
languageName: node
linkType: hard
"@babel/plugin-syntax-jsx@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/plugin-syntax-jsx@npm:7.25.9"
dependencies:
"@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 10c0/d56597aff4df39d3decda50193b6dfbe596ca53f437ff2934622ce19a743bf7f43492d3fb3308b0289f5cee2b825d99ceb56526a2b9e7b68bf04901546c5618c
languageName: node
linkType: hard
"@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6":
version: 7.18.6
resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6"
@ -2380,38 +2384,6 @@ __metadata:
languageName: node
linkType: hard
"@jest/expect-utils@npm:^29.7.0":
version: 29.7.0
resolution: "@jest/expect-utils@npm:29.7.0"
dependencies:
jest-get-type: "npm:^29.6.3"
checksum: 10c0/60b79d23a5358dc50d9510d726443316253ecda3a7fb8072e1526b3e0d3b14f066ee112db95699b7a43ad3f0b61b750c72e28a5a1cac361d7a2bb34747fa938a
languageName: node
linkType: hard
"@jest/schemas@npm:^29.6.3":
version: 29.6.3
resolution: "@jest/schemas@npm:29.6.3"
dependencies:
"@sinclair/typebox": "npm:^0.27.8"
checksum: 10c0/b329e89cd5f20b9278ae1233df74016ebf7b385e0d14b9f4c1ad18d096c4c19d1e687aa113a9c976b16ec07f021ae53dea811fb8c1248a50ac34fbe009fdf6be
languageName: node
linkType: hard
"@jest/types@npm:^29.6.3":
version: 29.6.3
resolution: "@jest/types@npm:29.6.3"
dependencies:
"@jest/schemas": "npm:^29.6.3"
"@types/istanbul-lib-coverage": "npm:^2.0.0"
"@types/istanbul-reports": "npm:^3.0.0"
"@types/node": "npm:*"
"@types/yargs": "npm:^17.0.8"
chalk: "npm:^4.0.0"
checksum: 10c0/ea4e493dd3fb47933b8ccab201ae573dcc451f951dc44ed2a86123cd8541b82aa9d2b1031caf9b1080d6673c517e2dcc25a44b2dc4f3fbc37bfc965d444888c0
languageName: node
linkType: hard
"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.5":
version: 0.3.5
resolution: "@jridgewell/gen-mapping@npm:0.3.5"
@ -2482,14 +2454,12 @@ __metadata:
"@react-spring/web": "npm:^9.7.5"
"@reduxjs/toolkit": "npm:^2.0.1"
"@testing-library/dom": "npm:^10.2.0"
"@testing-library/jest-dom": "npm:^6.0.0"
"@testing-library/react": "npm:^16.0.0"
"@types/emoji-mart": "npm:3.0.14"
"@types/escape-html": "npm:^1.0.2"
"@types/hoist-non-react-statics": "npm:^3.3.1"
"@types/http-link-header": "npm:^1.0.3"
"@types/intl": "npm:^1.2.0"
"@types/jest": "npm:^29.5.14"
"@types/js-yaml": "npm:^4.0.5"
"@types/lodash": "npm:^4.14.195"
"@types/object-assign": "npm:^4.0.30"
@ -2513,6 +2483,9 @@ __metadata:
arrow-key-navigation: "npm:^1.2.0"
async-mutex: "npm:^0.5.0"
axios: "npm:^1.4.0"
babel-plugin-formatjs: "npm:^10.5.37"
babel-plugin-preval: "npm:^5.1.0"
babel-plugin-transform-react-remove-prop-types: "npm:^0.4.24"
blurhash: "npm:^2.0.5"
classnames: "npm:^2.3.2"
color-blend: "npm:^4.0.0"
@ -2580,7 +2553,6 @@ __metadata:
substring-trie: "npm:^1.0.2"
tesseract.js: "npm:^6.0.0"
tiny-queue: "npm:^0.2.1"
ts-jest: "npm:^29.3.2"
twitter-text: "npm:3.1.0"
typescript: "npm:~5.7.3"
typescript-eslint: "npm:^8.29.1"
@ -2593,7 +2565,6 @@ __metadata:
vitest: "npm:^3.1.2"
wicg-inert: "npm:^3.1.2"
workbox-expiration: "npm:^7.0.0"
workbox-precaching: "npm:^7.0.0"
workbox-routing: "npm:^7.0.0"
workbox-strategies: "npm:^7.0.0"
workbox-window: "npm:^7.0.0"
@ -3240,13 +3211,6 @@ __metadata:
languageName: node
linkType: hard
"@sinclair/typebox@npm:^0.27.8":
version: 0.27.8
resolution: "@sinclair/typebox@npm:0.27.8"
checksum: 10c0/ef6351ae073c45c2ac89494dbb3e1f87cc60a93ce4cde797b782812b6f97da0d620ae81973f104b43c9b7eaa789ad20ba4f6a1359f1cc62f63729a55a7d22d4e
languageName: node
linkType: hard
"@surma/rollup-plugin-off-main-thread@npm:^2.2.3":
version: 2.2.3
resolution: "@surma/rollup-plugin-off-main-thread@npm:2.2.3"
@ -3402,21 +3366,6 @@ __metadata:
languageName: node
linkType: hard
"@testing-library/jest-dom@npm:^6.0.0":
version: 6.6.3
resolution: "@testing-library/jest-dom@npm:6.6.3"
dependencies:
"@adobe/css-tools": "npm:^4.4.0"
aria-query: "npm:^5.0.0"
chalk: "npm:^3.0.0"
css.escape: "npm:^1.5.1"
dom-accessibility-api: "npm:^0.6.3"
lodash: "npm:^4.17.21"
redent: "npm:^3.0.0"
checksum: 10c0/5566b6c0b7b0709bc244aec3aa3dc9e5f4663e8fb2b99d8cd456fc07279e59db6076cbf798f9d3099a98fca7ef4cd50e4e1f4c4dec5a60a8fad8d24a638a5bf6
languageName: node
linkType: hard
"@testing-library/react@npm:^16.0.0":
version: 16.1.0
resolution: "@testing-library/react@npm:16.1.0"
@ -3453,7 +3402,7 @@ __metadata:
languageName: node
linkType: hard
"@types/babel__core@npm:^7.20.5":
"@types/babel__core@npm:*, @types/babel__core@npm:^7.1.12, @types/babel__core@npm:^7.20.5":
version: 7.20.5
resolution: "@types/babel__core@npm:7.20.5"
dependencies:
@ -3475,6 +3424,15 @@ __metadata:
languageName: node
linkType: hard
"@types/babel__helper-plugin-utils@npm:^7.10.3":
version: 7.10.3
resolution: "@types/babel__helper-plugin-utils@npm:7.10.3"
dependencies:
"@types/babel__core": "npm:*"
checksum: 10c0/c22f68e8019c1e75e42fccc6eaca94a269fa177c4544599aa084b216b879b626f63f89755a4ac2dc9054b6e9ed4e0fab1e3460d36ce20767c99aef4a3c81fce3
languageName: node
linkType: hard
"@types/babel__template@npm:*":
version: 7.4.3
resolution: "@types/babel__template@npm:7.4.3"
@ -3494,6 +3452,15 @@ __metadata:
languageName: node
linkType: hard
"@types/babel__traverse@npm:^7.20.6":
version: 7.20.7
resolution: "@types/babel__traverse@npm:7.20.7"
dependencies:
"@babel/types": "npm:^7.20.7"
checksum: 10c0/5386f0af44f8746b063b87418f06129a814e16bb2686965a575e9d7376b360b088b89177778d8c426012abc43dd1a2d8ec3218bfc382280c898682746ce2ffbd
languageName: node
linkType: hard
"@types/body-parser@npm:*":
version: 1.19.5
resolution: "@types/body-parser@npm:1.19.5"
@ -3626,41 +3593,6 @@ __metadata:
languageName: node
linkType: hard
"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0":
version: 2.0.5
resolution: "@types/istanbul-lib-coverage@npm:2.0.5"
checksum: 10c0/e15cfc01a7ac60062f771314c959011bae7de7ceaef8e294f13427a11f21741cbfac98ad8cd9ecbf0e3d72ab7ddc327bacb3fab32c6b26ab19dbbbc1a69a9d3b
languageName: node
linkType: hard
"@types/istanbul-lib-report@npm:*":
version: 3.0.2
resolution: "@types/istanbul-lib-report@npm:3.0.2"
dependencies:
"@types/istanbul-lib-coverage": "npm:*"
checksum: 10c0/c168e425c95c167d83c7cbd65ff6b620cc53c5ef199a58428758586bbc28faf5c51291667e4455777b47ada12381e53fce7b92e32f431f85d8ac8025074d1908
languageName: node
linkType: hard
"@types/istanbul-reports@npm:^3.0.0":
version: 3.0.3
resolution: "@types/istanbul-reports@npm:3.0.3"
dependencies:
"@types/istanbul-lib-report": "npm:*"
checksum: 10c0/dcd8291370d9192aa980bf849309a7ca27e1d030ccc5e7edeef47d6612c2d57d611855543b9ffeb982d162a5ab2a44d8b40baa4dc93c1d7aa6fbcaeb16e69e78
languageName: node
linkType: hard
"@types/jest@npm:^29.5.14":
version: 29.5.14
resolution: "@types/jest@npm:29.5.14"
dependencies:
expect: "npm:^29.0.0"
pretty-format: "npm:^29.0.0"
checksum: 10c0/18e0712d818890db8a8dab3d91e9ea9f7f19e3f83c2e50b312f557017dc81466207a71f3ed79cf4428e813ba939954fa26ffa0a9a7f153181ba174581b1c2aed
languageName: node
linkType: hard
"@types/js-yaml@npm:^4.0.5":
version: 4.0.9
resolution: "@types/js-yaml@npm:4.0.9"
@ -3935,13 +3867,6 @@ __metadata:
languageName: node
linkType: hard
"@types/stack-utils@npm:^2.0.0":
version: 2.0.2
resolution: "@types/stack-utils@npm:2.0.2"
checksum: 10c0/c2bf0de59ee0a1e2b2031e8a6225f412976377868c42a66537e284a020e9eb4068ed9b9da69d14c1727ab56e605532e877777c7d1bbfd3e9a42ae17bcef7d213
languageName: node
linkType: hard
"@types/trusted-types@npm:^2.0.2":
version: 2.0.3
resolution: "@types/trusted-types@npm:2.0.3"
@ -3979,22 +3904,6 @@ __metadata:
languageName: node
linkType: hard
"@types/yargs-parser@npm:*":
version: 21.0.2
resolution: "@types/yargs-parser@npm:21.0.2"
checksum: 10c0/422b8c59e21d9594e5a94afa45a3692d96c14f8fc7554bb1c1c390276815f09996ce0f8ed11893b6f8b2efc4ced686231dca5be6d76a4c4ceb56534474e95aca
languageName: node
linkType: hard
"@types/yargs@npm:^17.0.8":
version: 17.0.32
resolution: "@types/yargs@npm:17.0.32"
dependencies:
"@types/yargs-parser": "npm:*"
checksum: 10c0/2095e8aad8a4e66b86147415364266b8d607a3b95b4239623423efd7e29df93ba81bb862784a6e08664f645cc1981b25fd598f532019174cd3e5e1e689e1cccf
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:8.29.1":
version: 8.29.1
resolution: "@typescript-eslint/eslint-plugin@npm:8.29.1"
@ -4473,7 +4382,7 @@ __metadata:
languageName: node
linkType: hard
"aria-query@npm:^5.0.0, aria-query@npm:^5.3.2":
"aria-query@npm:^5.3.2":
version: 5.3.2
resolution: "aria-query@npm:5.3.2"
checksum: 10c0/003c7e3e2cff5540bf7a7893775fc614de82b0c5dde8ae823d47b7a28a9d4da1f7ed85f340bdb93d5649caa927755f0e31ecc7ab63edfdfc00c8ef07e505e03e
@ -4715,7 +4624,26 @@ __metadata:
languageName: node
linkType: hard
"babel-plugin-macros@npm:^3.1.0":
"babel-plugin-formatjs@npm:^10.5.37":
version: 10.5.37
resolution: "babel-plugin-formatjs@npm:10.5.37"
dependencies:
"@babel/core": "npm:^7.26.10"
"@babel/helper-plugin-utils": "npm:^7.26.5"
"@babel/plugin-syntax-jsx": "npm:^7.25.9"
"@babel/traverse": "npm:^7.26.10"
"@babel/types": "npm:^7.26.10"
"@formatjs/icu-messageformat-parser": "npm:2.11.2"
"@formatjs/ts-transformer": "npm:3.13.34"
"@types/babel__core": "npm:^7.20.5"
"@types/babel__helper-plugin-utils": "npm:^7.10.3"
"@types/babel__traverse": "npm:^7.20.6"
tslib: "npm:^2.8.0"
checksum: 10c0/e206ff1a8ad3cbcb3db2d2735d8821701df9d54c8aeb5e8b2861c945af91d4662b9cd37b1ff9d7e17954cdd31aec81788a3d044a1cd9f3e7e8e4f93177097b83
languageName: node
linkType: hard
"babel-plugin-macros@npm:^3.0.1, babel-plugin-macros@npm:^3.1.0":
version: 3.1.0
resolution: "babel-plugin-macros@npm:3.1.0"
dependencies:
@ -4762,6 +4690,25 @@ __metadata:
languageName: node
linkType: hard
"babel-plugin-preval@npm:^5.1.0":
version: 5.1.0
resolution: "babel-plugin-preval@npm:5.1.0"
dependencies:
"@babel/runtime": "npm:^7.12.5"
"@types/babel__core": "npm:^7.1.12"
babel-plugin-macros: "npm:^3.0.1"
require-from-string: "npm:^2.0.2"
checksum: 10c0/d40814ca18f24df818a87e71ad8c1dc559cf69c0e44218bb9f5aef24680431a04e4bad8e96dc2679282b50b16a55c9597e37130d6bd5489b3eddab97d020ae5e
languageName: node
linkType: hard
"babel-plugin-transform-react-remove-prop-types@npm:^0.4.24":
version: 0.4.24
resolution: "babel-plugin-transform-react-remove-prop-types@npm:0.4.24"
checksum: 10c0/713441fd9fb663cc95709cb52d9c2c6228ea6d5406092a8a50094c810bcb13c3c347f8fca703d45b20cc401782743a91d7272025950147f9247d53360267f107
languageName: node
linkType: hard
"balanced-match@npm:^1.0.0":
version: 1.0.2
resolution: "balanced-match@npm:1.0.2"
@ -4859,15 +4806,6 @@ __metadata:
languageName: node
linkType: hard
"bs-logger@npm:^0.2.6":
version: 0.2.6
resolution: "bs-logger@npm:0.2.6"
dependencies:
fast-json-stable-stringify: "npm:2.x"
checksum: 10c0/80e89aaaed4b68e3374ce936f2eb097456a0dddbf11f75238dbd53140b1e39259f0d248a5089ed456f1158984f22191c3658d54a713982f676709fbe1a6fa5a0
languageName: node
linkType: hard
"buffer-from@npm:^1.0.0":
version: 1.1.2
resolution: "buffer-from@npm:1.1.2"
@ -4985,16 +4923,6 @@ __metadata:
languageName: node
linkType: hard
"chalk@npm:^3.0.0":
version: 3.0.0
resolution: "chalk@npm:3.0.0"
dependencies:
ansi-styles: "npm:^4.1.0"
supports-color: "npm:^7.1.0"
checksum: 10c0/ee650b0a065b3d7a6fda258e75d3a86fc8e4effa55871da730a9e42ccb035bf5fd203525e5a1ef45ec2582ecc4f65b47eb11357c526b84dd29a14fb162c414d2
languageName: node
linkType: hard
"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.2":
version: 4.1.2
resolution: "chalk@npm:4.1.2"
@ -5042,13 +4970,6 @@ __metadata:
languageName: node
linkType: hard
"ci-info@npm:^3.2.0":
version: 3.9.0
resolution: "ci-info@npm:3.9.0"
checksum: 10c0/6f0109e36e111684291d46123d491bc4e7b7a1934c3a20dea28cba89f1d4a03acd892f5f6a81ed3855c38647e285a150e3c9ba062e38943bef57fee6c1554c3a
languageName: node
linkType: hard
"classnames@npm:^2.2.5, classnames@npm:^2.3.2":
version: 2.5.1
resolution: "classnames@npm:2.5.1"
@ -5374,13 +5295,6 @@ __metadata:
languageName: node
linkType: hard
"css.escape@npm:^1.5.1":
version: 1.5.1
resolution: "css.escape@npm:1.5.1"
checksum: 10c0/5e09035e5bf6c2c422b40c6df2eb1529657a17df37fda5d0433d722609527ab98090baf25b13970ca754079a0f3161dd3dfc0e743563ded8cfa0749d861c1525
languageName: node
linkType: hard
"cssdb@npm:^8.2.3":
version: 8.2.3
resolution: "cssdb@npm:8.2.3"
@ -5611,13 +5525,6 @@ __metadata:
languageName: node
linkType: hard
"diff-sequences@npm:^29.6.3":
version: 29.6.3
resolution: "diff-sequences@npm:29.6.3"
checksum: 10c0/32e27ac7dbffdf2fb0eb5a84efd98a9ad084fbabd5ac9abb8757c6770d5320d2acd172830b28c4add29bb873d59420601dfc805ac4064330ce59b1adfd0593b2
languageName: node
linkType: hard
"dir-glob@npm:^3.0.1":
version: 3.0.1
resolution: "dir-glob@npm:3.0.1"
@ -5643,13 +5550,6 @@ __metadata:
languageName: node
linkType: hard
"dom-accessibility-api@npm:^0.6.3":
version: 0.6.3
resolution: "dom-accessibility-api@npm:0.6.3"
checksum: 10c0/10bee5aa514b2a9a37c87cd81268db607a2e933a050074abc2f6fa3da9080ebed206a320cbc123567f2c3087d22292853bdfdceaffdd4334ffe2af9510b29360
languageName: node
linkType: hard
"dom-helpers@npm:^3.4.0":
version: 3.4.0
resolution: "dom-helpers@npm:3.4.0"
@ -5711,7 +5611,7 @@ __metadata:
languageName: node
linkType: hard
"ejs@npm:^3.1.10, ejs@npm:^3.1.6":
"ejs@npm:^3.1.6":
version: 3.1.10
resolution: "ejs@npm:3.1.10"
dependencies:
@ -6086,13 +5986,6 @@ __metadata:
languageName: node
linkType: hard
"escape-string-regexp@npm:^2.0.0":
version: 2.0.0
resolution: "escape-string-regexp@npm:2.0.0"
checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507
languageName: node
linkType: hard
"escape-string-regexp@npm:^4.0.0":
version: 4.0.0
resolution: "escape-string-regexp@npm:4.0.0"
@ -6466,19 +6359,6 @@ __metadata:
languageName: node
linkType: hard
"expect@npm:^29.0.0":
version: 29.7.0
resolution: "expect@npm:29.7.0"
dependencies:
"@jest/expect-utils": "npm:^29.7.0"
jest-get-type: "npm:^29.6.3"
jest-matcher-utils: "npm:^29.7.0"
jest-message-util: "npm:^29.7.0"
jest-util: "npm:^29.7.0"
checksum: 10c0/2eddeace66e68b8d8ee5f7be57f3014b19770caaf6815c7a08d131821da527fb8c8cb7b3dcd7c883d2d3d8d184206a4268984618032d1e4b16dc8d6596475d41
languageName: node
linkType: hard
"exponential-backoff@npm:^3.1.1":
version: 3.1.1
resolution: "exponential-backoff@npm:3.1.1"
@ -6552,7 +6432,7 @@ __metadata:
languageName: node
linkType: hard
"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0":
"fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0":
version: 2.1.0
resolution: "fast-json-stable-stringify@npm:2.1.0"
checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b
@ -7072,7 +6952,7 @@ __metadata:
languageName: node
linkType: hard
"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6":
version: 4.2.11
resolution: "graceful-fs@npm:4.2.11"
checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2
@ -7833,68 +7713,6 @@ __metadata:
languageName: node
linkType: hard
"jest-diff@npm:^29.7.0":
version: 29.7.0
resolution: "jest-diff@npm:29.7.0"
dependencies:
chalk: "npm:^4.0.0"
diff-sequences: "npm:^29.6.3"
jest-get-type: "npm:^29.6.3"
pretty-format: "npm:^29.7.0"
checksum: 10c0/89a4a7f182590f56f526443dde69acefb1f2f0c9e59253c61d319569856c4931eae66b8a3790c443f529267a0ddba5ba80431c585deed81827032b2b2a1fc999
languageName: node
linkType: hard
"jest-get-type@npm:^29.6.3":
version: 29.6.3
resolution: "jest-get-type@npm:29.6.3"
checksum: 10c0/552e7a97a983d3c2d4e412a44eb7de0430ff773dd99f7500962c268d6dfbfa431d7d08f919c9d960530e5f7f78eb47f267ad9b318265e5092b3ff9ede0db7c2b
languageName: node
linkType: hard
"jest-matcher-utils@npm:^29.7.0":
version: 29.7.0
resolution: "jest-matcher-utils@npm:29.7.0"
dependencies:
chalk: "npm:^4.0.0"
jest-diff: "npm:^29.7.0"
jest-get-type: "npm:^29.6.3"
pretty-format: "npm:^29.7.0"
checksum: 10c0/0d0e70b28fa5c7d4dce701dc1f46ae0922102aadc24ed45d594dd9b7ae0a8a6ef8b216718d1ab79e451291217e05d4d49a82666e1a3cc2b428b75cd9c933244e
languageName: node
linkType: hard
"jest-message-util@npm:^29.7.0":
version: 29.7.0
resolution: "jest-message-util@npm:29.7.0"
dependencies:
"@babel/code-frame": "npm:^7.12.13"
"@jest/types": "npm:^29.6.3"
"@types/stack-utils": "npm:^2.0.0"
chalk: "npm:^4.0.0"
graceful-fs: "npm:^4.2.9"
micromatch: "npm:^4.0.4"
pretty-format: "npm:^29.7.0"
slash: "npm:^3.0.0"
stack-utils: "npm:^2.0.3"
checksum: 10c0/850ae35477f59f3e6f27efac5215f706296e2104af39232bb14e5403e067992afb5c015e87a9243ec4d9df38525ef1ca663af9f2f4766aa116f127247008bd22
languageName: node
linkType: hard
"jest-util@npm:^29.0.0, jest-util@npm:^29.7.0":
version: 29.7.0
resolution: "jest-util@npm:29.7.0"
dependencies:
"@jest/types": "npm:^29.6.3"
"@types/node": "npm:*"
chalk: "npm:^4.0.0"
ci-info: "npm:^3.2.0"
graceful-fs: "npm:^4.2.9"
picomatch: "npm:^2.2.3"
checksum: 10c0/bc55a8f49fdbb8f51baf31d2a4f312fb66c9db1483b82f602c9c990e659cdd7ec529c8e916d5a89452ecbcfae4949b21b40a7a59d4ffc0cd813a973ab08c8150
languageName: node
linkType: hard
"joycon@npm:^3.1.1":
version: 3.1.1
resolution: "joycon@npm:3.1.1"
@ -8254,13 +8072,6 @@ __metadata:
languageName: node
linkType: hard
"lodash.memoize@npm:^4.1.2":
version: 4.1.2
resolution: "lodash.memoize@npm:4.1.2"
checksum: 10c0/c8713e51eccc650422716a14cece1809cfe34bc5ab5e242b7f8b4e2241c2483697b971a604252807689b9dd69bfe3a98852e19a5b89d506b000b4187a1285df8
languageName: node
linkType: hard
"lodash.merge@npm:^4.6.2":
version: 4.6.2
resolution: "lodash.merge@npm:4.6.2"
@ -8379,13 +8190,6 @@ __metadata:
languageName: node
linkType: hard
"make-error@npm:^1.3.6":
version: 1.3.6
resolution: "make-error@npm:1.3.6"
checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f
languageName: node
linkType: hard
"make-fetch-happen@npm:^13.0.0":
version: 13.0.0
resolution: "make-fetch-happen@npm:13.0.0"
@ -8538,13 +8342,6 @@ __metadata:
languageName: node
linkType: hard
"min-indent@npm:^1.0.0":
version: 1.0.1
resolution: "min-indent@npm:1.0.1"
checksum: 10c0/7e207bd5c20401b292de291f02913230cb1163abca162044f7db1d951fa245b174dc00869d40dd9a9f32a885ad6a5f3e767ee104cf278f399cb4e92d3f582d5c
languageName: node
linkType: hard
"minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
@ -9280,7 +9077,7 @@ __metadata:
languageName: node
linkType: hard
"picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1":
"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1":
version: 2.3.1
resolution: "picomatch@npm:2.3.1"
checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be
@ -9906,17 +9703,6 @@ __metadata:
languageName: node
linkType: hard
"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0":
version: 29.7.0
resolution: "pretty-format@npm:29.7.0"
dependencies:
"@jest/schemas": "npm:^29.6.3"
ansi-styles: "npm:^5.0.0"
react-is: "npm:^18.0.0"
checksum: 10c0/edc5ff89f51916f036c62ed433506b55446ff739358de77207e63e88a28ca2894caac6e73dcb68166a606e51c8087d32d400473e6a9fdd2dbe743f46c9c0276f
languageName: node
linkType: hard
"proc-log@npm:^3.0.0":
version: 3.0.0
resolution: "proc-log@npm:3.0.0"
@ -10160,7 +9946,7 @@ __metadata:
languageName: node
linkType: hard
"react-is@npm:^16.12.0 || ^17.0.0 || ^18.0.0, react-is@npm:^18.0.0, react-is@npm:^18.3.1":
"react-is@npm:^16.12.0 || ^17.0.0 || ^18.0.0, react-is@npm:^18.3.1":
version: 18.3.1
resolution: "react-is@npm:18.3.1"
checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072
@ -10468,16 +10254,6 @@ __metadata:
languageName: node
linkType: hard
"redent@npm:^3.0.0":
version: 3.0.0
resolution: "redent@npm:3.0.0"
dependencies:
indent-string: "npm:^4.0.0"
strip-indent: "npm:^3.0.0"
checksum: 10c0/d64a6b5c0b50eb3ddce3ab770f866658a2b9998c678f797919ceb1b586bab9259b311407280bd80b804e2a7c7539b19238ae6a2a20c843f1a7fcff21d48c2eae
languageName: node
linkType: hard
"redis-errors@npm:^1.0.0, redis-errors@npm:^1.2.0":
version: 1.2.0
resolution: "redis-errors@npm:1.2.0"
@ -11387,15 +11163,6 @@ __metadata:
languageName: node
linkType: hard
"stack-utils@npm:^2.0.3":
version: 2.0.6
resolution: "stack-utils@npm:2.0.6"
dependencies:
escape-string-regexp: "npm:^2.0.0"
checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a
languageName: node
linkType: hard
"stackback@npm:0.0.2":
version: 0.0.2
resolution: "stackback@npm:0.0.2"
@ -11638,15 +11405,6 @@ __metadata:
languageName: node
linkType: hard
"strip-indent@npm:^3.0.0":
version: 3.0.0
resolution: "strip-indent@npm:3.0.0"
dependencies:
min-indent: "npm:^1.0.0"
checksum: 10c0/ae0deaf41c8d1001c5d4fbe16cb553865c1863da4fae036683b474fa926af9fc121e155cb3fc57a68262b2ae7d5b8420aa752c97a6428c315d00efe2a3875679
languageName: node
linkType: hard
"strip-json-comments@npm:^3.1.1":
version: 3.1.1
resolution: "strip-json-comments@npm:3.1.1"
@ -12108,44 +11866,6 @@ __metadata:
languageName: node
linkType: hard
"ts-jest@npm:^29.3.2":
version: 29.3.2
resolution: "ts-jest@npm:29.3.2"
dependencies:
bs-logger: "npm:^0.2.6"
ejs: "npm:^3.1.10"
fast-json-stable-stringify: "npm:^2.1.0"
jest-util: "npm:^29.0.0"
json5: "npm:^2.2.3"
lodash.memoize: "npm:^4.1.2"
make-error: "npm:^1.3.6"
semver: "npm:^7.7.1"
type-fest: "npm:^4.39.1"
yargs-parser: "npm:^21.1.1"
peerDependencies:
"@babel/core": ">=7.0.0-beta.0 <8"
"@jest/transform": ^29.0.0
"@jest/types": ^29.0.0
babel-jest: ^29.0.0
jest: ^29.0.0
typescript: ">=4.3 <6"
peerDependenciesMeta:
"@babel/core":
optional: true
"@jest/transform":
optional: true
"@jest/types":
optional: true
babel-jest:
optional: true
esbuild:
optional: true
bin:
ts-jest: cli.js
checksum: 10c0/84762720dbef45c1644348d67d0dcb8b7ad6369a16628c4752aceeb47f0ccdad63ae14485048b641c20ce096337a160ab816881361ef5517325bac6a5b3756e0
languageName: node
linkType: hard
"tsconfig-paths@npm:^3.15.0":
version: 3.15.0
resolution: "tsconfig-paths@npm:3.15.0"
@ -12200,13 +11920,6 @@ __metadata:
languageName: node
linkType: hard
"type-fest@npm:^4.39.1":
version: 4.39.1
resolution: "type-fest@npm:4.39.1"
checksum: 10c0/f5bf302eb2e2f70658be1757aa578f4a09da3f65699b0b12b7ae5502ccea76e5124521a6e6b69540f442c3dc924c394202a2ab58718d0582725c7ac23c072594
languageName: node
linkType: hard
"type-is@npm:~1.6.18":
version: 1.6.18
resolution: "type-is@npm:1.6.18"
@ -13178,7 +12891,7 @@ __metadata:
languageName: node
linkType: hard
"workbox-precaching@npm:7.3.0, workbox-precaching@npm:^7.0.0":
"workbox-precaching@npm:7.3.0":
version: 7.3.0
resolution: "workbox-precaching@npm:7.3.0"
dependencies:
@ -13373,13 +13086,6 @@ __metadata:
languageName: node
linkType: hard
"yargs-parser@npm:^21.1.1":
version: 21.1.1
resolution: "yargs-parser@npm:21.1.1"
checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2
languageName: node
linkType: hard
"yocto-queue@npm:^0.1.0":
version: 0.1.0
resolution: "yocto-queue@npm:0.1.0"