diff --git a/package.json b/package.json index 1061bfa0..07fe6afe 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "cosmiconfig": "^10.0.1", "dotenv": "^18.0.9", "form-data": "^4.0.6", - "glob": "^13.0.6", + "glob": "^14.0.2", "react": "^19.3.1", "react-dom": "^19.3.1", "zod": "^4.6.7" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95668bbf..4a73d6c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,8 +38,8 @@ importers: specifier: ^4.0.6 version: 4.0.6 glob: - specifier: ^13.0.6 - version: 13.0.6 + specifier: ^14.0.2 + version: 14.0.2 react: specifier: ^19.3.1 version: 19.3.1 @@ -2143,6 +2143,9 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/nonrecursive-glob-match@1.0.3': + resolution: {integrity: sha512-SI7kyKHq4XXDRozw+r9GlRZkia1ZkFrpLW98r2IC2Bpr8YkFGE3fvjzmxCG0x78A++69HmDNrDvSMYBZmHGpKA==} + '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4969,6 +4972,10 @@ packages: resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} engines: {node: 18 || 20 || >=22} + glob@14.0.2: + resolution: {integrity: sha512-vfMgTR2djMHPUchsJMLpZlYQvtjVL+mHpEr5wPpoCbQs2vr/FBNK+3Gnl9Ara1DSs4Aeg4eG9HiADb5/rkY/ZA==} + engines: {node: 18 || 20 || >=22} + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me @@ -5979,6 +5986,10 @@ packages: resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} + minimatch@11.0.4: + resolution: {integrity: sha512-/UJ1dEoVQTjPNDh6SGlUo+ueLMmoHTas4q+8yaAR/5t6nLAIiBDJtoYUh20IYleix7ehiQkgczb84PE3uzHkxg==} + engines: {node: 20 || >=22} + minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} @@ -6365,6 +6376,10 @@ packages: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} + path-scurry@3.0.0: + resolution: {integrity: sha512-1pTbQqH1wIwMi/eleQ5leFTTCkzFsPcgXNjwOA8YGGW/W4/kHT3dssE7Z6NH+zuqNLOzOB0uaD61yl7cAcVhgg==} + engines: {node: 18 || 20 || >=22} + path-to-regexp@3.3.0: resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} @@ -7414,7 +7429,7 @@ packages: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} tui-driver@https://codeload.github.com/vizzly-testing/tui-driver/tar.gz/f21ea93489f2160eccf4d58844e456a9b38a0491: - resolution: {gitHosted: true, tarball: https://codeload.github.com/vizzly-testing/tui-driver/tar.gz/f21ea93489f2160eccf4d58844e456a9b38a0491} + resolution: {gitHosted: true, integrity: sha512-8oRyQd13vio7sFSo42zt3TEb9prxHRpYuOtT9v7npjrWqOBNpUCsGhNZf3+/kQ+RoXxBXbJLZ52az72X4nXipg==, tarball: https://codeload.github.com/vizzly-testing/tui-driver/tar.gz/f21ea93489f2160eccf4d58844e456a9b38a0491} version: 0.1.0 engines: {node: '>=20'} @@ -10054,6 +10069,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/nonrecursive-glob-match@1.0.3': {} + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.12 @@ -13200,6 +13217,12 @@ snapshots: minipass: 7.1.3 path-scurry: 2.0.2 + glob@14.0.2: + dependencies: + minimatch: 11.0.4 + minipass: 7.1.3 + path-scurry: 3.0.0 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -14184,6 +14207,11 @@ snapshots: dependencies: brace-expansion: 5.0.12 + minimatch@11.0.4: + dependencies: + '@isaacs/nonrecursive-glob-match': 1.0.3 + brace-expansion: 5.0.12 + minimatch@3.1.5: dependencies: brace-expansion: 1.1.21 @@ -14536,6 +14564,11 @@ snapshots: lru-cache: 11.5.3 minipass: 7.1.3 + path-scurry@3.0.0: + dependencies: + lru-cache: 11.5.3 + minipass: 7.1.3 + path-to-regexp@3.3.0: {} path-to-regexp@8.4.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 440a6e99..dd1e2c62 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -19,10 +19,14 @@ overrides: minimumReleaseAge: 10080 minimumReleaseAgeStrict: true minimumReleaseAgeIgnoreMissingTime: false -# These exact security fixes are newer than the normal seven-day waiting period. +# These security fixes and their required dependencies are newer than seven days. minimumReleaseAgeExclude: + - '@isaacs/nonrecursive-glob-match@1.0.3' - body-parser@2.4.0 - fast-uri@3.1.9 + - glob@14.0.2 + - minimatch@11.0.4 + - path-scurry@3.0.0 onlyBuiltDependencies: - canvas - esbuild diff --git a/src/adapters/plugins/plugin-loader.test.js b/src/adapters/plugins/plugin-loader.test.js index f5f3a3ae..95793d32 100644 --- a/src/adapters/plugins/plugin-loader.test.js +++ b/src/adapters/plugins/plugin-loader.test.js @@ -5,6 +5,7 @@ import { join } from 'node:path'; import { afterEach, beforeEach, describe, it } from 'node:test'; import { loadPlugin, + loadPlugins, resolvePackagePluginPath, resolvePluginPath, } from './plugin-loader.js'; @@ -38,6 +39,26 @@ describe('plugin-loader', () => { await rm(workspace, { recursive: true, force: true }); }); + it('loads installed plugins from the Vizzly package scope', async () => { + let packageDir = await writePackage(workspace, '@vizzly-testing/example', { + name: '@vizzly-testing/example', + type: 'module', + vizzlyPlugin: 'plugin.js', + }); + await writeFile( + join(packageDir, 'plugin.js'), + `export default { name: 'installed-plugin', register() {} };` + ); + + let plugins = await loadPlugins(null, {}); + + assert.deepEqual( + plugins.map(plugin => plugin.name), + ['installed-plugin'] + ); + assert.equal(typeof plugins[0].register, 'function'); + }); + describe('resolvePackagePluginPath', () => { it('resolves package plugin paths inside the package directory', () => { let packageDir = join(workspace, 'node_modules', 'storybook-plugin'); diff --git a/tests/cli/uploads/upload-cli.test.js b/tests/cli/uploads/upload-cli.test.js index f9b1c497..b8012d1a 100644 --- a/tests/cli/uploads/upload-cli.test.js +++ b/tests/cli/uploads/upload-cli.test.js @@ -33,12 +33,14 @@ describe('commands/upload CLI', () => { assert.match(result.stderr, /API token required/); }); - it('uploads screenshots and finalizes the build through the CLI', async () => { + it('uploads nested PNG screenshots and finalizes the build through the CLI', async () => { let workspace = mkdtempSync(join(tmpdir(), 'vizzly-cli-upload-')); let screenshots = join(workspace, 'screenshots'); mkdirSync(screenshots); + mkdirSync(join(screenshots, 'nested')); writeFileSync(join(screenshots, 'home-chrome.png'), 'png'); - writeFileSync(join(screenshots, 'settings-firefox.png'), 'png'); + writeFileSync(join(screenshots, 'nested', 'settings-firefox.png'), 'png'); + writeFileSync(join(screenshots, 'nested', 'notes.txt'), 'not a screenshot'); await withUploadApiServer(async ({ apiUrl, requests }) => { let result = await runCLI(