mojulo 0.0.0 → 0.1.1

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 (121) hide show
  1. package/README.md +54 -4
  2. package/lib/audit-logger-new.js +11 -0
  3. package/lib/auth/gate.js +25 -0
  4. package/lib/auth/service.js +17 -0
  5. package/lib/auth/session.js +63 -0
  6. package/lib/builder/chat-processor.js +607 -0
  7. package/lib/builder/composer-bridge.js +82 -0
  8. package/lib/builder/evaluator.js +159 -0
  9. package/lib/builder/executor.js +252 -0
  10. package/lib/builder/index.js +48 -0
  11. package/lib/builder/session.js +248 -0
  12. package/lib/builder/system-prompt.js +422 -0
  13. package/lib/builder/tone-presets.js +75 -0
  14. package/lib/builder/tool-executors.js +1527 -0
  15. package/lib/builder/tools.js +338 -0
  16. package/lib/builder/validators.js +239 -0
  17. package/lib/composer/composer.js +225 -0
  18. package/lib/composer/index.js +40 -0
  19. package/lib/composer/protocols/00_base.txt +19 -0
  20. package/lib/composer/protocols/01_knowledge.txt +9 -0
  21. package/lib/composer/protocols/02_form-gathering.txt +32 -0
  22. package/lib/composer/protocols/03_appointments.txt +16 -0
  23. package/lib/composer/protocols/04_triage.txt +15 -0
  24. package/lib/composer/protocols/05_optical-read.txt +22 -0
  25. package/lib/composer/response-builder.js +98 -0
  26. package/lib/config-builder.js +650 -0
  27. package/lib/db/ids.js +10 -0
  28. package/lib/db/index.js +179 -0
  29. package/lib/db/repositories/apiKeys.js +72 -0
  30. package/lib/db/repositories/auditLogs.js +12 -0
  31. package/lib/db/repositories/botSpaces.js +12 -0
  32. package/lib/db/repositories/builderSessions.js +312 -0
  33. package/lib/db/repositories/deploymentEvents.js +12 -0
  34. package/lib/db/repositories/deployments.js +385 -0
  35. package/lib/db/repositories/documents.js +68 -0
  36. package/lib/db/repositories/mcpJobs.js +84 -0
  37. package/lib/deployers/bot-fleet.js +110 -0
  38. package/lib/deployers/bot-proxy.js +72 -0
  39. package/lib/deployers/build.js +89 -0
  40. package/lib/deployers/cloud-deploy.js +310 -0
  41. package/lib/deployers/docker.js +439 -0
  42. package/lib/deployers/fly.js +432 -0
  43. package/lib/deployers/index.js +38 -0
  44. package/lib/deployment-auth.js +36 -0
  45. package/lib/document-parser.js +171 -0
  46. package/lib/embedder/chunker.js +93 -0
  47. package/lib/embedder/local.js +101 -0
  48. package/lib/embedder/preview-rag.js +93 -0
  49. package/lib/envelope-schema.js +54 -0
  50. package/lib/fleet/scoped-sql.js +342 -0
  51. package/lib/form-schema-config/base.js +135 -0
  52. package/lib/form-schema-config/index.js +286 -0
  53. package/lib/form-schema-config/locales/af-ZA.js +153 -0
  54. package/lib/form-schema-config/locales/ar-AE.js +142 -0
  55. package/lib/form-schema-config/locales/ar-SA.js +164 -0
  56. package/lib/form-schema-config/locales/de-DE.js +152 -0
  57. package/lib/form-schema-config/locales/en-AU.js +161 -0
  58. package/lib/form-schema-config/locales/en-CA.js +115 -0
  59. package/lib/form-schema-config/locales/en-GB.js +132 -0
  60. package/lib/form-schema-config/locales/en-IN.js +219 -0
  61. package/lib/form-schema-config/locales/en-MY.js +171 -0
  62. package/lib/form-schema-config/locales/en-NG.js +198 -0
  63. package/lib/form-schema-config/locales/en-PH.js +186 -0
  64. package/lib/form-schema-config/locales/en-SG.js +153 -0
  65. package/lib/form-schema-config/locales/en-US.js +138 -0
  66. package/lib/form-schema-config/locales/es-ES.js +171 -0
  67. package/lib/form-schema-config/locales/es-MX.js +193 -0
  68. package/lib/form-schema-config/locales/fr-CA.js +138 -0
  69. package/lib/form-schema-config/locales/fr-FR.js +155 -0
  70. package/lib/form-schema-config/locales/hi-IN.js +219 -0
  71. package/lib/form-schema-config/locales/it-IT.js +157 -0
  72. package/lib/form-schema-config/locales/ja-JP.js +169 -0
  73. package/lib/form-schema-config/locales/ko-KR.js +140 -0
  74. package/lib/form-schema-config/locales/nl-NL.js +149 -0
  75. package/lib/form-schema-config/locales/pt-BR.js +168 -0
  76. package/lib/form-schema-config/locales/zh-CN.js +172 -0
  77. package/lib/form-schema-config/locales/zh-HK.js +142 -0
  78. package/lib/form-structure-schema.js +191 -0
  79. package/lib/llm-providers.js +828 -0
  80. package/lib/markdown.js +197 -0
  81. package/lib/mcp/catalysts/appointment-to-calendar.md +84 -0
  82. package/lib/mcp/catalysts/conversations-to-channel-digest.md +104 -0
  83. package/lib/mcp/catalysts/document-extract-to-store.md +92 -0
  84. package/lib/mcp/catalysts/knowledge-gap-miner.md +96 -0
  85. package/lib/mcp/catalysts/loader.js +144 -0
  86. package/lib/mcp/catalysts/qualify-lead-to-crm.md +83 -0
  87. package/lib/mcp/catalysts/scan-conversations-for-signal.md +92 -0
  88. package/lib/mcp/catalysts/submission-to-ticket.md +83 -0
  89. package/lib/mcp/catalysts/submissions-to-warehouse.md +103 -0
  90. package/lib/mcp/catalysts/weekly-submissions-digest.md +82 -0
  91. package/lib/mcp/jobs.js +64 -0
  92. package/lib/mcp/server.js +184 -0
  93. package/lib/mcp/session-binding.js +130 -0
  94. package/lib/mcp/tools/build.js +123 -0
  95. package/lib/mcp/tools/catalysts.js +477 -0
  96. package/lib/mcp/tools/context.js +325 -0
  97. package/lib/mcp/tools/fleet.js +391 -0
  98. package/lib/mcp/tools/jobs-tools.js +240 -0
  99. package/lib/mcp/tools/operate.js +314 -0
  100. package/lib/preview/build-preview-config.js +136 -0
  101. package/lib/rate-limiter.js +11 -0
  102. package/lib/resolve-api-key.js +142 -0
  103. package/lib/storage/index.js +40 -0
  104. package/messages/de.json +2136 -0
  105. package/messages/en.json +2136 -0
  106. package/messages/es.json +2136 -0
  107. package/messages/fr.json +2136 -0
  108. package/messages/it.json +2136 -0
  109. package/messages/ja.json +2136 -0
  110. package/messages/ko.json +2136 -0
  111. package/messages/nl.json +2136 -0
  112. package/messages/pl.json +2136 -0
  113. package/messages/pt.json +2136 -0
  114. package/messages/ru.json +2136 -0
  115. package/messages/uk.json +2136 -0
  116. package/messages/zh.json +2136 -0
  117. package/package.json +68 -5
  118. package/scripts/mcp-config.mjs +162 -0
  119. package/scripts/mcp-stdio-loader.mjs +42 -0
  120. package/scripts/mcp-stdio.mjs +108 -0
  121. package/scripts/mojulo-paths.mjs +48 -0
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Canadian English (en-CA) Locale Configuration
3
+ */
4
+
5
+ export const LOCALE_INFO = {
6
+ code: 'en-CA',
7
+ name: 'Canada',
8
+ region: 'NA',
9
+ currency: 'CAD',
10
+ dateFormat: 'YYYY-MM-DD'
11
+ };
12
+
13
+ export const PATTERNS = {
14
+ phone: {
15
+ pattern: '^(\\+1)?[-.\\s]?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}$',
16
+ error: 'Enter a valid Canadian phone number',
17
+ description: 'Canadian phone number'
18
+ },
19
+ postalCode: {
20
+ pattern: '^[A-Za-z]\\d[A-Za-z][ -]?\\d[A-Za-z]\\d$',
21
+ error: 'Enter a valid postal code (e.g., A1A 1A1)',
22
+ description: 'Canadian postal code'
23
+ },
24
+ sin: {
25
+ pattern: '^\\d{3}[- ]?\\d{3}[- ]?\\d{3}$',
26
+ error: 'Enter a valid SIN (XXX-XXX-XXX)',
27
+ description: 'Social Insurance Number'
28
+ },
29
+ provinceCode: {
30
+ pattern: '^[A-Z]{2}$',
31
+ error: 'Enter a 2-letter province code',
32
+ description: 'Canadian province code'
33
+ },
34
+ currency: {
35
+ pattern: '^\\$?\\d{1,3}(,\\d{3})*(\\.\\d{2})?$',
36
+ error: 'Enter a valid dollar amount',
37
+ description: 'Canadian currency'
38
+ },
39
+ driversLicense: {
40
+ pattern: '^[A-Z0-9]{5,15}$',
41
+ error: 'Enter a valid driver\'s license number',
42
+ description: 'Canadian driver\'s license (varies by province)'
43
+ },
44
+ healthCard: {
45
+ pattern: '^[A-Z0-9]{10,12}$',
46
+ error: 'Enter a valid health card number',
47
+ description: 'Provincial health card number'
48
+ }
49
+ };
50
+
51
+ export const ARCHETYPES = {
52
+ phone: {
53
+ type: 'tel',
54
+ autocomplete: 'tel',
55
+ inputMode: 'tel',
56
+ placeholder: '(555) 555-5555',
57
+ pattern: PATTERNS.phone.pattern,
58
+ patternError: PATTERNS.phone.error,
59
+ pii: true
60
+ },
61
+ postalCode: {
62
+ type: 'text',
63
+ autocomplete: 'postal-code',
64
+ inputMode: 'text',
65
+ placeholder: 'A1A 1A1',
66
+ pattern: PATTERNS.postalCode.pattern,
67
+ patternError: PATTERNS.postalCode.error,
68
+ maxLength: 7
69
+ },
70
+ sin: {
71
+ type: 'text',
72
+ inputMode: 'numeric',
73
+ placeholder: 'XXX-XXX-XXX',
74
+ pattern: PATTERNS.sin.pattern,
75
+ patternError: PATTERNS.sin.error,
76
+ pii: true,
77
+ sensitive: true,
78
+ helpText: 'Your Social Insurance Number will be kept secure'
79
+ },
80
+ province: {
81
+ type: 'dropdown',
82
+ autocomplete: 'address-level1',
83
+ options: [
84
+ { value: 'AB', label: 'Alberta' },
85
+ { value: 'BC', label: 'British Columbia' },
86
+ { value: 'MB', label: 'Manitoba' },
87
+ { value: 'NB', label: 'New Brunswick' },
88
+ { value: 'NL', label: 'Newfoundland and Labrador' },
89
+ { value: 'NS', label: 'Nova Scotia' },
90
+ { value: 'NT', label: 'Northwest Territories' },
91
+ { value: 'NU', label: 'Nunavut' },
92
+ { value: 'ON', label: 'Ontario' },
93
+ { value: 'PE', label: 'Prince Edward Island' },
94
+ { value: 'QC', label: 'Quebec' },
95
+ { value: 'SK', label: 'Saskatchewan' },
96
+ { value: 'YT', label: 'Yukon' }
97
+ ]
98
+ },
99
+ currency: {
100
+ type: 'text',
101
+ inputMode: 'decimal',
102
+ placeholder: '$0.00',
103
+ pattern: PATTERNS.currency.pattern,
104
+ patternError: PATTERNS.currency.error
105
+ }
106
+ };
107
+
108
+ /**
109
+ * Canada-specific field name mappings
110
+ */
111
+ export const FIELD_LABELS = {
112
+ postalCode: 'Postal Code',
113
+ state: 'Province',
114
+ nationalId: 'Social Insurance Number (SIN)'
115
+ };
@@ -0,0 +1,132 @@
1
+ /**
2
+ * British English (en-GB) Locale Configuration
3
+ */
4
+
5
+ export const LOCALE_INFO = {
6
+ code: 'en-GB',
7
+ name: 'United Kingdom',
8
+ region: 'EU',
9
+ currency: 'GBP',
10
+ dateFormat: 'DD/MM/YYYY'
11
+ };
12
+
13
+ export const PATTERNS = {
14
+ phone: {
15
+ pattern: '^(\\+44|0)\\d{10,11}$',
16
+ error: 'Enter a valid UK phone number',
17
+ description: 'UK phone number'
18
+ },
19
+ postalCode: {
20
+ pattern: '^[A-Z]{1,2}\\d[A-Z\\d]?\\s?\\d[A-Z]{2}$',
21
+ error: 'Enter a valid UK postcode (e.g., SW1A 1AA)',
22
+ description: 'UK postcode'
23
+ },
24
+ nationalInsurance: {
25
+ pattern: '^[A-CEGHJ-PR-TW-Z]{2}\\d{6}[A-D]$',
26
+ error: 'Enter a valid NI number (e.g., AB123456C)',
27
+ description: 'National Insurance number'
28
+ },
29
+ sortCode: {
30
+ pattern: '^\\d{2}[- ]?\\d{2}[- ]?\\d{2}$',
31
+ error: 'Enter a valid sort code (XX-XX-XX)',
32
+ description: 'Bank sort code'
33
+ },
34
+ accountNumber: {
35
+ pattern: '^\\d{8}$',
36
+ error: 'Enter an 8-digit account number',
37
+ description: 'UK bank account number'
38
+ },
39
+ vatNumber: {
40
+ pattern: '^GB\\d{9}$|^GB\\d{12}$|^GBGD\\d{3}$|^GBHA\\d{3}$',
41
+ error: 'Enter a valid UK VAT number',
42
+ description: 'UK VAT number'
43
+ },
44
+ driversLicense: {
45
+ pattern: '^[A-Z]{2}\\d{6}[A-Z]{2}\\d[A-Z]{2}$',
46
+ error: 'Enter a valid UK driving licence number',
47
+ description: 'UK driving licence'
48
+ },
49
+ nhsNumber: {
50
+ pattern: '^\\d{3}\\s?\\d{3}\\s?\\d{4}$',
51
+ error: 'Enter a valid NHS number',
52
+ description: 'NHS number'
53
+ },
54
+ currency: {
55
+ pattern: '^£?\\d{1,3}(,\\d{3})*(\\.\\d{2})?$',
56
+ error: 'Enter a valid amount in pounds',
57
+ description: 'British pounds'
58
+ }
59
+ };
60
+
61
+ export const ARCHETYPES = {
62
+ phone: {
63
+ type: 'tel',
64
+ autocomplete: 'tel',
65
+ inputMode: 'tel',
66
+ placeholder: '07700 900000',
67
+ pattern: PATTERNS.phone.pattern,
68
+ patternError: PATTERNS.phone.error,
69
+ pii: true
70
+ },
71
+ postalCode: {
72
+ type: 'text',
73
+ autocomplete: 'postal-code',
74
+ inputMode: 'text',
75
+ placeholder: 'SW1A 1AA',
76
+ pattern: PATTERNS.postalCode.pattern,
77
+ patternError: PATTERNS.postalCode.error,
78
+ maxLength: 8
79
+ },
80
+ nationalInsurance: {
81
+ type: 'text',
82
+ inputMode: 'text',
83
+ placeholder: 'AB 12 34 56 C',
84
+ pattern: PATTERNS.nationalInsurance.pattern,
85
+ patternError: PATTERNS.nationalInsurance.error,
86
+ pii: true,
87
+ sensitive: true,
88
+ helpText: 'Your National Insurance number will be kept secure'
89
+ },
90
+ county: {
91
+ type: 'text',
92
+ autocomplete: 'address-level1',
93
+ placeholder: 'County (optional)'
94
+ },
95
+ sortCode: {
96
+ type: 'text',
97
+ inputMode: 'numeric',
98
+ placeholder: '00-00-00',
99
+ pattern: PATTERNS.sortCode.pattern,
100
+ patternError: PATTERNS.sortCode.error,
101
+ pii: true
102
+ },
103
+ currency: {
104
+ type: 'text',
105
+ inputMode: 'decimal',
106
+ placeholder: '£0.00',
107
+ pattern: PATTERNS.currency.pattern,
108
+ patternError: PATTERNS.currency.error
109
+ }
110
+ };
111
+
112
+ /**
113
+ * UK-specific field name mappings
114
+ */
115
+ export const FIELD_LABELS = {
116
+ postalCode: 'Postcode',
117
+ state: 'County',
118
+ nationalId: 'National Insurance Number',
119
+ phone: 'Phone Number',
120
+ addressLine1: 'Address Line 1',
121
+ addressLine2: 'Address Line 2',
122
+ city: 'Town/City'
123
+ };
124
+
125
+ /**
126
+ * GDPR compliance hints for UK/EU
127
+ */
128
+ export const GDPR_HINTS = {
129
+ consentRequired: true,
130
+ dataRetentionNotice: true,
131
+ rightToErasure: true
132
+ };
@@ -0,0 +1,219 @@
1
+ /**
2
+ * English - India (en-IN) Locale Configuration
3
+ */
4
+
5
+ export const LOCALE_INFO = {
6
+ code: 'en-IN',
7
+ name: 'India',
8
+ region: 'Asia',
9
+ currency: 'INR',
10
+ dateFormat: 'DD/MM/YYYY'
11
+ };
12
+
13
+ export const PATTERNS = {
14
+ phone: {
15
+ pattern: '^(\\+91[\\s-]?)?[6-9]\\d{9}$',
16
+ error: 'Enter a valid Indian mobile number',
17
+ description: 'Indian mobile number'
18
+ },
19
+ landline: {
20
+ pattern: '^(\\+91[\\s-]?)?(0\\d{2,4})[\\s-]?\\d{6,8}$',
21
+ error: 'Enter a valid landline number',
22
+ description: 'Indian landline number'
23
+ },
24
+ postalCode: {
25
+ pattern: '^[1-9]\\d{5}$',
26
+ error: 'Enter a valid PIN code (6 digits)',
27
+ description: 'Indian PIN code'
28
+ },
29
+ aadhaar: {
30
+ pattern: '^\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}$',
31
+ error: 'Enter a valid Aadhaar number (12 digits)',
32
+ description: 'Aadhaar unique ID'
33
+ },
34
+ pan: {
35
+ pattern: '^[A-Z]{5}\\d{4}[A-Z]$',
36
+ error: 'Enter a valid PAN (e.g., ABCDE1234F)',
37
+ description: 'Permanent Account Number'
38
+ },
39
+ gstin: {
40
+ pattern: '^\\d{2}[A-Z]{5}\\d{4}[A-Z][A-Z\\d][Z][A-Z\\d]$',
41
+ error: 'Enter a valid GSTIN',
42
+ description: 'GST Identification Number'
43
+ },
44
+ voterId: {
45
+ pattern: '^[A-Z]{3}\\d{7}$',
46
+ error: 'Enter a valid Voter ID',
47
+ description: 'Electoral Photo Identity Card'
48
+ },
49
+ passport: {
50
+ pattern: '^[A-Z]\\d{7}$',
51
+ error: 'Enter a valid passport number',
52
+ description: 'Indian passport number'
53
+ },
54
+ ifsc: {
55
+ pattern: '^[A-Z]{4}0[A-Z0-9]{6}$',
56
+ error: 'Enter a valid IFSC code',
57
+ description: 'Indian Financial System Code'
58
+ },
59
+ bankAccount: {
60
+ pattern: '^\\d{9,18}$',
61
+ error: 'Enter a valid account number',
62
+ description: 'Indian bank account number'
63
+ },
64
+ upi: {
65
+ pattern: '^[\\w\\.\\-]+@[\\w]+$',
66
+ error: 'Enter a valid UPI ID',
67
+ description: 'UPI Virtual Payment Address'
68
+ },
69
+ currency: {
70
+ pattern: '^(Rs\\.?|₹)?\\s?[\\d,]+(\\.\\d{2})?$',
71
+ error: 'Enter a valid amount',
72
+ description: 'Indian Rupee amount'
73
+ }
74
+ };
75
+
76
+ export const ARCHETYPES = {
77
+ phone: {
78
+ type: 'tel',
79
+ autocomplete: 'tel',
80
+ inputMode: 'tel',
81
+ placeholder: '98765 43210',
82
+ pattern: PATTERNS.phone.pattern,
83
+ patternError: PATTERNS.phone.error,
84
+ pii: true
85
+ },
86
+ postalCode: {
87
+ type: 'text',
88
+ autocomplete: 'postal-code',
89
+ inputMode: 'numeric',
90
+ placeholder: '110001',
91
+ pattern: PATTERNS.postalCode.pattern,
92
+ patternError: PATTERNS.postalCode.error,
93
+ maxLength: 6
94
+ },
95
+ nationalId: {
96
+ type: 'text',
97
+ inputMode: 'numeric',
98
+ placeholder: '1234 5678 9012',
99
+ pattern: PATTERNS.aadhaar.pattern,
100
+ patternError: PATTERNS.aadhaar.error,
101
+ pii: true,
102
+ sensitive: true,
103
+ helpText: 'Your Aadhaar number will be stored securely'
104
+ },
105
+ pan: {
106
+ type: 'text',
107
+ inputMode: 'text',
108
+ placeholder: 'ABCDE1234F',
109
+ pattern: PATTERNS.pan.pattern,
110
+ patternError: PATTERNS.pan.error,
111
+ pii: true,
112
+ maxLength: 10
113
+ },
114
+ gstin: {
115
+ type: 'text',
116
+ inputMode: 'text',
117
+ placeholder: '22AAAAA0000A1Z5',
118
+ pattern: PATTERNS.gstin.pattern,
119
+ patternError: PATTERNS.gstin.error,
120
+ pii: true,
121
+ maxLength: 15
122
+ },
123
+ ifsc: {
124
+ type: 'text',
125
+ inputMode: 'text',
126
+ placeholder: 'SBIN0001234',
127
+ pattern: PATTERNS.ifsc.pattern,
128
+ patternError: PATTERNS.ifsc.error,
129
+ maxLength: 11
130
+ },
131
+ upi: {
132
+ type: 'text',
133
+ inputMode: 'text',
134
+ placeholder: 'name@upi',
135
+ pattern: PATTERNS.upi.pattern,
136
+ patternError: PATTERNS.upi.error,
137
+ pii: true
138
+ },
139
+ state: {
140
+ type: 'dropdown',
141
+ autocomplete: 'address-level1',
142
+ options: [
143
+ { value: 'AN', label: 'Andaman and Nicobar Islands' },
144
+ { value: 'AP', label: 'Andhra Pradesh' },
145
+ { value: 'AR', label: 'Arunachal Pradesh' },
146
+ { value: 'AS', label: 'Assam' },
147
+ { value: 'BR', label: 'Bihar' },
148
+ { value: 'CH', label: 'Chandigarh' },
149
+ { value: 'CT', label: 'Chhattisgarh' },
150
+ { value: 'DN', label: 'Dadra and Nagar Haveli and Daman and Diu' },
151
+ { value: 'DL', label: 'Delhi' },
152
+ { value: 'GA', label: 'Goa' },
153
+ { value: 'GJ', label: 'Gujarat' },
154
+ { value: 'HR', label: 'Haryana' },
155
+ { value: 'HP', label: 'Himachal Pradesh' },
156
+ { value: 'JK', label: 'Jammu and Kashmir' },
157
+ { value: 'JH', label: 'Jharkhand' },
158
+ { value: 'KA', label: 'Karnataka' },
159
+ { value: 'KL', label: 'Kerala' },
160
+ { value: 'LA', label: 'Ladakh' },
161
+ { value: 'LD', label: 'Lakshadweep' },
162
+ { value: 'MP', label: 'Madhya Pradesh' },
163
+ { value: 'MH', label: 'Maharashtra' },
164
+ { value: 'MN', label: 'Manipur' },
165
+ { value: 'ML', label: 'Meghalaya' },
166
+ { value: 'MZ', label: 'Mizoram' },
167
+ { value: 'NL', label: 'Nagaland' },
168
+ { value: 'OR', label: 'Odisha' },
169
+ { value: 'PY', label: 'Puducherry' },
170
+ { value: 'PB', label: 'Punjab' },
171
+ { value: 'RJ', label: 'Rajasthan' },
172
+ { value: 'SK', label: 'Sikkim' },
173
+ { value: 'TN', label: 'Tamil Nadu' },
174
+ { value: 'TG', label: 'Telangana' },
175
+ { value: 'TR', label: 'Tripura' },
176
+ { value: 'UP', label: 'Uttar Pradesh' },
177
+ { value: 'UK', label: 'Uttarakhand' },
178
+ { value: 'WB', label: 'West Bengal' }
179
+ ]
180
+ },
181
+ currency: {
182
+ type: 'text',
183
+ inputMode: 'decimal',
184
+ placeholder: '₹1,00,000',
185
+ pattern: PATTERNS.currency.pattern,
186
+ patternError: PATTERNS.currency.error
187
+ }
188
+ };
189
+
190
+ /**
191
+ * Indian English field name mappings
192
+ */
193
+ export const FIELD_LABELS = {
194
+ postalCode: 'PIN Code',
195
+ state: 'State/UT',
196
+ nationalId: 'Aadhaar Number',
197
+ phone: 'Phone Number',
198
+ mobile: 'Mobile Number',
199
+ firstName: 'First Name',
200
+ lastName: 'Last Name',
201
+ fullName: 'Full Name',
202
+ streetAddress: 'Address',
203
+ city: 'City/Town',
204
+ district: 'District',
205
+ email: 'Email Address',
206
+ dateOfBirth: 'Date of Birth',
207
+ company: 'Company Name',
208
+ fatherName: "Father's Name"
209
+ };
210
+
211
+ /**
212
+ * DPDP Act (Digital Personal Data Protection) compliance hints
213
+ */
214
+ export const GDPR_HINTS = {
215
+ consentRequired: true,
216
+ dataRetentionNotice: true,
217
+ rightToErasure: true,
218
+ explicitConsentLanguage: 'I consent to the processing of my personal data in accordance with the Privacy Policy.'
219
+ };
@@ -0,0 +1,171 @@
1
+ /**
2
+ * English - Malaysia (en-MY) Locale Configuration
3
+ */
4
+
5
+ export const LOCALE_INFO = {
6
+ code: 'en-MY',
7
+ name: 'Malaysia',
8
+ region: 'Asia',
9
+ currency: 'MYR',
10
+ dateFormat: 'DD/MM/YYYY'
11
+ };
12
+
13
+ export const PATTERNS = {
14
+ phone: {
15
+ pattern: '^(\\+60|0)[1-9]\\d{7,9}$',
16
+ error: 'Enter a valid Malaysian phone number',
17
+ description: 'Malaysian phone number'
18
+ },
19
+ mobile: {
20
+ pattern: '^(\\+60|0)1[0-9]\\d{7,8}$',
21
+ error: 'Enter a valid Malaysian mobile number',
22
+ description: 'Malaysian mobile number'
23
+ },
24
+ postalCode: {
25
+ pattern: '^\\d{5}$',
26
+ error: 'Enter a valid postcode (5 digits)',
27
+ description: 'Malaysian postcode'
28
+ },
29
+ nric: {
30
+ pattern: '^\\d{6}-?\\d{2}-?\\d{4}$',
31
+ error: 'Enter a valid NRIC (e.g., 880101-14-1234)',
32
+ description: 'National Registration Identity Card'
33
+ },
34
+ passport: {
35
+ pattern: '^[A-Z]\\d{8}$',
36
+ error: 'Enter a valid passport number',
37
+ description: 'Malaysian passport number'
38
+ },
39
+ brn: {
40
+ pattern: '^\\d{12}[A-Z]?$',
41
+ error: 'Enter a valid business registration number',
42
+ description: 'Business Registration Number'
43
+ },
44
+ tin: {
45
+ pattern: '^[A-Z]\\d{10}$',
46
+ error: 'Enter a valid TIN',
47
+ description: 'Tax Identification Number'
48
+ },
49
+ bankAccount: {
50
+ pattern: '^\\d{10,16}$',
51
+ error: 'Enter a valid bank account number',
52
+ description: 'Malaysian bank account'
53
+ },
54
+ duitnow: {
55
+ pattern: '^(\\+60|0)1[0-9]\\d{7,8}$|^\\d{6}-?\\d{2}-?\\d{4}$',
56
+ error: 'Enter a valid DuitNow ID',
57
+ description: 'DuitNow mobile/NRIC'
58
+ },
59
+ currency: {
60
+ pattern: '^(RM|MYR)?\\s?[\\d,]+(\\.\\d{2})?$',
61
+ error: 'Enter a valid amount',
62
+ description: 'Malaysian Ringgit amount'
63
+ }
64
+ };
65
+
66
+ export const ARCHETYPES = {
67
+ phone: {
68
+ type: 'tel',
69
+ autocomplete: 'tel',
70
+ inputMode: 'tel',
71
+ placeholder: '012-345 6789',
72
+ pattern: PATTERNS.mobile.pattern,
73
+ patternError: PATTERNS.mobile.error,
74
+ pii: true
75
+ },
76
+ postalCode: {
77
+ type: 'text',
78
+ autocomplete: 'postal-code',
79
+ inputMode: 'numeric',
80
+ placeholder: '50000',
81
+ pattern: PATTERNS.postalCode.pattern,
82
+ patternError: PATTERNS.postalCode.error,
83
+ maxLength: 5
84
+ },
85
+ nationalId: {
86
+ type: 'text',
87
+ inputMode: 'numeric',
88
+ placeholder: '880101-14-1234',
89
+ pattern: PATTERNS.nric.pattern,
90
+ patternError: PATTERNS.nric.error,
91
+ pii: true,
92
+ sensitive: true,
93
+ helpText: 'Your NRIC will be stored securely'
94
+ },
95
+ tin: {
96
+ type: 'text',
97
+ inputMode: 'text',
98
+ placeholder: 'C1234567890',
99
+ pattern: PATTERNS.tin.pattern,
100
+ patternError: PATTERNS.tin.error,
101
+ pii: true
102
+ },
103
+ duitnow: {
104
+ type: 'text',
105
+ inputMode: 'text',
106
+ placeholder: 'Mobile/NRIC',
107
+ pattern: PATTERNS.duitnow.pattern,
108
+ patternError: PATTERNS.duitnow.error,
109
+ pii: true
110
+ },
111
+ state: {
112
+ type: 'dropdown',
113
+ autocomplete: 'address-level1',
114
+ options: [
115
+ { value: 'JHR', label: 'Johor' },
116
+ { value: 'KDH', label: 'Kedah' },
117
+ { value: 'KTN', label: 'Kelantan' },
118
+ { value: 'KUL', label: 'Kuala Lumpur' },
119
+ { value: 'LBN', label: 'Labuan' },
120
+ { value: 'MLK', label: 'Melaka' },
121
+ { value: 'NSN', label: 'Negeri Sembilan' },
122
+ { value: 'PHG', label: 'Pahang' },
123
+ { value: 'PNG', label: 'Penang' },
124
+ { value: 'PRK', label: 'Perak' },
125
+ { value: 'PLS', label: 'Perlis' },
126
+ { value: 'PJY', label: 'Putrajaya' },
127
+ { value: 'SBH', label: 'Sabah' },
128
+ { value: 'SWK', label: 'Sarawak' },
129
+ { value: 'SGR', label: 'Selangor' },
130
+ { value: 'TRG', label: 'Terengganu' }
131
+ ]
132
+ },
133
+ currency: {
134
+ type: 'text',
135
+ inputMode: 'decimal',
136
+ placeholder: 'RM 1,000.00',
137
+ pattern: PATTERNS.currency.pattern,
138
+ patternError: PATTERNS.currency.error
139
+ }
140
+ };
141
+
142
+ /**
143
+ * Malaysian English field name mappings
144
+ */
145
+ export const FIELD_LABELS = {
146
+ postalCode: 'Postcode',
147
+ state: 'State',
148
+ nationalId: 'NRIC',
149
+ phone: 'Phone Number',
150
+ mobile: 'Mobile Number',
151
+ firstName: 'First Name',
152
+ lastName: 'Last Name',
153
+ fullName: 'Full Name (as in NRIC)',
154
+ streetAddress: 'Address',
155
+ city: 'City',
156
+ email: 'Email Address',
157
+ dateOfBirth: 'Date of Birth',
158
+ company: 'Company Name',
159
+ race: 'Race',
160
+ religion: 'Religion'
161
+ };
162
+
163
+ /**
164
+ * PDPA (Personal Data Protection Act 2010) compliance hints
165
+ */
166
+ export const GDPR_HINTS = {
167
+ consentRequired: true,
168
+ dataRetentionNotice: true,
169
+ rightToErasure: true,
170
+ explicitConsentLanguage: 'I consent to the processing of my personal data in accordance with the Privacy Policy and the Personal Data Protection Act 2010.'
171
+ };