saykit 0.6.1 → 0.8.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/README.md CHANGED
@@ -31,7 +31,7 @@ const say = new Say({
31
31
  say.activate('en');
32
32
 
33
33
  say`Hello, ${name}!`;
34
- say.plural(count, { one: '1 item', other: '# items' });
34
+ say.plural(count, { one: '1 item', other: `${count} items` });
35
35
  ```
36
36
 
37
37
  ## Documentation
@@ -11,13 +11,42 @@ type Awaitable<T> = T | PromiseLike<T>;
11
11
  type Named<T> = {
12
12
  [name: string]: T;
13
13
  };
14
- interface NumeralOptions extends Omit<Partial<Record<Intl.LDMLPluralRule, string>>, 'other'> {
15
- other: string;
16
- [digit: number]: string;
14
+ /**
15
+ * Branches of a choice, keyed by CLDR category or by exact number.
16
+ *
17
+ * `Branch` is what a case may be written as. It is text everywhere the message
18
+ * is text, and widens in JSX, where a case that shows the number has to be a
19
+ * fragment — a string attribute has nowhere to put a value.
20
+ */
21
+ interface NumeralOptions<Branch = string> extends Omit<Partial<Record<Intl.LDMLPluralRule, Branch>>, 'other'> {
22
+ other: Branch;
23
+ [digit: number]: Branch;
24
+ /**
25
+ * Subtracted from the value before `#` is formatted, so "You and 2 others"
26
+ * can select on a total of three. Reserved — it never names a branch.
27
+ */
28
+ offset?: number;
29
+ }
30
+ interface SelectOptions<Branch = string> {
31
+ other: Branch;
32
+ [match: string | number]: Branch;
17
33
  }
18
- interface SelectOptions {
19
- other: string;
20
- [match: string | number]: string;
34
+ /**
35
+ * Formatting for a `{arg, number}` placeholder.
36
+ *
37
+ * `currency` is not offered: MF1 has nowhere to write the currency code, so
38
+ * `{price, number, currency}` formats as a literal `{$price}` rather than an
39
+ * amount. A literal pattern such as `#,##0.00` is accepted for the cases the
40
+ * named styles do not cover.
41
+ */
42
+ interface NumberOptions {
43
+ style?: 'integer' | 'percent' | (string & {});
44
+ }
45
+ /**
46
+ * Formatting for a `{arg, date}` or `{arg, time}` placeholder.
47
+ */
48
+ interface DateTimeOptions {
49
+ style?: 'short' | 'medium' | 'long' | 'full';
21
50
  }
22
51
  //#endregion
23
52
  //#region src/runtime.d.ts
@@ -166,11 +195,12 @@ declare class Say<Locale extends string = string, Loader extends Say.Loader<Loca
166
195
  * ```ts
167
196
  * say.plural(count, {
168
197
  * one: 'You have 1 item',
169
- * other: 'You have # items',
198
+ * other: `You have ${count} items`,
170
199
  * })
171
200
  * ```
172
201
  *
173
- * The `#` symbol inside options is replaced with the numeric value.
202
+ * Interpolating the selector into a branch extracts as ICU's `#`, the number
203
+ * the message branched on. A `#` you write yourself is text.
174
204
  * @param _ Number to determine the plural form of
175
205
  * @param options Pluralisation rules keyed by CLDR categories or specific numbers
176
206
  * @returns The plural form of the number
@@ -179,15 +209,17 @@ declare class Say<Locale extends string = string, Loader extends Say.Loader<Loca
179
209
  plural(_: number | Named<number>, options: Disallow<NumeralOptions, 'id' | 'context'>): string;
180
210
  /**
181
211
  * Define an ordinal message (e.g. "1st", "2nd", "3rd").
182
- * The `#` symbol inside options is replaced with the numeric value.
212
+ *
213
+ * Interpolating the selector into a branch extracts as ICU's `#`, the number
214
+ * the message branched on. A `#` you write yourself is text.
183
215
  *
184
216
  * @example
185
217
  * ```ts
186
218
  * say.ordinal(position, {
187
- * 1: '#st',
188
- * 2: '#nd',
189
- * 3: '#rd',
190
- * other: '#th',
219
+ * 1: `${position}st`,
220
+ * 2: `${position}nd`,
221
+ * 3: `${position}rd`,
222
+ * other: `${position}th`,
191
223
  * })
192
224
  * ```
193
225
  *
@@ -214,7 +246,57 @@ declare class Say<Locale extends string = string, Loader extends Say.Loader<Loca
214
246
  * @returns The select form of the value
215
247
  * @remark This is a macro and must be used with the relevant saykit plugin
216
248
  */
217
- select(_: string | Named<string>, options: Disallow<SelectOptions, 'id' | 'context'>): string;
249
+ select(_: string | number | Named<string | number>, options: Disallow<SelectOptions, 'id' | 'context'>): string;
250
+ /**
251
+ * Format a number the way the active locale writes one, with its own grouping
252
+ * separators and decimal mark.
253
+ *
254
+ * Unlike `plural`, `ordinal`, and `select`, this is a fragment rather than a
255
+ * whole message, and is normally written inside one.
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * say`You have ${say.number(items.length)} items`
260
+ * say`Battery at ${say.number(level, { style: 'percent' })}`
261
+ * say`Total: ${say.number({ cartTotal: getTotal() }, { style: '#,##0.00' })}`
262
+ * ```
263
+ *
264
+ * @param _ Number to format
265
+ * @param options Formatting style, either a named style or a literal number pattern
266
+ * @returns The formatted number
267
+ * @remark This is a macro and must be used with the relevant saykit plugin
268
+ */
269
+ number(_: number | Named<number>, options?: Disallow<NumberOptions, 'id' | 'context'>): string;
270
+ /**
271
+ * Format the date portion of a value the way the active locale writes one.
272
+ *
273
+ * @example
274
+ * ```ts
275
+ * say`Published ${say.date(post.publishedAt)}`
276
+ * say`Published ${say.date(post.publishedAt, { style: 'full' })}`
277
+ * ```
278
+ *
279
+ * @param _ Date to format
280
+ * @param options Formatting style
281
+ * @returns The formatted date
282
+ * @remark This is a macro and must be used with the relevant saykit plugin
283
+ */
284
+ date(_: Date | number | Named<Date | number>, options?: Disallow<DateTimeOptions, 'id' | 'context'>): string;
285
+ /**
286
+ * Format the time portion of a value the way the active locale writes one.
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * say`Doors open at ${say.time(opensAt)}`
291
+ * say`Doors open at ${say.time(opensAt, { style: 'short' })}`
292
+ * ```
293
+ *
294
+ * @param _ Date to format
295
+ * @param options Formatting style
296
+ * @returns The formatted time
297
+ * @remark This is a macro and must be used with the relevant saykit plugin
298
+ */
299
+ time(_: Date | number | Named<Date | number>, options?: Disallow<DateTimeOptions, 'id' | 'context'>): string;
218
300
  }
219
301
  //#endregion
220
- export { Awaitable, Disallow, Named, NumeralOptions, ReadonlySay, Say, SelectOptions, Tuple };
302
+ export { Awaitable, DateTimeOptions, Disallow, Named, NumberOptions, NumeralOptions, ReadonlySay, Say, SelectOptions, Tuple };
package/dist/runtime.mjs CHANGED
@@ -203,11 +203,12 @@ var Say = class Say {
203
203
  * ```ts
204
204
  * say.plural(count, {
205
205
  * one: 'You have 1 item',
206
- * other: 'You have # items',
206
+ * other: `You have ${count} items`,
207
207
  * })
208
208
  * ```
209
209
  *
210
- * The `#` symbol inside options is replaced with the numeric value.
210
+ * Interpolating the selector into a branch extracts as ICU's `#`, the number
211
+ * the message branched on. A `#` you write yourself is text.
211
212
  * @param _ Number to determine the plural form of
212
213
  * @param options Pluralisation rules keyed by CLDR categories or specific numbers
213
214
  * @returns The plural form of the number
@@ -218,15 +219,17 @@ var Say = class Say {
218
219
  }
219
220
  /**
220
221
  * Define an ordinal message (e.g. "1st", "2nd", "3rd").
221
- * The `#` symbol inside options is replaced with the numeric value.
222
+ *
223
+ * Interpolating the selector into a branch extracts as ICU's `#`, the number
224
+ * the message branched on. A `#` you write yourself is text.
222
225
  *
223
226
  * @example
224
227
  * ```ts
225
228
  * say.ordinal(position, {
226
- * 1: '#st',
227
- * 2: '#nd',
228
- * 3: '#rd',
229
- * other: '#th',
229
+ * 1: `${position}st`,
230
+ * 2: `${position}nd`,
231
+ * 3: `${position}rd`,
232
+ * other: `${position}th`,
230
233
  * })
231
234
  * ```
232
235
  *
@@ -258,6 +261,62 @@ var Say = class Say {
258
261
  select(_, options) {
259
262
  throw new Error("'Say#select' is a macro and must be used with the relevant saykit plugin");
260
263
  }
264
+ /**
265
+ * Format a number the way the active locale writes one, with its own grouping
266
+ * separators and decimal mark.
267
+ *
268
+ * Unlike `plural`, `ordinal`, and `select`, this is a fragment rather than a
269
+ * whole message, and is normally written inside one.
270
+ *
271
+ * @example
272
+ * ```ts
273
+ * say`You have ${say.number(items.length)} items`
274
+ * say`Battery at ${say.number(level, { style: 'percent' })}`
275
+ * say`Total: ${say.number({ cartTotal: getTotal() }, { style: '#,##0.00' })}`
276
+ * ```
277
+ *
278
+ * @param _ Number to format
279
+ * @param options Formatting style, either a named style or a literal number pattern
280
+ * @returns The formatted number
281
+ * @remark This is a macro and must be used with the relevant saykit plugin
282
+ */
283
+ number(_, options) {
284
+ throw new Error("'Say#number' is a macro and must be used with the relevant saykit plugin");
285
+ }
286
+ /**
287
+ * Format the date portion of a value the way the active locale writes one.
288
+ *
289
+ * @example
290
+ * ```ts
291
+ * say`Published ${say.date(post.publishedAt)}`
292
+ * say`Published ${say.date(post.publishedAt, { style: 'full' })}`
293
+ * ```
294
+ *
295
+ * @param _ Date to format
296
+ * @param options Formatting style
297
+ * @returns The formatted date
298
+ * @remark This is a macro and must be used with the relevant saykit plugin
299
+ */
300
+ date(_, options) {
301
+ throw new Error("'Say#date' is a macro and must be used with the relevant saykit plugin");
302
+ }
303
+ /**
304
+ * Format the time portion of a value the way the active locale writes one.
305
+ *
306
+ * @example
307
+ * ```ts
308
+ * say`Doors open at ${say.time(opensAt)}`
309
+ * say`Doors open at ${say.time(opensAt, { style: 'short' })}`
310
+ * ```
311
+ *
312
+ * @param _ Date to format
313
+ * @param options Formatting style
314
+ * @returns The formatted time
315
+ * @remark This is a macro and must be used with the relevant saykit plugin
316
+ */
317
+ time(_, options) {
318
+ throw new Error("'Say#time' is a macro and must be used with the relevant saykit plugin");
319
+ }
261
320
  };
262
321
  function _call(locale, messages, descriptor) {
263
322
  const message = messages[descriptor.id];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saykit",
3
- "version": "0.6.1",
3
+ "version": "0.8.0",
4
4
  "description": "Type-safe i18n library with compile-time macro transforms",
5
5
  "keywords": [
6
6
  "i18n",