@sveltekit-i18n/parser-curly 3.0.0-next.1 → 3.0.0-next.3

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
@@ -107,7 +107,7 @@ i18n.t('welcome', { default: 'Anonymous' })
107
107
  // → "Welcome, Anonymous!"
108
108
  ```
109
109
 
110
- `default` is a reserved payload key: the fallback for every placeholder in the message whose value is absent, and `{{default}}` reads it. A placeholder with no value takes the first of these that yields text — the entry's own `default` (see [Payload](#payload)), the payload's `default`, the inline `default:`, the empty string — so the payload's `default` outranks the inline one. Only an absent value falls back: `0`, `false` and the empty string are values. A key that names no message resolves to the payload's `default` as well and, where the payload carries none, to the key itself, echoed verbatim and never read as a message.
110
+ `default` is a reserved payload key: the fallback for every placeholder in the message whose value is absent, and `{{default}}` reads it. A placeholder with no value takes the first of these that yields text — the entry's own `default` (see [Payload](#payload)), the payload's `default`, the inline `default:`, the empty string — so the payload's `default` outranks the inline one. Only an absent value falls back: `0`, `false` and the empty string are values. The chain belongs to the placeholder, not to the message: a key naming no message is nothing to resolve and yields the empty string, and what a missing translation renders as is [`fallbackValue`](https://github.com/sveltekit-i18n/base/blob/master/docs/README.md#fallbackvalue), which base answers before this parser is called.
111
111
 
112
112
  ### Modifiers
113
113
 
@@ -336,7 +336,7 @@ A `Report` carries:
336
336
  | `code` | `unknown-modifier`, `failed-modifier`, `missing-options`, `unserializable-value`, `missing-locale`, `pass-limit` or `output-limit` |
337
337
  | `origin` | who fixes it: `message` (the message as written), `payload` (what the call passed) or `limit` (a bound this parser set) |
338
338
  | `message` | a self-contained English sentence carrying nothing from the payload |
339
- | `key` | the message's key, where the call passed one |
339
+ | `id` | the message's id, where the call passed one; base passes the translation key |
340
340
  | `limit` | the limit reached, for the two limit reports |
341
341
  | `text` | the excerpt: the placeholder, or the output that would not settle — cut to 120 code units, with quotes, backslashes and line terminators escaped, so it can be written anywhere |
342
342
 
@@ -378,6 +378,40 @@ i18n.t('common.welcome', { aplicationName: 'My app' })
378
378
 
379
379
  `Config<Payload, Props>` types the payload and the props `i18n.t` accepts; left bare, `Config` accepts any payload key and the built-in modifiers' props. A custom modifier types its own props through `Modifier.T<OwnProps>`. The factory's type arguments check the parser options the same way: with `Props` spelled as the second, `parser<Payload, Props>({ ... })`, a `modifierDefaults` entry for a custom modifier is checked; a modifier written inline reads typed `props` once the modifier names are spelled as the third argument too, `parser<Payload, Props, 'truncate'>({ ... })`. `Parser` holds the option and parameter types (`Parser.Options`, `Parser.OnReport`, `Parser.Params`, `Parser.Payload`), `Modifier` the modifier and wrapper types (`Modifier.T`, `Modifier.Wrapper`, `Modifier.Props`), and `Report` is the report.
380
380
 
381
+ ## Extracting Parameters
382
+
383
+ What a message expects of its payload is fixed when the message is written, so a catalogue can be read for its parameters instead of them being discovered at render time. `extractParamsFactory` is the build-time half of the base parser contract, a named export beside the default one: a message scanner is of no use while rendering, so the package declares `sideEffects: false` and a bundle that never reaches it drops it.
384
+
385
+ ```typescript
386
+ import { extractParamsFactory } from '@sveltekit-i18n/parser-curly';
387
+
388
+ const extractParams = extractParamsFactory();
389
+
390
+ extractParams('You have {{count:number;}} {{count; 1:message; default:messages;}}.');
391
+ // → [{ name: 'count', kind: 'number', values: ['1'], optional: true }]
392
+ ```
393
+
394
+ Each parameter is reported once, in the order the message first names it, and says what every placeholder naming it says together. `name` is the payload key, already unescaped and arbitrary text rather than an identifier, so whatever writes it down quotes it. `kind` is what the modifiers narrow the value to; every value reaches a modifier as text, so a modifier reading it as text narrows nothing and the parameter accepts `unknown`.
395
+
396
+ | Modifier | `kind` |
397
+ | --- | --- |
398
+ | none, `eq`, `ne` | `'unknown'` |
399
+ | `lt`, `gt` | `'number'` |
400
+ | `lte`, `gte` | `['number', 'string']` — the equality leg selects on text before the numeric one is reached |
401
+ | `number`, `currency` | `'number'` |
402
+ | `ago` | `'number'` — a signed millisecond delta relative to now, not a point in time |
403
+ | `date` | `['date', 'string']` — milliseconds since the epoch, and failing that text the host reads as a date |
404
+
405
+ A parameter several placeholders name accepts what all of them say together, and `unknown` is the top of that lattice rather than a member of it: it is what a parameter accepts while nothing has narrowed it, and it drops out the moment something does. So `{{count}}` alone reports `unknown`, and the example above — where a second placeholder formats the same key with `number` — reports `'number'` rather than `['unknown', 'number']`.
406
+
407
+ `values` lists the option keys of an `eq` selection, which is the one comparison whose keys are values of the parameter: `ne`'s are what the value must differ from, and an inequality's are thresholds it is ordered against. It is a hint and never a closed set — a value none of them matches takes the fallback chain rather than failing.
408
+
409
+ `optional` reports what the message says rather than what resolution tolerates. Every placeholder renders without its value, an absent one taking the fallback chain, so a placeholder declaring an inline `default` is the message saying the value may be missing, and one declaring none is the message saying it is expected.
410
+
411
+ Build the extractor from the same options `parser()` is built from: a custom modifier registered under a name the format defines changes what a message naming it says about its value. `onReport` is not required here, and neither it nor `modifierDefaults` reaches anything — extraction formats nothing and reports nothing.
412
+
413
+ Only the text of a message is scanned. A translation leaf that is not text names no parameters rather than throwing, and a placeholder a payload value carries into a later interpolation pass is not one the message itself names.
414
+
381
415
  ## Examples
382
416
 
383
417
  See the [parser-curly example](https://github.com/sveltekit-i18n/lib/tree/master/examples/parser-default) for a complete working application.
package/dist/index.d.ts CHANGED
@@ -23,6 +23,23 @@ declare namespace Parser {
23
23
  type Params<P = PayloadDefault, M = Modifier.DefaultProps> = [payload?: Payload<P, M>, props?: Modifier.Props<M>];
24
24
  type T<P extends Parser$2.Params = Params> = Parser$2.T<P, string>;
25
25
  type Factory = <Payload = {}, Props = {}, Key extends string = Modifier.Key>(options: Options<Key, Props>) => T<Params<Payload & PayloadDefault, Props & Modifier.DefaultProps>>;
26
+ /**
27
+ * The options `extractParamsFactory()` takes: the same ones `parser()` takes,
28
+ * so an extractor is built the way the app builds its parser — a custom
29
+ * modifier registered under a name the format defines changes what a message
30
+ * naming it says about its value. `onReport` is not required here, and
31
+ * neither it nor `modifierDefaults` reaches anything: extraction formats
32
+ * nothing and reports nothing.
33
+ */
34
+ type ExtractOptions<Key extends string = Modifier.Key, Props = Modifier.DefaultProps> = Parser$1.Options<Key, Props>;
35
+ /**
36
+ * Reports the parameters a message names. The build-time half of the parser
37
+ * contract, which is why it is a named export rather than a member of the
38
+ * parser object: a message scanner is of no use while rendering, and a
39
+ * bundle that never reaches it drops it.
40
+ */
41
+ type ExtractParams = Parser$2.ExtractParams;
42
+ type ExtractParamsFactory = <Props = {}, Key extends string = Modifier.Key>(options?: ExtractOptions<Key, Props>) => ExtractParams;
26
43
  }
27
44
  /**
28
45
  * The base config carrying this parser, typed by the payload the messages
@@ -30,6 +47,15 @@ declare namespace Parser {
30
47
  */
31
48
  type Config<P = Parser.PayloadDefault, M = Modifier.DefaultProps> = Config$1.T<Parser.Params<P, M>, string>;
32
49
 
50
+ /**
51
+ * Builds the extractor the base library's build-time contract describes, from
52
+ * the same options `parser()` takes. The format's own scanner answers it: what
53
+ * a message expects of its payload is fixed when the message is written, so a
54
+ * catalogue is read for its parameters rather than them being discovered at
55
+ * render time.
56
+ */
57
+ declare const extractParamsFactory: Parser.ExtractParamsFactory;
58
+
33
59
  declare const parser: Parser.Factory;
34
60
 
35
- export { type Config, Parser, parser as default };
61
+ export { type Config, Parser, parser as default, extractParamsFactory };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{createParser as i}from"@curly-message/parser";var f=r=>{let{resolve:e}=i(r);return{parse:(o,[t,p],s,a)=>e(o,{payload:t,props:p,locale:s,key:a})}},c=f;export{c as default};
1
+ import{createParser as f}from"@curly-message/parser";import{createExtractor as i}from"@curly-message/parser";var c=i;var m=r=>{let{resolve:e}=f(r);return{parse:(t,[o,a],p,s)=>e(t,{payload:o,props:a,locale:p,id:s})}},n=m;export{n as default,c as extractParamsFactory};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltekit-i18n/parser-curly",
3
- "version": "3.0.0-next.1",
3
+ "version": "3.0.0-next.3",
4
4
  "description": "Curly Message Format parser for the sveltekit-i18n library.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -50,10 +50,10 @@
50
50
  "@sveltekit-i18n/base": "^3.0.0-next.0"
51
51
  },
52
52
  "dependencies": {
53
- "@curly-message/parser": "^1.0.0-next.2"
53
+ "@curly-message/parser": "^1.0.1"
54
54
  },
55
55
  "devDependencies": {
56
- "@curly-message/conformance": "^1.0.0-next.2",
56
+ "@curly-message/conformance": "^1.0.1",
57
57
  "@eslint/js": "^10.0.1",
58
58
  "@stylistic/eslint-plugin": "^5.10.0",
59
59
  "@sveltekit-i18n/base": "^3.0.0-next.0",