@stealthscale/vite-plugin-i18n 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,6 +48,12 @@ link and an installed copy are found alike. The root is the application where it
48
48
  `private`. A package built or tested on its own is a package, and its own files count as what it
49
49
  ships.
50
50
 
51
+ A component package publishes the words of its catalogue pages in the `specimen` namespace. An
52
+ application leaves that namespace out unless its configuration contains the specimen plugin
53
+ (`stealth:specimens`), which lists the pages. Otherwise every product that installs a component
54
+ package would load the words of every page at start. A package keeps the namespace, because its
55
+ specs and its types read the words.
56
+
51
57
  ## virtual:i18n
52
58
 
53
59
  ```ts
@@ -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":"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":"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-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"}],"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-i18n@0.3.2"}]}
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":"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":"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-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"}],"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-i18n@0.4.0"}]}
package/dist/index.d.mts CHANGED
@@ -15,48 +15,48 @@ import { Plugin } from "vite";
15
15
  */
16
16
  interface Catalogue {
17
17
  /**
18
- * Gives the absolute path of the file, with forward slashes.
18
+ * The absolute path of the file, with forward slashes.
19
19
  */
20
20
  readonly file: string;
21
21
  /**
22
- * Gives the BCP 47 tag the directory is named after, such as `en` or `nl-BE`.
22
+ * The BCP 47 tag of the directory's name, such as `en` or `nl-BE`.
23
23
  */
24
24
  readonly language: string;
25
25
  /**
26
- * Gives the first path segment under the language, without its extension. `menu.json` and
27
- * `menu/sections.json` both give `menu`.
26
+ * The first path segment under the language, without its extension. The namespace of
27
+ * `menu.json` and of `menu/sections.json` is `menu`.
28
28
  */
29
29
  readonly namespace: string;
30
30
  /**
31
- * Reports whether the application owns the file rather than a package shipping it.
31
+ * True where the file belongs to the application and not to a package that it installs.
32
32
  *
33
33
  * @remarks
34
- * The root counts as the application only where its manifest sets `private` to true. A package
35
- * built or tested from its own root gets false, so the check treats its files like a
36
- * dependency's.
34
+ * The root is the application only where its manifest has `"private": true`. A package built or
35
+ * tested from its own root gets false, so the check treats its files like a dependency's.
37
36
  */
38
37
  readonly own: boolean;
39
38
  /**
40
- * Gives the name of the package the file came from.
39
+ * The name of the package that the file comes from.
41
40
  */
42
41
  readonly owner: string;
43
42
  /**
44
- * Gives the path below the namespace, joined with dots. `menu/sections/billing.json` gives
45
- * `sections.billing`, and a file that is the namespace itself gives an empty string.
43
+ * The path below the namespace, joined with dots. The prefix of `menu/sections/billing.json` is
44
+ * `sections.billing`, and a file that is the namespace itself has an empty prefix.
46
45
  */
47
46
  readonly prefix: string;
48
47
  }
49
48
  /**
50
- * Gives the directory a package keeps its catalogues in.
49
+ * The directory that a package keeps its catalogues in.
51
50
  */
52
51
  export declare const LOCALES = "locales";
53
52
  /**
54
- * Lists every catalogue a root can reach, its dependencies' first and its own last.
53
+ * Lists every catalogue on a root's graph, with the dependencies' catalogues first and the root's
54
+ * own last.
55
55
  *
56
56
  * @remarks
57
- * Where two packages declare the same language and namespace, the one later in the result wins
58
- * the merge, and the root goes last for that reason. Each package is resolved through Node's
59
- * resolution, so a workspace link and an installed copy are both found.
57
+ * Where two packages declare the same language and namespace, the merge applies the later one in
58
+ * the result, so the root goes last. Each package is resolved through Node's resolution, so the
59
+ * walk finds a workspace link and an installed copy alike.
60
60
  * @param root - The application or package directory.
61
61
  * @param scopes - The scopes to follow. Defaults to the root's own scope and {@link HOUSE}.
62
62
  * @returns The catalogues in merge order.
package/dist/index.mjs CHANGED
@@ -15,21 +15,21 @@ import { manifestAt, packageAt, scratchDir, text, writeIfChanged } from "@stealt
15
15
  * is split across.
16
16
  */
17
17
  /**
18
- * Gives the directory a package keeps its catalogues in.
18
+ * The directory that a package keeps its catalogues in.
19
19
  */
20
20
  const LOCALES = "locales";
21
21
  /**
22
- * Matches the extensions a catalogue may use: `.json`, `.yaml` and `.yml`.
22
+ * Matches a `.json`, `.yaml` or `.yml` extension.
23
23
  */
24
24
  const EXTENSION = /\.(?:json|ya?ml)$/u;
25
25
  /**
26
- * The scope of the house's packages, which the walk follows from an application in any scope,
27
- * because the plugin host renders words from the catalogue its package publishes.
26
+ * The scope of the house's packages. The walk follows it from an application in any scope,
27
+ * because the plugin host renders words from the catalogue of its package.
28
28
  */
29
29
  const HOUSE = "@stealthscale";
30
30
  /**
31
- * Returns the namespace a file belongs to, which is its first path segment with any extension
32
- * stripped.
31
+ * Returns a file's namespace. The namespace is the file's first path segment without an
32
+ * extension.
33
33
  *
34
34
  * @param relative - The file's path under the language directory.
35
35
  */
@@ -38,7 +38,7 @@ function namespaceOf(relative) {
38
38
  return at === -1 ? relative.replace(EXTENSION, "") : relative.slice(0, at);
39
39
  }
40
40
  /**
41
- * Returns the dotted prefix a file's keys nest under, taken from its path below the namespace.
41
+ * Returns the dotted prefix of a file's keys, from the file's path below the namespace.
42
42
  *
43
43
  * @param relative - The file's path under the language directory.
44
44
  * @returns The prefix, or an empty string when the file is the namespace itself.
@@ -48,8 +48,8 @@ function prefixOf(relative) {
48
48
  return at === -1 ? "" : relative.slice(at + 1).replace(EXTENSION, "").replaceAll("/", ".");
49
49
  }
50
50
  /**
51
- * Lists every catalogue file under one directory's `locales`, at any depth, and nothing where the
52
- * directory has no `locales`.
51
+ * Lists every catalogue file at any depth under one directory's `locales`, and none for a directory
52
+ * without `locales`.
53
53
  *
54
54
  * @param directory - The package or application directory to search.
55
55
  * @param owner - The package name to record on each result.
@@ -75,7 +75,7 @@ function cataloguesIn(directory, owner, own) {
75
75
  /**
76
76
  * Returns the scope part of a package name.
77
77
  *
78
- * @param name - The package name, or undefined when the manifest declares none.
78
+ * @param name - The package name, or undefined for a manifest without a name.
79
79
  * @returns The scope such as `@stealthscale`, or undefined for an unscoped name.
80
80
  */
81
81
  function scopeOf(name) {
@@ -107,30 +107,34 @@ function namesIn(manifest, starting) {
107
107
  * @remarks
108
108
  * Only packages under one of the scopes are followed. Following every dependency of a rendering
109
109
  * engine would read hundreds of manifests and find no catalogue in any of them.
110
+ * The walk compares directories after `normalizePath`, because the root arrives with forward
111
+ * slashes and Node resolves a package with backslashes on Windows.
110
112
  * @param directory - The directory to start from.
111
113
  * @param walk - The scopes to follow and the directories already visited.
112
114
  * @param starting - True for the directory the search starts from, whose development dependencies
113
115
  * are followed.
114
116
  * @returns Each package with its manifest, the starting directory last, and nothing for a
115
- * directory already visited or holding no manifest.
117
+ * directory already visited or without a manifest.
116
118
  */
117
119
  function walked(directory, walk, starting) {
118
- if (walk.seen.has(directory)) return [];
119
- walk.seen.add(directory);
120
- const manifest = manifestAt(directory);
120
+ const at = normalizePath(directory);
121
+ if (walk.seen.has(at)) return [];
122
+ walk.seen.add(at);
123
+ const manifest = manifestAt(at);
121
124
  if (manifest === void 0) return [];
122
- return [...namesIn(manifest, starting).filter((name) => walk.scopes.has(scopeOf(name) ?? "")).map((name) => packageAt(name, directory)).filter((at) => at !== void 0).flatMap((at) => walked(at, walk, false)), {
123
- at: directory,
125
+ return [...namesIn(manifest, starting).filter((name) => walk.scopes.has(scopeOf(name) ?? "")).map((name) => packageAt(name, at)).filter((dependency) => dependency !== void 0).flatMap((dependency) => walked(dependency, walk, false)), {
126
+ at,
124
127
  manifest
125
128
  }];
126
129
  }
127
130
  /**
128
- * Lists every catalogue a root can reach, its dependencies' first and its own last.
131
+ * Lists every catalogue on a root's graph, with the dependencies' catalogues first and the root's
132
+ * own last.
129
133
  *
130
134
  * @remarks
131
- * Where two packages declare the same language and namespace, the one later in the result wins
132
- * the merge, and the root goes last for that reason. Each package is resolved through Node's
133
- * resolution, so a workspace link and an installed copy are both found.
135
+ * Where two packages declare the same language and namespace, the merge applies the later one in
136
+ * the result, so the root goes last. Each package is resolved through Node's resolution, so the
137
+ * walk finds a workspace link and an installed copy alike.
134
138
  * @param root - The application or package directory.
135
139
  * @param scopes - The scopes to follow. Defaults to the root's own scope and {@link HOUSE}.
136
140
  * @returns The catalogues in merge order.
@@ -139,10 +143,12 @@ function found(root, scopes) {
139
143
  const manifest = manifestAt(root);
140
144
  const named = manifest === void 0 ? void 0 : text(manifest, "name");
141
145
  const application = manifest?.["private"] === true;
142
- return walked(root, {
146
+ const walk = {
143
147
  scopes: new Set(scopes ?? [scopeOf(named), HOUSE].filter((scope) => scope !== void 0)),
144
148
  seen: /* @__PURE__ */ new Set()
145
- }, true).flatMap((one) => cataloguesIn(one.at, text(one.manifest, "name") ?? basename(one.at), application && one.at === root));
149
+ };
150
+ const home = normalizePath(root);
151
+ return walked(root, walk, true).flatMap((one) => cataloguesIn(one.at, text(one.manifest, "name") ?? basename(one.at), application && one.at === home));
146
152
  }
147
153
  //#endregion
148
154
  //#region src/emit.ts
@@ -556,6 +562,21 @@ function problems(index, fallback) {
556
562
  }
557
563
  return found;
558
564
  }
565
+ /**
566
+ * The name that the specimen plugin registers under.
567
+ */
568
+ const SPECIMENS = "stealth:specimens";
569
+ /**
570
+ * Returns true when a configuration keeps the words of the catalogue pages.
571
+ *
572
+ * @remarks
573
+ * The root counts as an application where its manifest sets `private` to true, as it does for
574
+ * the application's own catalogues.
575
+ */
576
+ function keepsPages(config) {
577
+ if (manifestAt(config.root)?.["private"] !== true) return true;
578
+ return (config.plugins ?? []).some((plugin) => plugin.name === SPECIMENS);
579
+ }
559
580
  //#endregion
560
581
  //#region src/typegen.ts
561
582
  /**
@@ -682,7 +703,7 @@ function shapeOf(index) {
682
703
  */
683
704
  function refound(state, options) {
684
705
  const wanted = options.namespaces ?? (() => true);
685
- state.catalogues = found(state.resolved.root, options.scopes).filter((one) => wanted(one.namespace));
706
+ state.catalogues = found(state.resolved.root, options.scopes).filter((one) => wanted(one.namespace) && (state.pages || one.namespace !== "specimen"));
686
707
  state.index = indexed(state.catalogues);
687
708
  const shape = shapeOf(state.index);
688
709
  const reshaped = shape !== state.shape;
@@ -922,6 +943,23 @@ function offered(state, options) {
922
943
  };
923
944
  }
924
945
  /**
946
+ * Returns the state of a plugin before its first hook runs, with the working directory as its root.
947
+ */
948
+ function initial() {
949
+ return {
950
+ catalogues: [],
951
+ index: /* @__PURE__ */ new Map(),
952
+ pages: true,
953
+ resolved: {
954
+ command: "serve",
955
+ root: process.cwd()
956
+ },
957
+ sent: "",
958
+ shape: "",
959
+ stamp: join(scratchDir(SCRATCH, process.cwd()), STAMP)
960
+ };
961
+ }
962
+ /**
925
963
  * Creates the plugin that finds the catalogues, types their keys, and serves `virtual:i18n`.
926
964
  *
927
965
  * @remarks
@@ -935,17 +973,7 @@ function offered(state, options) {
935
973
  * replaces it.
936
974
  */
937
975
  function i18n(options = {}) {
938
- const state = {
939
- catalogues: [],
940
- index: /* @__PURE__ */ new Map(),
941
- resolved: {
942
- command: "serve",
943
- root: process.cwd()
944
- },
945
- sent: "",
946
- shape: "",
947
- stamp: join(scratchDir(SCRATCH, process.cwd()), STAMP)
948
- };
976
+ const state = initial();
949
977
  return {
950
978
  api: offered(state, options),
951
979
  /**
@@ -962,12 +990,13 @@ function i18n(options = {}) {
962
990
  for (const line of lines) this.warn(line);
963
991
  },
964
992
  /**
965
- * Records the resolved configuration and the stamp's path for that root, then runs the first
966
- * search and writes the types.
993
+ * Records the resolved configuration, the stamp's path for that root and whether the words of
994
+ * the catalogue pages are kept, then runs the first search and writes the types.
967
995
  *
968
996
  * @param config - The resolved configuration.
969
997
  */
970
998
  configResolved(config) {
999
+ state.pages = keepsPages(config);
971
1000
  state.resolved = config;
972
1001
  state.stamp = join(scratchDir(SCRATCH, config.root), STAMP);
973
1002
  refound(state, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stealthscale/vite-plugin-i18n",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Finds every catalogue an application can reach, types their keys, and answers the module it loads them from.",
5
5
  "keywords": [
6
6
  "i18n",
@@ -42,7 +42,7 @@
42
42
  "@stealthscale/testing-config": "^0.6.0",
43
43
  "@stealthscale/vite-config": "^0.8.0",
44
44
  "@stealthscale/vite-config-typescript": "^0.3.0",
45
- "@stealthscale/vite-plugin-base": "^0.5.0",
45
+ "@stealthscale/vite-plugin-base": "^0.5.1",
46
46
  "@types/node": "^26.6",
47
47
  "@vitest/coverage-v8": "5.0.3",
48
48
  "publint": "^0.3",
@@ -51,7 +51,7 @@
51
51
  "vitest": "5.0.3"
52
52
  },
53
53
  "peerDependencies": {
54
- "@stealthscale/vite-plugin-base": "^0.5.0",
54
+ "@stealthscale/vite-plugin-base": "^0.5.1",
55
55
  "vite": "^8.3"
56
56
  },
57
57
  "engines": {