mojulo 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -4
- package/lib/audit-logger-new.js +11 -0
- package/lib/auth/gate.js +25 -0
- package/lib/auth/service.js +17 -0
- package/lib/auth/session.js +63 -0
- package/lib/builder/chat-processor.js +607 -0
- package/lib/builder/composer-bridge.js +82 -0
- package/lib/builder/evaluator.js +159 -0
- package/lib/builder/executor.js +252 -0
- package/lib/builder/index.js +48 -0
- package/lib/builder/session.js +248 -0
- package/lib/builder/system-prompt.js +422 -0
- package/lib/builder/tone-presets.js +75 -0
- package/lib/builder/tool-executors.js +1418 -0
- package/lib/builder/tools.js +338 -0
- package/lib/builder/validators.js +239 -0
- package/lib/composer/composer.js +225 -0
- package/lib/composer/index.js +40 -0
- package/lib/composer/protocols/00_base.txt +19 -0
- package/lib/composer/protocols/01_knowledge.txt +9 -0
- package/lib/composer/protocols/02_form-gathering.txt +32 -0
- package/lib/composer/protocols/03_appointments.txt +16 -0
- package/lib/composer/protocols/04_triage.txt +15 -0
- package/lib/composer/protocols/05_optical-read.txt +22 -0
- package/lib/composer/response-builder.js +98 -0
- package/lib/config-builder.js +650 -0
- package/lib/db/ids.js +10 -0
- package/lib/db/index.js +179 -0
- package/lib/db/repositories/apiKeys.js +72 -0
- package/lib/db/repositories/auditLogs.js +12 -0
- package/lib/db/repositories/botSpaces.js +12 -0
- package/lib/db/repositories/builderSessions.js +312 -0
- package/lib/db/repositories/deploymentEvents.js +12 -0
- package/lib/db/repositories/deployments.js +385 -0
- package/lib/db/repositories/documents.js +68 -0
- package/lib/db/repositories/mcpJobs.js +84 -0
- package/lib/deployers/bot-fleet.js +110 -0
- package/lib/deployers/bot-proxy.js +72 -0
- package/lib/deployers/build.js +89 -0
- package/lib/deployers/cloud-deploy.js +310 -0
- package/lib/deployers/docker.js +439 -0
- package/lib/deployers/fly.js +432 -0
- package/lib/deployers/index.js +38 -0
- package/lib/deployment-auth.js +36 -0
- package/lib/document-parser.js +171 -0
- package/lib/embedder/chunker.js +93 -0
- package/lib/embedder/local.js +101 -0
- package/lib/embedder/preview-rag.js +93 -0
- package/lib/envelope-schema.js +54 -0
- package/lib/fleet/scoped-sql.js +342 -0
- package/lib/form-schema-config/base.js +135 -0
- package/lib/form-schema-config/index.js +286 -0
- package/lib/form-schema-config/locales/af-ZA.js +153 -0
- package/lib/form-schema-config/locales/ar-AE.js +142 -0
- package/lib/form-schema-config/locales/ar-SA.js +164 -0
- package/lib/form-schema-config/locales/de-DE.js +152 -0
- package/lib/form-schema-config/locales/en-AU.js +161 -0
- package/lib/form-schema-config/locales/en-CA.js +115 -0
- package/lib/form-schema-config/locales/en-GB.js +132 -0
- package/lib/form-schema-config/locales/en-IN.js +219 -0
- package/lib/form-schema-config/locales/en-MY.js +171 -0
- package/lib/form-schema-config/locales/en-NG.js +198 -0
- package/lib/form-schema-config/locales/en-PH.js +186 -0
- package/lib/form-schema-config/locales/en-SG.js +153 -0
- package/lib/form-schema-config/locales/en-US.js +138 -0
- package/lib/form-schema-config/locales/es-ES.js +171 -0
- package/lib/form-schema-config/locales/es-MX.js +193 -0
- package/lib/form-schema-config/locales/fr-CA.js +138 -0
- package/lib/form-schema-config/locales/fr-FR.js +155 -0
- package/lib/form-schema-config/locales/hi-IN.js +219 -0
- package/lib/form-schema-config/locales/it-IT.js +157 -0
- package/lib/form-schema-config/locales/ja-JP.js +169 -0
- package/lib/form-schema-config/locales/ko-KR.js +140 -0
- package/lib/form-schema-config/locales/nl-NL.js +149 -0
- package/lib/form-schema-config/locales/pt-BR.js +168 -0
- package/lib/form-schema-config/locales/zh-CN.js +172 -0
- package/lib/form-schema-config/locales/zh-HK.js +142 -0
- package/lib/form-structure-schema.js +191 -0
- package/lib/llm-providers.js +828 -0
- package/lib/markdown.js +197 -0
- package/lib/mcp/catalysts/appointment-to-calendar.md +84 -0
- package/lib/mcp/catalysts/conversations-to-channel-digest.md +104 -0
- package/lib/mcp/catalysts/document-extract-to-store.md +92 -0
- package/lib/mcp/catalysts/knowledge-gap-miner.md +96 -0
- package/lib/mcp/catalysts/loader.js +144 -0
- package/lib/mcp/catalysts/qualify-lead-to-crm.md +83 -0
- package/lib/mcp/catalysts/scan-conversations-for-signal.md +92 -0
- package/lib/mcp/catalysts/submission-to-ticket.md +83 -0
- package/lib/mcp/catalysts/submissions-to-warehouse.md +103 -0
- package/lib/mcp/catalysts/weekly-submissions-digest.md +82 -0
- package/lib/mcp/jobs.js +64 -0
- package/lib/mcp/server.js +184 -0
- package/lib/mcp/session-binding.js +130 -0
- package/lib/mcp/tools/build.js +123 -0
- package/lib/mcp/tools/catalysts.js +477 -0
- package/lib/mcp/tools/context.js +325 -0
- package/lib/mcp/tools/fleet.js +391 -0
- package/lib/mcp/tools/jobs-tools.js +240 -0
- package/lib/mcp/tools/operate.js +314 -0
- package/lib/preview/build-preview-config.js +136 -0
- package/lib/rate-limiter.js +11 -0
- package/lib/resolve-api-key.js +142 -0
- package/lib/storage/index.js +40 -0
- package/messages/de.json +2136 -0
- package/messages/en.json +2136 -0
- package/messages/es.json +2136 -0
- package/messages/fr.json +2136 -0
- package/messages/it.json +2136 -0
- package/messages/ja.json +2136 -0
- package/messages/ko.json +2136 -0
- package/messages/nl.json +2136 -0
- package/messages/pl.json +2136 -0
- package/messages/pt.json +2136 -0
- package/messages/ru.json +2136 -0
- package/messages/uk.json +2136 -0
- package/messages/zh.json +2136 -0
- package/package.json +61 -5
- package/scripts/mcp-config.mjs +162 -0
- package/scripts/mcp-stdio-loader.mjs +42 -0
- package/scripts/mcp-stdio.mjs +108 -0
- 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
|
+
};
|