@adriangalilea/utils 0.8.0 → 0.9.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.
@@ -0,0 +1,62 @@
1
+ /**
2
+ * `say` — TypeScript-enforced polyglot strings, framework-agnostic.
3
+ *
4
+ * A "polyglot value" is a plain object literal with one string per
5
+ * supported language:
6
+ *
7
+ * { en: 'Hello', es: 'Hola' }
8
+ *
9
+ * The keys are the source of truth. There is no JSON file, no key
10
+ * registry, no extraction tool, no namespaces. The TS compiler
11
+ * enforces completeness: add a language to the plugin's `supported`
12
+ * list and every call site without that key becomes a compile error.
13
+ *
14
+ * Two entry points:
15
+ *
16
+ * `say(value, lang)` — pure resolver, no context, returns string.
17
+ * Use it for 3rd-party SDKs / cron / email
18
+ * / anything outside a bot ctx.
19
+ *
20
+ * `ctx.say(value)` — bot-bound; uses `ctx.lang`. Provided by
21
+ * `bot/language` (see that plugin for the
22
+ * `ctx.say.send / .edit / .answer` methods).
23
+ *
24
+ * @example
25
+ * import { say, type Polyglot } from '@adriangalilea/utils/say'
26
+ *
27
+ * await pushover.send({
28
+ * message: say({ en: 'Drop!', es: '¡Drop!' }, user.lang),
29
+ * })
30
+ *
31
+ * // typing your own adapter:
32
+ * const notify = (msg: string | Polyglot<'en' | 'es'>, lang: 'en' | 'es') =>
33
+ * transport.send(typeof msg === 'string' ? msg : say(msg, lang))
34
+ */
35
+ /**
36
+ * A value that exists in N languages. `L` is the union of supported
37
+ * language tags (typically inferred from the object literal's keys).
38
+ *
39
+ * Authoring: `{ en: 'Hi', es: 'Hola' }` — TS infers `L = 'en' | 'es'`.
40
+ *
41
+ * Typing your own API: `function notify(msg: Polyglot<'en' | 'es'>)`
42
+ * — callers must provide both keys.
43
+ */
44
+ export type Polyglot<L extends string> = Readonly<Record<L, string>>;
45
+ /**
46
+ * Resolve a polyglot value to a string at `lang`.
47
+ *
48
+ * If `lang` is missing from `value`, returns the first available key
49
+ * (lexicographic). This is a structural fallback — it should never
50
+ * happen when `lang` is constrained by the same `L` as `value`'s
51
+ * keys; it exists only for the dynamic-string escape hatch.
52
+ *
53
+ * @example
54
+ * say({ en: 'Hi', es: 'Hola' }, 'es') // → 'Hola'
55
+ * say({ en: 'Hi', es: 'Hola' }, 'fr') // TS error: '"fr"' not in '"en" | "es"'
56
+ *
57
+ * @example // typing-loose escape hatch with `as Polyglot<string>`
58
+ * const raw: Polyglot<string> = JSON.parse(blob)
59
+ * say(raw, userLang) // dynamic, falls back if missing
60
+ */
61
+ export declare const say: <L extends string>(value: Polyglot<L>, lang: L) => string;
62
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/say/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAG,MAKnE,CAAA"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * `say` — TypeScript-enforced polyglot strings, framework-agnostic.
3
+ *
4
+ * A "polyglot value" is a plain object literal with one string per
5
+ * supported language:
6
+ *
7
+ * { en: 'Hello', es: 'Hola' }
8
+ *
9
+ * The keys are the source of truth. There is no JSON file, no key
10
+ * registry, no extraction tool, no namespaces. The TS compiler
11
+ * enforces completeness: add a language to the plugin's `supported`
12
+ * list and every call site without that key becomes a compile error.
13
+ *
14
+ * Two entry points:
15
+ *
16
+ * `say(value, lang)` — pure resolver, no context, returns string.
17
+ * Use it for 3rd-party SDKs / cron / email
18
+ * / anything outside a bot ctx.
19
+ *
20
+ * `ctx.say(value)` — bot-bound; uses `ctx.lang`. Provided by
21
+ * `bot/language` (see that plugin for the
22
+ * `ctx.say.send / .edit / .answer` methods).
23
+ *
24
+ * @example
25
+ * import { say, type Polyglot } from '@adriangalilea/utils/say'
26
+ *
27
+ * await pushover.send({
28
+ * message: say({ en: 'Drop!', es: '¡Drop!' }, user.lang),
29
+ * })
30
+ *
31
+ * // typing your own adapter:
32
+ * const notify = (msg: string | Polyglot<'en' | 'es'>, lang: 'en' | 'es') =>
33
+ * transport.send(typeof msg === 'string' ? msg : say(msg, lang))
34
+ */
35
+ /**
36
+ * Resolve a polyglot value to a string at `lang`.
37
+ *
38
+ * If `lang` is missing from `value`, returns the first available key
39
+ * (lexicographic). This is a structural fallback — it should never
40
+ * happen when `lang` is constrained by the same `L` as `value`'s
41
+ * keys; it exists only for the dynamic-string escape hatch.
42
+ *
43
+ * @example
44
+ * say({ en: 'Hi', es: 'Hola' }, 'es') // → 'Hola'
45
+ * say({ en: 'Hi', es: 'Hola' }, 'fr') // TS error: '"fr"' not in '"en" | "es"'
46
+ *
47
+ * @example // typing-loose escape hatch with `as Polyglot<string>`
48
+ * const raw: Polyglot<string> = JSON.parse(blob)
49
+ * say(raw, userLang) // dynamic, falls back if missing
50
+ */
51
+ export const say = (value, lang) => {
52
+ const direct = value[lang];
53
+ if (typeof direct === 'string')
54
+ return direct;
55
+ for (const k in value)
56
+ return value[k];
57
+ return '';
58
+ };
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/say/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAaH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAAmB,KAAkB,EAAE,IAAO,EAAU,EAAE;IAC3E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAA;IAC7C,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,CAAM,CAAC,CAAA;IAC3C,OAAO,EAAE,CAAA;AACX,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adriangalilea/utils",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "TypeScript utilities - logger, currency, formatter, GramIO bot plugins, and more",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -28,6 +28,10 @@
28
28
  "types": "./dist/universal/currency/index.d.ts",
29
29
  "default": "./dist/universal/currency/index.js"
30
30
  },
31
+ "./say": {
32
+ "types": "./dist/say/index.d.ts",
33
+ "default": "./dist/say/index.js"
34
+ },
31
35
  "./bot": {
32
36
  "types": "./dist/bot/index.d.ts",
33
37
  "default": "./dist/bot/index.js"