@sonenta/astro 0.1.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/CONTRACT.md +85 -0
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/dist/chunk-CK2DAB6G.js +131 -0
- package/dist/chunk-CK2DAB6G.js.map +1 -0
- package/dist/index.cjs +252 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +53 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.cjs +163 -0
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.cts +160 -0
- package/dist/runtime.d.ts +160 -0
- package/dist/runtime.js +19 -0
- package/dist/runtime.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for `@sonenta/astro` v0.1 (standalone, pre-core).
|
|
3
|
+
*
|
|
4
|
+
* FORWARD-COMPATIBILITY CONTRACT (frozen day-one — see CONTRACT.md): every
|
|
5
|
+
* option key here is the SAME key the future `@sonenta/i18n-core`-backed
|
|
6
|
+
* release will consume, so the later refactor (0.2.0) is a non-breaking,
|
|
7
|
+
* additive internal swap. New capabilities (surfaces, a11y accessors, CLDR
|
|
8
|
+
* plurals, variants) arrive ADDITIVELY; nothing here changes meaning.
|
|
9
|
+
*/
|
|
10
|
+
/** A BCP-47 locale code, e.g. `"fr"`, `"en"`, `"fr-CA"`. */
|
|
11
|
+
type Locale = string;
|
|
12
|
+
/** A bundle namespace (the `{ns}.json` file on the CDN), e.g. `"common"`. */
|
|
13
|
+
type Namespace = string;
|
|
14
|
+
/** Interpolation variables for a `t()` call: `t("greeting", { name: "Ada" })`. */
|
|
15
|
+
type Vars = Record<string, string | number>;
|
|
16
|
+
/** A resolved, per-locale translation function. */
|
|
17
|
+
type TFn = (key: string, vars?: Vars) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Configuration for the Sonenta Astro integration / runtime.
|
|
20
|
+
*
|
|
21
|
+
* Bundles are fetched at BUILD time from
|
|
22
|
+
* `{cdnBase}/p/{project}/{version}/latest/{locale}/{namespace}.json`
|
|
23
|
+
* (the canonical Sonenta CDN layout, identical to `@sonenta/react-i18next`).
|
|
24
|
+
*/
|
|
25
|
+
interface SonentaI18nOptions {
|
|
26
|
+
/** Project UUID from your Sonenta dashboard. Required. */
|
|
27
|
+
project: string;
|
|
28
|
+
/**
|
|
29
|
+
* Released version slug or pinned content hash. Default `"main"`.
|
|
30
|
+
* The CDN serves the latest release of this version under `/latest/`.
|
|
31
|
+
*/
|
|
32
|
+
version?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Locales to fetch and freeze into the static build. Required, non-empty.
|
|
35
|
+
* A locale whose bundle 404s (e.g. a plan-limit-blocked language) is kept
|
|
36
|
+
* as `null` and transparently falls back to the source language.
|
|
37
|
+
*/
|
|
38
|
+
locales: Locale[];
|
|
39
|
+
/**
|
|
40
|
+
* Source / default locale. Default = `locales[0]`. Used as the implicit
|
|
41
|
+
* final fallback target and as Astro's source language.
|
|
42
|
+
*/
|
|
43
|
+
defaultLocale?: Locale;
|
|
44
|
+
/**
|
|
45
|
+
* Ordered fallback chain applied when a key is missing in the active
|
|
46
|
+
* locale. Default = `[defaultLocale]`. v0.1 applies these locales in
|
|
47
|
+
* order; BCP-47 variant→base inheritance (`fr-CA → fr`) is deliberately
|
|
48
|
+
* left to the core-backed release.
|
|
49
|
+
*/
|
|
50
|
+
fallbackLng?: Locale | Locale[];
|
|
51
|
+
/**
|
|
52
|
+
* Namespaces (bundle files) to fetch. Default `["common"]`. The first
|
|
53
|
+
* entry is the default namespace for un-prefixed keys; address others with
|
|
54
|
+
* the i18next-style `"ns:key"` syntax.
|
|
55
|
+
*/
|
|
56
|
+
namespaces?: Namespace[];
|
|
57
|
+
/**
|
|
58
|
+
* CDN host root for translation bundles, WITHOUT the `/p` segment.
|
|
59
|
+
* Default `"https://cdn.sonenta.com"`. Overridable via the
|
|
60
|
+
* `SONENTA_CDN_BASE` env var (also a bare host; for local dev point it at
|
|
61
|
+
* your translation CDN). The `/p/{project}/{version}/latest/...` path is
|
|
62
|
+
* appended by the loader.
|
|
63
|
+
*/
|
|
64
|
+
cdnBase?: string;
|
|
65
|
+
/**
|
|
66
|
+
* API host root. Reserved for forward-compatibility (the core-backed
|
|
67
|
+
* release uses it for the public language manifest and dev-mode runtime
|
|
68
|
+
* fetch). Default `"https://api.sonenta.dev"`. Unused by v0.1's prod
|
|
69
|
+
* build-time path.
|
|
70
|
+
*/
|
|
71
|
+
apiBase?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Injectable `fetch` implementation (testing / proxies / custom agents).
|
|
74
|
+
* Defaults to the global `fetch`.
|
|
75
|
+
*/
|
|
76
|
+
fetchImpl?: typeof fetch;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The resolved Sonenta i18n handle returned by `createSonentaI18n` and
|
|
80
|
+
* exposed through the `sonenta:i18n` virtual module.
|
|
81
|
+
*/
|
|
82
|
+
interface SonentaI18n {
|
|
83
|
+
/** Build a translation function bound to `locale`. */
|
|
84
|
+
getT(locale: Locale): TFn;
|
|
85
|
+
/** The locales that were fetched (the configured `locales`). */
|
|
86
|
+
readonly locales: Locale[];
|
|
87
|
+
/** The resolved source/default locale. */
|
|
88
|
+
readonly defaultLocale: Locale;
|
|
89
|
+
/**
|
|
90
|
+
* Raw fetched dictionary for `locale` / `namespace` (default namespace when
|
|
91
|
+
* omitted), or `null` when that bundle was absent (404 / plan-limit).
|
|
92
|
+
*/
|
|
93
|
+
getCatalog(locale: Locale, namespace?: Namespace): Record<string, unknown> | null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Build-time CDN loader for Sonenta translation bundles.
|
|
98
|
+
*
|
|
99
|
+
* Mirrors the canonical Sonenta CDN layout used by `@sonenta/react-i18next`:
|
|
100
|
+
* `{cdnBase}/p/{project}/{version}/latest/{locale}/{namespace}.json`
|
|
101
|
+
*
|
|
102
|
+
* Pure data fetch — no DOM, no React, no runtime. Called during `astro build`
|
|
103
|
+
* so the strings inline into the static HTML (zero client JS).
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
/** A fetched bundle (a flat or nested dictionary of message strings). */
|
|
107
|
+
type Bundle = Record<string, unknown>;
|
|
108
|
+
/**
|
|
109
|
+
* Resolve the effective CDN host (no `/p`): explicit option wins, then the
|
|
110
|
+
* `SONENTA_CDN_BASE` env var, then the production default.
|
|
111
|
+
*/
|
|
112
|
+
declare function resolveCdnBase(opts: Pick<SonentaI18nOptions, "cdnBase">): string;
|
|
113
|
+
/**
|
|
114
|
+
* Build the bundle URL for one `(locale, namespace)` pair.
|
|
115
|
+
* `{cdnBase}/p/{project}/{version}/latest/{locale}/{namespace}.json`
|
|
116
|
+
*/
|
|
117
|
+
declare function buildBundleUrl(opts: Pick<SonentaI18nOptions, "project" | "version" | "cdnBase">, locale: Locale, namespace: Namespace): string;
|
|
118
|
+
/**
|
|
119
|
+
* Fetch a single bundle. Resolves to `null` on 404 (locale absent from the
|
|
120
|
+
* project — e.g. a plan-limit-blocked language) so callers fall back to the
|
|
121
|
+
* source language. Any other non-OK status or transport error throws so a
|
|
122
|
+
* misconfigured build fails loudly rather than silently shipping empty pages.
|
|
123
|
+
*/
|
|
124
|
+
declare function fetchBundle(opts: Pick<SonentaI18nOptions, "project" | "version" | "cdnBase" | "fetchImpl">, locale: Locale, namespace: Namespace): Promise<Bundle | null>;
|
|
125
|
+
/**
|
|
126
|
+
* Fetch one namespace across every locale, in parallel. Absent locales map to
|
|
127
|
+
* `null`. Returns `Record<Locale, Bundle | null>`.
|
|
128
|
+
*/
|
|
129
|
+
declare function fetchNamespace(opts: Pick<SonentaI18nOptions, "project" | "version" | "cdnBase" | "fetchImpl">, locales: Locale[], namespace: Namespace): Promise<Record<Locale, Bundle | null>>;
|
|
130
|
+
/**
|
|
131
|
+
* Fetch every `(locale, namespace)` pair. Returns a nested map keyed by
|
|
132
|
+
* locale then namespace: `data[locale][namespace] = Bundle | null`.
|
|
133
|
+
*/
|
|
134
|
+
declare function fetchAll(opts: Pick<SonentaI18nOptions, "project" | "version" | "cdnBase" | "fetchImpl">, locales: Locale[], namespaces: Namespace[]): Promise<Record<Locale, Record<Namespace, Bundle | null>>>;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Build-time translation resolver.
|
|
138
|
+
*
|
|
139
|
+
* v0.1 SCOPE (frozen — see CONTRACT.md): string resolution + `{var}`
|
|
140
|
+
* interpolation + source-language fallback ONLY. Deliberately NO CLDR
|
|
141
|
+
* plurals, NO surfaces, NO a11y accessors, NO BCP-47 variant→base
|
|
142
|
+
* inheritance — those carry real i18n SEMANTICS owned by `@sonenta/i18n-core`
|
|
143
|
+
* and arrive additively in 0.2.0. Keeping them out of v0.1 means there is no
|
|
144
|
+
* naive semantics to break when the core swaps in underneath this same API.
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Build a `t()` bound to `locale`, given the fetched data and resolution
|
|
149
|
+
* order. Lookup: active locale's namespace dict → each fallback locale's same
|
|
150
|
+
* namespace dict → the raw key (i18next-parity missing-key behaviour).
|
|
151
|
+
*/
|
|
152
|
+
declare function createT(data: Record<Locale, Record<Namespace, Bundle | null>>, locale: Locale, fallbackChain: Locale[], defaultNamespace: Namespace): TFn;
|
|
153
|
+
/**
|
|
154
|
+
* Fetch every configured bundle at build time and return a resolved
|
|
155
|
+
* {@link SonentaI18n} handle. Call once (top-level `await`) and reuse its
|
|
156
|
+
* `getT(locale)` across pages.
|
|
157
|
+
*/
|
|
158
|
+
declare function createSonentaI18n(options: SonentaI18nOptions): Promise<SonentaI18n>;
|
|
159
|
+
|
|
160
|
+
export { type Bundle, type Locale, type Namespace, type SonentaI18n, type SonentaI18nOptions, type TFn, type Vars, buildBundleUrl, createSonentaI18n, createT, fetchAll, fetchBundle, fetchNamespace, resolveCdnBase };
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildBundleUrl,
|
|
3
|
+
createSonentaI18n,
|
|
4
|
+
createT,
|
|
5
|
+
fetchAll,
|
|
6
|
+
fetchBundle,
|
|
7
|
+
fetchNamespace,
|
|
8
|
+
resolveCdnBase
|
|
9
|
+
} from "./chunk-CK2DAB6G.js";
|
|
10
|
+
export {
|
|
11
|
+
buildBundleUrl,
|
|
12
|
+
createSonentaI18n,
|
|
13
|
+
createT,
|
|
14
|
+
fetchAll,
|
|
15
|
+
fetchBundle,
|
|
16
|
+
fetchNamespace,
|
|
17
|
+
resolveCdnBase
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sonenta/astro",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official Astro integration for Sonenta i18n — build-time CDN translations, zero client JS (SSG).",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://sonenta.com",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/sonenta/sdk.git",
|
|
10
|
+
"directory": "packages/astro"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"i18n",
|
|
14
|
+
"translations",
|
|
15
|
+
"astro",
|
|
16
|
+
"astro-integration",
|
|
17
|
+
"astro-component",
|
|
18
|
+
"ssg",
|
|
19
|
+
"sonenta"
|
|
20
|
+
],
|
|
21
|
+
"author": "Sonenta",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"require": "./dist/index.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./runtime": {
|
|
31
|
+
"types": "./dist/runtime.d.ts",
|
|
32
|
+
"import": "./dist/runtime.js",
|
|
33
|
+
"require": "./dist/runtime.cjs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"README.md",
|
|
39
|
+
"CONTRACT.md",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
],
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"astro": ">=4.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^20.0.0",
|
|
50
|
+
"astro": "^5.0.0",
|
|
51
|
+
"tsup": "^8.3.0",
|
|
52
|
+
"typescript": "^5.5.0",
|
|
53
|
+
"vite": "^6.0.0",
|
|
54
|
+
"vitest": "^2.1.0"
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public",
|
|
58
|
+
"registry": "https://registry.npmjs.org/"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsup",
|
|
62
|
+
"test": "vitest run",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
64
|
+
"pack:dry-run": "pnpm pack --dry-run"
|
|
65
|
+
}
|
|
66
|
+
}
|