@sharpee/lang-en-us 0.9.61-beta

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.
Files changed (287) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/dist-npm/actions/about.d.ts +35 -0
  4. package/dist-npm/actions/about.d.ts.map +1 -0
  5. package/dist-npm/actions/about.js +50 -0
  6. package/dist-npm/actions/about.js.map +1 -0
  7. package/dist-npm/actions/again.d.ts +16 -0
  8. package/dist-npm/actions/again.d.ts.map +1 -0
  9. package/dist-npm/actions/again.js +23 -0
  10. package/dist-npm/actions/again.js.map +1 -0
  11. package/dist-npm/actions/answering.d.ts +29 -0
  12. package/dist-npm/actions/answering.d.ts.map +1 -0
  13. package/dist-npm/actions/answering.js +44 -0
  14. package/dist-npm/actions/answering.js.map +1 -0
  15. package/dist-npm/actions/asking.d.ts +31 -0
  16. package/dist-npm/actions/asking.d.ts.map +1 -0
  17. package/dist-npm/actions/asking.js +44 -0
  18. package/dist-npm/actions/asking.js.map +1 -0
  19. package/dist-npm/actions/attacking.d.ts +82 -0
  20. package/dist-npm/actions/attacking.d.ts.map +1 -0
  21. package/dist-npm/actions/attacking.js +111 -0
  22. package/dist-npm/actions/attacking.js.map +1 -0
  23. package/dist-npm/actions/climbing.d.ts +27 -0
  24. package/dist-npm/actions/climbing.d.ts.map +1 -0
  25. package/dist-npm/actions/climbing.js +48 -0
  26. package/dist-npm/actions/climbing.js.map +1 -0
  27. package/dist-npm/actions/closing.d.ts +21 -0
  28. package/dist-npm/actions/closing.d.ts.map +1 -0
  29. package/dist-npm/actions/closing.js +27 -0
  30. package/dist-npm/actions/closing.js.map +1 -0
  31. package/dist-npm/actions/drinking.d.ts +40 -0
  32. package/dist-npm/actions/drinking.d.ts.map +1 -0
  33. package/dist-npm/actions/drinking.js +57 -0
  34. package/dist-npm/actions/drinking.js.map +1 -0
  35. package/dist-npm/actions/dropping.d.ts +22 -0
  36. package/dist-npm/actions/dropping.d.ts.map +1 -0
  37. package/dist-npm/actions/dropping.js +31 -0
  38. package/dist-npm/actions/dropping.js.map +1 -0
  39. package/dist-npm/actions/eating.d.ts +37 -0
  40. package/dist-npm/actions/eating.d.ts.map +1 -0
  41. package/dist-npm/actions/eating.js +54 -0
  42. package/dist-npm/actions/eating.js.map +1 -0
  43. package/dist-npm/actions/entering.d.ts +26 -0
  44. package/dist-npm/actions/entering.d.ts.map +1 -0
  45. package/dist-npm/actions/entering.js +49 -0
  46. package/dist-npm/actions/entering.js.map +1 -0
  47. package/dist-npm/actions/examining.d.ts +37 -0
  48. package/dist-npm/actions/examining.d.ts.map +1 -0
  49. package/dist-npm/actions/examining.js +50 -0
  50. package/dist-npm/actions/examining.js.map +1 -0
  51. package/dist-npm/actions/exiting.d.ts +23 -0
  52. package/dist-npm/actions/exiting.d.ts.map +1 -0
  53. package/dist-npm/actions/exiting.js +40 -0
  54. package/dist-npm/actions/exiting.js.map +1 -0
  55. package/dist-npm/actions/giving.d.ts +30 -0
  56. package/dist-npm/actions/giving.d.ts.map +1 -0
  57. package/dist-npm/actions/giving.js +45 -0
  58. package/dist-npm/actions/giving.js.map +1 -0
  59. package/dist-npm/actions/going.d.ts +35 -0
  60. package/dist-npm/actions/going.d.ts.map +1 -0
  61. package/dist-npm/actions/going.js +45 -0
  62. package/dist-npm/actions/going.js.map +1 -0
  63. package/dist-npm/actions/help.d.ts +26 -0
  64. package/dist-npm/actions/help.d.ts.map +1 -0
  65. package/dist-npm/actions/help.js +44 -0
  66. package/dist-npm/actions/help.js.map +1 -0
  67. package/dist-npm/actions/index.d.ts +1327 -0
  68. package/dist-npm/actions/index.d.ts.map +1 -0
  69. package/dist-npm/actions/index.js +208 -0
  70. package/dist-npm/actions/index.js.map +1 -0
  71. package/dist-npm/actions/inserting.d.ts +25 -0
  72. package/dist-npm/actions/inserting.d.ts.map +1 -0
  73. package/dist-npm/actions/inserting.js +33 -0
  74. package/dist-npm/actions/inserting.js.map +1 -0
  75. package/dist-npm/actions/inventory.d.ts +32 -0
  76. package/dist-npm/actions/inventory.d.ts.map +1 -0
  77. package/dist-npm/actions/inventory.js +41 -0
  78. package/dist-npm/actions/inventory.js.map +1 -0
  79. package/dist-npm/actions/listening.d.ts +26 -0
  80. package/dist-npm/actions/listening.d.ts.map +1 -0
  81. package/dist-npm/actions/listening.js +37 -0
  82. package/dist-npm/actions/listening.js.map +1 -0
  83. package/dist-npm/actions/locking.d.ts +25 -0
  84. package/dist-npm/actions/locking.d.ts.map +1 -0
  85. package/dist-npm/actions/locking.js +33 -0
  86. package/dist-npm/actions/locking.js.map +1 -0
  87. package/dist-npm/actions/looking.d.ts +23 -0
  88. package/dist-npm/actions/looking.d.ts.map +1 -0
  89. package/dist-npm/actions/looking.js +34 -0
  90. package/dist-npm/actions/looking.js.map +1 -0
  91. package/dist-npm/actions/lowering.d.ts +22 -0
  92. package/dist-npm/actions/lowering.d.ts.map +1 -0
  93. package/dist-npm/actions/lowering.js +29 -0
  94. package/dist-npm/actions/lowering.js.map +1 -0
  95. package/dist-npm/actions/opening.d.ts +23 -0
  96. package/dist-npm/actions/opening.d.ts.map +1 -0
  97. package/dist-npm/actions/opening.js +30 -0
  98. package/dist-npm/actions/opening.js.map +1 -0
  99. package/dist-npm/actions/pulling.d.ts +35 -0
  100. package/dist-npm/actions/pulling.d.ts.map +1 -0
  101. package/dist-npm/actions/pulling.js +53 -0
  102. package/dist-npm/actions/pulling.js.map +1 -0
  103. package/dist-npm/actions/pushing.d.ts +30 -0
  104. package/dist-npm/actions/pushing.d.ts.map +1 -0
  105. package/dist-npm/actions/pushing.js +45 -0
  106. package/dist-npm/actions/pushing.js.map +1 -0
  107. package/dist-npm/actions/putting.d.ts +28 -0
  108. package/dist-npm/actions/putting.d.ts.map +1 -0
  109. package/dist-npm/actions/putting.js +40 -0
  110. package/dist-npm/actions/putting.js.map +1 -0
  111. package/dist-npm/actions/quitting.d.ts +31 -0
  112. package/dist-npm/actions/quitting.d.ts.map +1 -0
  113. package/dist-npm/actions/quitting.js +47 -0
  114. package/dist-npm/actions/quitting.js.map +1 -0
  115. package/dist-npm/actions/raising.d.ts +22 -0
  116. package/dist-npm/actions/raising.d.ts.map +1 -0
  117. package/dist-npm/actions/raising.js +30 -0
  118. package/dist-npm/actions/raising.js.map +1 -0
  119. package/dist-npm/actions/reading.d.ts +23 -0
  120. package/dist-npm/actions/reading.d.ts.map +1 -0
  121. package/dist-npm/actions/reading.js +32 -0
  122. package/dist-npm/actions/reading.js.map +1 -0
  123. package/dist-npm/actions/removing.d.ts +25 -0
  124. package/dist-npm/actions/removing.d.ts.map +1 -0
  125. package/dist-npm/actions/removing.js +34 -0
  126. package/dist-npm/actions/removing.js.map +1 -0
  127. package/dist-npm/actions/restoring.d.ts +35 -0
  128. package/dist-npm/actions/restoring.d.ts.map +1 -0
  129. package/dist-npm/actions/restoring.js +51 -0
  130. package/dist-npm/actions/restoring.js.map +1 -0
  131. package/dist-npm/actions/saving.d.ts +33 -0
  132. package/dist-npm/actions/saving.d.ts.map +1 -0
  133. package/dist-npm/actions/saving.js +48 -0
  134. package/dist-npm/actions/saving.js.map +1 -0
  135. package/dist-npm/actions/scoring.d.ts +42 -0
  136. package/dist-npm/actions/scoring.d.ts.map +1 -0
  137. package/dist-npm/actions/scoring.js +70 -0
  138. package/dist-npm/actions/scoring.js.map +1 -0
  139. package/dist-npm/actions/searching.d.ts +26 -0
  140. package/dist-npm/actions/searching.d.ts.map +1 -0
  141. package/dist-npm/actions/searching.js +40 -0
  142. package/dist-npm/actions/searching.js.map +1 -0
  143. package/dist-npm/actions/showing.d.ts +29 -0
  144. package/dist-npm/actions/showing.d.ts.map +1 -0
  145. package/dist-npm/actions/showing.js +40 -0
  146. package/dist-npm/actions/showing.js.map +1 -0
  147. package/dist-npm/actions/sleeping.d.ts +28 -0
  148. package/dist-npm/actions/sleeping.d.ts.map +1 -0
  149. package/dist-npm/actions/sleeping.js +41 -0
  150. package/dist-npm/actions/sleeping.js.map +1 -0
  151. package/dist-npm/actions/smelling.d.ts +30 -0
  152. package/dist-npm/actions/smelling.d.ts.map +1 -0
  153. package/dist-npm/actions/smelling.js +43 -0
  154. package/dist-npm/actions/smelling.js.map +1 -0
  155. package/dist-npm/actions/switching-off.d.ts +28 -0
  156. package/dist-npm/actions/switching-off.d.ts.map +1 -0
  157. package/dist-npm/actions/switching-off.js +42 -0
  158. package/dist-npm/actions/switching-off.js.map +1 -0
  159. package/dist-npm/actions/switching-on.d.ts +28 -0
  160. package/dist-npm/actions/switching-on.d.ts.map +1 -0
  161. package/dist-npm/actions/switching-on.js +42 -0
  162. package/dist-npm/actions/switching-on.js.map +1 -0
  163. package/dist-npm/actions/taking-off.d.ts +20 -0
  164. package/dist-npm/actions/taking-off.d.ts.map +1 -0
  165. package/dist-npm/actions/taking-off.js +28 -0
  166. package/dist-npm/actions/taking-off.js.map +1 -0
  167. package/dist-npm/actions/taking.d.ts +26 -0
  168. package/dist-npm/actions/taking.d.ts.map +1 -0
  169. package/dist-npm/actions/taking.js +36 -0
  170. package/dist-npm/actions/taking.js.map +1 -0
  171. package/dist-npm/actions/talking.d.ts +33 -0
  172. package/dist-npm/actions/talking.d.ts.map +1 -0
  173. package/dist-npm/actions/talking.js +49 -0
  174. package/dist-npm/actions/talking.js.map +1 -0
  175. package/dist-npm/actions/telling.d.ts +30 -0
  176. package/dist-npm/actions/telling.d.ts.map +1 -0
  177. package/dist-npm/actions/telling.js +42 -0
  178. package/dist-npm/actions/telling.js.map +1 -0
  179. package/dist-npm/actions/throwing.d.ts +39 -0
  180. package/dist-npm/actions/throwing.d.ts.map +1 -0
  181. package/dist-npm/actions/throwing.js +60 -0
  182. package/dist-npm/actions/throwing.js.map +1 -0
  183. package/dist-npm/actions/touching.d.ts +36 -0
  184. package/dist-npm/actions/touching.d.ts.map +1 -0
  185. package/dist-npm/actions/touching.js +50 -0
  186. package/dist-npm/actions/touching.js.map +1 -0
  187. package/dist-npm/actions/turning.d.ts +40 -0
  188. package/dist-npm/actions/turning.d.ts.map +1 -0
  189. package/dist-npm/actions/turning.js +62 -0
  190. package/dist-npm/actions/turning.js.map +1 -0
  191. package/dist-npm/actions/undoing.d.ts +19 -0
  192. package/dist-npm/actions/undoing.d.ts.map +1 -0
  193. package/dist-npm/actions/undoing.js +26 -0
  194. package/dist-npm/actions/undoing.js.map +1 -0
  195. package/dist-npm/actions/unlocking.d.ts +25 -0
  196. package/dist-npm/actions/unlocking.d.ts.map +1 -0
  197. package/dist-npm/actions/unlocking.js +32 -0
  198. package/dist-npm/actions/unlocking.js.map +1 -0
  199. package/dist-npm/actions/using.d.ts +43 -0
  200. package/dist-npm/actions/using.d.ts.map +1 -0
  201. package/dist-npm/actions/using.js +61 -0
  202. package/dist-npm/actions/using.js.map +1 -0
  203. package/dist-npm/actions/version.d.ts +18 -0
  204. package/dist-npm/actions/version.d.ts.map +1 -0
  205. package/dist-npm/actions/version.js +26 -0
  206. package/dist-npm/actions/version.js.map +1 -0
  207. package/dist-npm/actions/waiting.d.ts +27 -0
  208. package/dist-npm/actions/waiting.d.ts.map +1 -0
  209. package/dist-npm/actions/waiting.js +36 -0
  210. package/dist-npm/actions/waiting.js.map +1 -0
  211. package/dist-npm/actions/wearing.d.ts +22 -0
  212. package/dist-npm/actions/wearing.d.ts.map +1 -0
  213. package/dist-npm/actions/wearing.js +30 -0
  214. package/dist-npm/actions/wearing.js.map +1 -0
  215. package/dist-npm/data/events.d.ts +134 -0
  216. package/dist-npm/data/events.d.ts.map +1 -0
  217. package/dist-npm/data/events.js +301 -0
  218. package/dist-npm/data/events.js.map +1 -0
  219. package/dist-npm/data/messages.d.ts +141 -0
  220. package/dist-npm/data/messages.d.ts.map +1 -0
  221. package/dist-npm/data/messages.js +300 -0
  222. package/dist-npm/data/messages.js.map +1 -0
  223. package/dist-npm/data/templates.d.ts +257 -0
  224. package/dist-npm/data/templates.d.ts.map +1 -0
  225. package/dist-npm/data/templates.js +289 -0
  226. package/dist-npm/data/templates.js.map +1 -0
  227. package/dist-npm/data/verbs.d.ts +68 -0
  228. package/dist-npm/data/verbs.d.ts.map +1 -0
  229. package/dist-npm/data/verbs.js +324 -0
  230. package/dist-npm/data/verbs.js.map +1 -0
  231. package/dist-npm/data/words.d.ts +79 -0
  232. package/dist-npm/data/words.d.ts.map +1 -0
  233. package/dist-npm/data/words.js +218 -0
  234. package/dist-npm/data/words.js.map +1 -0
  235. package/dist-npm/formatters/article.d.ts +41 -0
  236. package/dist-npm/formatters/article.d.ts.map +1 -0
  237. package/dist-npm/formatters/article.js +143 -0
  238. package/dist-npm/formatters/article.js.map +1 -0
  239. package/dist-npm/formatters/index.d.ts +18 -0
  240. package/dist-npm/formatters/index.d.ts.map +1 -0
  241. package/dist-npm/formatters/index.js +38 -0
  242. package/dist-npm/formatters/index.js.map +1 -0
  243. package/dist-npm/formatters/list.d.ts +38 -0
  244. package/dist-npm/formatters/list.d.ts.map +1 -0
  245. package/dist-npm/formatters/list.js +94 -0
  246. package/dist-npm/formatters/list.js.map +1 -0
  247. package/dist-npm/formatters/registry.d.ts +48 -0
  248. package/dist-npm/formatters/registry.d.ts.map +1 -0
  249. package/dist-npm/formatters/registry.js +128 -0
  250. package/dist-npm/formatters/registry.js.map +1 -0
  251. package/dist-npm/formatters/text.d.ts +33 -0
  252. package/dist-npm/formatters/text.d.ts.map +1 -0
  253. package/dist-npm/formatters/text.js +80 -0
  254. package/dist-npm/formatters/text.js.map +1 -0
  255. package/dist-npm/formatters/types.d.ts +41 -0
  256. package/dist-npm/formatters/types.d.ts.map +1 -0
  257. package/dist-npm/formatters/types.js +14 -0
  258. package/dist-npm/formatters/types.js.map +1 -0
  259. package/dist-npm/grammar.d.ts +189 -0
  260. package/dist-npm/grammar.d.ts.map +1 -0
  261. package/dist-npm/grammar.js +203 -0
  262. package/dist-npm/grammar.js.map +1 -0
  263. package/dist-npm/index.d.ts +22 -0
  264. package/dist-npm/index.d.ts.map +1 -0
  265. package/dist-npm/index.js +59 -0
  266. package/dist-npm/index.js.map +1 -0
  267. package/dist-npm/language-provider.d.ts +159 -0
  268. package/dist-npm/language-provider.d.ts.map +1 -0
  269. package/dist-npm/language-provider.js +527 -0
  270. package/dist-npm/language-provider.js.map +1 -0
  271. package/dist-npm/npc/index.d.ts +5 -0
  272. package/dist-npm/npc/index.d.ts.map +1 -0
  273. package/dist-npm/npc/index.js +21 -0
  274. package/dist-npm/npc/index.js.map +1 -0
  275. package/dist-npm/npc/npc.d.ts +43 -0
  276. package/dist-npm/npc/npc.d.ts.map +1 -0
  277. package/dist-npm/npc/npc.js +55 -0
  278. package/dist-npm/npc/npc.js.map +1 -0
  279. package/dist-npm/perspective/index.d.ts +5 -0
  280. package/dist-npm/perspective/index.d.ts.map +1 -0
  281. package/dist-npm/perspective/index.js +12 -0
  282. package/dist-npm/perspective/index.js.map +1 -0
  283. package/dist-npm/perspective/placeholder-resolver.d.ts +102 -0
  284. package/dist-npm/perspective/placeholder-resolver.d.ts.map +1 -0
  285. package/dist-npm/perspective/placeholder-resolver.js +275 -0
  286. package/dist-npm/perspective/placeholder-resolver.js.map +1 -0
  287. package/package.json +65 -0
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Article Formatters
3
+ *
4
+ * Formatters for adding articles to nouns based on noun type.
5
+ *
6
+ * @see ADR-095 Message Templates with Formatters
7
+ */
8
+ import type { Formatter } from './types.js';
9
+ /**
10
+ * "a" formatter - indefinite article
11
+ *
12
+ * Respects nounType:
13
+ * - common: "a sword" / "an apple"
14
+ * - proper: "John" (no article)
15
+ * - mass: "some water"
16
+ * - unique: "the sun"
17
+ * - plural: "swords" (no article for indefinite plural)
18
+ */
19
+ export declare const aFormatter: Formatter;
20
+ /**
21
+ * "the" formatter - definite article
22
+ *
23
+ * Respects nounType:
24
+ * - proper: "John" (no article)
25
+ * - all others: "the X"
26
+ */
27
+ export declare const theFormatter: Formatter;
28
+ /**
29
+ * "some" formatter - partitive article
30
+ *
31
+ * Primarily for mass nouns: "some water"
32
+ * Also works for plurals: "some coins"
33
+ */
34
+ export declare const someFormatter: Formatter;
35
+ /**
36
+ * "your" formatter - possessive
37
+ *
38
+ * Creates "your X" phrases
39
+ */
40
+ export declare const yourFormatter: Formatter;
41
+ //# sourceMappingURL=article.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"article.d.ts","sourceRoot":"","sources":["../../src/formatters/article.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAgC,MAAM,YAAY,CAAC;AAwC1E;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,EAAE,SA6BxB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,SAiB1B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAiB3B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,SAQ3B,CAAC"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ /**
3
+ * Article Formatters
4
+ *
5
+ * Formatters for adding articles to nouns based on noun type.
6
+ *
7
+ * @see ADR-095 Message Templates with Formatters
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.yourFormatter = exports.someFormatter = exports.theFormatter = exports.aFormatter = void 0;
11
+ /**
12
+ * Get indefinite article for a word (a/an)
13
+ */
14
+ function getIndefiniteArticle(word) {
15
+ if (!word || word.length === 0)
16
+ return 'a';
17
+ const lower = word.toLowerCase();
18
+ // Special cases
19
+ if (lower.startsWith('hour'))
20
+ return 'an';
21
+ if (lower.startsWith('honest'))
22
+ return 'an';
23
+ if (lower.startsWith('heir'))
24
+ return 'an';
25
+ if (lower.startsWith('uni'))
26
+ return 'a'; // university
27
+ if (lower.startsWith('one'))
28
+ return 'a'; // one-way
29
+ const firstChar = lower[0];
30
+ const vowels = ['a', 'e', 'i', 'o', 'u'];
31
+ return vowels.includes(firstChar) ? 'an' : 'a';
32
+ }
33
+ /**
34
+ * Extract name from value (string or EntityInfo)
35
+ */
36
+ function getName(value) {
37
+ return typeof value === 'string' ? value : value.name;
38
+ }
39
+ /**
40
+ * Get entity info from value
41
+ */
42
+ function getEntityInfo(value) {
43
+ if (typeof value === 'string') {
44
+ return { name: value };
45
+ }
46
+ return value;
47
+ }
48
+ /**
49
+ * "a" formatter - indefinite article
50
+ *
51
+ * Respects nounType:
52
+ * - common: "a sword" / "an apple"
53
+ * - proper: "John" (no article)
54
+ * - mass: "some water"
55
+ * - unique: "the sun"
56
+ * - plural: "swords" (no article for indefinite plural)
57
+ */
58
+ const aFormatter = (value, _context) => {
59
+ // Handle arrays - format each item
60
+ if (Array.isArray(value)) {
61
+ return value.map((v) => (0, exports.aFormatter)(v, _context)).join(', ');
62
+ }
63
+ const info = getEntityInfo(value);
64
+ const name = info.name;
65
+ // Check noun type
66
+ const nounType = info.nounType ?? (info.properName ? 'proper' : 'common');
67
+ switch (nounType) {
68
+ case 'proper':
69
+ return name; // No article for proper names
70
+ case 'mass':
71
+ return `some ${name}`;
72
+ case 'unique':
73
+ return `the ${name}`;
74
+ case 'plural':
75
+ return name; // No article for indefinite plurals
76
+ case 'common':
77
+ default:
78
+ // Check if entity has custom article
79
+ if (info.article && info.article !== 'a' && info.article !== 'an') {
80
+ return `${info.article} ${name}`;
81
+ }
82
+ return `${getIndefiniteArticle(name)} ${name}`;
83
+ }
84
+ };
85
+ exports.aFormatter = aFormatter;
86
+ /**
87
+ * "the" formatter - definite article
88
+ *
89
+ * Respects nounType:
90
+ * - proper: "John" (no article)
91
+ * - all others: "the X"
92
+ */
93
+ const theFormatter = (value, _context) => {
94
+ // Handle arrays - format each item
95
+ if (Array.isArray(value)) {
96
+ return value.map((v) => (0, exports.theFormatter)(v, _context)).join(', ');
97
+ }
98
+ const info = getEntityInfo(value);
99
+ const name = info.name;
100
+ // Check noun type
101
+ const nounType = info.nounType ?? (info.properName ? 'proper' : 'common');
102
+ if (nounType === 'proper') {
103
+ return name; // No article for proper names
104
+ }
105
+ return `the ${name}`;
106
+ };
107
+ exports.theFormatter = theFormatter;
108
+ /**
109
+ * "some" formatter - partitive article
110
+ *
111
+ * Primarily for mass nouns: "some water"
112
+ * Also works for plurals: "some coins"
113
+ */
114
+ const someFormatter = (value, _context) => {
115
+ // Handle arrays - format each item
116
+ if (Array.isArray(value)) {
117
+ return value.map((v) => (0, exports.someFormatter)(v, _context)).join(', ');
118
+ }
119
+ const info = getEntityInfo(value);
120
+ const name = info.name;
121
+ // Check noun type
122
+ const nounType = info.nounType ?? (info.properName ? 'proper' : 'common');
123
+ if (nounType === 'proper') {
124
+ return name; // No article for proper names
125
+ }
126
+ return `some ${name}`;
127
+ };
128
+ exports.someFormatter = someFormatter;
129
+ /**
130
+ * "your" formatter - possessive
131
+ *
132
+ * Creates "your X" phrases
133
+ */
134
+ const yourFormatter = (value, _context) => {
135
+ // Handle arrays
136
+ if (Array.isArray(value)) {
137
+ return value.map((v) => (0, exports.yourFormatter)(v, _context)).join(', ');
138
+ }
139
+ const name = getName(value);
140
+ return `your ${name}`;
141
+ };
142
+ exports.yourFormatter = yourFormatter;
143
+ //# sourceMappingURL=article.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"article.js","sourceRoot":"","sources":["../../src/formatters/article.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAIH;;GAEG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAE3C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAEjC,gBAAgB;IAChB,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,CAAE,aAAa;IACvD,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,CAAG,UAAU;IAErD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAEzC,OAAO,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,KAA0B;IACzC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,KAA0B;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACI,MAAM,UAAU,GAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;IACvD,mCAAmC;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,kBAAU,EAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAEvB,kBAAkB;IAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAE1E,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,CAAC,8BAA8B;QAC7C,KAAK,MAAM;YACT,OAAO,QAAQ,IAAI,EAAE,CAAC;QACxB,KAAK,QAAQ;YACX,OAAO,OAAO,IAAI,EAAE,CAAC;QACvB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,CAAC,oCAAoC;QACnD,KAAK,QAAQ,CAAC;QACd;YACE,qCAAqC;YACrC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAClE,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;YACnC,CAAC;YACD,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IACnD,CAAC;AACH,CAAC,CAAC;AA7BW,QAAA,UAAU,cA6BrB;AAEF;;;;;;GAMG;AACI,MAAM,YAAY,GAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;IACzD,mCAAmC;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,oBAAY,EAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAEvB,kBAAkB;IAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAE1E,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,CAAC,8BAA8B;IAC7C,CAAC;IAED,OAAO,OAAO,IAAI,EAAE,CAAC;AACvB,CAAC,CAAC;AAjBW,QAAA,YAAY,gBAiBvB;AAEF;;;;;GAKG;AACI,MAAM,aAAa,GAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;IAC1D,mCAAmC;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,qBAAa,EAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAEvB,kBAAkB;IAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAE1E,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,CAAC,8BAA8B;IAC7C,CAAC;IAED,OAAO,QAAQ,IAAI,EAAE,CAAC;AACxB,CAAC,CAAC;AAjBW,QAAA,aAAa,iBAiBxB;AAEF;;;;GAIG;AACI,MAAM,aAAa,GAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;IAC1D,gBAAgB;IAChB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,qBAAa,EAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,QAAQ,IAAI,EAAE,CAAC;AACxB,CAAC,CAAC;AARW,QAAA,aAAa,iBAQxB"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Formatter System
3
+ *
4
+ * Formatters transform placeholder values in message templates.
5
+ *
6
+ * Syntax: {formatter:formatter:...:placeholder}
7
+ * Example: {a:item} → "a sword"
8
+ * Example: {items:list} → "a sword, a key, and a coin"
9
+ * Example: {a:items:list} → applies 'a' to each item, then 'list' to join
10
+ *
11
+ * @see ADR-095 Message Templates with Formatters
12
+ */
13
+ export type { Formatter, FormatterRegistry, FormatterContext, EntityInfo, } from './types.js';
14
+ export { createFormatterRegistry, parsePlaceholder, applyFormatters, formatMessage, } from './registry.js';
15
+ export { aFormatter, theFormatter, someFormatter, yourFormatter } from './article.js';
16
+ export { listFormatter, orListFormatter, commaListFormatter, countFormatter } from './list.js';
17
+ export { capFormatter, upperFormatter, lowerFormatter, titleFormatter } from './text.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /**
3
+ * Formatter System
4
+ *
5
+ * Formatters transform placeholder values in message templates.
6
+ *
7
+ * Syntax: {formatter:formatter:...:placeholder}
8
+ * Example: {a:item} → "a sword"
9
+ * Example: {items:list} → "a sword, a key, and a coin"
10
+ * Example: {a:items:list} → applies 'a' to each item, then 'list' to join
11
+ *
12
+ * @see ADR-095 Message Templates with Formatters
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.titleFormatter = exports.lowerFormatter = exports.upperFormatter = exports.capFormatter = exports.countFormatter = exports.commaListFormatter = exports.orListFormatter = exports.listFormatter = exports.yourFormatter = exports.someFormatter = exports.theFormatter = exports.aFormatter = exports.formatMessage = exports.applyFormatters = exports.parsePlaceholder = exports.createFormatterRegistry = void 0;
16
+ // Registry and utilities
17
+ var registry_js_1 = require("./registry.js");
18
+ Object.defineProperty(exports, "createFormatterRegistry", { enumerable: true, get: function () { return registry_js_1.createFormatterRegistry; } });
19
+ Object.defineProperty(exports, "parsePlaceholder", { enumerable: true, get: function () { return registry_js_1.parsePlaceholder; } });
20
+ Object.defineProperty(exports, "applyFormatters", { enumerable: true, get: function () { return registry_js_1.applyFormatters; } });
21
+ Object.defineProperty(exports, "formatMessage", { enumerable: true, get: function () { return registry_js_1.formatMessage; } });
22
+ // Individual formatters (for direct use or testing)
23
+ var article_js_1 = require("./article.js");
24
+ Object.defineProperty(exports, "aFormatter", { enumerable: true, get: function () { return article_js_1.aFormatter; } });
25
+ Object.defineProperty(exports, "theFormatter", { enumerable: true, get: function () { return article_js_1.theFormatter; } });
26
+ Object.defineProperty(exports, "someFormatter", { enumerable: true, get: function () { return article_js_1.someFormatter; } });
27
+ Object.defineProperty(exports, "yourFormatter", { enumerable: true, get: function () { return article_js_1.yourFormatter; } });
28
+ var list_js_1 = require("./list.js");
29
+ Object.defineProperty(exports, "listFormatter", { enumerable: true, get: function () { return list_js_1.listFormatter; } });
30
+ Object.defineProperty(exports, "orListFormatter", { enumerable: true, get: function () { return list_js_1.orListFormatter; } });
31
+ Object.defineProperty(exports, "commaListFormatter", { enumerable: true, get: function () { return list_js_1.commaListFormatter; } });
32
+ Object.defineProperty(exports, "countFormatter", { enumerable: true, get: function () { return list_js_1.countFormatter; } });
33
+ var text_js_1 = require("./text.js");
34
+ Object.defineProperty(exports, "capFormatter", { enumerable: true, get: function () { return text_js_1.capFormatter; } });
35
+ Object.defineProperty(exports, "upperFormatter", { enumerable: true, get: function () { return text_js_1.upperFormatter; } });
36
+ Object.defineProperty(exports, "lowerFormatter", { enumerable: true, get: function () { return text_js_1.lowerFormatter; } });
37
+ Object.defineProperty(exports, "titleFormatter", { enumerable: true, get: function () { return text_js_1.titleFormatter; } });
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAUH,yBAAyB;AACzB,6CAKuB;AAJrB,sHAAA,uBAAuB,OAAA;AACvB,+GAAA,gBAAgB,OAAA;AAChB,8GAAA,eAAe,OAAA;AACf,4GAAA,aAAa,OAAA;AAGf,oDAAoD;AACpD,2CAAsF;AAA7E,wGAAA,UAAU,OAAA;AAAE,0GAAA,YAAY,OAAA;AAAE,2GAAA,aAAa,OAAA;AAAE,2GAAA,aAAa,OAAA;AAC/D,qCAA+F;AAAtF,wGAAA,aAAa,OAAA;AAAE,0GAAA,eAAe,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAAE,yGAAA,cAAc,OAAA;AAC3E,qCAAyF;AAAhF,uGAAA,YAAY,OAAA;AAAE,yGAAA,cAAc,OAAA;AAAE,yGAAA,cAAc,OAAA;AAAE,yGAAA,cAAc,OAAA"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * List Formatters
3
+ *
4
+ * Formatters for joining arrays of items into prose.
5
+ *
6
+ * @see ADR-095 Message Templates with Formatters
7
+ */
8
+ import type { Formatter } from './types.js';
9
+ /**
10
+ * "list" formatter - join with commas and "and"
11
+ *
12
+ * Single: "a sword"
13
+ * Two: "a sword and a key"
14
+ * Three+: "a sword, a key, and a coin"
15
+ */
16
+ export declare const listFormatter: Formatter;
17
+ /**
18
+ * "or-list" formatter - join with commas and "or"
19
+ *
20
+ * Single: "north"
21
+ * Two: "north or south"
22
+ * Three+: "north, south, or east"
23
+ */
24
+ export declare const orListFormatter: Formatter;
25
+ /**
26
+ * "comma-list" formatter - join with commas only (no conjunction)
27
+ *
28
+ * "a sword, a key, a coin"
29
+ */
30
+ export declare const commaListFormatter: Formatter;
31
+ /**
32
+ * "count" formatter - number + noun (with pluralization)
33
+ *
34
+ * Example: {items:count} with 3 swords → "3 swords"
35
+ * Example: {items:count} with 1 sword → "1 sword"
36
+ */
37
+ export declare const countFormatter: Formatter;
38
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/formatters/list.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;AAmBxD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,SAU3B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,SAU7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAGhC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,SAU5B,CAAC"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ /**
3
+ * List Formatters
4
+ *
5
+ * Formatters for joining arrays of items into prose.
6
+ *
7
+ * @see ADR-095 Message Templates with Formatters
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.countFormatter = exports.commaListFormatter = exports.orListFormatter = exports.listFormatter = void 0;
11
+ /**
12
+ * Extract name from value (string or EntityInfo)
13
+ */
14
+ function getName(value) {
15
+ return typeof value === 'string' ? value : value.name;
16
+ }
17
+ /**
18
+ * Ensure value is an array
19
+ */
20
+ function ensureArray(value) {
21
+ if (Array.isArray(value)) {
22
+ return value.map((v) => getName(v));
23
+ }
24
+ return [getName(value)];
25
+ }
26
+ /**
27
+ * "list" formatter - join with commas and "and"
28
+ *
29
+ * Single: "a sword"
30
+ * Two: "a sword and a key"
31
+ * Three+: "a sword, a key, and a coin"
32
+ */
33
+ const listFormatter = (value, _context) => {
34
+ const items = ensureArray(value);
35
+ if (items.length === 0)
36
+ return '';
37
+ if (items.length === 1)
38
+ return items[0];
39
+ if (items.length === 2)
40
+ return `${items[0]} and ${items[1]}`;
41
+ const allButLast = items.slice(0, -1);
42
+ const last = items[items.length - 1];
43
+ return `${allButLast.join(', ')}, and ${last}`;
44
+ };
45
+ exports.listFormatter = listFormatter;
46
+ /**
47
+ * "or-list" formatter - join with commas and "or"
48
+ *
49
+ * Single: "north"
50
+ * Two: "north or south"
51
+ * Three+: "north, south, or east"
52
+ */
53
+ const orListFormatter = (value, _context) => {
54
+ const items = ensureArray(value);
55
+ if (items.length === 0)
56
+ return '';
57
+ if (items.length === 1)
58
+ return items[0];
59
+ if (items.length === 2)
60
+ return `${items[0]} or ${items[1]}`;
61
+ const allButLast = items.slice(0, -1);
62
+ const last = items[items.length - 1];
63
+ return `${allButLast.join(', ')}, or ${last}`;
64
+ };
65
+ exports.orListFormatter = orListFormatter;
66
+ /**
67
+ * "comma-list" formatter - join with commas only (no conjunction)
68
+ *
69
+ * "a sword, a key, a coin"
70
+ */
71
+ const commaListFormatter = (value, _context) => {
72
+ const items = ensureArray(value);
73
+ return items.join(', ');
74
+ };
75
+ exports.commaListFormatter = commaListFormatter;
76
+ /**
77
+ * "count" formatter - number + noun (with pluralization)
78
+ *
79
+ * Example: {items:count} with 3 swords → "3 swords"
80
+ * Example: {items:count} with 1 sword → "1 sword"
81
+ */
82
+ const countFormatter = (value, _context) => {
83
+ const items = ensureArray(value);
84
+ const count = items.length;
85
+ if (count === 0)
86
+ return 'nothing';
87
+ if (count === 1)
88
+ return `1 ${items[0]}`;
89
+ // For count > 1, assume the items are already formatted
90
+ // The item name should be pluralized by caller or be inherently plural
91
+ return `${count} items`;
92
+ };
93
+ exports.countFormatter = countFormatter;
94
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/formatters/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Formatter Registry
3
+ *
4
+ * Central registry of all formatters, with support for story extensions.
5
+ *
6
+ * @see ADR-095 Message Templates with Formatters
7
+ */
8
+ import type { FormatterRegistry, FormatterContext, EntityInfo } from './types.js';
9
+ /**
10
+ * Create the default formatter registry with all built-in formatters
11
+ */
12
+ export declare function createFormatterRegistry(): FormatterRegistry;
13
+ /**
14
+ * Parse a placeholder with formatters
15
+ *
16
+ * Syntax: {formatter:formatter:...:placeholder}
17
+ *
18
+ * @returns Object with formatters array and final placeholder name
19
+ */
20
+ export declare function parsePlaceholder(placeholder: string): {
21
+ formatters: string[];
22
+ name: string;
23
+ };
24
+ /**
25
+ * Apply formatters to a value in sequence
26
+ *
27
+ * @param value - The value to format
28
+ * @param formatters - Array of formatter names to apply in order
29
+ * @param registry - The formatter registry
30
+ * @param context - Formatting context
31
+ * @returns Formatted string
32
+ */
33
+ export declare function applyFormatters(value: string | number | boolean | string[] | EntityInfo | EntityInfo[], formatters: string[], registry: FormatterRegistry, context: FormatterContext): string;
34
+ /**
35
+ * Format a message template with placeholders
36
+ *
37
+ * Supports both:
38
+ * - Simple placeholders: {item}
39
+ * - Formatted placeholders: {a:item}, {items:list}, {a:items:list}
40
+ *
41
+ * @param template - Message template with {placeholder} syntax
42
+ * @param params - Values for placeholders
43
+ * @param registry - Formatter registry
44
+ * @param context - Formatting context
45
+ * @returns Formatted message
46
+ */
47
+ export declare function formatMessage(template: string, params: Record<string, string | number | boolean | string[] | EntityInfo | EntityInfo[]>, registry: FormatterRegistry, context?: FormatterContext): string;
48
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/formatters/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAa,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK7F;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,iBAAiB,CAuB3D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG;IACrD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,CAYA;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,UAAU,GAAG,UAAU,EAAE,EACvE,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,gBAAgB,GACxB,MAAM,CAuBR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,UAAU,GAAG,UAAU,EAAE,CAAC,EACxF,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,gBAAqB,GAC7B,MAAM,CA8BR"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ /**
3
+ * Formatter Registry
4
+ *
5
+ * Central registry of all formatters, with support for story extensions.
6
+ *
7
+ * @see ADR-095 Message Templates with Formatters
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.createFormatterRegistry = createFormatterRegistry;
11
+ exports.parsePlaceholder = parsePlaceholder;
12
+ exports.applyFormatters = applyFormatters;
13
+ exports.formatMessage = formatMessage;
14
+ const article_js_1 = require("./article.js");
15
+ const list_js_1 = require("./list.js");
16
+ const text_js_1 = require("./text.js");
17
+ /**
18
+ * Create the default formatter registry with all built-in formatters
19
+ */
20
+ function createFormatterRegistry() {
21
+ const registry = new Map();
22
+ // Article formatters
23
+ registry.set('a', article_js_1.aFormatter);
24
+ registry.set('an', article_js_1.aFormatter); // Alias
25
+ registry.set('the', article_js_1.theFormatter);
26
+ registry.set('some', article_js_1.someFormatter);
27
+ registry.set('your', article_js_1.yourFormatter);
28
+ // List formatters
29
+ registry.set('list', list_js_1.listFormatter);
30
+ registry.set('or-list', list_js_1.orListFormatter);
31
+ registry.set('comma-list', list_js_1.commaListFormatter);
32
+ registry.set('count', list_js_1.countFormatter);
33
+ // Text formatters
34
+ registry.set('cap', text_js_1.capFormatter);
35
+ registry.set('upper', text_js_1.upperFormatter);
36
+ registry.set('lower', text_js_1.lowerFormatter);
37
+ registry.set('title', text_js_1.titleFormatter);
38
+ return registry;
39
+ }
40
+ /**
41
+ * Parse a placeholder with formatters
42
+ *
43
+ * Syntax: {formatter:formatter:...:placeholder}
44
+ *
45
+ * @returns Object with formatters array and final placeholder name
46
+ */
47
+ function parsePlaceholder(placeholder) {
48
+ const parts = placeholder.split(':');
49
+ if (parts.length === 1) {
50
+ return { formatters: [], name: parts[0] };
51
+ }
52
+ // Last part is the placeholder name, everything before is formatters
53
+ const name = parts[parts.length - 1];
54
+ const formatters = parts.slice(0, -1);
55
+ return { formatters, name };
56
+ }
57
+ /**
58
+ * Apply formatters to a value in sequence
59
+ *
60
+ * @param value - The value to format
61
+ * @param formatters - Array of formatter names to apply in order
62
+ * @param registry - The formatter registry
63
+ * @param context - Formatting context
64
+ * @returns Formatted string
65
+ */
66
+ function applyFormatters(value, formatters, registry, context) {
67
+ // Convert numbers/booleans to strings first
68
+ let result = (typeof value === 'number' || typeof value === 'boolean') ? String(value) : value;
69
+ for (const formatterName of formatters) {
70
+ const formatter = registry.get(formatterName);
71
+ if (formatter) {
72
+ // Apply formatter - result becomes a string
73
+ const formatted = formatter(result, context);
74
+ result = formatted;
75
+ }
76
+ // If formatter not found, skip it (could log warning)
77
+ }
78
+ // Ensure we return a string
79
+ if (Array.isArray(result)) {
80
+ return result.map((v) => (typeof v === 'string' ? v : v.name)).join(', ');
81
+ }
82
+ if (typeof result === 'string') {
83
+ return result;
84
+ }
85
+ return result.name;
86
+ }
87
+ /**
88
+ * Format a message template with placeholders
89
+ *
90
+ * Supports both:
91
+ * - Simple placeholders: {item}
92
+ * - Formatted placeholders: {a:item}, {items:list}, {a:items:list}
93
+ *
94
+ * @param template - Message template with {placeholder} syntax
95
+ * @param params - Values for placeholders
96
+ * @param registry - Formatter registry
97
+ * @param context - Formatting context
98
+ * @returns Formatted message
99
+ */
100
+ function formatMessage(template, params, registry, context = {}) {
101
+ // Match {anything} placeholders
102
+ return template.replace(/\{([^}]+)\}/g, (match, placeholder) => {
103
+ const { formatters, name } = parsePlaceholder(placeholder);
104
+ // Get the value for this placeholder
105
+ const value = params[name];
106
+ if (value === undefined) {
107
+ // Placeholder not found in params - leave it as is
108
+ // (might be a perspective placeholder like {You})
109
+ return match;
110
+ }
111
+ // Apply formatters
112
+ if (formatters.length > 0) {
113
+ return applyFormatters(value, formatters, registry, context);
114
+ }
115
+ // No formatters - just convert to string
116
+ if (Array.isArray(value)) {
117
+ return value.map((v) => (typeof v === 'string' ? v : v.name)).join(', ');
118
+ }
119
+ if (typeof value === 'string') {
120
+ return value;
121
+ }
122
+ if (typeof value === 'number' || typeof value === 'boolean') {
123
+ return String(value);
124
+ }
125
+ return value.name;
126
+ });
127
+ }
128
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/formatters/registry.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAUH,0DAuBC;AASD,4CAeC;AAWD,0CA4BC;AAeD,sCAmCC;AA/ID,6CAAsF;AACtF,uCAA+F;AAC/F,uCAAyF;AAEzF;;GAEG;AACH,SAAgB,uBAAuB;IACrC,MAAM,QAAQ,GAAsB,IAAI,GAAG,EAAE,CAAC;IAE9C,qBAAqB;IACrB,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,uBAAU,CAAC,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,uBAAU,CAAC,CAAC,CAAC,QAAQ;IACxC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,yBAAY,CAAC,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,0BAAa,CAAC,CAAC;IACpC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,0BAAa,CAAC,CAAC;IAEpC,kBAAkB;IAClB,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,uBAAa,CAAC,CAAC;IACpC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,yBAAe,CAAC,CAAC;IACzC,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE,4BAAkB,CAAC,CAAC;IAC/C,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAc,CAAC,CAAC;IAEtC,kBAAkB;IAClB,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,sBAAY,CAAC,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAc,CAAC,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAc,CAAC,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAc,CAAC,CAAC;IAEtC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,WAAmB;IAIlD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAErC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,qEAAqE;IACrE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,eAAe,CAC7B,KAAuE,EACvE,UAAoB,EACpB,QAA2B,EAC3B,OAAyB;IAEzB,4CAA4C;IAC5C,IAAI,MAAM,GACR,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEpF,KAAK,MAAM,aAAa,IAAI,UAAU,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC9C,IAAI,SAAS,EAAE,CAAC;YACd,4CAA4C;YAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,GAAG,SAAS,CAAC;QACrB,CAAC;QACD,sDAAsD;IACxD,CAAC;IAED,4BAA4B;IAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,aAAa,CAC3B,QAAgB,EAChB,MAAwF,EACxF,QAA2B,EAC3B,UAA4B,EAAE;IAE9B,gCAAgC;IAChC,OAAO,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE;QAC7D,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAE3D,qCAAqC;QACrC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,mDAAmD;YACnD,kDAAkD;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,mBAAmB;QACnB,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;QAED,yCAAyC;QACzC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Text Formatters
3
+ *
4
+ * Formatters for case transformation and text manipulation.
5
+ *
6
+ * @see ADR-095 Message Templates with Formatters
7
+ */
8
+ import type { Formatter } from './types.js';
9
+ /**
10
+ * "cap" formatter - capitalize first letter
11
+ *
12
+ * "sword" → "Sword"
13
+ */
14
+ export declare const capFormatter: Formatter;
15
+ /**
16
+ * "upper" formatter - all uppercase
17
+ *
18
+ * "sword" → "SWORD"
19
+ */
20
+ export declare const upperFormatter: Formatter;
21
+ /**
22
+ * "lower" formatter - all lowercase
23
+ *
24
+ * "SWORD" → "sword"
25
+ */
26
+ export declare const lowerFormatter: Formatter;
27
+ /**
28
+ * "title" formatter - title case (capitalize each word)
29
+ *
30
+ * "brass lantern" → "Brass Lantern"
31
+ */
32
+ export declare const titleFormatter: Formatter;
33
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/formatters/text.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;AASxD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,SAU1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,SAQ5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,SAQ5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,SAa5B,CAAC"}