intor-translator 1.4.9 → 1.4.11

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/dist/index.cjs CHANGED
@@ -520,3 +520,4 @@ function renderRichMessage(message, renderer) {
520
520
  exports.Translator = ScopeTranslator;
521
521
  exports.parseRichMessage = parseRichMessage;
522
522
  exports.renderRichMessage = renderRichMessage;
523
+ exports.tokenize = tokenize;
package/dist/index.d.cts CHANGED
@@ -239,6 +239,46 @@ type LocalizedReplacement<ReplacementSchema, K extends string> = ReplacementSche
239
239
  */
240
240
  type ScopedReplacement<ReplacementSchema, PK extends string | undefined, K extends string> = LocalizedReplacement<ReplacementSchema, `${PK}.${K}`>;
241
241
 
242
+ /** Semantic tag attributes map. */
243
+ type Attributes = Record<string, string>;
244
+
245
+ /**
246
+ * Generic rich tag map used when no schema is available.
247
+ *
248
+ * Acts as a safe fallback for dynamic or unknown rich tag shapes.
249
+ */
250
+ type Rich = Record<string, Attributes>;
251
+ /**
252
+ * Rich tag map resolved from a localized rich schema.
253
+ *
254
+ * - If the key exists in the schema, resolves to the declared tag map
255
+ * - Otherwise falls back to generic `Rich`
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * type RichSchema = { "{locale}": { link: { a: { href: string } } } }
260
+ * LocalizedRich<RichSchema, "link"> // => { a: { href: string } }
261
+ * LocalizedRich<RichSchema, "missing">; // => Rich
262
+ * ```
263
+ */
264
+ type LocalizedRich<RichSchema, K extends string> = RichSchema extends {
265
+ "{locale}": infer LM;
266
+ } ? IsNever<AtPath<LM, K>> extends true ? Rich : AtPath<LM, K> extends MessageObject ? AtPath<LM, K> : Rich : Rich;
267
+ /**
268
+ * Rich tag map resolved under a scoped prefix key.
269
+ *
270
+ * Internally composes the full dot-path (`"${PK}.${K}"`)
271
+ * and delegates resolution to `LocalizedRich`.
272
+ *
273
+ * @example
274
+ * ```ts
275
+ * type RichSchema = { "{locale}": { app: { link: { a: { href: string } } } } };
276
+ * ScopedRich<RichSchema, "app", "link">; // => { a: { href: string } }
277
+ * ScopedRich<RichSchema, "app", "missing">; // => Rich
278
+ * ```
279
+ */
280
+ type ScopedRich<RichSchema, PK extends string | undefined, K extends string> = LocalizedRich<RichSchema, `${PK}.${K}`>;
281
+
242
282
  /**
243
283
  * Options for initializing a translator
244
284
  *
@@ -418,9 +458,6 @@ declare class ScopeTranslator<M extends LocaleMessages | unknown = unknown, Repl
418
458
  scoped<PK extends LocalizedPreKey<M> | undefined = undefined>(preKey?: PK): PK extends string ? ScopeTranslatorMethods<M, ReplacementSchema, PK> : ScopeTranslatorMethods<M, ReplacementSchema>;
419
459
  }
420
460
 
421
- /** Semantic tag attributes map. */
422
- type Attributes = Record<string, string>;
423
-
424
461
  /** Semantic node produced by the AST builder. */
425
462
  type ASTNode = TextNode | TagNode | RawNode;
426
463
  /** Plain text node in the semantic AST. */
@@ -441,6 +478,46 @@ interface RawNode {
441
478
  value: Exclude<MessageValue, string>;
442
479
  }
443
480
 
481
+ /** Flat semantic token produced by the message tokenizer. */
482
+ type Token = TextToken | TagOpenToken | TagCloseToken;
483
+ /** Plain text segment in the message. */
484
+ interface TextToken {
485
+ type: "text";
486
+ value: string;
487
+ position: number;
488
+ }
489
+ /** Opening semantic tag with parsed attributes. */
490
+ interface TagOpenToken {
491
+ type: "tag-open";
492
+ name: string;
493
+ attributes: Attributes;
494
+ position: number;
495
+ }
496
+ /** Closing semantic tag (no attributes). */
497
+ interface TagCloseToken {
498
+ type: "tag-close";
499
+ name: string;
500
+ position: number;
501
+ }
502
+
503
+ /**
504
+ * Tokenize a localized message string into semantic tokens.
505
+ *
506
+ * Supported syntax:
507
+ * - <tag>text</tag>
508
+ * - <tag key="value">text</tag>
509
+ *
510
+ * Notes:
511
+ * - Produces a flat token stream (nesting is handled in a later stage)
512
+ * - Tag names are identifier-like and case-sensitive
513
+ * - Attributes are strict key="value" pairs (double quotes only)
514
+ * - Variables are assumed to be interpolated beforehand
515
+ *
516
+ * This tokenizer is intentionally minimal and fail-closed:
517
+ * any unrecognized or partially valid syntax is treated as plain text.
518
+ */
519
+ declare const tokenize: (message: string) => Token[];
520
+
444
521
  /**
445
522
  * Parse a rich message value into a semantic AST.
446
523
  *
@@ -490,4 +567,4 @@ interface Renderer<Output> {
490
567
  */
491
568
  declare function renderRichMessage<Output>(message: MessageValue, renderer: Renderer<Output>): Output[];
492
569
 
493
- export { type ASTNode, type AtPath, type Attributes, type FallbackLocalesMap, type FormatHandler, type GeneratePaths, type HandlerContext, type IfLocaleMessages, type IfMessageObject, type Key, type LoadingHandler, type Locale, type LocaleMessages, type LocalizedKey, type LocalizedPreKey, type LocalizedReplacement, type LocalizedValue, type MessageObject, type MessageValue, type MissingHandler, type PreKey, type Renderer, type Replacement, type ScopedKey, type ScopedReplacement, type ScopedValue, type TranslateConfig, type TranslateContext, type TranslateHandlers, type TranslateHook, ScopeTranslator as Translator, type ScopeTranslatorMethods as TranslatorMethods, type ScopeTranslatorOptions as TranslatorOptions, type TranslatorPlugin, type Value, parseRichMessage, renderRichMessage };
570
+ export { type ASTNode, type AtPath, type Attributes, type FallbackLocalesMap, type FormatHandler, type GeneratePaths, type HandlerContext, type IfLocaleMessages, type IfMessageObject, type Key, type LoadingHandler, type Locale, type LocaleMessages, type LocalizedKey, type LocalizedPreKey, type LocalizedReplacement, type LocalizedRich, type LocalizedValue, type MessageObject, type MessageValue, type MissingHandler, type PreKey, type Renderer, type Replacement, type Rich, type ScopedKey, type ScopedReplacement, type ScopedRich, type ScopedValue, type Token, type TranslateConfig, type TranslateContext, type TranslateHandlers, type TranslateHook, ScopeTranslator as Translator, type ScopeTranslatorMethods as TranslatorMethods, type ScopeTranslatorOptions as TranslatorOptions, type TranslatorPlugin, type Value, parseRichMessage, renderRichMessage, tokenize };
package/dist/index.d.ts CHANGED
@@ -239,6 +239,46 @@ type LocalizedReplacement<ReplacementSchema, K extends string> = ReplacementSche
239
239
  */
240
240
  type ScopedReplacement<ReplacementSchema, PK extends string | undefined, K extends string> = LocalizedReplacement<ReplacementSchema, `${PK}.${K}`>;
241
241
 
242
+ /** Semantic tag attributes map. */
243
+ type Attributes = Record<string, string>;
244
+
245
+ /**
246
+ * Generic rich tag map used when no schema is available.
247
+ *
248
+ * Acts as a safe fallback for dynamic or unknown rich tag shapes.
249
+ */
250
+ type Rich = Record<string, Attributes>;
251
+ /**
252
+ * Rich tag map resolved from a localized rich schema.
253
+ *
254
+ * - If the key exists in the schema, resolves to the declared tag map
255
+ * - Otherwise falls back to generic `Rich`
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * type RichSchema = { "{locale}": { link: { a: { href: string } } } }
260
+ * LocalizedRich<RichSchema, "link"> // => { a: { href: string } }
261
+ * LocalizedRich<RichSchema, "missing">; // => Rich
262
+ * ```
263
+ */
264
+ type LocalizedRich<RichSchema, K extends string> = RichSchema extends {
265
+ "{locale}": infer LM;
266
+ } ? IsNever<AtPath<LM, K>> extends true ? Rich : AtPath<LM, K> extends MessageObject ? AtPath<LM, K> : Rich : Rich;
267
+ /**
268
+ * Rich tag map resolved under a scoped prefix key.
269
+ *
270
+ * Internally composes the full dot-path (`"${PK}.${K}"`)
271
+ * and delegates resolution to `LocalizedRich`.
272
+ *
273
+ * @example
274
+ * ```ts
275
+ * type RichSchema = { "{locale}": { app: { link: { a: { href: string } } } } };
276
+ * ScopedRich<RichSchema, "app", "link">; // => { a: { href: string } }
277
+ * ScopedRich<RichSchema, "app", "missing">; // => Rich
278
+ * ```
279
+ */
280
+ type ScopedRich<RichSchema, PK extends string | undefined, K extends string> = LocalizedRich<RichSchema, `${PK}.${K}`>;
281
+
242
282
  /**
243
283
  * Options for initializing a translator
244
284
  *
@@ -418,9 +458,6 @@ declare class ScopeTranslator<M extends LocaleMessages | unknown = unknown, Repl
418
458
  scoped<PK extends LocalizedPreKey<M> | undefined = undefined>(preKey?: PK): PK extends string ? ScopeTranslatorMethods<M, ReplacementSchema, PK> : ScopeTranslatorMethods<M, ReplacementSchema>;
419
459
  }
420
460
 
421
- /** Semantic tag attributes map. */
422
- type Attributes = Record<string, string>;
423
-
424
461
  /** Semantic node produced by the AST builder. */
425
462
  type ASTNode = TextNode | TagNode | RawNode;
426
463
  /** Plain text node in the semantic AST. */
@@ -441,6 +478,46 @@ interface RawNode {
441
478
  value: Exclude<MessageValue, string>;
442
479
  }
443
480
 
481
+ /** Flat semantic token produced by the message tokenizer. */
482
+ type Token = TextToken | TagOpenToken | TagCloseToken;
483
+ /** Plain text segment in the message. */
484
+ interface TextToken {
485
+ type: "text";
486
+ value: string;
487
+ position: number;
488
+ }
489
+ /** Opening semantic tag with parsed attributes. */
490
+ interface TagOpenToken {
491
+ type: "tag-open";
492
+ name: string;
493
+ attributes: Attributes;
494
+ position: number;
495
+ }
496
+ /** Closing semantic tag (no attributes). */
497
+ interface TagCloseToken {
498
+ type: "tag-close";
499
+ name: string;
500
+ position: number;
501
+ }
502
+
503
+ /**
504
+ * Tokenize a localized message string into semantic tokens.
505
+ *
506
+ * Supported syntax:
507
+ * - <tag>text</tag>
508
+ * - <tag key="value">text</tag>
509
+ *
510
+ * Notes:
511
+ * - Produces a flat token stream (nesting is handled in a later stage)
512
+ * - Tag names are identifier-like and case-sensitive
513
+ * - Attributes are strict key="value" pairs (double quotes only)
514
+ * - Variables are assumed to be interpolated beforehand
515
+ *
516
+ * This tokenizer is intentionally minimal and fail-closed:
517
+ * any unrecognized or partially valid syntax is treated as plain text.
518
+ */
519
+ declare const tokenize: (message: string) => Token[];
520
+
444
521
  /**
445
522
  * Parse a rich message value into a semantic AST.
446
523
  *
@@ -490,4 +567,4 @@ interface Renderer<Output> {
490
567
  */
491
568
  declare function renderRichMessage<Output>(message: MessageValue, renderer: Renderer<Output>): Output[];
492
569
 
493
- export { type ASTNode, type AtPath, type Attributes, type FallbackLocalesMap, type FormatHandler, type GeneratePaths, type HandlerContext, type IfLocaleMessages, type IfMessageObject, type Key, type LoadingHandler, type Locale, type LocaleMessages, type LocalizedKey, type LocalizedPreKey, type LocalizedReplacement, type LocalizedValue, type MessageObject, type MessageValue, type MissingHandler, type PreKey, type Renderer, type Replacement, type ScopedKey, type ScopedReplacement, type ScopedValue, type TranslateConfig, type TranslateContext, type TranslateHandlers, type TranslateHook, ScopeTranslator as Translator, type ScopeTranslatorMethods as TranslatorMethods, type ScopeTranslatorOptions as TranslatorOptions, type TranslatorPlugin, type Value, parseRichMessage, renderRichMessage };
570
+ export { type ASTNode, type AtPath, type Attributes, type FallbackLocalesMap, type FormatHandler, type GeneratePaths, type HandlerContext, type IfLocaleMessages, type IfMessageObject, type Key, type LoadingHandler, type Locale, type LocaleMessages, type LocalizedKey, type LocalizedPreKey, type LocalizedReplacement, type LocalizedRich, type LocalizedValue, type MessageObject, type MessageValue, type MissingHandler, type PreKey, type Renderer, type Replacement, type Rich, type ScopedKey, type ScopedReplacement, type ScopedRich, type ScopedValue, type Token, type TranslateConfig, type TranslateContext, type TranslateHandlers, type TranslateHook, ScopeTranslator as Translator, type ScopeTranslatorMethods as TranslatorMethods, type ScopeTranslatorOptions as TranslatorOptions, type TranslatorPlugin, type Value, parseRichMessage, renderRichMessage, tokenize };
package/dist/index.js CHANGED
@@ -515,4 +515,4 @@ function renderRichMessage(message, renderer) {
515
515
  return render(nodes, renderer);
516
516
  }
517
517
 
518
- export { ScopeTranslator as Translator, parseRichMessage, renderRichMessage };
518
+ export { ScopeTranslator as Translator, parseRichMessage, renderRichMessage, tokenize };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "intor-translator",
3
- "version": "1.4.9",
3
+ "version": "1.4.11",
4
4
  "description": "🤖 A modern, type-safe i18n engine.",
5
5
  "author": {
6
6
  "name": "Yiming Liao",