@secundus-studio/stift-generator 0.0.0-stage → 0.4.31
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/CHANGELOG.md +155 -0
- package/LICENSE +41 -0
- package/README.md +50 -2
- package/dist/index.cjs +37 -0
- package/dist/index.d.cts +1149 -0
- package/dist/index.d.ts +1149 -0
- package/dist/index.js +37 -0
- package/package.json +57 -3
- package/skills/authoring-translations/SKILL.md +142 -0
- package/skills/config/REFERENCE.md +145 -0
- package/skills/config/SKILL.md +62 -0
- package/skills/params-units/SKILL.md +107 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# @secundus-studio/stift-generator
|
|
2
|
+
|
|
3
|
+
## 0.4.31
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @secundus-studio/stift-core@0.4.31
|
|
8
|
+
|
|
9
|
+
## 0.4.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Republish 0.4.1 as 0.4.2 with installable tarballs: the 0.4.1 artifacts carried literal `workspace:*` dependency ranges and could not be installed by any package manager. No code changes.
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
- @secundus-studio/stift-core@0.4.2
|
|
16
|
+
|
|
17
|
+
## 0.4.1
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- ec4a6c1: Replace the three per-concern persistence options with one persisted-state
|
|
22
|
+
config. `createStift` no longer takes `localePersistence`, `paramsPersistence`,
|
|
23
|
+
and `unitsPersistence`; the active locale, context-param overrides, and unit
|
|
24
|
+
overrides now live in one state store keyed `${prefix}${field}` (default
|
|
25
|
+
`__stift_locale`, `__stift_gender`, `__stift_length`, …) and backed by
|
|
26
|
+
`state.storage` (`'webStorage'` default, `'cookie'`, or `'none'`). Reads are
|
|
27
|
+
synchronous, so persisted values apply before the first render — no flash.
|
|
28
|
+
`state.prefix` and `state.storage` are configurable globally in
|
|
29
|
+
`stift.config.ts`, and per-field `persist: false` opts a param/unit out.
|
|
30
|
+
|
|
31
|
+
Add `createStiftApp()`: resolves a lazy persister factory and returns a
|
|
32
|
+
`boot()` that owns the offline-first `detectLocale → setLocale → initialize`
|
|
33
|
+
loop, so apps stop hand-writing the async singleton.
|
|
34
|
+
|
|
35
|
+
Detection gains a reserved `'persisted'` detector for the stored locale — rank
|
|
36
|
+
it in `detection.order` where the user's saved choice should sit; the
|
|
37
|
+
`detectors.custom` glue is no longer needed. `serializeStiftState`/`hydrate`
|
|
38
|
+
now also carry param/unit overrides so a backend-resolved value renders on the
|
|
39
|
+
first client frame.
|
|
40
|
+
|
|
41
|
+
BREAKING (pre-1.0): `createStift({ localePersistence | paramsPersistence |
|
|
42
|
+
unitsPersistence })` is removed — move to `state`.
|
|
43
|
+
`@secundus-studio/stift-tanstack-router-plugin`'s
|
|
44
|
+
`localStoragePersister`/`cookiePersister` now default to `__stift_locale`
|
|
45
|
+
(previously `stift:locale` / `locale`) so the router and the Stift instance
|
|
46
|
+
share one persisted choice.
|
|
47
|
+
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- Updated dependencies [ec4a6c1]
|
|
51
|
+
- @secundus-studio/stift-core@0.4.1
|
|
52
|
+
|
|
53
|
+
## 0.4.0
|
|
54
|
+
|
|
55
|
+
### Minor Changes
|
|
56
|
+
|
|
57
|
+
- d60faf6: Split the pack catalog into a slim `catalog.json` index plus one
|
|
58
|
+
content-addressed shard per locale. The index (namespaces, sizes,
|
|
59
|
+
coverage, shard URL + hash) is all that's inlined or fetched for an
|
|
60
|
+
update check; per-namespace URLs and hashes move to
|
|
61
|
+
`catalog/<locale>.<hash>.json`, fetched lazily and never re-downloaded
|
|
62
|
+
for locales that didn't change. Update checks short-circuit at the
|
|
63
|
+
locale level via the shard hash, so a one-key edit no longer invalidates
|
|
64
|
+
every namespace in a locale.
|
|
65
|
+
|
|
66
|
+
BREAKING (pre-1.0): `PackCatalog` is now an object with a `buildId` and a
|
|
67
|
+
`locales[]` array of index rows (not a bare entry array), and the
|
|
68
|
+
per-namespace `namespaces[]` detail lives in the new `LocaleShard`
|
|
69
|
+
type. Code that read `PackCatalogEntry.namespaces`/`.url` directly must
|
|
70
|
+
go through the runtime's lazy shard source or `parseLocaleShard`.
|
|
71
|
+
|
|
72
|
+
### Patch Changes
|
|
73
|
+
|
|
74
|
+
- Updated dependencies [d60faf6]
|
|
75
|
+
- @secundus-studio/stift-core@0.4.0
|
|
76
|
+
|
|
77
|
+
## 0.3.0
|
|
78
|
+
|
|
79
|
+
### Minor Changes
|
|
80
|
+
|
|
81
|
+
- 71e677d: Rename the library from l10n to Stift. Packages move to `@secundus-studio/stift-*`, the config file is `stift.config.ts`, the CLI is `stift`, and the API follows (`createStift`, `Stift`, `StiftProvider`, `StiftConfig`, `virtual:stift/runtime`). BREAKING (pre-1.0): update imports, the config filename, and pack tooling; old `.dat` packs (I18NKIT magic) are rejected by the new decoder and re-fetched, and renamed storage keys, cookie names, and devtools routes start fresh.
|
|
82
|
+
|
|
83
|
+
### Patch Changes
|
|
84
|
+
|
|
85
|
+
- Updated dependencies [71e677d]
|
|
86
|
+
- @secundus-studio/stift-core@0.3.0
|
|
87
|
+
|
|
88
|
+
## 0.2.0
|
|
89
|
+
|
|
90
|
+
### Minor Changes
|
|
91
|
+
|
|
92
|
+
- 13824b6: Remove `timezones` and `calendars` from `l10n.config.ts` and make `numberingSystems` optional. Timezones and calendars are per-user runtime values from the browser's own ICU data, not something the project ships — the format call-sites take plain strings and `Intl` still throws on invalid values. BREAKING (pre-1.0): delete those keys from your config; the format option types widen to `string`.
|
|
93
|
+
- 1770b34: Add `security.encoding: "json"` for plain readable packs. Builds emit raw `.json` per locale×namespace with catalog URLs to match, and the runtime fetches and parses them with no codec, decompression, or key — offline persisters, update checks, and devtools live-edit keep working unchanged.
|
|
94
|
+
|
|
95
|
+
### Patch Changes
|
|
96
|
+
|
|
97
|
+
- fe77724: Reject `messageFormat: "icu-mf2"` at config load. Only `"icu-mf1"` has a formatter engine, so selecting MF2 now fails fast instead of silently building MF1 packs.
|
|
98
|
+
- Updated dependencies [13824b6]
|
|
99
|
+
- Updated dependencies [1770b34]
|
|
100
|
+
- @secundus-studio/l10n-core@0.2.0
|
|
101
|
+
|
|
102
|
+
## 0.1.0
|
|
103
|
+
|
|
104
|
+
### Minor Changes
|
|
105
|
+
|
|
106
|
+
- 275184d: Pack truth, catalog v2, boot modes, SSR hydration, TTL, and a new Cache API persister.
|
|
107
|
+
|
|
108
|
+
**Core**
|
|
109
|
+
|
|
110
|
+
- `pack.rehydrateInstalled()` + `initialize()` seeds reactive pack status from
|
|
111
|
+
the persister — returning visits read `installed` from the first notification.
|
|
112
|
+
- Honest lifecycle: per-namespace `__meta` writes (a failed install/refresh
|
|
113
|
+
never corrupts the previous good pack), in-flight healing, `error` (not fake
|
|
114
|
+
`idle`) on partial wipes, `installLocale` failures via `hooks.onError`.
|
|
115
|
+
- Byte-true `bytesReceived`/`bytesTotal` from the catalog; unified "installed"
|
|
116
|
+
definition (`isInstalled`/`getPackSize`/status all key on `__meta`);
|
|
117
|
+
`isNamespaceAvailable` honors cache ∪ persister.
|
|
118
|
+
- `pack.durability` (`'durable' | 'memory' | 'none'`); background full-locale
|
|
119
|
+
installs skip catalog-matching namespaces.
|
|
120
|
+
- `pack.checkAllForUpdates()`: one catalog fetch diffed against every
|
|
121
|
+
persisted locale.
|
|
122
|
+
- `createI18n({ persisterTtlMs })`: expired packs stay usable, report
|
|
123
|
+
`reason: 'ttl-expired'`, and refresh in the background on `activate`.
|
|
124
|
+
- `serializeI18nState()` + `createI18n({ hydrate })`: SSR hydration without an
|
|
125
|
+
SSR boot mode. `scope()` single-tuple overload.
|
|
126
|
+
- Deprecated `interpolate`/`plainFormatterEngine` (ICU MF1 supersedes them).
|
|
127
|
+
|
|
128
|
+
**Catalog (generator + vite-plugin)**
|
|
129
|
+
|
|
130
|
+
- Content-hashed pack URLs (`<ns>.<hash>.dat`), identical in dev and prod.
|
|
131
|
+
- Conditional catalog ping (ETag/`If-None-Match`, `no-cache`, no cache-buster).
|
|
132
|
+
- Catalog entries gain `buildId`, `publishedAt`, `coverage` (authored fraction
|
|
133
|
+
from completion, key-presence fallback for direct `compileAll` use).
|
|
134
|
+
|
|
135
|
+
**React**
|
|
136
|
+
|
|
137
|
+
- `I18nProvider onBootError` (rejected `boot` reports instead of swallowing).
|
|
138
|
+
- Missing translator type exports (`MultiScopedTranslationResult`,
|
|
139
|
+
`BoundMultiT`, multi/rich/markdown variants); suspense single-flight keyed
|
|
140
|
+
per i18n instance.
|
|
141
|
+
|
|
142
|
+
**Devtools**: snapshot exposes `packDurability`; Pack state hides
|
|
143
|
+
install/delete affordances unless durable; memory-cache buckets relabeled.
|
|
144
|
+
|
|
145
|
+
**OPFS**: write queue self-heals after a transient failure.
|
|
146
|
+
|
|
147
|
+
**New package** `@secundus-studio/l10n-persisters`: OPFS, IndexedDB (idb-keyval), and
|
|
148
|
+
Cache Storage persisters (`/opfs`, `/idb-keyval`, `/cache-api` subpaths) plus
|
|
149
|
+
a `createBestEffortPersister()` fallback chain.
|
|
150
|
+
|
|
151
|
+
### Patch Changes
|
|
152
|
+
|
|
153
|
+
- Updated dependencies [275184d]
|
|
154
|
+
- Updated dependencies [275184d]
|
|
155
|
+
- @secundus-studio/l10n-core@0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Copyright (c) 2026 Ali Alkhateeb. All rights reserved.
|
|
2
|
+
|
|
3
|
+
SECUNDUS L10N — PROPRIETARY LICENSE
|
|
4
|
+
|
|
5
|
+
The compiled software packages distributed under the @secundus-studio scope on
|
|
6
|
+
the public npm registry (the "Software") are proprietary to Ali Alkhateeb. They
|
|
7
|
+
are licensed, not sold.
|
|
8
|
+
|
|
9
|
+
1. Grant. Subject to this license, Ali Alkhateeb grants you a non-exclusive,
|
|
10
|
+
non-transferable, royalty-free right to install and use the Software, in
|
|
11
|
+
object-code form, as a dependency of your own applications, including
|
|
12
|
+
commercial and closed-source applications.
|
|
13
|
+
|
|
14
|
+
2. Restrictions. You may not:
|
|
15
|
+
(a) copy, publish, distribute, sublicense, or sell the Software, or make
|
|
16
|
+
it available to any third party, except as embedded in your own
|
|
17
|
+
application;
|
|
18
|
+
(b) modify, translate, reverse engineer, decompile, or disassemble the
|
|
19
|
+
Software, or attempt to derive its source code;
|
|
20
|
+
(c) remove or alter any copyright, license, or proprietary notices.
|
|
21
|
+
|
|
22
|
+
3. No source code. This license grants no rights to the source code of the
|
|
23
|
+
Software. The source is confidential, is not distributed, and remains the
|
|
24
|
+
property of Ali Alkhateeb.
|
|
25
|
+
|
|
26
|
+
4. Contributions. Any feedback, bug report, or suggestion you provide may be
|
|
27
|
+
used by Ali Alkhateeb without restriction or obligation.
|
|
28
|
+
|
|
29
|
+
5. Termination. This license terminates automatically if you breach any of its
|
|
30
|
+
terms. On termination you must stop using the Software and delete all
|
|
31
|
+
copies in your possession or control.
|
|
32
|
+
|
|
33
|
+
6. Disclaimer. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
34
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
35
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
36
|
+
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
37
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
38
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
39
|
+
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
40
|
+
|
|
41
|
+
For licensing inquiries, contact hello@secundus.studio.
|
package/README.md
CHANGED
|
@@ -1,3 +1,51 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @secundus-studio/stift-generator
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Bundler-agnostic build core: config loading/validation, namespace discovery, pack compiler, and typegen.
|
|
4
|
+
|
|
5
|
+
## What it is
|
|
6
|
+
|
|
7
|
+
The shared build engine behind [`@secundus-studio/stift-cli`](https://www.npmjs.com/package/@secundus-studio/stift-cli) and [`@secundus-studio/stift-vite-plugin`](https://www.npmjs.com/package/@secundus-studio/stift-vite-plugin): config loading and validation (`stift.config.ts`), locale/namespace discovery, message-shape extraction, the pack compiler (`.dat` packs plus `catalog.json` and per-locale shards), and `Register` typegen (`stift.gen.d.ts`). Most users meet it through the CLI or the Vite plugin and never install it directly — reach for it when you need the pipeline programmatically (custom scripts, tests, or your own tooling).
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @secundus-studio/stift-generator
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Generator } from '@secundus-studio/stift-generator'
|
|
17
|
+
|
|
18
|
+
const generator = new Generator({ root: process.cwd() })
|
|
19
|
+
|
|
20
|
+
// Load stift.config.ts, discover locales/<locale>/<namespace>.json,
|
|
21
|
+
// extract param shapes, diff locales, emit src/stift.gen.d.ts.
|
|
22
|
+
await generator.generateAsync()
|
|
23
|
+
|
|
24
|
+
// Compile every (locale, namespace) into packs + catalog.json + shards.
|
|
25
|
+
await generator.compileAsync({ outDir: 'dist/packs' })
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`stift.config.ts` is authored with the `defineConfig` helper and resolved with `loadConfig` / `findConfigFile`.
|
|
29
|
+
|
|
30
|
+
## API
|
|
31
|
+
|
|
32
|
+
- `Generator` — one-shot pipeline: `generateAsync()` (config → discovery → extraction → diff → `stift.gen.d.ts`) and `compileAsync()` (packs + catalog + shards, written to `outDir` or returned in memory).
|
|
33
|
+
- `DEFAULT_OUTPUT_REL` — default relative output path for the generated declaration file.
|
|
34
|
+
- `compileAll` — compile every (locale, namespace) source into pack bytes, the catalog index, and one shard per locale.
|
|
35
|
+
- `compileNamespace` — compile a single namespace message map into pack bytes.
|
|
36
|
+
- `resolveCompileSecurity` — resolve the effective compiler security config from a loaded config (with static-key fallback).
|
|
37
|
+
- `loadConfig` / `findConfigFile` — resolve and schema-validate `stift.config.ts`.
|
|
38
|
+
- `defineConfig` — typed helper for authoring `stift.config.ts`.
|
|
39
|
+
- `discoverConvention` — walk `locales/<locale>/<namespace>.json` (nested namespaces supported) into a stable discovery result.
|
|
40
|
+
- `generateTypegen` — emit the `stift.gen.d.ts` `Register` declaration from config plus extraction.
|
|
41
|
+
- `extractShapes` / `deriveLocaleShape` — infer union-across-locale param shapes from message sources.
|
|
42
|
+
- `diffLocales` — diff key coverage across supported locales against the default locale.
|
|
43
|
+
- `parseMessage` / `collectFunctions` — ICU message parsing and function collection (re-exported from core).
|
|
44
|
+
- `configSchema` — schema the loaded config is validated against.
|
|
45
|
+
- Type-only: `GenerateOptions`, `GenerateResult`, `CompileOptions`, `CompileResult`, `CompileAllOptions`, `CompileAllResult`, `CompileNamespaceOptions`, `CompiledNamespaceOutput`, `CompiledNamespaceCacheEntry`, `CompiledCache`, `LocaleShardOutput`, `CompileSecurityConfig`, `StiftConfig`, `ParamsConfig`, `ContextParamConfig`, `NamespacesConfig`, `DetectionConfig`, `LoadConfigOptions`, `LoadedConfig`, `DiscoveredNamespace`, `DiscoveryResult`, `ExtractResult`, `KeyShape`, `KeyLocaleShape`, `MessageSourceInput`, `ParamType`, `DiffResult`, `MissingDiffIssue`, `GenerateTypegenOptions`, `IcuNode`, `IcuOption`, `ParseResult`.
|
|
46
|
+
|
|
47
|
+
## Docs
|
|
48
|
+
|
|
49
|
+
- Config file: https://stift.secundus.studio/docs/latest/vanilla/configuration/config-file
|
|
50
|
+
- Build pipeline: https://stift.secundus.studio/docs/latest/vanilla/tooling/build
|
|
51
|
+
- Authoring messages: https://stift.secundus.studio/docs/latest/vanilla/authoring/messages
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';var N=require('fs/promises'),v=require('path'),q=require('fs'),jiti=require('jiti'),zod=require('zod'),stiftCore=require('@secundus-studio/stift-core'),msgpack=require('@secundus-studio/stift-core/codecs/msgpack'),cbor=require('@secundus-studio/stift-core/codecs/cbor'),node=require('@secundus-studio/stift-core/decompress/node');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var N__namespace=/*#__PURE__*/_interopNamespace(N);var v__namespace=/*#__PURE__*/_interopNamespace(v);var q__namespace=/*#__PURE__*/_interopNamespace(q);var Te=Object.defineProperty;var c=(e,t)=>Te(e,"name",{value:t,configurable:true});function Re(e){if(typeof e!="string"||e.trim()==="")return false;try{return new Intl.Locale(e),!0}catch{return false}}c(Re,"localeTagGuard");var G=zod.z.string().refine(Re);function Ne(e,t){if(typeof t!="string"||t.trim()==="")return false;if(e==="numberingSystem")try{return Intl.supportedValuesOf(e).includes(t)}catch{return true}try{return new Intl.NumberFormat("und",{style:"currency",currency:t}),!0}catch{return false}}c(Ne,"engineValueGuard");function ue(e,t){return zod.z.union([zod.z.literal("any"),zod.z.array(zod.z.string().min(1).refine(o=>Ne(e,o),{message:t})).min(1)])}c(ue,"engineList");var Ie=zod.z.object({name:zod.z.string().min(1),values:zod.z.array(zod.z.string().min(1)).min(1),defaults:zod.z.record(zod.z.string().min(1),zod.z.string()),persist:zod.z.boolean().optional()}),$e=zod.z.object({context:zod.z.array(Ie).optional()}).optional(),Oe=new Set(Object.values(stiftCore.UNITS_BY_CATEGORY).flat()),Z=zod.z.string().min(1).refine(e=>Oe.has(e),{message:"not a sanctioned ECMA-402 unit (docs/17-units.md)"}),Fe=zod.z.union([zod.z.literal("all"),zod.z.record(zod.z.enum(["length","mass","area","temperature","digital"]),zod.z.object({supportedValues:zod.z.union([zod.z.literal("all"),zod.z.array(Z).min(1)]),defaults:zod.z.object({all:Z}).catchall(Z),persist:zod.z.boolean().optional()}))]).optional(),Ee=zod.z.object({tier:zod.z.enum(["none","obfuscated","encrypted-static","encrypted-session"]),encoding:zod.z.enum(["msgpack","cbor","json"]),compression:zod.z.enum(["none","gzip","brotli"]),staticKey:zod.z.string().min(1).optional()}).superRefine((e,t)=>{e.encoding==="json"&&(e.tier!=="none"&&t.addIssue({code:zod.z.ZodIssueCode.custom,path:["tier"],message:`encoding "json" requires tier "none" (got "${e.tier}") \u2014 JSON packs are plain readable bytes`}),e.compression!=="none"&&t.addIssue({code:zod.z.ZodIssueCode.custom,path:["compression"],message:`encoding "json" requires compression "none" (got "${e.compression}") \u2014 JSON packs are served uncompressed`}));}).optional(),De=zod.z.object({maxCachedNamespaces:zod.z.number().int().positive().optional(),evictionPolicy:zod.z.enum(["lru","ttl"]).optional(),ttlMs:zod.z.number().positive().optional()}).optional(),Ke=zod.z.enum(["lazy-per-namespace","critical-then-full-background","boot-all"]).optional(),Ae=zod.z.object({order:zod.z.array(zod.z.string()).min(1),timeout:zod.z.union([zod.z.number(),zod.z.record(zod.z.string(),zod.z.number()).and(zod.z.object({default:zod.z.number()})),zod.z.function()]).optional(),url:zod.z.object({strategy:zod.z.enum(["path-prefix","subdomain","domain","query-param"]),paramName:zod.z.string().optional(),domainMap:zod.z.record(zod.z.string(),G).optional()}).optional(),cookie:zod.z.object({name:zod.z.string().optional(),maxAge:zod.z.number().optional(),path:zod.z.string().optional(),sameSite:zod.z.enum(["strict","lax","none"]).optional(),secure:zod.z.boolean().optional()}).optional(),fallback:G.optional()}).optional(),Ue=zod.z.object({prefix:zod.z.string().min(1).optional(),storage:zod.z.enum(["webStorage","cookie","none"]).optional()}).optional(),B=zod.z.object({locales:zod.z.object({default:G,supported:zod.z.array(G).min(1)}),numberingSystems:ue("numberingSystem","not a numbering system this engine recognizes").optional(),currencies:ue("currency","not a currency code this engine recognizes").optional(),namespaces:zod.z.object({dir:zod.z.string().min(1),discovery:zod.z.enum(["convention","manifest"]),default:zod.z.array(zod.z.string())}),messageFormat:zod.z.enum(["icu-mf1","icu-mf2"]).superRefine((e,t)=>{e==="icu-mf2"&&t.addIssue({code:zod.z.ZodIssueCode.custom,message:'messageFormat "icu-mf2" is not implemented yet \u2014 use "icu-mf1"'});}),params:$e,units:Fe,security:Ee,memory:De,loadingStrategy:Ke,bootExclude:zod.z.array(zod.z.string()).optional(),detection:Ae,state:Ue}).superRefine((e,t)=>{e.locales.supported.includes(e.locales.default)||t.addIssue({code:zod.z.ZodIssueCode.custom,path:["locales","supported"],message:`default locale "${e.locales.default}" must be listed in supported locales`});let o=e.params?.context;if(o){let n=e.locales.supported,a=new Set;o.forEach((i,g)=>{let l=["params","context",g];a.has(i.name)&&t.addIssue({code:zod.z.ZodIssueCode.custom,path:[...l,"name"],message:`context param name "${i.name}" is declared more than once`}),a.add(i.name),"all"in i.defaults||t.addIssue({code:zod.z.ZodIssueCode.custom,path:[...l,"defaults"],message:`context param "${i.name}" must declare an "all" fallback default`});let u=c((m,b)=>{i.values.includes(m)||t.addIssue({code:zod.z.ZodIssueCode.custom,path:b,message:`defaults value "${m}" for context param "${i.name}" is not one of its values [${i.values.join(", ")}]`});},"check");for(let[m,b]of Object.entries(i.defaults))u(b,[...l,"defaults",m]),m!=="all"&&!n.includes(m)&&t.addIssue({code:zod.z.ZodIssueCode.custom,path:[...l,"defaults",m],message:`defaults locale "${m}" is not in locales.supported`});});}let s=e.units;if(s&&s!=="all"){let n=e.locales.supported;for(let[a,i]of Object.entries(s)){let g=["units",a],l=i.supportedValues,u=i.defaults?.all;Array.isArray(l)&&u&&!l.includes(u)&&t.addIssue({code:zod.z.ZodIssueCode.custom,path:[...g,"defaults","all"],message:`default unit "${u}" for "${a}" is not in supportedValues [${l.join(", ")}]`});for(let[m]of Object.entries(i.defaults??{}))m!=="all"&&(n.includes(m)||t.addIssue({code:zod.z.ZodIssueCode.custom,path:[...g,"defaults",m],message:`units locale "${m}" is not in locales.supported`}));}}});var He=["stift.config.ts","stift.config.mts","stift.config.js"];function me(e){for(let t of He){let o=v__namespace.join(e,t);if(q__namespace.existsSync(o))return o}}c(me,"findConfigFile");async function H(e={}){let t=e.root??process.cwd(),o=e.configFile??me(t)??(()=>{throw new Error(`No stift.config.ts found under "${t}". Create one or pass configFile.`)})(),n=await jiti.createJiti((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)),{interopDefault:true,moduleCache:false}).import(o),a=Je(n),i=B.safeParse(a);if(!i.success){let g=i.error.issues.map(l=>` - ${l.path.join(".")}: ${l.message}`).join(`
|
|
2
|
+
`);throw new Error(`Invalid stift config at ${o}:
|
|
3
|
+
${g}`)}return {config:i.data,file:o}}c(H,"loadConfig");function Je(e){return e&&typeof e=="object"&&"default"in e&&e.default?e.default:e}c(Je,"constructConfig");async function J(e,t="locales"){let o=v__namespace.join(e,t),s;try{s=await q__namespace.promises.readdir(o,{withFileTypes:!0});}catch{return {byLocale:new Map,all:[]}}let n=new Map,a=[];for(let i of s){if(!i.isDirectory())continue;let g=i.name,l=[];await de(v__namespace.join(o,g),g,v__namespace.join(o,g),l),l.length>0&&(n.set(g,l),a.push(...l));}return a.sort((i,g)=>(i.locale+"/"+i.namespace).localeCompare(g.locale+"/"+g.namespace)),{byLocale:n,all:a}}c(J,"discoverConvention");async function de(e,t,o,s){let n;try{n=await q__namespace.promises.readdir(e,{withFileTypes:!0});}catch{return}for(let a of n){let i=v__namespace.join(e,a.name);if(a.isDirectory())await de(i,t,o,s);else if(a.isFile()&&a.name.endsWith(".json")){let l=v__namespace.relative(o,i).split(v__namespace.sep).join("/").replace(/\.json$/,"");s.push({locale:t,namespace:l,file:i});}}}c(de,"walkNamespaceDir");function V(e){return typeof e=="string"?e:e.value}c(V,"messageValue");function ye(e){let{ast:t}=stiftCore.parseMessage(e),o={};return he(t,o),o}c(ye,"deriveLocaleShape");function he(e,t){for(let o of e){if(o.type!=="argument"&&o.type!=="function")continue;let s=o.name,n=t[s];if(o.argType&&o.argType.toLowerCase()==="select"){let a=o.type==="function"?ze(o):[],i=n?_e(n,a):{kind:"select",categories:a};t[s]=i;}else o.argType&&(o.argType.toLowerCase()==="plural"||o.argType.toLowerCase()==="selectordinal"||o.argType.toLowerCase()==="number")?t[s]={kind:"number"}:t[s]={kind:"primitive"};for(let a of o.options)he(a.value,t);}}c(he,"collectParams");function _e(e,t){return e.kind!=="select"?{kind:"select",categories:t}:{kind:"select",categories:Ce(e.categories,t)}}c(_e,"unionCategories");function ze(e){return e.options.map(t=>t.key)}c(ze,"optionKeys");function Ce(...e){let t=new Set;for(let o of e)for(let s of o)t.add(s);return [...t].sort()}c(Ce,"mergeStrings");function W(e,t){let o=new Map,s=[],n=new Map;for(let a of e){let i=`${a.namespace}\0${a.key}`,g=n.get(i);g?g.push(a):n.set(i,[a]);}for(let[a,i]of n){let[g,l]=a.split("\0"),u={},m={};for(let p of i){let f=ye(p.value);for(let[y,d]of Object.entries(f)){u[y]=Ze(u[y],d);let C=m[y]??(m[y]=[]);C.includes(p.locale)||C.push(p.locale);}}if(t?.context?.length){let p=new Map;for(let f of t.context)p.set(f.name,f);for(let[f,y]of Object.entries(u)){let d=p.get(f);d&&y.kind==="select"&&Be(s,g,l,f,y.categories,d,m[f]??[]);}}let b=o.get(g);b||(b=new Map,o.set(g,b));let L={};for(let[p,f]of Object.entries(u))L[p]=f.kind==="select"?{kind:"select",categories:[...f.categories].sort()}:f;b.set(l,{params:L,paramLocales:m});}return {byNamespace:o,warnings:s}}c(W,"extractShapes");function Ze(e,t){return e?e.kind==="number"&&t.kind==="number"||e.kind==="primitive"&&t.kind==="primitive"?e:e.kind==="select"&&t.kind==="select"?{kind:"select",categories:Ce(e.categories,t.categories)}:e.kind==="number"&&t.kind==="primitive"||e.kind==="primitive"&&t.kind==="number"?{kind:"number"}:t.kind==="select"?t:e:t}c(Ze,"unionParam");function Be(e,t,o,s,n,a,i){let g=new Set(a.values),l=n.filter(u=>u!=="other"&&!g.has(u));l.length!==0&&e.push(`[${t}:${o}] param "${s}" uses categories [${l.join(", ")}] outside the configured canonical set [${a.values.join(", ")}] (used by ${i.join(", ")})`);}c(Be,"warnOnCategoryMismatch");async function Y(e){let t=[];for(let o of e){let s=await N__namespace.readFile(o.file,"utf8"),n;try{n=JSON.parse(s);}catch(a){throw new Error(`Invalid JSON in ${o.file}: ${a.message}`)}if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`Namespace file ${o.file} must contain a JSON object`);for(let[a,i]of Object.entries(n)){if(typeof i!="string"&&!qe(i))throw new Error(`Message "${a}" in ${o.file} must be a string or { value: string }`);t.push({locale:o.locale,namespace:o.namespace,key:a,value:V(i)});}}return t}c(Y,"readNamespaceSources");function qe(e){return typeof e=="object"&&e!==null&&typeof e.value=="string"}c(qe,"isMessageSource");function We(e){let t=new Map;for(let o of e){let s=t.get(o.locale);s||(s=new Map,t.set(o.locale,s));let n=s.get(o.namespace);n||(n=new Set,s.set(o.namespace,n)),n.add(o.key);}return t}c(We,"presenceByLocale");function Q(e,t,o){let s=We(e),n=s.get(o);if(!n)return {missing:[]};let a=new Set(t),i=t.filter(l=>!Ye(l,a)),g=[];for(let l of i){if(l===o)continue;let u=s.get(l);for(let[m,b]of n){let L=u?.get(m);for(let p of b)L?.has(p)||g.push({namespace:m,key:p,locale:l});}}return g.sort((l,u)=>(l.namespace+"/"+l.key+"/"+l.locale).localeCompare(u.namespace+"/"+u.key+"/"+u.locale)),{missing:g}}c(Q,"diffLocales");function Ye(e,t){let o=e;for(;;){let s=o.lastIndexOf("-");if(s<=0||s===o.length-1)return false;if(o=o.slice(0,s),t.has(o))return true}}c(Ye,"hasParentWithin");function T(e){return JSON.stringify(e)}c(T,"quote");function Xe(e){return e.kind==="number"?"number":e.kind==="primitive"?"string | number":e.categories.map(T).join(" | ")}c(Xe,"paramToTs");var X={};function et(e){if(X[e])return X[e];let t=[];try{t=Intl.supportedValuesOf(e);}catch{t=[];}return X[e]=t,t}c(et,"engineValues");function xe(e,t){if(e==="any"){let s=et(t);return s.length===0?"string":s.map(T).join(" | ")}return e.map(T).join(" | ")||"string"}c(xe,"listOrAny");function tt(e,t){let o=e.units;if(o==="all"||!o)return stiftCore.UNITS_BY_CATEGORY[t];let s=o[t];if(!s)return null;let n=s.supportedValues;return !n||n==="all"?stiftCore.UNITS_BY_CATEGORY[t]:[...n]}c(tt,"unitsForCategory");function ee(e){let{config:t,extract:o}=e,s=[...o.byNamespace.keys()].sort(),n=new Map;for(let u of t.params?.context??[])n.set(u.name,u.values);let a=[];for(let u of s){let m=o.byNamespace.get(u),b=[];for(let L of [...m.keys()].sort()){let p=m.get(L),f=Object.keys(p.params).sort();if(f.length===0){b.push(` ${T(L)}: {}`);continue}let y=f.map(d=>{let C=n.get(d),x=C!==void 0,I=C?C.map(T).join(" | "):Xe(p.params[d]);return ` ${T(d)}${x?"?":""}: ${I}`}).join(`
|
|
4
|
+
`);b.push(` ${T(L)}: {
|
|
5
|
+
${y}
|
|
6
|
+
}`);}a.push(` ${T(u)}: {
|
|
7
|
+
${b.join(`
|
|
8
|
+
`)}
|
|
9
|
+
}`);}let i=[];if(n.size>0)for(let u of [...n.keys()].sort()){let m=n.get(u).map(T).join(" | ");i.push(` ${T(u)}: ${m}`);}let g=i.length>0?` context: {
|
|
10
|
+
${i.join(`
|
|
11
|
+
`)}
|
|
12
|
+
}
|
|
13
|
+
`:"",l=stiftCore.UNIT_CATEGORIES.flatMap(u=>{let m=tt(t,u);return m?[` ${T(u)}: ${m.map(T).join(" | ")}`]:[]});return `/**
|
|
14
|
+
* Generated by @secundus-studio/stift-generator \u2014 do not edit by hand.
|
|
15
|
+
* Regenerate with \`stift generate\` (and in Phase 5, the dev plugin watches).
|
|
16
|
+
*/
|
|
17
|
+
import "@secundus-studio/stift-core"
|
|
18
|
+
declare module "@secundus-studio/stift-core" {
|
|
19
|
+
interface Register {
|
|
20
|
+
locale: ${t.locales.supported.map(T).join(" | ")}
|
|
21
|
+
numberingSystems: ${xe(t.numberingSystems??"any","numberingSystem")}
|
|
22
|
+
currencies: ${xe(t.currencies??"any","currency")}
|
|
23
|
+
units: {
|
|
24
|
+
${l.join(`
|
|
25
|
+
`)}
|
|
26
|
+
}
|
|
27
|
+
messages: {
|
|
28
|
+
${a.join(`
|
|
29
|
+
`)}
|
|
30
|
+
}
|
|
31
|
+
${g} }
|
|
32
|
+
}
|
|
33
|
+
`}c(ee,"generateTypegen");async function oe(e,t,o){let s=v__namespace.join(e,t),n=[];for(let a of o){let i=v__namespace.join(s,a);try{await N__namespace.access(i);}catch{await N__namespace.mkdir(i,{recursive:true}),n.push(i);}}return {createdDirs:n}}c(oe,"ensureLocaleDirectories");async function ot(e){let t=new Map;for(let o of e){let s=JSON.parse(await N__namespace.readFile(o.file,"utf8"));if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Namespace file ${o.file} must contain a JSON object`);let n=t.get(o.locale);n||(n=new Map,t.set(o.locale,n)),n.set(o.namespace,s);}return t}c(ot,"readRawFiles");function nt(e){let t=Object.entries(e);return t.length===0?"{}":`{
|
|
34
|
+
${t.map(([s,n])=>` ${JSON.stringify(s)}: ${JSON.stringify(n)}`).join(`,
|
|
35
|
+
`)}
|
|
36
|
+
}`}c(nt,"serializeNamespace");async function ne(e){let{root:t,localesDir:o,defaultLocale:s,locales:n}=e,a=await ot(e.discovery.all),i=new Map,g=a.get(s);if(g)for(let[h,S]of g)i.set(h,{order:Object.keys(S),values:S});let l=[];i.size===0&&l.push(`[stift] default locale "${s}" has no namespace files \u2014 nothing to complete`);let u=new Set(n);function m(h){let S=[],k=h;for(;;){let M=k.lastIndexOf("-");if(M<=0)break;k=k.slice(0,M),k!==s&&u.has(k)&&S.push(k);}return [...S,s]}c(m,"fillChain");function b(h,S,k,M){for(let F of k){let $=a.get(F)?.get(S)?.[h];if($!==void 0)return $}return M[h]}c(b,"resolveValue");let L=[],p=[],f=[],y=[],d=0,C=new Set,x={[s]:1};for(let h of n){if(h===s)continue;let S=a.get(h),k=m(h),M=0,F=0,$=c(w=>w!==s,"inheritedIsTranslated");for(let[w,P]of i){let A=S?.get(w),D=v__namespace.join(t,o,h,`${w}.json`),Me=S?.has(w)??false;C.add(`${h}\0${w}`);let je=new Set(P.order),K={};for(let j of P.order){let U=A?.[j];if(U!==void 0)K[j]=U,M++;else {K[j]=b(j,w,k,P.values),d++;for(let pe of k){if(!$(pe))break;if(a.get(pe)?.get(w)?.[j]!==void 0){M++;break}}}F++;}if(A)for(let j of Object.keys(A))je.has(j)||(K[j]=A[j],y.push({namespace:w,key:j,locale:h}));let ce=nt(K)+`
|
|
37
|
+
`,le=true;try{le=await N__namespace.readFile(D,"utf8")!==ce;}catch{}le&&(await N__namespace.mkdir(v__namespace.dirname(D),{recursive:true}),await N__namespace.writeFile(D,ce,"utf8"),p.push(D),Me||f.push(D));for(let[j,U]of Object.entries(K))L.push({locale:h,namespace:w,key:j,value:V(U)});}x[h]=F>0?Math.min(1,M/F):1;}let R=[...e.sources.filter(h=>!(h.locale!==s&&C.has(`${h.locale}\0${h.namespace}`))),...L];return R.sort((h,S)=>h.locale.localeCompare(S.locale)||h.namespace.localeCompare(S.namespace)||h.key.localeCompare(S.key)),{sources:R,writtenFiles:p,createdFiles:f,orphanKeys:y,filledKeys:d,authoredCoverage:x,warnings:l}}c(ne,"completeSources");var pt={tier:"obfuscated",encoding:"msgpack",compression:"gzip"};function re(e){let t=e.security??pt;return {tier:t.tier,encoding:t.encoding,compression:t.compression,staticKey:t.staticKey??process.env.STIFT_STATIC_KEY??void 0}}c(re,"resolveCompileSecurity");function ut(e){if(e==="cbor")return cbor.cborCodec;if(e==="msgpack")return msgpack.msgpackCodec;throw new Error(`[stift] encoding "${e}" has no binary codec \u2014 JSON packs are raw bytes, not a compiled container`)}c(ut,"codecFor");async function ve(e,t){let{tier:o,encoding:s,compression:n}=t.security;if(s==="json"){if(o!=="none")throw new Error(`[stift] encoding "json" requires tier "none" (got "${o}")`);if(n!=="none")throw new Error(`[stift] encoding "json" requires compression "none" (got "${n}")`);return stiftCore.encodeJsonPack(e)}let a;if(o==="encrypted-static"||o==="encrypted-session"){if(!t.security.staticKey)throw new Error("[stift] security.staticKey is required to compile encrypted tiers");a=await stiftCore.deriveStaticKey(t.security.staticKey);}return stiftCore.encodeCompiled(e,{codec:ut(s),compression:n,tier:o,compress:node.createNodeCompress(n),key:a})}c(ve,"compileNamespace");function ft(e){let t=new Map;for(let o of e){let s=t.get(o.locale);s||(s=new Map,t.set(o.locale,s));let n=s.get(o.namespace);n||(n={},s.set(o.namespace,n)),n[o.key]=o.value;}return t}c(ft,"groupMessages");async function ae(e){let t=ft(e.sources),o=[],s=[],n=[],a=new Map,i=0,g=0,l=new Map;for(let p of e.locales){let f=t.get(p);if(!f||f.size===0)continue;let y=mt(p,e.locales,e.defaultLocale),d=[],C=[];for(let[S,k]of f){let M=`${p}/${S}`,F=await stiftCore.sha256Hex(gt(JSON.stringify(k))),$=e.cache?.get(M),w,P;$&&$.sourceHash===F?(w=$.bytes,P=$.contentHash,g++):(w=await ve(k,{security:e.security}),P=await stiftCore.sha256Hex(w),i++),d.push({namespace:S,url:e.urlFor(p,S,P),persistKey:M,byteLength:w.byteLength,contentHash:P}),C.push(P),o.push({locale:p,namespace:S,persistKey:M,bytes:w,byteLength:w.byteLength,contentHash:P}),a.set(M,{sourceHash:F,bytes:w,byteLength:w.byteLength,contentHash:P});}d.sort((S,k)=>S.namespace.localeCompare(k.namespace));let x=t.get(e.defaultLocale),I=0,R=0;if(x)for(let[S,k]of x)R+=Object.keys(k).length,I+=f.has(S)?Object.keys(f.get(S)).length:0;let h=e.coverageByLocale?.[p];l.set(p,{baseLocale:y,namespaces:d,hashes:C,coverage:h??(R>0?Math.min(1,I/R):void 0)});}let u=ke([...l.values()].flatMap(p=>p.hashes)),m=Date.now(),b=e.shardUrlFor??((p,f)=>`catalog/${p}.${f}.json`);for(let[p,f]of [...l.entries()].sort(([y],[d])=>y.localeCompare(d))){let y={version:stiftCore.CATALOG_VERSION,locale:p,namespaces:f.namespaces},d=new TextEncoder().encode(JSON.stringify(y)),C=await stiftCore.sha256Hex(d),x=f.namespaces.reduce((R,h)=>R+h.byteLength,0);n.push({locale:p,shard:y,bytes:d,byteLength:d.byteLength,namespacesHash:C});let I={locale:p,namespacesUrl:b(p,C),namespacesHash:C,namespaces:f.namespaces.map(R=>R.namespace),packVersion:ke(f.hashes),totalBytes:x};f.baseLocale!==void 0&&(I.baseLocale=f.baseLocale),f.coverage!==void 0&&(I.coverage=f.coverage),s.push(I);}return {outputs:o,catalog:{version:stiftCore.CATALOG_VERSION,buildId:u,publishedAt:m,locales:s},shards:n,cache:a,compiledCount:i,reusedCount:g}}c(ae,"compileAll");function gt(e){return new TextEncoder().encode(e)}c(gt,"utf8Bytes");function mt(e,t,o){if(e===o)return;let n=e.split("-");for(let a=n.length;a>=2;a--){let i=n.slice(0,a-1).join("-");if(t.includes(i))return i}}c(mt,"directParent");function ke(e){let t=e.sort().join(""),o=0;for(let s=0;s<t.length;s++)o=o*31+t.charCodeAt(s)>>>0;return o.toString(16)}c(ke,"shortHash");var Le=v__namespace.join("src","stift.gen.d.ts"),ie=class{static{c(this,"Generator");}constructor(t={}){this.root=t.root??process.cwd();}root;async generateAsync(t={}){let o=t.root??this.root,n=(await H({root:o,configFile:t.configFile})).config,a=await oe(o,n.namespaces.dir,n.locales.supported),i=await J(o,n.namespaces.dir),g=await Y(i.all),l=await ne({root:o,localesDir:n.namespaces.dir,defaultLocale:n.locales.default,locales:[...n.locales.supported],sources:g,discovery:i}),u=l.sources,m=W(u,n.params),b=[...n.locales.supported],L=Q(u,b,n.locales.default),p=v__namespace.resolve(o,t.outputFile??Le),f=ee({config:n,extract:m});await N__namespace.mkdir(v__namespace.dirname(p),{recursive:true}),await N__namespace.writeFile(p,f,"utf8");let y=l.orphanKeys.map(({namespace:d,key:C,locale:x})=>`[stift] key "${C}" in locale "${x}" (namespace "${d}") is not part of the default locale's schema \u2014 orphan`);return {config:n,discovery:i,extract:m,diff:L,sources:u,scaffold:a,completion:l,outputFile:p,warnings:[...m.warnings,...y,...l.warnings]}}makeWatchFilter(t,o){let s=v__namespace.resolve(t,o);return n=>{let a=v__namespace.resolve(n);return a.startsWith(s+v__namespace.sep)&&a.endsWith(".json")}}async compileAsync(t={}){let o=t.root??this.root,n=(await H({root:o,configFile:t.configFile})).config;await oe(o,n.namespaces.dir,n.locales.supported);let a=await J(o,n.namespaces.dir),i=await Y(a.all),g=await ne({root:o,localesDir:n.namespaces.dir,defaultLocale:n.locales.default,locales:[...n.locales.supported],sources:i,discovery:a}),l=[...n.locales.supported],u=t.security??re(n),m=u.encoding==="json"?"json":"dat",b=t.urlFor??((y,d)=>`${y}/${d}.${m}`),L=t.shardUrlFor??((y,d)=>`catalog/${y}.${d}.json`),p=await ae({sources:g.sources,locales:l,defaultLocale:n.locales.default,security:u,urlFor:b,shardUrlFor:L,coverageByLocale:g.authoredCoverage}),f=[];if(t.outDir){let y=v__namespace.resolve(o,t.outDir);for(let C of p.outputs){let x=v__namespace.join(y,`${C.persistKey}.${m}`);await N__namespace.mkdir(v__namespace.dirname(x),{recursive:true}),await N__namespace.writeFile(x,C.bytes),f.push(x);}let d=v__namespace.join(y,"catalog.json");await N__namespace.mkdir(v__namespace.dirname(d),{recursive:true}),await N__namespace.writeFile(d,JSON.stringify(p.catalog,null,2),"utf8"),f.push(d);for(let C of p.shards){let x=v__namespace.join(y,"catalog",`${C.locale}.${C.namespacesHash}.json`);await N__namespace.mkdir(v__namespace.dirname(x),{recursive:true}),await N__namespace.writeFile(x,C.bytes),f.push(x);}}return {config:n,result:p,writtenFiles:f}}};function dt(e){return e}c(dt,"defineConfig");Object.defineProperty(exports,"collectFunctions",{enumerable:true,get:function(){return stiftCore.collectFunctions}});Object.defineProperty(exports,"parseMessage",{enumerable:true,get:function(){return stiftCore.parseMessage}});exports.DEFAULT_OUTPUT_REL=Le;exports.Generator=ie;exports.compileAll=ae;exports.compileNamespace=ve;exports.configSchema=B;exports.defineConfig=dt;exports.deriveLocaleShape=ye;exports.diffLocales=Q;exports.discoverConvention=J;exports.extractShapes=W;exports.findConfigFile=me;exports.generateTypegen=ee;exports.loadConfig=H;exports.resolveCompileSecurity=re;
|