@stealthscale/vite-plugin-product 0.3.1 → 0.3.2

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.
@@ -1 +1 @@
1
- {"$schema":"http://cyclonedx.org/schema/bom-1.7.schema.json","bomFormat":"CycloneDX","specVersion":"1.7","version":1,"metadata":{"lifecycles":[{"phase":"build"}],"tools":{"components":[{"type":"application","name":"rolldown","version":"1.2.12"},{"type":"application","name":"vite","version":"8.3.3"},{"type":"library","name":"core","group":"@arethetypeswrong","version":"0.18.5","bom-ref":"pkg:npm/%40arethetypeswrong/core@0.18.5","author":"Andrew Branch","description":"The API behind arethetypeswrong.github.io","hashes":[{"alg":"SHA-512","content":"f72b63cc6c318e6f54cfb23d6af7dbb79be542deae93db914444b3263aabce797a58abc8e9dc184e8faf277534d96aeafe64778aa97f3f386f1e129d2480230d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40arethetypeswrong/core@0.18.5","externalReferences":[{"url":"https://github.com/arethetypeswrong/arethetypeswrong.github.io.git#packages/core","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20"}]},{"type":"library","name":"sdk-core","group":"@stealthscale","version":"0.3.0","bom-ref":"pkg:npm/%40stealthscale/sdk-core@0.3.0","description":"Declares the contracts and manifests of plugins, evaluates their conditions, and resolves a product from them, without loading another package at run time.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/sdk-core@0.3.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#sdk/core","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/sdk/core#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"testing-config","group":"@stealthscale","version":"0.6.0","bom-ref":"pkg:npm/%40stealthscale/testing-config@0.6.0","description":"Lists every part of the house contract a config, plugin or library package breaks.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/testing-config@0.6.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/testing-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/testing-config#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"testing","group":"@stealthscale","version":"0.4.0","bom-ref":"pkg:npm/%40stealthscale/testing@0.4.0","description":"Supplies the scratch workspaces, manifests, element measurements and plugin drivers a specification needs.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/testing@0.4.0","externalReferences":[{"url":"git+https://github.com/stealth-scale/scale.git#packages/testing","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config-typescript","group":"@stealthscale","version":"0.3.0","bom-ref":"pkg:npm/%40stealthscale/vite-config-typescript@0.3.0","description":"Sets the TypeScript options every stealthscale package compiles with.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config-typescript@0.3.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-config-typescript","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-config-typescript#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config","group":"@stealthscale","version":"0.8.0","bom-ref":"pkg:npm/%40stealthscale/vite-config@0.8.0","description":"Configures a package from five Vite+ tiers and a named layer for every block.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config@0.8.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-config#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-plugin-base","group":"@stealthscale","version":"0.5.0","bom-ref":"pkg:npm/%40stealthscale/vite-plugin-base@0.5.0","description":"Turns a name and one write step into a bundler plugin that reads the module graph.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-plugin-base@0.5.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-plugin-base","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-plugin-base#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-plugin-i18n","group":"@stealthscale","version":"0.3.2","bom-ref":"pkg:npm/%40stealthscale/vite-plugin-i18n@0.3.2","description":"Finds every catalogue an application can reach, types their keys, and answers the module it loads them from.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-plugin-i18n@0.3.2","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-plugin-i18n","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-plugin-i18n#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"node","group":"@types","version":"26.6.4","bom-ref":"pkg:npm/%40types/node@26.6.4","description":"TypeScript definitions for node","hashes":[{"alg":"SHA-512","content":"95d54f0c2ce3edfb1a199acb07436e1ee4ef25cb0d6accac040a8ca25aff720c6b2ddd716eac48af75c988f9c71c9502c63e6c345d6f9d18fd6969eb561e4972"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40types/node@26.6.4","externalReferences":[{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped.git#types/node","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"coverage-v8","group":"@vitest","version":"5.0.3","bom-ref":"pkg:npm/%40vitest/coverage-v8@5.0.3","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"V8 coverage provider for Vitest","hashes":[{"alg":"SHA-512","content":"fa496ccb3ec1bd3d6f094dbc6647f39acd486bbf170f4578d54dc552d45a6b74bebceaff117bcad4ee81bd50fb9754731239ba48e351d9ac9b3af0c37fdbb499"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40vitest/coverage-v8@5.0.3","externalReferences":[{"url":"https://github.com/vitest-dev/vitest/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/vitest-dev/vitest.git#packages/coverage-v8","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://vitest.dev/guide/coverage","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"vite-plus-core","group":"@voidzero-dev","version":"1.1.0","bom-ref":"pkg:npm/%40voidzero-dev/vite-plus-core@1.1.0","author":"VoidZero Inc.","description":"The Unified Toolchain for the Web","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40voidzero-dev/vite-plus-core@1.1.0","externalReferences":[{"url":"https://github.com/voidzero-dev/vite-plus/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/voidzero-dev/vite-plus.git#packages/core","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://viteplus.dev/guide","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":"^20.19.0 || ^22.18.0 || >=24.11.0"}]},{"type":"library","name":"typescript","version":"7.0.2","bom-ref":"pkg:npm/typescript@7.0.2","author":"Microsoft Corp.","description":"TypeScript is a language for application scale JavaScript development","hashes":[{"alg":"SHA-512","content":"f0561abbdea8dcd28e85b8ca8bfa8dbc6fd6e63873c646dd9b9b23f406d9ff94f9b16aa7de12602df1b1dbbb11299593bf2cc23fc74b4414dfe6d05349155434"}],"licenses":[{"license":{"id":"Apache-2.0"}}],"purl":"pkg:npm/typescript@7.0.2","externalReferences":[{"url":"https://github.com/microsoft/TypeScript/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"https://github.com/microsoft/TypeScript.git","type":"vcs","comment":"as detected from PackageJson property \"repository.url\""},{"url":"https://www.typescriptlang.org/","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=16.20.0"}]},{"type":"library","name":"vitest","version":"5.0.3","bom-ref":"pkg:npm/vitest@5.0.3","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"Next generation testing framework powered by Vite","hashes":[{"alg":"SHA-512","content":"c4cc3ded2deb8ddb63e5d9156adee30aca96069bdc86cdd196941cb54ab0243d0a904464e34bf3d9f27bee50f05bf57387fa64d7c788b5803392876149eb378d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/vitest@5.0.3","externalReferences":[{"url":"https://github.com/vitest-dev/vitest/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/vitest-dev/vitest.git#packages/vitest","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://vitest.dev","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":"^22.12.0 || ^24.0.0 || >=26.0.0"}]}]},"component":{"type":"library","name":"vite-plugin-product","group":"@stealthscale","version":"0.3.1","bom-ref":"pkg:npm/%40stealthscale/vite-plugin-product@0.3.1","description":"Composes a product from its plugins while it builds: checks every plugin against the others, resolves the product, and serves it as virtual:product.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-plugin-product@0.3.1","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-plugin-product","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-plugin-product#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}],"evidence":{"licenses":[{"license":{"name":"file: LICENSE","text":{"content":"TUlUIExpY2Vuc2UKCkNvcHlyaWdodCAoYykgMjAyNiBTdGVhbHRoIFNjYWxlIEIuVi4KClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKU09GVFdBUkUuCg==","contentType":"text/plain","encoding":"base64"}}}]}},"supplier":{"name":"Stealth Scale B.V.","url":["https://stealthscale.io"]}},"components":[],"dependencies":[{"ref":"pkg:npm/%40stealthscale/vite-plugin-product@0.3.1"}]}
1
+ {"$schema":"http://cyclonedx.org/schema/bom-1.7.schema.json","bomFormat":"CycloneDX","specVersion":"1.7","version":1,"metadata":{"lifecycles":[{"phase":"build"}],"tools":{"components":[{"type":"application","name":"rolldown","version":"1.2.12"},{"type":"application","name":"vite","version":"8.3.3"},{"type":"library","name":"core","group":"@arethetypeswrong","version":"0.18.5","bom-ref":"pkg:npm/%40arethetypeswrong/core@0.18.5","author":"Andrew Branch","description":"The API behind arethetypeswrong.github.io","hashes":[{"alg":"SHA-512","content":"f72b63cc6c318e6f54cfb23d6af7dbb79be542deae93db914444b3263aabce797a58abc8e9dc184e8faf277534d96aeafe64778aa97f3f386f1e129d2480230d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40arethetypeswrong/core@0.18.5","externalReferences":[{"url":"https://github.com/arethetypeswrong/arethetypeswrong.github.io.git#packages/core","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20"}]},{"type":"library","name":"sdk-core","group":"@stealthscale","version":"0.3.0","bom-ref":"pkg:npm/%40stealthscale/sdk-core@0.3.0","description":"Declares the contracts and manifests of plugins, evaluates their conditions, and resolves a product from them, without loading another package at run time.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/sdk-core@0.3.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#sdk/core","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/sdk/core#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"testing-config","group":"@stealthscale","version":"0.6.0","bom-ref":"pkg:npm/%40stealthscale/testing-config@0.6.0","description":"Lists every part of the house contract a config, plugin or library package breaks.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/testing-config@0.6.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/testing-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/testing-config#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"testing","group":"@stealthscale","version":"0.4.0","bom-ref":"pkg:npm/%40stealthscale/testing@0.4.0","description":"Supplies the scratch workspaces, manifests, element measurements and plugin drivers a specification needs.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/testing@0.4.0","externalReferences":[{"url":"git+https://github.com/stealth-scale/scale.git#packages/testing","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config-typescript","group":"@stealthscale","version":"0.3.0","bom-ref":"pkg:npm/%40stealthscale/vite-config-typescript@0.3.0","description":"Sets the TypeScript options every stealthscale package compiles with.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config-typescript@0.3.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-config-typescript","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-config-typescript#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config","group":"@stealthscale","version":"0.8.0","bom-ref":"pkg:npm/%40stealthscale/vite-config@0.8.0","description":"Configures a package from five Vite+ tiers and a named layer for every block.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config@0.8.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-config#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-plugin-base","group":"@stealthscale","version":"0.5.1","bom-ref":"pkg:npm/%40stealthscale/vite-plugin-base@0.5.1","description":"Turns a name and one write step into a bundler plugin that reads the module graph.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-plugin-base@0.5.1","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-plugin-base","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-plugin-base#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-plugin-i18n","group":"@stealthscale","version":"0.4.0","bom-ref":"pkg:npm/%40stealthscale/vite-plugin-i18n@0.4.0","description":"Finds every catalogue an application can reach, types their keys, and answers the module it loads them from.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-plugin-i18n@0.4.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-plugin-i18n","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-plugin-i18n#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"node","group":"@types","version":"26.6.4","bom-ref":"pkg:npm/%40types/node@26.6.4","description":"TypeScript definitions for node","hashes":[{"alg":"SHA-512","content":"95d54f0c2ce3edfb1a199acb07436e1ee4ef25cb0d6accac040a8ca25aff720c6b2ddd716eac48af75c988f9c71c9502c63e6c345d6f9d18fd6969eb561e4972"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40types/node@26.6.4","externalReferences":[{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped.git#types/node","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"coverage-v8","group":"@vitest","version":"5.0.3","bom-ref":"pkg:npm/%40vitest/coverage-v8@5.0.3","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"V8 coverage provider for Vitest","hashes":[{"alg":"SHA-512","content":"fa496ccb3ec1bd3d6f094dbc6647f39acd486bbf170f4578d54dc552d45a6b74bebceaff117bcad4ee81bd50fb9754731239ba48e351d9ac9b3af0c37fdbb499"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40vitest/coverage-v8@5.0.3","externalReferences":[{"url":"https://github.com/vitest-dev/vitest/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/vitest-dev/vitest.git#packages/coverage-v8","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://vitest.dev/guide/coverage","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"vite-plus-core","group":"@voidzero-dev","version":"1.1.0","bom-ref":"pkg:npm/%40voidzero-dev/vite-plus-core@1.1.0","author":"VoidZero Inc.","description":"The Unified Toolchain for the Web","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40voidzero-dev/vite-plus-core@1.1.0","externalReferences":[{"url":"https://github.com/voidzero-dev/vite-plus/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/voidzero-dev/vite-plus.git#packages/core","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://viteplus.dev/guide","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":"^20.19.0 || ^22.18.0 || >=24.11.0"}]},{"type":"library","name":"typescript","version":"7.0.2","bom-ref":"pkg:npm/typescript@7.0.2","author":"Microsoft Corp.","description":"TypeScript is a language for application scale JavaScript development","hashes":[{"alg":"SHA-512","content":"f0561abbdea8dcd28e85b8ca8bfa8dbc6fd6e63873c646dd9b9b23f406d9ff94f9b16aa7de12602df1b1dbbb11299593bf2cc23fc74b4414dfe6d05349155434"}],"licenses":[{"license":{"id":"Apache-2.0"}}],"purl":"pkg:npm/typescript@7.0.2","externalReferences":[{"url":"https://github.com/microsoft/TypeScript/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"https://github.com/microsoft/TypeScript.git","type":"vcs","comment":"as detected from PackageJson property \"repository.url\""},{"url":"https://www.typescriptlang.org/","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=16.20.0"}]},{"type":"library","name":"vitest","version":"5.0.3","bom-ref":"pkg:npm/vitest@5.0.3","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"Next generation testing framework powered by Vite","hashes":[{"alg":"SHA-512","content":"c4cc3ded2deb8ddb63e5d9156adee30aca96069bdc86cdd196941cb54ab0243d0a904464e34bf3d9f27bee50f05bf57387fa64d7c788b5803392876149eb378d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/vitest@5.0.3","externalReferences":[{"url":"https://github.com/vitest-dev/vitest/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/vitest-dev/vitest.git#packages/vitest","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://vitest.dev","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":"^22.12.0 || ^24.0.0 || >=26.0.0"}]}]},"component":{"type":"library","name":"vite-plugin-product","group":"@stealthscale","version":"0.3.2","bom-ref":"pkg:npm/%40stealthscale/vite-plugin-product@0.3.2","description":"Composes a product from its plugins while it builds: checks every plugin against the others, resolves the product, and serves it as virtual:product.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-plugin-product@0.3.2","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-plugin-product","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-plugin-product#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}],"evidence":{"licenses":[{"license":{"name":"file: LICENSE","text":{"content":"TUlUIExpY2Vuc2UKCkNvcHlyaWdodCAoYykgMjAyNiBTdGVhbHRoIFNjYWxlIEIuVi4KClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKU09GVFdBUkUuCg==","contentType":"text/plain","encoding":"base64"}}}]}},"supplier":{"name":"Stealth Scale B.V.","url":["https://stealthscale.io"]}},"components":[],"dependencies":[{"ref":"pkg:npm/%40stealthscale/vite-plugin-product@0.3.2"}]}
package/dist/index.mjs CHANGED
@@ -9,27 +9,32 @@ import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from
9
9
  import { createHash } from "node:crypto";
10
10
  //#region src/page.ts
11
11
  /**
12
- * Writes the document and the entry of a page the plugin serves at `index.html`: a product's page
13
- * or a plugin's standalone page.
12
+ * Writes the document and the entry of the page that the plugin serves at `index.html`. The page
13
+ * is a product's page or a plugin's standalone page.
14
14
  */
15
15
  /**
16
16
  * The page's document, from the project root.
17
17
  */
18
18
  const DOCUMENT = "index.html";
19
19
  /**
20
- * The language of a document whose page states none.
20
+ * The language of a document whose page has no language.
21
21
  */
22
22
  const LANGUAGE = "en-US";
23
23
  /**
24
- * Returns the path of the page's document for a specifier that names it, and undefined for any
24
+ * Returns the path of the page's document for a specifier of the document, and undefined for any
25
25
  * other specifier.
26
26
  *
27
+ * @remarks
28
+ * The function compares the specifier after `normalizePath`. A build's default input is the
29
+ * document's path from `path.resolve`, which has backslashes on Windows.
27
30
  * @param root - The project root.
28
- * @param id - The specifier: `index.html`, `/index.html` or the document's path name the document.
31
+ * @param id - The specifier. The document's specifiers are `index.html`, `/index.html` and the
32
+ * document's path.
29
33
  */
30
34
  function documentIdOf(root, id) {
31
35
  const document = normalizePath(join(root, DOCUMENT));
32
- return id === DOCUMENT || id === `/${DOCUMENT}` || id === document ? document : void 0;
36
+ const file = normalizePath(id);
37
+ return file === DOCUMENT || file === `/${DOCUMENT}` || file === document ? document : void 0;
33
38
  }
34
39
  /**
35
40
  * Returns the specifier of a module by its path from the project root, such as `/src/glyphs.tsx`.
@@ -38,8 +43,8 @@ function rootedOf(path) {
38
43
  return posix.join("/", normalizePath(path));
39
44
  }
40
45
  /**
41
- * Returns the source of a page's document: its language and title, an element with the id `root`,
42
- * and the entry.
46
+ * Returns the source of a page's document. The document has its language and title, an element
47
+ * with the id `root`, and the entry.
43
48
  */
44
49
  function documentSource({ entry, language, title }) {
45
50
  return [
@@ -59,18 +64,18 @@ function documentSource({ entry, language, title }) {
59
64
  ].join("\n");
60
65
  }
61
66
  /**
62
- * Returns the source of a page's entry: the stylesheet and the static imports, every other module
63
- * through `import()`, and a call of the render function with the members.
67
+ * Returns the source of a page's entry. The entry imports the stylesheet and the static modules,
68
+ * imports every other module through `import()`, and calls the render function with the members.
64
69
  *
65
70
  * @remarks
66
71
  * The entry imports the stylesheet and modules without components statically, and the page's
67
72
  * other modules through `import()`. The bundled dev server installs the React refresh runtime in
68
- * the entry's own body, and a chunk the entry imports statically runs before that body, so a
69
- * component in a chunk the bundler shares between the entry and a lazy module would run before
70
- * the runtime and throw. Behind `import()`, every component runs after it. A module the entry
71
- * alone imports statically builds into the entry's chunk, so it adds no chunk of its own. The
72
- * entry awaits nothing at its top level, because a module with a top-level await makes the
73
- * bundler move every module it shares with a lazy module into a chunk of its own.
73
+ * the entry's own body. A chunk that the entry imports statically runs before that body, so a
74
+ * component in a chunk that the entry shares with a lazy module would run before the runtime and
75
+ * throw. A component that the entry imports through `import()` runs after the runtime. A module
76
+ * that only the entry imports statically builds into the entry's chunk, so it adds no chunk of
77
+ * its own. The entry does not await at its top level, because a module with a top-level await
78
+ * makes the bundler move every module it shares with a lazy module into a chunk of its own.
74
79
  * @param render - The name of the render function, which the first module exports.
75
80
  * @param modules - The modules the entry imports through `import()`, the render function's first.
76
81
  * @param members - The members of the object the render function receives.
@@ -428,22 +433,22 @@ function moduleOf(definition, product) {
428
433
  //#endregion
429
434
  //#region src/chunks.ts
430
435
  /**
431
- * Names the chunk each module of a product builds into: one chunk per plugin, which every page,
432
- * extension, command and settings section of the plugin shares, and under a build one chunk for the
433
- * other modules outside the application that the startup or a plugin imports statically.
436
+ * Names the chunk that each module of a product builds into.
434
437
  *
435
438
  * @remarks
436
- * The product imports each web package's main entry statically, through its definition. The main
437
- * entry and every module it imports statically build into the chunks the entry loads, because in
438
- * the plugin's chunk they would make the first load fetch the whole plugin. Groups that place a
439
- * module by its path alone make rolldown 1.2 build a module the groups leave into the chunk of a
440
- * lazy module that imports it, and export it from there to the chunks that need it. `import()` of
441
- * that lazy module then resolves to a namespace with the other module's exports as well. A module
442
- * outside every web package that one plugin's lazy modules alone import goes into the plugin's
443
- * chunk. Every other module outside the application that the startup or a plugin's modules import
444
- * statically goes into the `dependencies` chunk, so a lazy module's chunk contains the lazy
445
- * module alone. A module that only another `import()` loads, such as a page the application
446
- * loads on demand, keeps its own chunk, so it does not load with the startup.
439
+ * Each plugin has one chunk for its pages, extensions, commands and settings sections. A build
440
+ * also has one chunk for the other modules outside the application that the startup or a plugin
441
+ * imports statically. The product's definition imports the main entry of each web package
442
+ * statically. The main entry and every module it imports statically build into the chunks that
443
+ * the entry loads, because in the plugin's chunk they would make the first load fetch the whole
444
+ * plugin. Groups that place a module by its path alone make rolldown 1.2 build a module that no
445
+ * group takes into the chunk of a lazy module that imports it. Rolldown then exports the module
446
+ * from that chunk to the chunks that need it, and `import()` of the lazy module resolves to a
447
+ * namespace with the other module's exports as well. A module outside every web package that
448
+ * only one plugin's lazy modules import goes into the plugin's chunk. Every other module outside
449
+ * the application that the startup or a plugin's modules import statically goes into the
450
+ * `dependencies` chunk. A lazy module's chunk then contains the lazy module alone. A module that
451
+ * only another `import()` loads keeps its own chunk and does not load with the startup.
447
452
  */
448
453
  /**
449
454
  * Name of the chunk that a module outside the application builds into where the startup or a
@@ -451,12 +456,13 @@ function moduleOf(definition, product) {
451
456
  */
452
457
  const DEPENDENCIES = "dependencies";
453
458
  /**
454
- * Priority of the plugin chunks' group: above the shared chunk's 3, below the vendor chunk's 5.
459
+ * Priority of the plugin chunks' group. It is above the shared chunk's 3 and below the vendor
460
+ * chunk's 5.
455
461
  */
456
462
  const PRIORITY = 4;
457
463
  /**
458
- * Priority of the dependencies' group: below every other group's, so it claims only the modules
459
- * they leave.
464
+ * Priority of the dependencies' group. It is below the priority of every other group, so the group
465
+ * claims only the modules that the other groups leave.
460
466
  */
461
467
  const LAST = 1;
462
468
  /**
@@ -466,13 +472,18 @@ const INSTALLED = /(?:^|[\\/])node_modules[\\/]/u;
466
472
  /**
467
473
  * Returns the id of the plugin whose web package contains a module, or undefined for a module
468
474
  * outside every web package.
475
+ *
476
+ * @remarks
477
+ * The web packages' directories have forward slashes. The function compares the module's id
478
+ * after `normalizePath`, so an id with backslashes on Windows matches too.
469
479
  */
470
480
  function ownerOf(id, packages) {
471
- return Object.entries(packages).find(([, { directory }]) => id.startsWith(`${directory}${sep}`))?.[0];
481
+ const file = normalizePath(id);
482
+ return Object.entries(packages).find(([, { directory }]) => file.startsWith(`${directory}/`))?.[0];
472
483
  }
473
484
  /**
474
- * Returns true where the walk over a module's static importers meets a module the test accepts,
475
- * the module itself included.
485
+ * Returns true where the walk over a module's static importers meets a module that the test
486
+ * accepts. The walk starts at the module itself.
476
487
  */
477
488
  function leadsTo(id, chunking, ends) {
478
489
  const seen = /* @__PURE__ */ new Set();
@@ -492,28 +503,28 @@ function startup(id, info) {
492
503
  return id === RESOLVED || info?.isEntry === true;
493
504
  }
494
505
  /**
495
- * Returns true where an entry of the build or `virtual:product` imports a module statically,
496
- * directly or through other modules.
506
+ * Returns true where an entry of the build or `virtual:product` imports a module statically. The
507
+ * import may pass through other modules.
497
508
  *
498
509
  * @remarks
499
- * The walk follows each module's static importers back towards the entries, and ends at
500
- * `virtual:product`, because every module the product imports statically loads with it. The
501
- * standalone page's entry imports the product through `import()`, so no entry imports the
502
- * definition statically there. A dynamic import ends the walk elsewhere, because a module behind
503
- * one loads after the entry.
510
+ * The walk follows each module's static importers back towards the entries. It ends at
511
+ * `virtual:product`, because every module that the product imports statically loads with it. The
512
+ * standalone page's entry imports the product through `import()`, and no entry imports the
513
+ * definition statically there. A dynamic import ends the walk elsewhere, because the module that
514
+ * it imports loads after the entry.
504
515
  */
505
516
  function initial(id, chunking) {
506
517
  return leadsTo(id, chunking, startup);
507
518
  }
508
519
  /**
509
- * Returns the one plugin whose web package's modules import a module outside every web package,
510
- * directly or through other modules.
520
+ * Returns the one plugin whose web package's modules import a module outside every web package.
521
+ * The import may pass through other modules.
511
522
  *
512
523
  * @remarks
513
- * Returns undefined where an entry or `virtual:product` imports the module statically, where the
514
- * walk meets a module outside every web package that no module imports statically, such as a lazy
515
- * page of the application, or a module the build does not know, and where the modules of two
516
- * plugins import it.
524
+ * The function returns undefined in four cases. An entry or `virtual:product` imports the module
525
+ * statically. The walk meets a module outside every web package that no module imports
526
+ * statically, such as a lazy page of the application. The walk meets a module that the build does
527
+ * not know. The modules of two plugins import the module.
517
528
  */
518
529
  function soleOwnerOf(id, chunking, packages) {
519
530
  const owners = /* @__PURE__ */ new Set();
@@ -534,11 +545,13 @@ function soleOwnerOf(id, chunking, packages) {
534
545
  return owners.size === 1 ? sole : void 0;
535
546
  }
536
547
  /**
537
- * Returns the chunk a module builds into: `plugin-<id>` for a module of an installed plugin's web
538
- * package that no entry imports statically, and for a module outside every web package that only
539
- * that plugin's lazy modules import, and null for every other module.
548
+ * Returns the plugin chunk that a module builds into, or null for a module of no plugin chunk.
540
549
  *
541
- * @param id - The module's id, its absolute path.
550
+ * @remarks
551
+ * A module of an installed plugin's web package that no entry imports statically builds into
552
+ * `plugin-<id>`. A module outside every web package that only that plugin's lazy modules import
553
+ * builds into the same chunk.
554
+ * @param id - The module's id. A file's id is its absolute path.
542
555
  * @param chunking - The context rolldown passes a group's name function.
543
556
  * @param packages - Each installed plugin's web package, by plugin id.
544
557
  */
@@ -549,17 +562,17 @@ function pluginChunkOf(id, chunking, packages) {
549
562
  return sole === void 0 ? null : `plugin-${sole}`;
550
563
  }
551
564
  /**
552
- * Returns the chunk a module builds into where the groups with a higher priority leave it:
553
- * `dependencies` for a module outside the application that the startup or a plugin's modules import
554
- * statically, and null for every other module.
565
+ * Returns `dependencies` for a module outside the application that the startup or a plugin's
566
+ * modules import statically, and null for every other module.
555
567
  *
556
568
  * @remarks
557
- * A module of the application is a file under the project root and outside its `node_modules`. A
558
- * virtual module's id is not an absolute path. The walk over the module's static importers ends
559
- * at an entry, at `virtual:product` and at a module of an installed plugin's web package. A
560
- * module it does not meet is one that only another `import()` loads, such as a page the
561
- * application loads on demand, which keeps its own chunk.
562
- * @param id - The module's id, its absolute path for a file.
569
+ * The groups with a higher priority place a module first. A module of the application is a file
570
+ * under the project root and outside its `node_modules`. A virtual module's id is not an absolute
571
+ * path. The walk over the module's static importers ends at an entry, at `virtual:product` and at
572
+ * a module of an installed plugin's web package. A page that the application loads on demand is a
573
+ * module that only another `import()` loads. The walk does not meet such a module, and the module
574
+ * keeps its own chunk.
575
+ * @param id - The module's id. A file's id is its absolute path.
563
576
  * @param chunking - The context rolldown passes a group's name function.
564
577
  * @param root - The project root.
565
578
  * @param packages - Each installed plugin's web package, by plugin id.
@@ -572,16 +585,17 @@ function dependencyChunkOf(id, chunking, root, packages) {
572
585
  }
573
586
  /**
574
587
  * Returns the configuration whose groups build each installed plugin's lazy modules into a chunk
575
- * of its own, and under a build every other module outside the application that the startup or a
576
- * plugin imports statically into the `dependencies` chunk.
588
+ * of its own.
577
589
  *
578
590
  * @remarks
579
- * Both groups read the web packages the composition found, and the dependencies' group reads the
580
- * project root. Both are read when the bundler places a module, after the composition. A dev
581
- * server takes no dependencies' group: `import()` of a lazy module resolves to the module's own
582
- * exports there without it, and `vite-config` leaves out its library and shared groups there too,
583
- * whose chunks would run components before the React refresh runtime is installed.
584
- * @param placing - The web packages and the project root, which each group reads when the bundler
591
+ * A build also builds every other module outside the application that the startup or a plugin
592
+ * imports statically into the `dependencies` chunk. Both groups read the web packages that the
593
+ * composition found, and the dependencies' group also reads the project root. The bundler calls
594
+ * both groups after the composition, when it places a module. A dev server has no dependencies'
595
+ * group, because `import()` of a lazy module resolves to the module's own exports there without
596
+ * it. `vite-config` leaves out its library and shared groups on a dev server too. Their chunks
597
+ * would run components before the React refresh runtime is installed.
598
+ * @param placing - The web packages and the project root. Each group reads them when the bundler
585
599
  * places a module.
586
600
  * @param command - The command Vite runs under, `build` or `serve`.
587
601
  */
@@ -599,15 +613,16 @@ function chunked(placing, command) {
599
613
  //#endregion
600
614
  //#region src/discover.ts
601
615
  /**
602
- * Finds each installed plugin's web package and contract package among the modules the product's
603
- * definition loaded.
616
+ * Finds each installed plugin's web package and contract package among the modules that the
617
+ * evaluation of the product's definition loaded.
604
618
  *
605
619
  * @remarks
606
- * The definition imports every installed plugin's manifest, and each manifest names its contract,
607
- * so the modules its evaluation loaded already contain both. A package is the one that contains
608
- * the module defining the object, matched by identity. A manifest the definition builds itself,
609
- * which no module exports, belongs to the definition module's package. No package is imported for
610
- * the search alone, so no component package and no React is loaded in Node.
620
+ * The definition module imports the manifest of every installed plugin, and each manifest
621
+ * contains its contract. The modules of the evaluation therefore contain both. An object belongs
622
+ * to the package of the module that defines it, and the search matches objects by identity. No
623
+ * module exports a manifest that the definition module creates itself, so that manifest belongs
624
+ * to the package of the definition module. The search imports no package of its own, so Node does
625
+ * not load a component package or React.
611
626
  */
612
627
  /**
613
628
  * Returns true where a value is an object whose members can be read by name.
@@ -616,10 +631,11 @@ function isRecord(value) {
616
631
  return typeof value === "object" && value !== null;
617
632
  }
618
633
  /**
619
- * Returns each installed plugin the definition states with a readable manifest and contract.
634
+ * Returns each installed plugin of the definition that has a readable manifest and contract.
620
635
  *
621
636
  * @remarks
622
- * A definition of another shape installs nothing here, and the resolver's shape check reports it.
637
+ * The function returns no plugin for a definition of another shape. The resolver's shape check
638
+ * reports that definition.
623
639
  * @param definition - The definition's default export.
624
640
  */
625
641
  function installationsOf(definition) {
@@ -640,9 +656,9 @@ function installationsOf(definition) {
640
656
  *
641
657
  * @remarks
642
658
  * A module evaluates after every module it imports, and a module that re-exports an object
643
- * imports the module that defines it. The first module that exports an object, in evaluation
644
- * order, is therefore the one that defines it.
645
- * @param loaded - Every module the definition's evaluation loaded, in evaluation order.
659
+ * imports the module that defines it. The first module in evaluation order that exports an object
660
+ * is therefore the module that defines it.
661
+ * @param loaded - Every module that the evaluation of the definition loaded, in evaluation order.
646
662
  */
647
663
  function ownersOf(loaded) {
648
664
  const owners = /* @__PURE__ */ new Map();
@@ -653,13 +669,17 @@ function ownersOf(loaded) {
653
669
  return owners;
654
670
  }
655
671
  /**
656
- * Returns the package at a directory, or undefined where its manifest states no name.
672
+ * Returns the package at a directory, or undefined where its manifest has no name.
673
+ *
674
+ * @remarks
675
+ * The package's directory goes through `normalizePath`, so on Windows it has the forward slashes
676
+ * of a module id.
657
677
  */
658
678
  function packageIn(directory) {
659
679
  const manifest = directory === void 0 ? void 0 : manifestAt(directory);
660
680
  const name = manifest === void 0 ? void 0 : text(manifest, "name");
661
681
  return directory === void 0 || name === void 0 ? void 0 : {
662
- directory,
682
+ directory: normalizePath(directory),
663
683
  name
664
684
  };
665
685
  }
@@ -667,18 +687,21 @@ function packageIn(directory) {
667
687
  * Finds each installed plugin's web package and contract package.
668
688
  *
669
689
  * @remarks
670
- * A web package outside the product's own package and its dependencies is left out, so the
671
- * resolver reports the plugin. A contract package is recorded wherever it is, because the build
672
- * reads it to leave the plugin's own catalogue out of the namespaces another package publishes.
690
+ * The function leaves out a web package outside the product's own package and its dependencies,
691
+ * so the resolver reports the plugin. It records a contract package wherever it is, because the
692
+ * build reads it to leave the plugin's own catalogue out of the namespaces of other packages. The
693
+ * function compares directories after `normalizePath`, because on Windows the module runner and
694
+ * `realpathSync` write them with different separators.
673
695
  * @param definition - The definition's default export.
674
- * @param loaded - Every module the definition's evaluation loaded, in evaluation order.
675
- * @param root - The product's directory, whose dependencies are walked.
676
- * @param file - The definition module, whose package a manifest the definition builds belongs to.
696
+ * @param loaded - Every module that the evaluation of the definition loaded, in evaluation order.
697
+ * @param root - The product's directory. The walk over its dependencies starts there.
698
+ * @param file - The definition module. A manifest that the definition module creates belongs to the
699
+ * package of this module.
677
700
  */
678
701
  function discover(definition, loaded, root, file) {
679
702
  const owners = ownersOf(loaded);
680
703
  const own = owning(realpathSync(file));
681
- const depended = /* @__PURE__ */ new Set([realpathSync(root), ...dependencies(root).map(({ at }) => at)]);
704
+ const depended = new Set([realpathSync(root), ...dependencies(root).map(({ at }) => at)].map((at) => normalizePath(at)));
682
705
  const contracts = {};
683
706
  const packages = {};
684
707
  for (const { contract, manifest, pluginId } of installationsOf(definition)) {
@@ -1573,14 +1596,13 @@ function importerOf(provided, specifier) {
1573
1596
  * A facade keeps every export of its specifier's module, so the second build keeps code that the
1574
1597
  * first build removed from a module the product uses. A published package bundles its components
1575
1598
  * into few modules, and the code that the first build removed imports modules that the first
1576
- * build left out. Those modules have no pin, so rolldown builds them into a chunk of their own,
1577
- * and that chunk imports the pinned chunk that imports it. In such a cycle a module can read a
1599
+ * build left out. Those modules have no pin, so rolldown builds them into a chunk of their own.
1600
+ * That chunk imports the pinned chunk that imports it. In such a cycle a module can read a
1578
1601
  * binding of the other chunk before that chunk has run. The first build therefore appends to each
1579
1602
  * module of a provided package a statement that passes the module's namespace to a global hook.
1580
1603
  * The statement keeps every export of a module that the build includes, so the first build places
1581
- * the modules that those exports import. The statement adds no module to the build, because a
1582
- * package that states its side effects lets the build leave out a module whose exports nothing
1583
- * uses.
1604
+ * the modules that those exports import. The statement adds no module to the build. The build
1605
+ * leaves out a module whose exports nothing uses when its package has a `sideEffects` field.
1584
1606
  */
1585
1607
  /**
1586
1608
  * The extensions of an ES module in any package.
@@ -1602,7 +1624,7 @@ const TYPED = /* @__PURE__ */ new Set([
1602
1624
  const HOOK = "stealth.kept";
1603
1625
  /**
1604
1626
  * Returns the patterns of a package's files that have side effects, or undefined where the
1605
- * package does not state them.
1627
+ * manifest's `sideEffects` is neither false nor an array.
1606
1628
  */
1607
1629
  function effectsOf(sideEffects) {
1608
1630
  if (sideEffects === false) return [];
@@ -1610,9 +1632,11 @@ function effectsOf(sideEffects) {
1610
1632
  return sideEffects.filter((pattern) => typeof pattern === "string");
1611
1633
  }
1612
1634
  /**
1613
- * Returns the provided packages whose modules the first build keeps whole: each installed package
1614
- * whose manifest states which of its files have side effects.
1635
+ * Returns the provided packages whose modules the first build keeps whole.
1615
1636
  *
1637
+ * @remarks
1638
+ * Each is an installed package whose `sideEffects` is false or a list of patterns. Its directory
1639
+ * goes through `normalizePath`, so on Windows it has the forward slashes of a module id.
1616
1640
  * @param packages - The packages the product provides.
1617
1641
  */
1618
1642
  function keptPackages(packages) {
@@ -1621,7 +1645,7 @@ function keptPackages(packages) {
1621
1645
  const manifest = directory === void 0 ? void 0 : manifestAt(directory);
1622
1646
  const effects = effectsOf(manifest?.["sideEffects"]);
1623
1647
  return directory === void 0 || effects === void 0 ? [] : [{
1624
- directory,
1648
+ directory: normalizePath(directory),
1625
1649
  effects,
1626
1650
  typed: manifest?.["type"] === "module"
1627
1651
  }];
@@ -1638,24 +1662,27 @@ function affects(pattern, path) {
1638
1662
  return matchesGlob(path, pattern.includes("/") ? pattern.replace(/^\.\//u, "") : `**/${pattern}`);
1639
1663
  }
1640
1664
  /**
1641
- * Returns true for a module whose exports the first build keeps whole: an ES module file of a kept
1642
- * package that no side-effect pattern of the package matches.
1665
+ * Returns true for an ES module file of a kept package that no side-effect pattern of the package
1666
+ * matches. The first build keeps the exports of such a module whole.
1643
1667
  *
1644
1668
  * @remarks
1645
- * A file below a `node_modules` directory inside the package belongs to another package.
1669
+ * A file below a `node_modules` directory inside the package belongs to another package. The
1670
+ * function compares the id after `normalizePath`, so an id with backslashes on Windows matches
1671
+ * too.
1646
1672
  * @param id - The module's id.
1647
1673
  * @param packages - The packages whose modules the first build keeps whole.
1648
1674
  */
1649
1675
  function isKept(id, packages) {
1650
- const owner = isAbsolute(id) ? packages.find(({ directory }) => id.startsWith(`${directory}${sep}`)) : void 0;
1676
+ const file = normalizePath(id);
1677
+ const owner = isAbsolute(file) ? packages.find(({ directory }) => file.startsWith(`${directory}/`)) : void 0;
1651
1678
  if (owner === void 0) return false;
1652
- const path = relative(owner.directory, id);
1653
- const extension = extname(id);
1654
- return (MODULES.has(extension) || owner.typed && TYPED.has(extension)) && !path.split(sep).includes("node_modules") && !owner.effects.some((pattern) => affects(pattern, path));
1679
+ const path = file.slice(owner.directory.length + 1);
1680
+ const extension = extname(file);
1681
+ return (MODULES.has(extension) || owner.typed && TYPED.has(extension)) && !path.split("/").includes("node_modules") && !owner.effects.some((pattern) => affects(pattern, path));
1655
1682
  }
1656
1683
  /**
1657
- * Returns a module's code with the statement that keeps its exports appended: a namespace import of
1658
- * the module's own file, passed to a global hook.
1684
+ * Returns a module's code with the statement that keeps its exports appended. The statement
1685
+ * imports the namespace of the module's own file and passes it to a global hook.
1659
1686
  *
1660
1687
  * @param code - The module's code.
1661
1688
  * @param id - The module's id, the absolute path of its file.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stealthscale/vite-plugin-product",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Composes a product from its plugins while it builds: checks every plugin against the others, resolves the product, and serves it as virtual:product.",
5
5
  "keywords": [
6
6
  "plugins",
@@ -43,8 +43,8 @@
43
43
  "@stealthscale/testing-config": "^0.6.0",
44
44
  "@stealthscale/vite-config": "^0.8.0",
45
45
  "@stealthscale/vite-config-typescript": "^0.3.0",
46
- "@stealthscale/vite-plugin-base": "^0.5.0",
47
- "@stealthscale/vite-plugin-i18n": "^0.3.2",
46
+ "@stealthscale/vite-plugin-base": "^0.5.1",
47
+ "@stealthscale/vite-plugin-i18n": "^0.4.0",
48
48
  "@types/node": "^26.6",
49
49
  "@vitest/coverage-v8": "5.0.3",
50
50
  "publint": "^0.3",
@@ -54,8 +54,8 @@
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@stealthscale/sdk-core": "^0.3.0",
57
- "@stealthscale/vite-plugin-base": "^0.5.0",
58
- "@stealthscale/vite-plugin-i18n": "^0.3.2",
57
+ "@stealthscale/vite-plugin-base": "^0.5.1",
58
+ "@stealthscale/vite-plugin-i18n": "^0.4.0",
59
59
  "vite": "^8.3"
60
60
  },
61
61
  "engines": {