@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.
- package/LICENSE +21 -0
- package/README.md +105 -0
- package/dist-npm/actions/about.d.ts +35 -0
- package/dist-npm/actions/about.d.ts.map +1 -0
- package/dist-npm/actions/about.js +50 -0
- package/dist-npm/actions/about.js.map +1 -0
- package/dist-npm/actions/again.d.ts +16 -0
- package/dist-npm/actions/again.d.ts.map +1 -0
- package/dist-npm/actions/again.js +23 -0
- package/dist-npm/actions/again.js.map +1 -0
- package/dist-npm/actions/answering.d.ts +29 -0
- package/dist-npm/actions/answering.d.ts.map +1 -0
- package/dist-npm/actions/answering.js +44 -0
- package/dist-npm/actions/answering.js.map +1 -0
- package/dist-npm/actions/asking.d.ts +31 -0
- package/dist-npm/actions/asking.d.ts.map +1 -0
- package/dist-npm/actions/asking.js +44 -0
- package/dist-npm/actions/asking.js.map +1 -0
- package/dist-npm/actions/attacking.d.ts +82 -0
- package/dist-npm/actions/attacking.d.ts.map +1 -0
- package/dist-npm/actions/attacking.js +111 -0
- package/dist-npm/actions/attacking.js.map +1 -0
- package/dist-npm/actions/climbing.d.ts +27 -0
- package/dist-npm/actions/climbing.d.ts.map +1 -0
- package/dist-npm/actions/climbing.js +48 -0
- package/dist-npm/actions/climbing.js.map +1 -0
- package/dist-npm/actions/closing.d.ts +21 -0
- package/dist-npm/actions/closing.d.ts.map +1 -0
- package/dist-npm/actions/closing.js +27 -0
- package/dist-npm/actions/closing.js.map +1 -0
- package/dist-npm/actions/drinking.d.ts +40 -0
- package/dist-npm/actions/drinking.d.ts.map +1 -0
- package/dist-npm/actions/drinking.js +57 -0
- package/dist-npm/actions/drinking.js.map +1 -0
- package/dist-npm/actions/dropping.d.ts +22 -0
- package/dist-npm/actions/dropping.d.ts.map +1 -0
- package/dist-npm/actions/dropping.js +31 -0
- package/dist-npm/actions/dropping.js.map +1 -0
- package/dist-npm/actions/eating.d.ts +37 -0
- package/dist-npm/actions/eating.d.ts.map +1 -0
- package/dist-npm/actions/eating.js +54 -0
- package/dist-npm/actions/eating.js.map +1 -0
- package/dist-npm/actions/entering.d.ts +26 -0
- package/dist-npm/actions/entering.d.ts.map +1 -0
- package/dist-npm/actions/entering.js +49 -0
- package/dist-npm/actions/entering.js.map +1 -0
- package/dist-npm/actions/examining.d.ts +37 -0
- package/dist-npm/actions/examining.d.ts.map +1 -0
- package/dist-npm/actions/examining.js +50 -0
- package/dist-npm/actions/examining.js.map +1 -0
- package/dist-npm/actions/exiting.d.ts +23 -0
- package/dist-npm/actions/exiting.d.ts.map +1 -0
- package/dist-npm/actions/exiting.js +40 -0
- package/dist-npm/actions/exiting.js.map +1 -0
- package/dist-npm/actions/giving.d.ts +30 -0
- package/dist-npm/actions/giving.d.ts.map +1 -0
- package/dist-npm/actions/giving.js +45 -0
- package/dist-npm/actions/giving.js.map +1 -0
- package/dist-npm/actions/going.d.ts +35 -0
- package/dist-npm/actions/going.d.ts.map +1 -0
- package/dist-npm/actions/going.js +45 -0
- package/dist-npm/actions/going.js.map +1 -0
- package/dist-npm/actions/help.d.ts +26 -0
- package/dist-npm/actions/help.d.ts.map +1 -0
- package/dist-npm/actions/help.js +44 -0
- package/dist-npm/actions/help.js.map +1 -0
- package/dist-npm/actions/index.d.ts +1327 -0
- package/dist-npm/actions/index.d.ts.map +1 -0
- package/dist-npm/actions/index.js +208 -0
- package/dist-npm/actions/index.js.map +1 -0
- package/dist-npm/actions/inserting.d.ts +25 -0
- package/dist-npm/actions/inserting.d.ts.map +1 -0
- package/dist-npm/actions/inserting.js +33 -0
- package/dist-npm/actions/inserting.js.map +1 -0
- package/dist-npm/actions/inventory.d.ts +32 -0
- package/dist-npm/actions/inventory.d.ts.map +1 -0
- package/dist-npm/actions/inventory.js +41 -0
- package/dist-npm/actions/inventory.js.map +1 -0
- package/dist-npm/actions/listening.d.ts +26 -0
- package/dist-npm/actions/listening.d.ts.map +1 -0
- package/dist-npm/actions/listening.js +37 -0
- package/dist-npm/actions/listening.js.map +1 -0
- package/dist-npm/actions/locking.d.ts +25 -0
- package/dist-npm/actions/locking.d.ts.map +1 -0
- package/dist-npm/actions/locking.js +33 -0
- package/dist-npm/actions/locking.js.map +1 -0
- package/dist-npm/actions/looking.d.ts +23 -0
- package/dist-npm/actions/looking.d.ts.map +1 -0
- package/dist-npm/actions/looking.js +34 -0
- package/dist-npm/actions/looking.js.map +1 -0
- package/dist-npm/actions/lowering.d.ts +22 -0
- package/dist-npm/actions/lowering.d.ts.map +1 -0
- package/dist-npm/actions/lowering.js +29 -0
- package/dist-npm/actions/lowering.js.map +1 -0
- package/dist-npm/actions/opening.d.ts +23 -0
- package/dist-npm/actions/opening.d.ts.map +1 -0
- package/dist-npm/actions/opening.js +30 -0
- package/dist-npm/actions/opening.js.map +1 -0
- package/dist-npm/actions/pulling.d.ts +35 -0
- package/dist-npm/actions/pulling.d.ts.map +1 -0
- package/dist-npm/actions/pulling.js +53 -0
- package/dist-npm/actions/pulling.js.map +1 -0
- package/dist-npm/actions/pushing.d.ts +30 -0
- package/dist-npm/actions/pushing.d.ts.map +1 -0
- package/dist-npm/actions/pushing.js +45 -0
- package/dist-npm/actions/pushing.js.map +1 -0
- package/dist-npm/actions/putting.d.ts +28 -0
- package/dist-npm/actions/putting.d.ts.map +1 -0
- package/dist-npm/actions/putting.js +40 -0
- package/dist-npm/actions/putting.js.map +1 -0
- package/dist-npm/actions/quitting.d.ts +31 -0
- package/dist-npm/actions/quitting.d.ts.map +1 -0
- package/dist-npm/actions/quitting.js +47 -0
- package/dist-npm/actions/quitting.js.map +1 -0
- package/dist-npm/actions/raising.d.ts +22 -0
- package/dist-npm/actions/raising.d.ts.map +1 -0
- package/dist-npm/actions/raising.js +30 -0
- package/dist-npm/actions/raising.js.map +1 -0
- package/dist-npm/actions/reading.d.ts +23 -0
- package/dist-npm/actions/reading.d.ts.map +1 -0
- package/dist-npm/actions/reading.js +32 -0
- package/dist-npm/actions/reading.js.map +1 -0
- package/dist-npm/actions/removing.d.ts +25 -0
- package/dist-npm/actions/removing.d.ts.map +1 -0
- package/dist-npm/actions/removing.js +34 -0
- package/dist-npm/actions/removing.js.map +1 -0
- package/dist-npm/actions/restoring.d.ts +35 -0
- package/dist-npm/actions/restoring.d.ts.map +1 -0
- package/dist-npm/actions/restoring.js +51 -0
- package/dist-npm/actions/restoring.js.map +1 -0
- package/dist-npm/actions/saving.d.ts +33 -0
- package/dist-npm/actions/saving.d.ts.map +1 -0
- package/dist-npm/actions/saving.js +48 -0
- package/dist-npm/actions/saving.js.map +1 -0
- package/dist-npm/actions/scoring.d.ts +42 -0
- package/dist-npm/actions/scoring.d.ts.map +1 -0
- package/dist-npm/actions/scoring.js +70 -0
- package/dist-npm/actions/scoring.js.map +1 -0
- package/dist-npm/actions/searching.d.ts +26 -0
- package/dist-npm/actions/searching.d.ts.map +1 -0
- package/dist-npm/actions/searching.js +40 -0
- package/dist-npm/actions/searching.js.map +1 -0
- package/dist-npm/actions/showing.d.ts +29 -0
- package/dist-npm/actions/showing.d.ts.map +1 -0
- package/dist-npm/actions/showing.js +40 -0
- package/dist-npm/actions/showing.js.map +1 -0
- package/dist-npm/actions/sleeping.d.ts +28 -0
- package/dist-npm/actions/sleeping.d.ts.map +1 -0
- package/dist-npm/actions/sleeping.js +41 -0
- package/dist-npm/actions/sleeping.js.map +1 -0
- package/dist-npm/actions/smelling.d.ts +30 -0
- package/dist-npm/actions/smelling.d.ts.map +1 -0
- package/dist-npm/actions/smelling.js +43 -0
- package/dist-npm/actions/smelling.js.map +1 -0
- package/dist-npm/actions/switching-off.d.ts +28 -0
- package/dist-npm/actions/switching-off.d.ts.map +1 -0
- package/dist-npm/actions/switching-off.js +42 -0
- package/dist-npm/actions/switching-off.js.map +1 -0
- package/dist-npm/actions/switching-on.d.ts +28 -0
- package/dist-npm/actions/switching-on.d.ts.map +1 -0
- package/dist-npm/actions/switching-on.js +42 -0
- package/dist-npm/actions/switching-on.js.map +1 -0
- package/dist-npm/actions/taking-off.d.ts +20 -0
- package/dist-npm/actions/taking-off.d.ts.map +1 -0
- package/dist-npm/actions/taking-off.js +28 -0
- package/dist-npm/actions/taking-off.js.map +1 -0
- package/dist-npm/actions/taking.d.ts +26 -0
- package/dist-npm/actions/taking.d.ts.map +1 -0
- package/dist-npm/actions/taking.js +36 -0
- package/dist-npm/actions/taking.js.map +1 -0
- package/dist-npm/actions/talking.d.ts +33 -0
- package/dist-npm/actions/talking.d.ts.map +1 -0
- package/dist-npm/actions/talking.js +49 -0
- package/dist-npm/actions/talking.js.map +1 -0
- package/dist-npm/actions/telling.d.ts +30 -0
- package/dist-npm/actions/telling.d.ts.map +1 -0
- package/dist-npm/actions/telling.js +42 -0
- package/dist-npm/actions/telling.js.map +1 -0
- package/dist-npm/actions/throwing.d.ts +39 -0
- package/dist-npm/actions/throwing.d.ts.map +1 -0
- package/dist-npm/actions/throwing.js +60 -0
- package/dist-npm/actions/throwing.js.map +1 -0
- package/dist-npm/actions/touching.d.ts +36 -0
- package/dist-npm/actions/touching.d.ts.map +1 -0
- package/dist-npm/actions/touching.js +50 -0
- package/dist-npm/actions/touching.js.map +1 -0
- package/dist-npm/actions/turning.d.ts +40 -0
- package/dist-npm/actions/turning.d.ts.map +1 -0
- package/dist-npm/actions/turning.js +62 -0
- package/dist-npm/actions/turning.js.map +1 -0
- package/dist-npm/actions/undoing.d.ts +19 -0
- package/dist-npm/actions/undoing.d.ts.map +1 -0
- package/dist-npm/actions/undoing.js +26 -0
- package/dist-npm/actions/undoing.js.map +1 -0
- package/dist-npm/actions/unlocking.d.ts +25 -0
- package/dist-npm/actions/unlocking.d.ts.map +1 -0
- package/dist-npm/actions/unlocking.js +32 -0
- package/dist-npm/actions/unlocking.js.map +1 -0
- package/dist-npm/actions/using.d.ts +43 -0
- package/dist-npm/actions/using.d.ts.map +1 -0
- package/dist-npm/actions/using.js +61 -0
- package/dist-npm/actions/using.js.map +1 -0
- package/dist-npm/actions/version.d.ts +18 -0
- package/dist-npm/actions/version.d.ts.map +1 -0
- package/dist-npm/actions/version.js +26 -0
- package/dist-npm/actions/version.js.map +1 -0
- package/dist-npm/actions/waiting.d.ts +27 -0
- package/dist-npm/actions/waiting.d.ts.map +1 -0
- package/dist-npm/actions/waiting.js +36 -0
- package/dist-npm/actions/waiting.js.map +1 -0
- package/dist-npm/actions/wearing.d.ts +22 -0
- package/dist-npm/actions/wearing.d.ts.map +1 -0
- package/dist-npm/actions/wearing.js +30 -0
- package/dist-npm/actions/wearing.js.map +1 -0
- package/dist-npm/data/events.d.ts +134 -0
- package/dist-npm/data/events.d.ts.map +1 -0
- package/dist-npm/data/events.js +301 -0
- package/dist-npm/data/events.js.map +1 -0
- package/dist-npm/data/messages.d.ts +141 -0
- package/dist-npm/data/messages.d.ts.map +1 -0
- package/dist-npm/data/messages.js +300 -0
- package/dist-npm/data/messages.js.map +1 -0
- package/dist-npm/data/templates.d.ts +257 -0
- package/dist-npm/data/templates.d.ts.map +1 -0
- package/dist-npm/data/templates.js +289 -0
- package/dist-npm/data/templates.js.map +1 -0
- package/dist-npm/data/verbs.d.ts +68 -0
- package/dist-npm/data/verbs.d.ts.map +1 -0
- package/dist-npm/data/verbs.js +324 -0
- package/dist-npm/data/verbs.js.map +1 -0
- package/dist-npm/data/words.d.ts +79 -0
- package/dist-npm/data/words.d.ts.map +1 -0
- package/dist-npm/data/words.js +218 -0
- package/dist-npm/data/words.js.map +1 -0
- package/dist-npm/formatters/article.d.ts +41 -0
- package/dist-npm/formatters/article.d.ts.map +1 -0
- package/dist-npm/formatters/article.js +143 -0
- package/dist-npm/formatters/article.js.map +1 -0
- package/dist-npm/formatters/index.d.ts +18 -0
- package/dist-npm/formatters/index.d.ts.map +1 -0
- package/dist-npm/formatters/index.js +38 -0
- package/dist-npm/formatters/index.js.map +1 -0
- package/dist-npm/formatters/list.d.ts +38 -0
- package/dist-npm/formatters/list.d.ts.map +1 -0
- package/dist-npm/formatters/list.js +94 -0
- package/dist-npm/formatters/list.js.map +1 -0
- package/dist-npm/formatters/registry.d.ts +48 -0
- package/dist-npm/formatters/registry.d.ts.map +1 -0
- package/dist-npm/formatters/registry.js +128 -0
- package/dist-npm/formatters/registry.js.map +1 -0
- package/dist-npm/formatters/text.d.ts +33 -0
- package/dist-npm/formatters/text.d.ts.map +1 -0
- package/dist-npm/formatters/text.js +80 -0
- package/dist-npm/formatters/text.js.map +1 -0
- package/dist-npm/formatters/types.d.ts +41 -0
- package/dist-npm/formatters/types.d.ts.map +1 -0
- package/dist-npm/formatters/types.js +14 -0
- package/dist-npm/formatters/types.js.map +1 -0
- package/dist-npm/grammar.d.ts +189 -0
- package/dist-npm/grammar.d.ts.map +1 -0
- package/dist-npm/grammar.js +203 -0
- package/dist-npm/grammar.js.map +1 -0
- package/dist-npm/index.d.ts +22 -0
- package/dist-npm/index.d.ts.map +1 -0
- package/dist-npm/index.js +59 -0
- package/dist-npm/index.js.map +1 -0
- package/dist-npm/language-provider.d.ts +159 -0
- package/dist-npm/language-provider.d.ts.map +1 -0
- package/dist-npm/language-provider.js +527 -0
- package/dist-npm/language-provider.js.map +1 -0
- package/dist-npm/npc/index.d.ts +5 -0
- package/dist-npm/npc/index.d.ts.map +1 -0
- package/dist-npm/npc/index.js +21 -0
- package/dist-npm/npc/index.js.map +1 -0
- package/dist-npm/npc/npc.d.ts +43 -0
- package/dist-npm/npc/npc.d.ts.map +1 -0
- package/dist-npm/npc/npc.js +55 -0
- package/dist-npm/npc/npc.js.map +1 -0
- package/dist-npm/perspective/index.d.ts +5 -0
- package/dist-npm/perspective/index.d.ts.map +1 -0
- package/dist-npm/perspective/index.js +12 -0
- package/dist-npm/perspective/index.js.map +1 -0
- package/dist-npm/perspective/placeholder-resolver.d.ts +102 -0
- package/dist-npm/perspective/placeholder-resolver.d.ts.map +1 -0
- package/dist-npm/perspective/placeholder-resolver.js +275 -0
- package/dist-npm/perspective/placeholder-resolver.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* English Language Provider
|
|
3
|
+
*
|
|
4
|
+
* Self-contained language implementation with no external dependencies
|
|
5
|
+
* Enhanced to support getMessage interface for text service
|
|
6
|
+
*/
|
|
7
|
+
import { ParserLanguageProvider, ActionHelp, VerbVocabulary, DirectionVocabulary, SpecialVocabulary, LanguageGrammarPattern } from '@sharpee/if-domain';
|
|
8
|
+
import { NarrativeContext } from './perspective';
|
|
9
|
+
import { FormatterRegistry, FormatterContext, EntityInfo } from './formatters';
|
|
10
|
+
/**
|
|
11
|
+
* English language data and rules
|
|
12
|
+
*/
|
|
13
|
+
export declare class EnglishLanguageProvider implements ParserLanguageProvider {
|
|
14
|
+
readonly languageCode = "en-US";
|
|
15
|
+
readonly languageName = "English (US)";
|
|
16
|
+
readonly textDirection: "ltr";
|
|
17
|
+
private messages;
|
|
18
|
+
private customActionPatterns;
|
|
19
|
+
private narrativeContext;
|
|
20
|
+
private formatterRegistry;
|
|
21
|
+
private entityLookup?;
|
|
22
|
+
constructor();
|
|
23
|
+
/**
|
|
24
|
+
* Load core system messages (command failures, etc.)
|
|
25
|
+
* These are used by text-service for command.failed events
|
|
26
|
+
*/
|
|
27
|
+
private loadCoreMessages;
|
|
28
|
+
/**
|
|
29
|
+
* Set narrative settings for perspective-aware message resolution (ADR-089)
|
|
30
|
+
*
|
|
31
|
+
* This should be called by the engine after loading a story to configure
|
|
32
|
+
* how {You}, {your}, {take} placeholders are resolved.
|
|
33
|
+
*
|
|
34
|
+
* @param settings Narrative settings from story config
|
|
35
|
+
*/
|
|
36
|
+
setNarrativeSettings(settings: NarrativeContext): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get current narrative context
|
|
39
|
+
*/
|
|
40
|
+
getNarrativeContext(): NarrativeContext;
|
|
41
|
+
/**
|
|
42
|
+
* Load messages from all action language definitions
|
|
43
|
+
*/
|
|
44
|
+
private loadActionMessages;
|
|
45
|
+
/**
|
|
46
|
+
* Load NPC messages (ADR-070)
|
|
47
|
+
*/
|
|
48
|
+
private loadNpcMessages;
|
|
49
|
+
/**
|
|
50
|
+
* Get a message by its ID with optional parameter substitution
|
|
51
|
+
*
|
|
52
|
+
* Supports three types of placeholders:
|
|
53
|
+
* 1. Perspective placeholders (ADR-089): {You}, {your}, {take}, etc.
|
|
54
|
+
* - Resolved based on narrative context (1st/2nd/3rd person)
|
|
55
|
+
* 2. Formatted placeholders (ADR-095): {a:item}, {items:list}, etc.
|
|
56
|
+
* - Applies formatters before substitution
|
|
57
|
+
* 3. Simple placeholders: {item}, {target}, etc.
|
|
58
|
+
* - Replaced with values from params object
|
|
59
|
+
*
|
|
60
|
+
* @param messageId Full message ID (e.g., 'if.action.taking.taken')
|
|
61
|
+
* @param params Parameters to substitute in the message
|
|
62
|
+
* @returns The resolved message text, or null if not found
|
|
63
|
+
*/
|
|
64
|
+
getMessage(messageId: string, params?: Record<string, any>): string;
|
|
65
|
+
/**
|
|
66
|
+
* Set entity lookup function for formatters (ADR-095)
|
|
67
|
+
*
|
|
68
|
+
* This allows formatters to look up entity info (nounType, etc.)
|
|
69
|
+
* for proper article selection.
|
|
70
|
+
*
|
|
71
|
+
* @param lookup Function that returns EntityInfo for an entity ID
|
|
72
|
+
*/
|
|
73
|
+
setEntityLookup(lookup: (id: string) => EntityInfo | undefined): void;
|
|
74
|
+
/**
|
|
75
|
+
* Register a custom formatter (ADR-095)
|
|
76
|
+
*
|
|
77
|
+
* Stories can register custom formatters for special formatting needs.
|
|
78
|
+
*
|
|
79
|
+
* @param name Formatter name (used in templates as {name:placeholder})
|
|
80
|
+
* @param formatter Formatter function
|
|
81
|
+
*/
|
|
82
|
+
registerFormatter(name: string, formatter: (value: any, context: FormatterContext) => string): void;
|
|
83
|
+
/**
|
|
84
|
+
* Get the formatter registry (for testing or advanced use)
|
|
85
|
+
*/
|
|
86
|
+
getFormatterRegistry(): FormatterRegistry;
|
|
87
|
+
/**
|
|
88
|
+
* Check if a message exists
|
|
89
|
+
* @param messageId The message identifier
|
|
90
|
+
* @returns True if the message exists
|
|
91
|
+
*/
|
|
92
|
+
hasMessage(messageId: string): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Get patterns/aliases for an action
|
|
95
|
+
* @param actionId The action identifier (e.g., 'if.action.taking')
|
|
96
|
+
* @returns Array of patterns or undefined if action not found
|
|
97
|
+
*/
|
|
98
|
+
getActionPatterns(actionId: string): string[] | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Get structured help information for an action
|
|
101
|
+
* @param actionId The action identifier (e.g., 'if.action.taking')
|
|
102
|
+
* @returns Structured help information or undefined if not found
|
|
103
|
+
*/
|
|
104
|
+
getActionHelp(actionId: string): ActionHelp | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Get all supported actions
|
|
107
|
+
* @returns Array of action IDs
|
|
108
|
+
*/
|
|
109
|
+
getSupportedActions(): string[];
|
|
110
|
+
/**
|
|
111
|
+
* Get entity name/description
|
|
112
|
+
* @param entity Entity object or ID
|
|
113
|
+
* @returns Entity name or fallback
|
|
114
|
+
*/
|
|
115
|
+
getEntityName(entity: any): string;
|
|
116
|
+
/**
|
|
117
|
+
* Get all messages for a given action
|
|
118
|
+
* @param actionId Action identifier
|
|
119
|
+
* @returns Map of message keys to messages
|
|
120
|
+
*/
|
|
121
|
+
getActionMessages(actionId: string): Map<string, string> | null;
|
|
122
|
+
getVerbs(): VerbVocabulary[];
|
|
123
|
+
getDirections(): DirectionVocabulary[];
|
|
124
|
+
getSpecialVocabulary(): SpecialVocabulary;
|
|
125
|
+
getCommonAdjectives(): string[];
|
|
126
|
+
getCommonNouns(): string[];
|
|
127
|
+
getPrepositions(): string[];
|
|
128
|
+
getDeterminers(): string[];
|
|
129
|
+
getConjunctions(): string[];
|
|
130
|
+
getNumbers(): string[];
|
|
131
|
+
getGrammarPatterns(): LanguageGrammarPattern[];
|
|
132
|
+
lemmatize(word: string): string;
|
|
133
|
+
expandAbbreviation(abbreviation: string): string | null;
|
|
134
|
+
formatList(items: string[], conjunction?: 'and' | 'or'): string;
|
|
135
|
+
getIndefiniteArticle(noun: string): string;
|
|
136
|
+
pluralize(noun: string): string;
|
|
137
|
+
isIgnoreWord(word: string): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Add a custom message to the language provider
|
|
140
|
+
* @param messageId The message identifier (e.g., 'custom.action.message')
|
|
141
|
+
* @param template The message template with optional {param} placeholders
|
|
142
|
+
*/
|
|
143
|
+
addMessage(messageId: string, template: string): void;
|
|
144
|
+
/**
|
|
145
|
+
* Add help information for a custom action
|
|
146
|
+
* @param actionId The action identifier (e.g., 'custom.action.foo')
|
|
147
|
+
* @param help The help information including usage, description, examples
|
|
148
|
+
*/
|
|
149
|
+
addActionHelp(actionId: string, help: ActionHelp): void;
|
|
150
|
+
/**
|
|
151
|
+
* Add custom patterns/aliases for an action
|
|
152
|
+
* @param actionId The action identifier
|
|
153
|
+
* @param patterns Array of verb patterns/aliases
|
|
154
|
+
*/
|
|
155
|
+
addActionPatterns(actionId: string, patterns: string[]): void;
|
|
156
|
+
}
|
|
157
|
+
declare const _default: EnglishLanguageProvider;
|
|
158
|
+
export default _default;
|
|
159
|
+
//# sourceMappingURL=language-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language-provider.d.ts","sourceRoot":"","sources":["../src/language-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* English Language Provider
|
|
4
|
+
*
|
|
5
|
+
* Self-contained language implementation with no external dependencies
|
|
6
|
+
* Enhanced to support getMessage interface for text service
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.EnglishLanguageProvider = void 0;
|
|
10
|
+
const verbs_1 = require("./data/verbs");
|
|
11
|
+
const words_1 = require("./data/words");
|
|
12
|
+
const actions_1 = require("./actions");
|
|
13
|
+
const npc_1 = require("./npc");
|
|
14
|
+
const perspective_1 = require("./perspective");
|
|
15
|
+
const formatters_1 = require("./formatters");
|
|
16
|
+
// Types are now imported from @sharpee/if-domain
|
|
17
|
+
/**
|
|
18
|
+
* English language data and rules
|
|
19
|
+
*/
|
|
20
|
+
class EnglishLanguageProvider {
|
|
21
|
+
languageCode = 'en-US';
|
|
22
|
+
languageName = 'English (US)';
|
|
23
|
+
textDirection = 'ltr';
|
|
24
|
+
// Message storage
|
|
25
|
+
messages = new Map();
|
|
26
|
+
customActionPatterns = new Map();
|
|
27
|
+
// Narrative context for perspective-aware message resolution (ADR-089)
|
|
28
|
+
narrativeContext = perspective_1.DEFAULT_NARRATIVE_CONTEXT;
|
|
29
|
+
// Formatter registry for {a:item}, {items:list}, etc. (ADR-095)
|
|
30
|
+
formatterRegistry;
|
|
31
|
+
// Entity lookup function for formatters (set by engine)
|
|
32
|
+
entityLookup;
|
|
33
|
+
constructor() {
|
|
34
|
+
// Initialize formatter registry
|
|
35
|
+
this.formatterRegistry = (0, formatters_1.createFormatterRegistry)();
|
|
36
|
+
// Load core system messages
|
|
37
|
+
this.loadCoreMessages();
|
|
38
|
+
// Load all action messages
|
|
39
|
+
this.loadActionMessages();
|
|
40
|
+
// Load NPC messages (ADR-070)
|
|
41
|
+
this.loadNpcMessages();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Load core system messages (command failures, etc.)
|
|
45
|
+
* These are used by text-service for command.failed events
|
|
46
|
+
*/
|
|
47
|
+
loadCoreMessages() {
|
|
48
|
+
const coreMessages = {
|
|
49
|
+
'core.entity_not_found': "You can't see any such thing.",
|
|
50
|
+
'core.ambiguous_reference': "Which do you mean?",
|
|
51
|
+
'core.disambiguation_prompt': "Which do you mean: {options}?",
|
|
52
|
+
'core.command_not_understood': "I don't understand that command.",
|
|
53
|
+
'core.command_failed': "I don't understand that.",
|
|
54
|
+
// Game lifecycle messages
|
|
55
|
+
'game.started.banner': "{title}\nBy {author}\n\nType HELP for instructions.",
|
|
56
|
+
};
|
|
57
|
+
for (const [key, value] of Object.entries(coreMessages)) {
|
|
58
|
+
this.messages.set(key, value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Set narrative settings for perspective-aware message resolution (ADR-089)
|
|
63
|
+
*
|
|
64
|
+
* This should be called by the engine after loading a story to configure
|
|
65
|
+
* how {You}, {your}, {take} placeholders are resolved.
|
|
66
|
+
*
|
|
67
|
+
* @param settings Narrative settings from story config
|
|
68
|
+
*/
|
|
69
|
+
setNarrativeSettings(settings) {
|
|
70
|
+
this.narrativeContext = settings;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get current narrative context
|
|
74
|
+
*/
|
|
75
|
+
getNarrativeContext() {
|
|
76
|
+
return this.narrativeContext;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Load messages from all action language definitions
|
|
80
|
+
*/
|
|
81
|
+
loadActionMessages() {
|
|
82
|
+
for (const actionLang of actions_1.standardActionLanguage) {
|
|
83
|
+
if (actionLang.messages) {
|
|
84
|
+
Object.entries(actionLang.messages).forEach(([key, value]) => {
|
|
85
|
+
// Store with full action ID prefix
|
|
86
|
+
const fullKey = `${actionLang.actionId}.${key}`;
|
|
87
|
+
this.messages.set(fullKey, value);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Load NPC messages (ADR-070)
|
|
94
|
+
*/
|
|
95
|
+
loadNpcMessages() {
|
|
96
|
+
if (npc_1.npcLanguage.messages) {
|
|
97
|
+
for (const [key, value] of Object.entries(npc_1.npcLanguage.messages)) {
|
|
98
|
+
this.messages.set(key, value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get a message by its ID with optional parameter substitution
|
|
104
|
+
*
|
|
105
|
+
* Supports three types of placeholders:
|
|
106
|
+
* 1. Perspective placeholders (ADR-089): {You}, {your}, {take}, etc.
|
|
107
|
+
* - Resolved based on narrative context (1st/2nd/3rd person)
|
|
108
|
+
* 2. Formatted placeholders (ADR-095): {a:item}, {items:list}, etc.
|
|
109
|
+
* - Applies formatters before substitution
|
|
110
|
+
* 3. Simple placeholders: {item}, {target}, etc.
|
|
111
|
+
* - Replaced with values from params object
|
|
112
|
+
*
|
|
113
|
+
* @param messageId Full message ID (e.g., 'if.action.taking.taken')
|
|
114
|
+
* @param params Parameters to substitute in the message
|
|
115
|
+
* @returns The resolved message text, or null if not found
|
|
116
|
+
*/
|
|
117
|
+
getMessage(messageId, params) {
|
|
118
|
+
let message = this.messages.get(messageId);
|
|
119
|
+
if (!message) {
|
|
120
|
+
return messageId; // Return the ID as fallback
|
|
121
|
+
}
|
|
122
|
+
// Step 1: Resolve perspective placeholders (ADR-089)
|
|
123
|
+
// This handles {You}, {your}, {take}, etc.
|
|
124
|
+
message = (0, perspective_1.resolvePerspectivePlaceholders)(message, this.narrativeContext);
|
|
125
|
+
// Step 2: Apply formatters and substitute parameters (ADR-095)
|
|
126
|
+
if (params) {
|
|
127
|
+
const context = {
|
|
128
|
+
getEntity: this.entityLookup,
|
|
129
|
+
};
|
|
130
|
+
message = (0, formatters_1.formatMessage)(message, params, this.formatterRegistry, context);
|
|
131
|
+
}
|
|
132
|
+
return message;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Set entity lookup function for formatters (ADR-095)
|
|
136
|
+
*
|
|
137
|
+
* This allows formatters to look up entity info (nounType, etc.)
|
|
138
|
+
* for proper article selection.
|
|
139
|
+
*
|
|
140
|
+
* @param lookup Function that returns EntityInfo for an entity ID
|
|
141
|
+
*/
|
|
142
|
+
setEntityLookup(lookup) {
|
|
143
|
+
this.entityLookup = lookup;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Register a custom formatter (ADR-095)
|
|
147
|
+
*
|
|
148
|
+
* Stories can register custom formatters for special formatting needs.
|
|
149
|
+
*
|
|
150
|
+
* @param name Formatter name (used in templates as {name:placeholder})
|
|
151
|
+
* @param formatter Formatter function
|
|
152
|
+
*/
|
|
153
|
+
registerFormatter(name, formatter) {
|
|
154
|
+
this.formatterRegistry.set(name, formatter);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get the formatter registry (for testing or advanced use)
|
|
158
|
+
*/
|
|
159
|
+
getFormatterRegistry() {
|
|
160
|
+
return this.formatterRegistry;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Check if a message exists
|
|
164
|
+
* @param messageId The message identifier
|
|
165
|
+
* @returns True if the message exists
|
|
166
|
+
*/
|
|
167
|
+
hasMessage(messageId) {
|
|
168
|
+
return this.messages.has(messageId);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get patterns/aliases for an action
|
|
172
|
+
* @param actionId The action identifier (e.g., 'if.action.taking')
|
|
173
|
+
* @returns Array of patterns or undefined if action not found
|
|
174
|
+
*/
|
|
175
|
+
getActionPatterns(actionId) {
|
|
176
|
+
// First check custom patterns
|
|
177
|
+
const customPatterns = this.customActionPatterns.get(actionId);
|
|
178
|
+
// Then check standard action language
|
|
179
|
+
const actionLang = actions_1.standardActionLanguage.find(lang => lang.actionId === actionId);
|
|
180
|
+
const standardPatterns = actionLang?.patterns;
|
|
181
|
+
// Merge both sources if they exist
|
|
182
|
+
if (customPatterns && standardPatterns) {
|
|
183
|
+
return [...standardPatterns, ...customPatterns];
|
|
184
|
+
}
|
|
185
|
+
return customPatterns || standardPatterns;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get structured help information for an action
|
|
189
|
+
* @param actionId The action identifier (e.g., 'if.action.taking')
|
|
190
|
+
* @returns Structured help information or undefined if not found
|
|
191
|
+
*/
|
|
192
|
+
getActionHelp(actionId) {
|
|
193
|
+
const actionLang = actions_1.standardActionLanguage.find(lang => lang.actionId === actionId);
|
|
194
|
+
if (!actionLang) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
// Extract verbs from patterns
|
|
198
|
+
const verbs = [];
|
|
199
|
+
if (actionLang.patterns) {
|
|
200
|
+
actionLang.patterns.forEach(pattern => {
|
|
201
|
+
// Extract the verb from patterns like "take [something]"
|
|
202
|
+
const match = pattern.match(/^(\w+)/);
|
|
203
|
+
if (match) {
|
|
204
|
+
const verb = match[1].toUpperCase();
|
|
205
|
+
if (!verbs.includes(verb)) {
|
|
206
|
+
verbs.push(verb);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
// Parse examples from help object
|
|
212
|
+
let examples = [];
|
|
213
|
+
if (actionLang.help?.examples) {
|
|
214
|
+
// Split by comma and trim
|
|
215
|
+
examples = actionLang.help.examples.split(',').map(ex => ex.trim());
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
description: actionLang.help?.description || 'No description available.',
|
|
219
|
+
verbs,
|
|
220
|
+
examples,
|
|
221
|
+
summary: actionLang.help?.summary
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Get all supported actions
|
|
226
|
+
* @returns Array of action IDs
|
|
227
|
+
*/
|
|
228
|
+
getSupportedActions() {
|
|
229
|
+
return actions_1.standardActionLanguage.map(lang => lang.actionId);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Get entity name/description
|
|
233
|
+
* @param entity Entity object or ID
|
|
234
|
+
* @returns Entity name or fallback
|
|
235
|
+
*/
|
|
236
|
+
getEntityName(entity) {
|
|
237
|
+
if (!entity)
|
|
238
|
+
return 'something';
|
|
239
|
+
// If it's a string, return it
|
|
240
|
+
if (typeof entity === 'string') {
|
|
241
|
+
return entity;
|
|
242
|
+
}
|
|
243
|
+
// Try various properties
|
|
244
|
+
if (entity.name) {
|
|
245
|
+
return entity.name;
|
|
246
|
+
}
|
|
247
|
+
// Try identity trait
|
|
248
|
+
if (entity.traits && entity.traits.get) {
|
|
249
|
+
const identity = entity.traits.get('IDENTITY');
|
|
250
|
+
if (identity && identity.name) {
|
|
251
|
+
return identity.name;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Try direct trait access
|
|
255
|
+
if (entity.get && typeof entity.get === 'function') {
|
|
256
|
+
const identity = entity.get('IDENTITY');
|
|
257
|
+
if (identity && identity.name) {
|
|
258
|
+
return identity.name;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Fall back to ID
|
|
262
|
+
if (entity.id) {
|
|
263
|
+
return entity.id;
|
|
264
|
+
}
|
|
265
|
+
return 'something';
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Get all messages for a given action
|
|
269
|
+
* @param actionId Action identifier
|
|
270
|
+
* @returns Map of message keys to messages
|
|
271
|
+
*/
|
|
272
|
+
getActionMessages(actionId) {
|
|
273
|
+
const actionMessages = new Map();
|
|
274
|
+
const prefix = `${actionId}.`;
|
|
275
|
+
// Find all messages for this action
|
|
276
|
+
for (const [key, value] of this.messages) {
|
|
277
|
+
if (key.startsWith(prefix)) {
|
|
278
|
+
const messageKey = key.substring(prefix.length);
|
|
279
|
+
actionMessages.set(messageKey, value);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return actionMessages.size > 0 ? actionMessages : null;
|
|
283
|
+
}
|
|
284
|
+
getVerbs() {
|
|
285
|
+
return verbs_1.englishVerbs.map(verb => ({
|
|
286
|
+
actionId: verb.action,
|
|
287
|
+
verbs: verb.verbs,
|
|
288
|
+
pattern: verb.requiresObject ?
|
|
289
|
+
(verb.allowsIndirectObject ? 'VERB_OBJ_PREP_OBJ' : 'VERB_OBJ') :
|
|
290
|
+
'VERB_ONLY',
|
|
291
|
+
prepositions: verb.allowsIndirectObject ? ['in', 'on', 'to', 'with'] : undefined
|
|
292
|
+
}));
|
|
293
|
+
}
|
|
294
|
+
getDirections() {
|
|
295
|
+
return [
|
|
296
|
+
{ direction: 'north', words: ['north'], abbreviations: ['n'] },
|
|
297
|
+
{ direction: 'south', words: ['south'], abbreviations: ['s'] },
|
|
298
|
+
{ direction: 'east', words: ['east'], abbreviations: ['e'] },
|
|
299
|
+
{ direction: 'west', words: ['west'], abbreviations: ['w'] },
|
|
300
|
+
{ direction: 'northeast', words: ['northeast'], abbreviations: ['ne'] },
|
|
301
|
+
{ direction: 'northwest', words: ['northwest'], abbreviations: ['nw'] },
|
|
302
|
+
{ direction: 'southeast', words: ['southeast'], abbreviations: ['se'] },
|
|
303
|
+
{ direction: 'southwest', words: ['southwest'], abbreviations: ['sw'] },
|
|
304
|
+
{ direction: 'up', words: ['up', 'upward', 'upwards'], abbreviations: ['u'] },
|
|
305
|
+
{ direction: 'down', words: ['down', 'downward', 'downwards'], abbreviations: ['d'] },
|
|
306
|
+
{ direction: 'in', words: ['in', 'inside'] },
|
|
307
|
+
{ direction: 'out', words: ['out', 'outside'] }
|
|
308
|
+
];
|
|
309
|
+
}
|
|
310
|
+
getSpecialVocabulary() {
|
|
311
|
+
return {
|
|
312
|
+
articles: words_1.englishWords.articles,
|
|
313
|
+
pronouns: words_1.englishWords.pronouns,
|
|
314
|
+
allWords: ['all', 'everything', 'every'],
|
|
315
|
+
exceptWords: ['except', 'but']
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
getCommonAdjectives() {
|
|
319
|
+
return words_1.englishWords.commonAdjectives;
|
|
320
|
+
}
|
|
321
|
+
getCommonNouns() {
|
|
322
|
+
return words_1.englishWords.commonNouns || [];
|
|
323
|
+
}
|
|
324
|
+
getPrepositions() {
|
|
325
|
+
return words_1.englishWords.prepositions;
|
|
326
|
+
}
|
|
327
|
+
getDeterminers() {
|
|
328
|
+
return words_1.englishWords.determiners || [];
|
|
329
|
+
}
|
|
330
|
+
getConjunctions() {
|
|
331
|
+
return words_1.englishWords.conjunctions || [];
|
|
332
|
+
}
|
|
333
|
+
getNumbers() {
|
|
334
|
+
return words_1.englishWords.numberWords || [];
|
|
335
|
+
}
|
|
336
|
+
getGrammarPatterns() {
|
|
337
|
+
return [
|
|
338
|
+
{
|
|
339
|
+
name: 'verb_noun_prep_noun',
|
|
340
|
+
pattern: 'VERB NOUN+ PREP NOUN+',
|
|
341
|
+
example: 'put ball in box',
|
|
342
|
+
priority: 100
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
name: 'verb_prep_noun',
|
|
346
|
+
pattern: 'VERB PREP NOUN+',
|
|
347
|
+
example: 'look at painting',
|
|
348
|
+
priority: 90
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
name: 'verb_noun',
|
|
352
|
+
pattern: 'VERB NOUN+',
|
|
353
|
+
example: 'take ball',
|
|
354
|
+
priority: 80
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: 'verb_only',
|
|
358
|
+
pattern: 'VERB',
|
|
359
|
+
example: 'look',
|
|
360
|
+
priority: 70
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
name: 'direction_only',
|
|
364
|
+
pattern: 'DIRECTION',
|
|
365
|
+
example: 'north',
|
|
366
|
+
priority: 60
|
|
367
|
+
}
|
|
368
|
+
];
|
|
369
|
+
}
|
|
370
|
+
lemmatize(word) {
|
|
371
|
+
if (!word)
|
|
372
|
+
return '';
|
|
373
|
+
const lower = word.toLowerCase();
|
|
374
|
+
// Check irregular plurals
|
|
375
|
+
const singular = words_1.irregularPlurals.get(lower);
|
|
376
|
+
if (singular)
|
|
377
|
+
return singular;
|
|
378
|
+
// Handle special cases first
|
|
379
|
+
if (lower === 'yes' || lower === 'ties')
|
|
380
|
+
return lower;
|
|
381
|
+
// Simple rules for common endings
|
|
382
|
+
if (lower.endsWith('ies') && lower.length > 4) {
|
|
383
|
+
return lower.slice(0, -3) + 'y';
|
|
384
|
+
}
|
|
385
|
+
if (lower.endsWith('es') && lower.length > 3) {
|
|
386
|
+
// Don't lemmatize words like 'yes'
|
|
387
|
+
if (lower === 'yes')
|
|
388
|
+
return lower;
|
|
389
|
+
return lower.slice(0, -2);
|
|
390
|
+
}
|
|
391
|
+
if (lower.endsWith('s') && !lower.endsWith('ss') && lower.length > 2) {
|
|
392
|
+
return lower.slice(0, -1);
|
|
393
|
+
}
|
|
394
|
+
if (lower.endsWith('ed') && lower.length > 3) {
|
|
395
|
+
// Handle double consonants (dropped -> drop)
|
|
396
|
+
if (lower.length > 4 && lower[lower.length - 3] === lower[lower.length - 4]) {
|
|
397
|
+
return lower.slice(0, -3);
|
|
398
|
+
}
|
|
399
|
+
return lower.slice(0, -2);
|
|
400
|
+
}
|
|
401
|
+
if (lower.endsWith('ing') && lower.length > 4 && !lower.includes('-')) {
|
|
402
|
+
return lower.slice(0, -3);
|
|
403
|
+
}
|
|
404
|
+
return lower;
|
|
405
|
+
}
|
|
406
|
+
expandAbbreviation(abbreviation) {
|
|
407
|
+
return words_1.abbreviations.get(abbreviation.toLowerCase()) || null;
|
|
408
|
+
}
|
|
409
|
+
formatList(items, conjunction = 'and') {
|
|
410
|
+
if (items.length === 0)
|
|
411
|
+
return '';
|
|
412
|
+
if (items.length === 1)
|
|
413
|
+
return items[0];
|
|
414
|
+
if (items.length === 2)
|
|
415
|
+
return `${items[0]} ${conjunction} ${items[1]}`;
|
|
416
|
+
const allButLast = items.slice(0, -1);
|
|
417
|
+
const last = items[items.length - 1];
|
|
418
|
+
return `${allButLast.join(', ')}, ${conjunction} ${last}`;
|
|
419
|
+
}
|
|
420
|
+
getIndefiniteArticle(noun) {
|
|
421
|
+
if (!noun || noun.length === 0)
|
|
422
|
+
return 'a';
|
|
423
|
+
const firstChar = noun[0].toLowerCase();
|
|
424
|
+
const vowels = ['a', 'e', 'i', 'o', 'u'];
|
|
425
|
+
// Special cases
|
|
426
|
+
if (noun.toLowerCase().startsWith('hour'))
|
|
427
|
+
return 'an';
|
|
428
|
+
if (noun.toLowerCase().startsWith('honest'))
|
|
429
|
+
return 'an';
|
|
430
|
+
if (noun.toLowerCase().startsWith('uni'))
|
|
431
|
+
return 'a';
|
|
432
|
+
if (noun.toLowerCase().startsWith('one'))
|
|
433
|
+
return 'a';
|
|
434
|
+
return vowels.includes(firstChar) ? 'an' : 'a';
|
|
435
|
+
}
|
|
436
|
+
pluralize(noun) {
|
|
437
|
+
if (!noun)
|
|
438
|
+
return 's';
|
|
439
|
+
const lower = noun.toLowerCase();
|
|
440
|
+
// Check irregular plurals - the map is plural->singular, so we need to reverse lookup
|
|
441
|
+
for (const [plural, singular] of words_1.irregularPlurals) {
|
|
442
|
+
if (singular === lower) {
|
|
443
|
+
// Preserve the case pattern of the original noun
|
|
444
|
+
if (noun === noun.toUpperCase()) {
|
|
445
|
+
return plural.toUpperCase();
|
|
446
|
+
}
|
|
447
|
+
else if (noun[0] === noun[0].toUpperCase()) {
|
|
448
|
+
return plural[0].toUpperCase() + plural.slice(1);
|
|
449
|
+
}
|
|
450
|
+
return plural;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// Regular rules
|
|
454
|
+
if (lower.endsWith('s') || lower.endsWith('x') || lower.endsWith('z') ||
|
|
455
|
+
lower.endsWith('ch') || lower.endsWith('sh')) {
|
|
456
|
+
return noun + 'es';
|
|
457
|
+
}
|
|
458
|
+
if (lower.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lower[lower.length - 2])) {
|
|
459
|
+
// Special handling for case preservation with -ies
|
|
460
|
+
if (noun === noun.toUpperCase()) {
|
|
461
|
+
return noun.slice(0, -1) + 'IES';
|
|
462
|
+
}
|
|
463
|
+
return noun.slice(0, -1) + 'ies';
|
|
464
|
+
}
|
|
465
|
+
if (lower.endsWith('f')) {
|
|
466
|
+
return noun.slice(0, -1) + 'ves';
|
|
467
|
+
}
|
|
468
|
+
if (lower.endsWith('fe')) {
|
|
469
|
+
return noun.slice(0, -2) + 'ves';
|
|
470
|
+
}
|
|
471
|
+
return noun + 's';
|
|
472
|
+
}
|
|
473
|
+
isIgnoreWord(word) {
|
|
474
|
+
return words_1.englishWords.ignoreWords.includes(word.toLowerCase());
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Add a custom message to the language provider
|
|
478
|
+
* @param messageId The message identifier (e.g., 'custom.action.message')
|
|
479
|
+
* @param template The message template with optional {param} placeholders
|
|
480
|
+
*/
|
|
481
|
+
addMessage(messageId, template) {
|
|
482
|
+
this.messages.set(messageId, template);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Add help information for a custom action
|
|
486
|
+
* @param actionId The action identifier (e.g., 'custom.action.foo')
|
|
487
|
+
* @param help The help information including usage, description, examples
|
|
488
|
+
*/
|
|
489
|
+
addActionHelp(actionId, help) {
|
|
490
|
+
// Store the help information associated with the action
|
|
491
|
+
// This would require maintaining a separate help registry
|
|
492
|
+
// For now, we'll store it as messages with a special prefix
|
|
493
|
+
if (help.summary) {
|
|
494
|
+
this.messages.set(`${actionId}.help.summary`, help.summary);
|
|
495
|
+
}
|
|
496
|
+
if (help.description) {
|
|
497
|
+
this.messages.set(`${actionId}.help.description`, help.description);
|
|
498
|
+
}
|
|
499
|
+
if (help.examples) {
|
|
500
|
+
help.examples.forEach((example, index) => {
|
|
501
|
+
this.messages.set(`${actionId}.help.example.${index}`, example);
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Add custom patterns/aliases for an action
|
|
507
|
+
* @param actionId The action identifier
|
|
508
|
+
* @param patterns Array of verb patterns/aliases
|
|
509
|
+
*/
|
|
510
|
+
addActionPatterns(actionId, patterns) {
|
|
511
|
+
// Get existing custom patterns
|
|
512
|
+
const existing = this.customActionPatterns.get(actionId) || [];
|
|
513
|
+
// Merge with new patterns (avoiding duplicates)
|
|
514
|
+
const merged = [...existing];
|
|
515
|
+
for (const pattern of patterns) {
|
|
516
|
+
if (!merged.includes(pattern)) {
|
|
517
|
+
merged.push(pattern);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// Store the merged patterns
|
|
521
|
+
this.customActionPatterns.set(actionId, merged);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
exports.EnglishLanguageProvider = EnglishLanguageProvider;
|
|
525
|
+
// Default export - create an instance
|
|
526
|
+
exports.default = new EnglishLanguageProvider();
|
|
527
|
+
//# sourceMappingURL=language-provider.js.map
|