@stealthscale/vite-plugin-i18n 0.1.0 → 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.
package/README.md CHANGED
@@ -37,12 +37,16 @@ is always fetched as one module, whatever it is split into.
37
37
 
38
38
  The search starts at the application and follows every package it depends on, through runtime
39
39
  dependencies, peers, and its own development dependencies. Only packages under the application's
40
- scope are followed, because a walk that read every dependency of a rendering engine would open
41
- hundreds of manifests to find no catalogue in any of them. Pass `scopes` to follow others.
40
+ scope and `@stealthscale` are followed, because a walk that read every dependency of a rendering
41
+ engine would open hundreds of manifests to find no catalogue in any of them. The plugin host renders
42
+ words from the catalogue `@stealthscale/sdk-host` publishes, so an application in any scope follows
43
+ the house's packages. Pass `scopes` to follow others, and list every scope the search follows.
42
44
 
43
45
  Packages are read deepest first and the application last, so where two name the same language and
44
46
  namespace the application's words win. A package is resolved the way its import is, so a workspace
45
- link and an installed copy are found alike.
47
+ link and an installed copy are found alike. The root is the application where its manifest is
48
+ `private`. A package built or tested on its own is a package, and its own files count as what it
49
+ ships.
46
50
 
47
51
  ## virtual:i18n
48
52
 
@@ -52,7 +56,13 @@ import { catalogues } from "virtual:i18n";
52
56
 
53
57
  `catalogues` carries the languages and namespaces found, the fallback language's words inlined so
54
58
  the first paint has them, and a loader that fetches any other language's namespace as one module.
55
- Set `eager` to inline every language and fetch nothing.
59
+ Set `eager` to inline every language and fetch nothing. A workspace with no catalogue at all gets
60
+ empty lists and an empty loader table, and the module runs.
61
+
62
+ Each module lists the catalogue files it read as files to watch, so a bundler that rebuilds on a
63
+ watched file's change rebuilds the module. The catalogues module also lists a stamp file. The plugin
64
+ rewrites the stamp whenever a catalogue file appears or disappears. A bundler watches only the files
65
+ a module read.
56
66
 
57
67
  Add the types with a triple-slash directive from a file the project already compiles.
58
68
 
@@ -77,14 +87,51 @@ A build fails on any of three faults:
77
87
 
78
88
  A dev server reports all three and keeps serving.
79
89
 
90
+ An application may override a key a package ships and may not add one to that package's namespace,
91
+ because a key nobody defines is a typo. A package under its own root adds what it ships.
92
+
80
93
  A plural form is checked against any form of the same key, and may write the count out in words:
81
94
  `één pagina` is accepted against `{{count}} page`. Every other placeholder is still required.
82
95
 
83
96
  ## Hot updates
84
97
 
85
- On a dev server a changed catalogue is sent to the page as an `i18n:catalogue` event carrying the
86
- pair merged afresh. The foundation replaces the words in place, so the page keeps its state. A
87
- catalogue appearing or disappearing regenerates the types as well.
98
+ A dev server watches the `locales` directory of every package the search found, including one
99
+ outside the project root. A file, a namespace or a language added under it is found without a
100
+ restart.
101
+
102
+ On a dev server that serves a module per file, a changed catalogue is sent to the page as an
103
+ `i18n:catalogue` event carrying the pair merged afresh. The foundation replaces the words in place,
104
+ so the page keeps its state, and the types are written again for a key or a placeholder the edit
105
+ added. A file joining a namespace that exists is pushed the same way. A language or a namespace
106
+ appearing or disappearing changes the set a running page has, so the catalogues module is handed
107
+ back for a reload rather than pushed.
108
+
109
+ A dev server that bundles does not call the hot update hook. There, `watchChange` sends the same
110
+ event and writes the types again. The server's watcher and the bundler's both report an edit, and
111
+ the plugin sends the event once. A language or a namespace appearing or disappearing reloads the
112
+ page, because a running page cannot take a new set from an event. A watching build writes the types
113
+ and the stamp the same way and does not send the event.
114
+
115
+ ## The plugin's api
116
+
117
+ Another plugin reads what the catalogue plugin found through its `api`. `cataloguesOf` returns it
118
+ from the plugins of a resolved configuration, and returns undefined where the configuration has no
119
+ `stealth:i18n` plugin.
120
+
121
+ ```ts
122
+ import { cataloguesOf } from "@stealthscale/vite-plugin-i18n";
123
+
124
+ const words = cataloguesOf(config.plugins);
125
+ ```
126
+
127
+ | Member | Returns |
128
+ | ---------------------------- | --------------------------------------------------------------------------- |
129
+ | `catalogues()` | Every catalogue the last search found and `namespaces` kept, in merge order |
130
+ | `fallback` | The language every key is defined in |
131
+ | `words(language, namespace)` | The pair's words with every file merged, as the page loads them |
132
+
133
+ `catalogues()` and `words()` read the last search when they are called, so they follow every change
134
+ on a dev server.
88
135
 
89
136
  ## Licence
90
137
 
@@ -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.7"},{"type":"application","name":"vite","version":"8.2.2"},{"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.4.0","bom-ref":"pkg:npm/%40stealthscale/testing-config@0.4.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.4.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/testing-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/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.3.0","bom-ref":"pkg:npm/%40stealthscale/testing@0.3.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.3.0","externalReferences":[{"url":"git+https://github.com/stealth-scale/config.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/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/vite-config-typescript","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/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.6.0","bom-ref":"pkg:npm/%40stealthscale/vite-config@0.6.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.6.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/vite-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/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.2.0","bom-ref":"pkg:npm/%40stealthscale/vite-plugin-base@0.2.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.2.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/vite-plugin-base","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/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.5.1","bom-ref":"pkg:npm/%40types/node@26.5.1","description":"TypeScript definitions for node","hashes":[{"alg":"SHA-512","content":"0b3366d857b35b8551fcb8c6eb251d88480b13fac043d4a58f9802bbf0b656b75c5bb2346a1359f0345b1d3ef3399eabdce36077f6ec4087926a80c6addd42ea"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40types/node@26.5.1","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":"4.1.11","bom-ref":"pkg:npm/%40vitest/coverage-v8@4.1.11","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"V8 coverage provider for Vitest","hashes":[{"alg":"SHA-512","content":"f0c5461059c921c7468dc6df2a67aaf33d296471f426556da15647f50feac14a7ac3216710950132bc3d0c26a3fab6b7bd28469a16af8da94c2213cdc5901473"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40vitest/coverage-v8@4.1.11","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":"0.3.1","bom-ref":"pkg:npm/%40voidzero-dev/vite-plus-core@0.3.1","author":"VoidZero Inc.","description":"The Unified Toolchain for the Web","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40voidzero-dev/vite-plus-core@0.3.1","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":"4.1.11","bom-ref":"pkg:npm/vitest@4.1.11","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"Next generation testing framework powered by Vite","hashes":[{"alg":"SHA-512","content":"7e1002acd5d489d21b19206be4595bb8190eed5582d59c8b9740cee025360eb42800fc57f3862cc6cf877864298a2e656565754388016534eee3d985f80e8477"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/vitest@4.1.11","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":"^20.0.0 || ^22.0.0 || >=24.0.0"}]}]},"component":{"type":"library","name":"vite-plugin-i18n","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/vite-plugin-i18n@0.1.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.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/vite-plugin-i18n","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/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.1.0"}]}
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"}]}
package/dist/index.d.mts CHANGED
@@ -1,73 +1,79 @@
1
1
  import { Plugin } from "vite";
2
2
  //#region src/find.d.ts
3
3
  /**
4
- * Locates every `locales/<language>/<namespace>.json` an application and its dependencies ship.
4
+ * Finds every catalogue file under `locales/<language>/` that an application and its dependencies
5
+ * ship.
5
6
  *
6
7
  * @remarks
7
- * A namespace is the first path segment under the language. `menu.json` and
8
+ * A namespace is the first path segment under the language, so `menu.json` and
8
9
  * `menu/sections/billing.json` both belong to the namespace `menu`, and the second contributes
9
- * its keys under `sections.billing`. A namespace is fetched as one module whatever it is split
10
- * into.
10
+ * its keys under `sections.billing`. A namespace is fetched as one module however many files it
11
+ * is split across.
11
12
  */
12
13
  /**
13
- * One catalogue file, with the language, namespace and package it belongs to.
14
+ * Describes one catalogue file: its language, its namespace and the package that ships it.
14
15
  */
15
16
  interface Catalogue {
16
17
  /**
17
- * The absolute path of the file, with forward slashes.
18
+ * Gives the absolute path of the file, with forward slashes.
18
19
  */
19
20
  readonly file: string;
20
21
  /**
21
- * The BCP 47 tag the directory is named after, such as `en` or `nl-BE`.
22
+ * Gives the BCP 47 tag the directory is named after, such as `en` or `nl-BE`.
22
23
  */
23
24
  readonly language: string;
24
25
  /**
25
- * The first path segment under the language, without its extension. `menu.json` and
26
+ * Gives the first path segment under the language, without its extension. `menu.json` and
26
27
  * `menu/sections.json` both give `menu`.
27
28
  */
28
29
  readonly namespace: string;
29
30
  /**
30
- * True when the application owns the file, false when a dependency ships it.
31
+ * Reports whether the application owns the file rather than a package shipping it.
32
+ *
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.
31
37
  */
32
38
  readonly own: boolean;
33
39
  /**
34
- * The name of the package the file came from.
40
+ * Gives the name of the package the file came from.
35
41
  */
36
42
  readonly owner: string;
37
43
  /**
38
- * The path below the namespace, joined with dots. `menu/sections/billing.json` gives
44
+ * Gives the path below the namespace, joined with dots. `menu/sections/billing.json` gives
39
45
  * `sections.billing`, and a file that is the namespace itself gives an empty string.
40
46
  */
41
47
  readonly prefix: string;
42
48
  }
43
49
  /**
44
- * The directory a package keeps its catalogues in.
50
+ * Gives the directory a package keeps its catalogues in.
45
51
  */
46
52
  export declare const LOCALES = "locales";
47
53
  /**
48
- * Returns every catalogue an application can reach, its dependencies' first and its own last.
54
+ * Lists every catalogue a root can reach, its dependencies' first and its own last.
49
55
  *
50
56
  * @remarks
51
- * When two packages declare the same language and namespace, the one later in the result wins the
52
- * merge, which puts the application last. Each package is resolved the way an import of it
53
- * resolves, so a workspace link and an installed copy are found alike.
54
- * @param root - The application directory.
55
- * @param scopes - The scopes to follow. Defaults to the application's own scope.
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.
60
+ * @param root - The application or package directory.
61
+ * @param scopes - The scopes to follow. Defaults to the root's own scope and {@link HOUSE}.
56
62
  * @returns The catalogues in merge order.
57
63
  */
58
64
  export declare function found(root: string, scopes?: readonly string[]): readonly Catalogue[];
59
65
  //#endregion
60
66
  //#region src/emit.d.ts
61
67
  /**
62
- * The specifier an application imports to reach its catalogues.
68
+ * Specifier an application imports to reach its catalogues.
63
69
  */
64
70
  export declare const ID = "virtual:i18n";
65
71
  /**
66
72
  * Builds the specifier one language's namespace is fetched under.
67
73
  *
68
74
  * @remarks
69
- * Neither a language tag nor a namespace contains a slash, so `pairOfId` splits the result back
70
- * without ambiguity.
75
+ * Neither a language tag nor a namespace contains a slash, so {@link pairOfId} splits the result
76
+ * back without ambiguity.
71
77
  * @param language - The BCP 47 tag.
72
78
  * @param namespace - The namespace name.
73
79
  * @returns A specifier such as `virtual:i18n/nl/menu`.
@@ -80,12 +86,12 @@ type Pair = Pick<Catalogue, "language" | "namespace">;
80
86
  /**
81
87
  * Splits a pair module's specifier back into its language and namespace.
82
88
  *
83
- * @param id - A specifier, with or without the resolution prefix.
89
+ * @param id - A specifier, with or without the resolved-module prefix.
84
90
  * @returns The pair, or undefined when the specifier addresses something else.
85
91
  */
86
92
  export declare function pairOfId(id: string): Pair | undefined;
87
93
  /**
88
- * The contents of one catalogue: keys mapped to strings, nested to any depth.
94
+ * Contents of one catalogue: keys mapped to strings, nested to any depth.
89
95
  */
90
96
  interface Words {
91
97
  readonly [key: string]: string | Words;
@@ -95,7 +101,7 @@ interface Words {
95
101
  */
96
102
  type CatalogueIndex = ReadonlyMap<string, ReadonlyMap<string, readonly Catalogue[]>>;
97
103
  /**
98
- * Indexes catalogues by language and namespace, preserving the order they were found in.
104
+ * Indexes catalogues by language and namespace, keeping the order they were found in.
99
105
  *
100
106
  * @param catalogues - Every catalogue found.
101
107
  */
@@ -104,12 +110,12 @@ export declare function indexed(catalogues: readonly Catalogue[]): CatalogueInde
104
110
  * Generates the module an application imports its catalogues from.
105
111
  *
106
112
  * @remarks
107
- * The fallback language is inlined so the first paint needs no request. Every other language is
108
- * reached through the loader. Under `eager` every language is inlined instead and the loader
109
- * fetches nothing, which costs one larger bundle and saves a request per language.
113
+ * The fallback language is inlined, so the first paint needs no request. Every other language is
114
+ * fetched through the loader. Under `eager` every language is inlined and the loader fetches
115
+ * nothing, trading a larger bundle for one saved request per language.
110
116
  * @param index - The indexed catalogues.
111
117
  * @param fallback - The language that defines every key.
112
- * @param eager - Inlines every language when true.
118
+ * @param eager - Whether to inline every language rather than the fallback alone.
113
119
  * @returns The module as JavaScript source.
114
120
  */
115
121
  export declare function cataloguesModule(index: CatalogueIndex, fallback: string, eager?: boolean): string;
@@ -120,7 +126,7 @@ export declare function cataloguesModule(index: CatalogueIndex, fallback: string
120
126
  */
121
127
  interface Problem {
122
128
  /**
123
- * The absolute path of the file holding the fault.
129
+ * Absolute path of the file the fault is in.
124
130
  */
125
131
  readonly file: string;
126
132
  /**
@@ -128,31 +134,59 @@ interface Problem {
128
134
  */
129
135
  readonly key: string;
130
136
  /**
131
- * The fault, phrased as a clause that follows the key.
137
+ * The fault, phrased as a clause that follows the key in the reported line.
132
138
  */
133
139
  readonly says: string;
134
140
  }
135
141
  /**
136
- * Validates every catalogue: the fallback's files against each other, then each translation against
137
- * the fallback.
142
+ * Validates the fallback's files against each other, then every translation against the fallback.
138
143
  *
144
+ * @remarks
145
+ * An index with no entry for the fallback language reports nothing, on the grounds that there is
146
+ * nothing to check against.
139
147
  * @param index - The indexed catalogues.
140
148
  * @param fallback - The language that defines every key.
141
- * @returns Every fault, the fallback's first, then in file order.
149
+ * @returns Every fault, the fallback's first and the rest in file order.
142
150
  */
143
151
  export declare function problems(index: CatalogueIndex, fallback: string): readonly Problem[];
144
152
  //#endregion
145
153
  //#region src/plugin.d.ts
146
154
  /**
147
- * The custom event name a changed catalogue is sent to the page under.
155
+ * Describes what the catalogue plugin offers another plugin through its `api`: the catalogues the
156
+ * page loads, and their words.
157
+ */
158
+ interface CataloguesApi {
159
+ /**
160
+ * Returns every catalogue the last search found and the namespaces option kept, in merge order.
161
+ */
162
+ readonly catalogues: () => readonly Catalogue[];
163
+ /**
164
+ * The language every key is defined in.
165
+ */
166
+ readonly fallback: string;
167
+ /**
168
+ * Returns one language's namespace with every file of the pair merged, or an empty object where
169
+ * no catalogue names the pair.
170
+ */
171
+ readonly words: (language: string, namespace: string) => Words;
172
+ }
173
+ /**
174
+ * Returns the catalogue plugin's `api` among a configuration's plugins, or undefined where the
175
+ * configuration has no catalogue plugin.
176
+ *
177
+ * @param plugins - The plugins of a resolved configuration.
178
+ */
179
+ export declare function cataloguesOf(plugins: readonly Plugin[]): CataloguesApi | undefined;
180
+ /**
181
+ * Name of the custom event a changed catalogue is sent to the page under.
148
182
  *
149
183
  * @remarks
150
184
  * The foundation listens for the same string. Neither package imports the other, so the name is a
151
- * contract between them rather than a shared constant.
185
+ * contract between them and not a shared constant.
152
186
  */
153
187
  export declare const EVENT = "i18n:catalogue";
154
188
  /**
155
- * The payload the change event carries.
189
+ * The payload sent to the page under {@link EVENT}.
156
190
  */
157
191
  interface Changed {
158
192
  /**
@@ -160,7 +194,7 @@ interface Changed {
160
194
  */
161
195
  readonly language: string;
162
196
  /**
163
- * The namespace.
197
+ * The namespace that changed.
164
198
  */
165
199
  readonly namespace: string;
166
200
  /**
@@ -169,11 +203,11 @@ interface Changed {
169
203
  readonly words: Readonly<Record<string, unknown>>;
170
204
  }
171
205
  /**
172
- * Configures the catalogues.
206
+ * The settings a repository configures the plugin with. Every member has a default.
173
207
  */
174
208
  interface Options {
175
209
  /**
176
- * Inlines every language rather than the fallback alone, so nothing is fetched. Off by default.
210
+ * Inlines every language, not the fallback alone, so the page fetches nothing. Off by default.
177
211
  */
178
212
  readonly eager?: boolean | undefined;
179
213
  /**
@@ -185,7 +219,8 @@ interface Options {
185
219
  */
186
220
  readonly namespaces?: ((namespace: string) => boolean) | undefined;
187
221
  /**
188
- * The scopes whose packages are searched. The application's own scope by default.
222
+ * The scopes whose packages are searched. The application's own scope and `@stealthscale` by
223
+ * default.
189
224
  */
190
225
  readonly scopes?: readonly string[] | undefined;
191
226
  /**
@@ -195,13 +230,17 @@ interface Options {
195
230
  readonly types?: false | string | undefined;
196
231
  }
197
232
  /**
198
- * Builds the plugin that finds the catalogues, types their keys, and serves `virtual:i18n`.
233
+ * Creates the plugin that finds the catalogues, types their keys, and serves `virtual:i18n`.
199
234
  *
200
235
  * @remarks
201
- * On a dev server a catalogue change is pushed to the page as an event rather than a reload, so
202
- * the page keeps its state. In a build an invalid catalogue throws instead.
203
- * @param options - Where to search and what to write. `Options` documents every member.
204
- * @returns The plugin.
236
+ * On a dev server the plugin sends a changed catalogue to the page as an event and not as a
237
+ * reload, so the page keeps its state. A build throws on an invalid catalogue. Every module
238
+ * lists the files it read as files to watch, so a bundler that rebuilds on a change rebuilds the
239
+ * module.
240
+ * @param options - Where to search and what to write. {@link Options} Documents every member, and
241
+ * every one has a default.
242
+ * @returns The plugin, with its state set to the working directory until `configResolved`
243
+ * replaces it.
205
244
  */
206
245
  export declare function i18n(options?: Options): Plugin;
207
246
  //#endregion
@@ -219,4 +258,4 @@ export declare const FOUNDATION = "@stealthscale/provider-i18n";
219
258
  */
220
259
  export declare function declared(index: CatalogueIndex, fallback: string): string;
221
260
  //#endregion
222
- export type { Catalogue, CatalogueIndex, Changed, Options, Pair, Problem, Words };
261
+ export type { Catalogue, CatalogueIndex, CataloguesApi, Changed, Options, Pair, Problem, Words };