udp-schema 0.1.21 → 0.2.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/dist/field-helpers.d.ts +55 -0
- package/dist/field-helpers.d.ts.map +1 -0
- package/dist/field-helpers.js +85 -0
- package/dist/field-helpers.js.map +1 -0
- package/dist/field-meta.d.ts +40 -0
- package/dist/field-meta.d.ts.map +1 -0
- package/dist/field-meta.js +1025 -0
- package/dist/field-meta.js.map +1 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/progress-fields.d.ts +28 -0
- package/dist/progress-fields.d.ts.map +1 -0
- package/dist/progress-fields.js +207 -0
- package/dist/progress-fields.js.map +1 -0
- package/dist/step-01.schema.d.ts +5 -5
- package/dist/step-01.schema.d.ts.map +1 -1
- package/dist/step-01.schema.js +5 -5
- package/dist/step-01.schema.js.map +1 -1
- package/dist/step-02.schema.js +1 -1
- package/dist/step-02.schema.js.map +1 -1
- package/dist/step-06.schema.d.ts +1 -1
- package/dist/step-07.schema.js +1 -1
- package/dist/step-07.schema.js.map +1 -1
- package/dist/step-14.schema.d.ts +2 -2
- package/dist/{helpers.d.ts → zod-helpers.d.ts} +1 -1
- package/dist/zod-helpers.d.ts.map +1 -0
- package/dist/{helpers.js → zod-helpers.js} +1 -1
- package/dist/zod-helpers.js.map +1 -0
- package/package.json +1 -1
- package/dist/helpers.d.ts.map +0 -1
- package/dist/helpers.js.map +0 -1
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UDP Progress Fields — Single source of truth for step progress counting.
|
|
3
|
+
*
|
|
4
|
+
* Used by both frontend (stepper UI) and backend (computeStepProgressCounts).
|
|
5
|
+
* Each step lists the curated fields that determine filled/total progress.
|
|
6
|
+
*
|
|
7
|
+
* Dot-paths (e.g., "socialMedia.facebook") resolve nested subdocument fields.
|
|
8
|
+
* Only these fields count toward progress — extra fields in the schema are ignored.
|
|
9
|
+
*/
|
|
10
|
+
export const UDP_PROGRESS_FIELDS = {
|
|
11
|
+
1: [
|
|
12
|
+
'profilePhotoUrl',
|
|
13
|
+
'email',
|
|
14
|
+
'firstName',
|
|
15
|
+
'middleName',
|
|
16
|
+
'lastName',
|
|
17
|
+
'gender',
|
|
18
|
+
'dateOfBirth',
|
|
19
|
+
'aadhaarNumber',
|
|
20
|
+
'assistedByVolunteer',
|
|
21
|
+
'primaryLanguage',
|
|
22
|
+
'secondaryLanguages',
|
|
23
|
+
],
|
|
24
|
+
2: [
|
|
25
|
+
'phonePrimary',
|
|
26
|
+
'whatsappNumber',
|
|
27
|
+
'socialMedia.facebook',
|
|
28
|
+
'socialMedia.twitter',
|
|
29
|
+
'socialMedia.instagram',
|
|
30
|
+
'socialMedia.linkedin',
|
|
31
|
+
'socialMedia.youtube',
|
|
32
|
+
'emergencyContact.contactName',
|
|
33
|
+
'emergencyContact.contactRelation',
|
|
34
|
+
'emergencyContact.contactPhone',
|
|
35
|
+
],
|
|
36
|
+
3: [
|
|
37
|
+
'domicileSource',
|
|
38
|
+
'birthPlace',
|
|
39
|
+
'homeNativePlace',
|
|
40
|
+
'ancestralNativePlace',
|
|
41
|
+
'yearsAtCurrentAddress',
|
|
42
|
+
'currentAddress.state',
|
|
43
|
+
'currentAddress.division',
|
|
44
|
+
'currentAddress.district',
|
|
45
|
+
'currentAddress.tehsil',
|
|
46
|
+
'currentAddress.areaType',
|
|
47
|
+
'currentAddress.housePlotDetails',
|
|
48
|
+
'currentAddress.pincode',
|
|
49
|
+
'permanentAddress.state',
|
|
50
|
+
'permanentAddress.division',
|
|
51
|
+
'permanentAddress.district',
|
|
52
|
+
'permanentAddress.tehsil',
|
|
53
|
+
'permanentAddress.areaType',
|
|
54
|
+
'permanentAddress.housePlotDetails',
|
|
55
|
+
'permanentAddress.pincode',
|
|
56
|
+
],
|
|
57
|
+
4: [
|
|
58
|
+
'familyReligion',
|
|
59
|
+
'individualReligion',
|
|
60
|
+
'casteCategoryReservation',
|
|
61
|
+
'minorityStatus',
|
|
62
|
+
'viewOnLgbtqStatements',
|
|
63
|
+
'viewOnTransgenderInclusionStatements',
|
|
64
|
+
],
|
|
65
|
+
5: [
|
|
66
|
+
'desireToBeLeader',
|
|
67
|
+
'desiredPoliticalPosition',
|
|
68
|
+
'politicalPartyJoiningIntent',
|
|
69
|
+
'visionChangesYouWillBring',
|
|
70
|
+
'leadershipSkillset',
|
|
71
|
+
'politicalExposureLevel',
|
|
72
|
+
'publicVisibilityComfort',
|
|
73
|
+
'leadershipTrainingInterest',
|
|
74
|
+
'pastLeadershipRoles',
|
|
75
|
+
'socialInfluenceLevel',
|
|
76
|
+
'whyJoinMovement',
|
|
77
|
+
],
|
|
78
|
+
6: [
|
|
79
|
+
'areYouMigrant',
|
|
80
|
+
'maritalStatus',
|
|
81
|
+
'familyStructureType',
|
|
82
|
+
'householdSize',
|
|
83
|
+
'housingType',
|
|
84
|
+
'annualPersonalIncomeRange',
|
|
85
|
+
'annualHouseholdIncomeRange',
|
|
86
|
+
'digitalAccess',
|
|
87
|
+
'digitalSkillLevel',
|
|
88
|
+
'literacyLevel',
|
|
89
|
+
],
|
|
90
|
+
7: [
|
|
91
|
+
'highestQualification',
|
|
92
|
+
'education10th.board',
|
|
93
|
+
'education10th.schoolName',
|
|
94
|
+
'education10th.yearOfPassing',
|
|
95
|
+
'education12th.institutionName',
|
|
96
|
+
'education12th.yearOfPassing',
|
|
97
|
+
'diplomas',
|
|
98
|
+
'graduations',
|
|
99
|
+
'postGraduations',
|
|
100
|
+
'doctorates',
|
|
101
|
+
'postDoctorates',
|
|
102
|
+
],
|
|
103
|
+
8: [
|
|
104
|
+
'employmentStatus',
|
|
105
|
+
'employedSince',
|
|
106
|
+
'jobOccupationType',
|
|
107
|
+
'currentWorkShift',
|
|
108
|
+
'personalIncomeRange',
|
|
109
|
+
'workExperienceSummary',
|
|
110
|
+
],
|
|
111
|
+
9: [
|
|
112
|
+
'neurodivergentSelfIdentification',
|
|
113
|
+
'sensorySensitivities',
|
|
114
|
+
'learningStylePreference',
|
|
115
|
+
'communicationPreferences',
|
|
116
|
+
],
|
|
117
|
+
10: [
|
|
118
|
+
'mbtiType',
|
|
119
|
+
'enneagramType',
|
|
120
|
+
'attachmentStyle',
|
|
121
|
+
'assessmentAccuracyRating',
|
|
122
|
+
],
|
|
123
|
+
11: [
|
|
124
|
+
'selfPartyAssociation',
|
|
125
|
+
'familyPartyAssociation',
|
|
126
|
+
'publicOfficeHistory',
|
|
127
|
+
'politicalNetworkLevel',
|
|
128
|
+
],
|
|
129
|
+
12: [
|
|
130
|
+
'willVoteThisTime',
|
|
131
|
+
'votedLastTime',
|
|
132
|
+
'politicalSpectrumSelf',
|
|
133
|
+
'votingFrequency',
|
|
134
|
+
],
|
|
135
|
+
13: [
|
|
136
|
+
'overallHealthStatus',
|
|
137
|
+
'foodHabitType',
|
|
138
|
+
'physicalActivityLevel',
|
|
139
|
+
'sleepHoursPerDay',
|
|
140
|
+
'tobaccoUse',
|
|
141
|
+
'hasHealthInsurance',
|
|
142
|
+
],
|
|
143
|
+
14: [
|
|
144
|
+
'topPrioritiesThisYear',
|
|
145
|
+
'priorityCategoryTags',
|
|
146
|
+
'alignmentWithMovement',
|
|
147
|
+
'openToVolunteering',
|
|
148
|
+
],
|
|
149
|
+
};
|
|
150
|
+
/** Total number of UDP steps */
|
|
151
|
+
export const UDP_TOTAL_STEPS = 14;
|
|
152
|
+
/**
|
|
153
|
+
* Resolve a dot-path (e.g., "socialMedia.facebook") against a data object.
|
|
154
|
+
* Works with both plain objects and Mongoose subdocuments.
|
|
155
|
+
*/
|
|
156
|
+
export function getNestedValue(obj, path) {
|
|
157
|
+
const parts = path.split('.');
|
|
158
|
+
let current = obj;
|
|
159
|
+
for (const part of parts) {
|
|
160
|
+
if (current === null || current === undefined || typeof current !== 'object') {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
current = current[part];
|
|
164
|
+
}
|
|
165
|
+
return current;
|
|
166
|
+
}
|
|
167
|
+
/** Determine if a field value counts as "filled" for progress */
|
|
168
|
+
export function isFieldFilled(value) {
|
|
169
|
+
if (value === null || value === undefined)
|
|
170
|
+
return false;
|
|
171
|
+
if (typeof value === 'string')
|
|
172
|
+
return value.trim().length > 0;
|
|
173
|
+
if (typeof value === 'number')
|
|
174
|
+
return true;
|
|
175
|
+
if (typeof value === 'boolean')
|
|
176
|
+
return true;
|
|
177
|
+
if (Array.isArray(value))
|
|
178
|
+
return value.length > 0;
|
|
179
|
+
if (typeof value === 'object') {
|
|
180
|
+
// Area entity ref - check for name
|
|
181
|
+
if ('name' in value && typeof value.name === 'string') {
|
|
182
|
+
return value.name !== '';
|
|
183
|
+
}
|
|
184
|
+
return Object.keys(value).length > 0;
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Calculate progress for a single step.
|
|
190
|
+
* Shared between frontend (stepper UI) and backend (API response).
|
|
191
|
+
*/
|
|
192
|
+
export function calculateStepProgress(stepNumber, formData) {
|
|
193
|
+
const fields = UDP_PROGRESS_FIELDS[stepNumber];
|
|
194
|
+
if (!fields)
|
|
195
|
+
return { filled: 0, total: 0 };
|
|
196
|
+
const total = fields.length;
|
|
197
|
+
if (!formData || total === 0)
|
|
198
|
+
return { filled: 0, total };
|
|
199
|
+
let filled = 0;
|
|
200
|
+
for (const fieldPath of fields) {
|
|
201
|
+
if (isFieldFilled(getNestedValue(formData, fieldPath))) {
|
|
202
|
+
filled++;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return { filled, total };
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=progress-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-fields.js","sourceRoot":"","sources":["../src/progress-fields.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * UDP Progress Fields — Single source of truth for step progress counting.\n *\n * Used by both frontend (stepper UI) and backend (computeStepProgressCounts).\n * Each step lists the curated fields that determine filled/total progress.\n *\n * Dot-paths (e.g., \"socialMedia.facebook\") resolve nested subdocument fields.\n * Only these fields count toward progress — extra fields in the schema are ignored.\n */\n\nexport const UDP_PROGRESS_FIELDS: Record<number, readonly string[]> = {\n 1: [\n 'profilePhotoUrl',\n 'email',\n 'firstName',\n 'middleName',\n 'lastName',\n 'gender',\n 'dateOfBirth',\n 'aadhaarNumber',\n 'assistedByVolunteer',\n 'primaryLanguage',\n 'secondaryLanguages',\n ],\n 2: [\n 'phonePrimary',\n 'whatsappNumber',\n 'socialMedia.facebook',\n 'socialMedia.twitter',\n 'socialMedia.instagram',\n 'socialMedia.linkedin',\n 'socialMedia.youtube',\n 'emergencyContact.contactName',\n 'emergencyContact.contactRelation',\n 'emergencyContact.contactPhone',\n ],\n 3: [\n 'domicileSource',\n 'birthPlace',\n 'homeNativePlace',\n 'ancestralNativePlace',\n 'yearsAtCurrentAddress',\n 'currentAddress.state',\n 'currentAddress.division',\n 'currentAddress.district',\n 'currentAddress.tehsil',\n 'currentAddress.areaType',\n 'currentAddress.housePlotDetails',\n 'currentAddress.pincode',\n 'permanentAddress.state',\n 'permanentAddress.division',\n 'permanentAddress.district',\n 'permanentAddress.tehsil',\n 'permanentAddress.areaType',\n 'permanentAddress.housePlotDetails',\n 'permanentAddress.pincode',\n ],\n 4: [\n 'familyReligion',\n 'individualReligion',\n 'casteCategoryReservation',\n 'minorityStatus',\n 'viewOnLgbtqStatements',\n 'viewOnTransgenderInclusionStatements',\n ],\n 5: [\n 'desireToBeLeader',\n 'desiredPoliticalPosition',\n 'politicalPartyJoiningIntent',\n 'visionChangesYouWillBring',\n 'leadershipSkillset',\n 'politicalExposureLevel',\n 'publicVisibilityComfort',\n 'leadershipTrainingInterest',\n 'pastLeadershipRoles',\n 'socialInfluenceLevel',\n 'whyJoinMovement',\n ],\n 6: [\n 'areYouMigrant',\n 'maritalStatus',\n 'familyStructureType',\n 'householdSize',\n 'housingType',\n 'annualPersonalIncomeRange',\n 'annualHouseholdIncomeRange',\n 'digitalAccess',\n 'digitalSkillLevel',\n 'literacyLevel',\n ],\n 7: [\n 'highestQualification',\n 'education10th.board',\n 'education10th.schoolName',\n 'education10th.yearOfPassing',\n 'education12th.institutionName',\n 'education12th.yearOfPassing',\n 'diplomas',\n 'graduations',\n 'postGraduations',\n 'doctorates',\n 'postDoctorates',\n ],\n 8: [\n 'employmentStatus',\n 'employedSince',\n 'jobOccupationType',\n 'currentWorkShift',\n 'personalIncomeRange',\n 'workExperienceSummary',\n ],\n 9: [\n 'neurodivergentSelfIdentification',\n 'sensorySensitivities',\n 'learningStylePreference',\n 'communicationPreferences',\n ],\n 10: [\n 'mbtiType',\n 'enneagramType',\n 'attachmentStyle',\n 'assessmentAccuracyRating',\n ],\n 11: [\n 'selfPartyAssociation',\n 'familyPartyAssociation',\n 'publicOfficeHistory',\n 'politicalNetworkLevel',\n ],\n 12: [\n 'willVoteThisTime',\n 'votedLastTime',\n 'politicalSpectrumSelf',\n 'votingFrequency',\n ],\n 13: [\n 'overallHealthStatus',\n 'foodHabitType',\n 'physicalActivityLevel',\n 'sleepHoursPerDay',\n 'tobaccoUse',\n 'hasHealthInsurance',\n ],\n 14: [\n 'topPrioritiesThisYear',\n 'priorityCategoryTags',\n 'alignmentWithMovement',\n 'openToVolunteering',\n ],\n} as const;\n\n/** Total number of UDP steps */\nexport const UDP_TOTAL_STEPS = 14;\n\n/**\n * Resolve a dot-path (e.g., \"socialMedia.facebook\") against a data object.\n * Works with both plain objects and Mongoose subdocuments.\n */\nexport function getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n}\n\n/** Determine if a field value counts as \"filled\" for progress */\nexport function isFieldFilled(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n if (typeof value === 'number') return true;\n if (typeof value === 'boolean') return true;\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === 'object') {\n // Area entity ref - check for name\n if ('name' in value && typeof (value as Record<string, unknown>).name === 'string') {\n return (value as Record<string, unknown>).name !== '';\n }\n return Object.keys(value).length > 0;\n }\n return false;\n}\n\n/**\n * Calculate progress for a single step.\n * Shared between frontend (stepper UI) and backend (API response).\n */\nexport function calculateStepProgress(\n stepNumber: number,\n formData: Record<string, unknown> | undefined | null,\n): { filled: number; total: number } {\n const fields = UDP_PROGRESS_FIELDS[stepNumber];\n if (!fields) return { filled: 0, total: 0 };\n\n const total = fields.length;\n if (!formData || total === 0) return { filled: 0, total };\n\n let filled = 0;\n for (const fieldPath of fields) {\n if (isFieldFilled(getNestedValue(formData, fieldPath))) {\n filled++;\n }\n }\n\n return { filled, total };\n}\n"]}
|
package/dist/step-01.schema.d.ts
CHANGED
|
@@ -49,9 +49,9 @@ export declare const profilePhotoSchema: z.ZodOptional<z.ZodUnion<readonly [z.Zo
|
|
|
49
49
|
mimeType: z.ZodOptional<z.ZodString>;
|
|
50
50
|
sizeBytes: z.ZodOptional<z.ZodNumber>;
|
|
51
51
|
}, z.core.$strip>]>>;
|
|
52
|
-
/**
|
|
53
|
-
export declare const
|
|
54
|
-
|
|
52
|
+
/** Volunteer who assisted with the form. */
|
|
53
|
+
export declare const assistedByVolunteerSchema: z.ZodOptional<z.ZodObject<{
|
|
54
|
+
volunteerId: z.ZodOptional<z.ZodString>;
|
|
55
55
|
displayName: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodString>>;
|
|
56
56
|
source: z.ZodOptional<z.ZodEnum<{
|
|
57
57
|
selected: "selected";
|
|
@@ -82,8 +82,8 @@ export declare const step01OnboardingSchema: z.ZodObject<{
|
|
|
82
82
|
mimeType: z.ZodOptional<z.ZodString>;
|
|
83
83
|
sizeBytes: z.ZodOptional<z.ZodNumber>;
|
|
84
84
|
}, z.core.$strip>]>>;
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
assistedByVolunteer: z.ZodOptional<z.ZodObject<{
|
|
86
|
+
volunteerId: z.ZodOptional<z.ZodString>;
|
|
87
87
|
displayName: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodString>>;
|
|
88
88
|
source: z.ZodOptional<z.ZodEnum<{
|
|
89
89
|
selected: "selected";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-01.schema.d.ts","sourceRoot":"","sources":["../src/step-01.schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,iEAAiE;AACjE,eAAO,MAAM,mBAAmB;;;;;iBAU7B,CAAC;AAEJ,iDAAiD;AACjD,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;iBAMtC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;oBAgBlB,CAAC;AAEd,
|
|
1
|
+
{"version":3,"file":"step-01.schema.d.ts","sourceRoot":"","sources":["../src/step-01.schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,iEAAiE;AACjE,eAAO,MAAM,mBAAmB;;;;;iBAU7B,CAAC;AAEJ,iDAAiD;AACjD,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;iBAMtC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;oBAgBlB,CAAC;AAEd,4CAA4C;AAC5C,eAAO,MAAM,yBAAyB;;;;;;;kBAMzB,CAAC;AAId,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwDjC,CAAC;AAIH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC3E,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
|
package/dist/step-01.schema.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module udp-schema/step-01
|
|
8
8
|
*/
|
|
9
9
|
import { z } from 'zod';
|
|
10
|
-
import { emptyStringToUndefined, optionalTrimmedString } from './helpers.js';
|
|
10
|
+
import { emptyStringToUndefined, optionalTrimmedString } from './zod-helpers.js';
|
|
11
11
|
// ─── Sub-schemas ────────────────────────────────────────
|
|
12
12
|
/** Language value (code / nativeName / englishName / script). */
|
|
13
13
|
export const languageValueSchema = z
|
|
@@ -49,10 +49,10 @@ export const profilePhotoSchema = z
|
|
|
49
49
|
}),
|
|
50
50
|
])
|
|
51
51
|
.optional();
|
|
52
|
-
/**
|
|
53
|
-
export const
|
|
52
|
+
/** Volunteer who assisted with the form. */
|
|
53
|
+
export const assistedByVolunteerSchema = z
|
|
54
54
|
.object({
|
|
55
|
-
|
|
55
|
+
volunteerId: z.string().optional(),
|
|
56
56
|
displayName: optionalTrimmedString,
|
|
57
57
|
source: z.enum(['selected', 'manual']).optional(),
|
|
58
58
|
})
|
|
@@ -80,7 +80,7 @@ export const step01OnboardingSchema = z.object({
|
|
|
80
80
|
.regex(/^\d{12}$/, 'Aadhaar must be exactly 12 digits')
|
|
81
81
|
.optional()),
|
|
82
82
|
profilePhotoUrl: profilePhotoSchema,
|
|
83
|
-
|
|
83
|
+
assistedByVolunteer: assistedByVolunteerSchema,
|
|
84
84
|
formFilledLocation: z
|
|
85
85
|
.object({
|
|
86
86
|
latitude: z.number().min(-90).max(90),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-01.schema.js","sourceRoot":"","sources":["../src/step-01.schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"step-01.schema.js","sourceRoot":"","sources":["../src/step-01.schema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Step 01 — Profile Onboarding Schema\n *\n * Single source of truth used by both frontend and backend.\n * Field names match the MongoDB document keys exactly.\n *\n * @module udp-schema/step-01\n */\n\nimport { z } from 'zod';\nimport { emptyStringToUndefined, optionalTrimmedString } from './zod-helpers.js';\n\n// ─── Sub-schemas ────────────────────────────────────────\n\n/** Language value (code / nativeName / englishName / script). */\nexport const languageValueSchema = z\n .object({\n code: optionalTrimmedString,\n nativeName: optionalTrimmedString,\n englishName: optionalTrimmedString,\n script: optionalTrimmedString,\n })\n .refine(\n (v) => Boolean(v.code || v.nativeName || v.englishName),\n 'Language must include at least code, native name, or english name',\n );\n\n/** One entry in the secondaryLanguages array. */\nexport const secondaryLanguageItemSchema = z.object({\n language: languageValueSchema,\n fluency: z.enum(['basic', 'conversational', 'professional', 'native']),\n canSpeak: z.boolean().optional(),\n canRead: z.boolean().optional(),\n canWrite: z.boolean().optional(),\n});\n\n/**\n * Profile photo — accepts either:\n * • a plain URL string (returned by backend on prefill)\n * • an upload-result object (sent after fresh upload)\n * • a File-like object (frontend pre-upload state)\n */\nexport const profilePhotoSchema = z\n .union([\n z.object({\n name: z.string().optional(),\n type: z.string().optional(),\n size: z.number().min(0).optional(),\n lastModified: z.number().min(0).optional(),\n }),\n z.string(),\n z.object({\n assetId: z.string().trim().optional(),\n url: z.string().trim().optional(),\n mimeType: z.string().trim().optional(),\n sizeBytes: z.number().min(0).optional(),\n }),\n ])\n .optional();\n\n/** Volunteer who assisted with the form. */\nexport const assistedByVolunteerSchema = z\n .object({\n volunteerId: z.string().optional(),\n displayName: optionalTrimmedString,\n source: z.enum(['selected', 'manual']).optional(),\n })\n .optional();\n\n// ─── Main step-01 schema ────────────────────────────────\n\nexport const step01OnboardingSchema = z.object({\n email: z.string().trim().toLowerCase().email('Enter a valid email address'),\n firstName: z\n .string()\n .trim()\n .min(1, 'First name is required')\n .max(50, 'First name must be at most 50 characters'),\n middleName: optionalTrimmedString,\n lastName: optionalTrimmedString,\n gender: z.enum(['male', 'female', 'other', 'prefer_not']).optional(),\n dateOfBirth: z.preprocess(emptyStringToUndefined, z.coerce.date().optional()),\n aadhaarNumber: z.preprocess(\n (value) => {\n const normalized = emptyStringToUndefined(value);\n if (typeof normalized === 'string') {\n return normalized.replace(/\\D/g, '');\n }\n return normalized;\n },\n z\n .string()\n .regex(/^\\d{12}$/, 'Aadhaar must be exactly 12 digits')\n .optional(),\n ),\n profilePhotoUrl: profilePhotoSchema,\n assistedByVolunteer: assistedByVolunteerSchema,\n formFilledLocation: z\n .object({\n latitude: z.number().min(-90).max(90),\n longitude: z.number().min(-180).max(180),\n accuracy: z.number().optional(),\n capturedAt: z.coerce.date().optional(),\n })\n .optional(),\n primaryLanguage: languageValueSchema.optional(),\n secondaryLanguages: z\n .array(secondaryLanguageItemSchema)\n .max(5, 'You can add up to 5 secondary languages')\n .optional()\n .superRefine((items, context) => {\n if (!items) return;\n const seenCodes = new Map<string, number>();\n items.forEach((item, index) => {\n const code = item.language.code?.toLowerCase();\n if (!code) return;\n if (seenCodes.has(code)) {\n context.addIssue({\n code: 'custom',\n path: [index, 'language', 'code'],\n message: 'Duplicate secondary language is not allowed',\n });\n return;\n }\n seenCodes.set(code, index);\n });\n }),\n});\n\n// ─── Inferred types ─────────────────────────────────────\n\nexport type Step01OnboardingInput = z.infer<typeof step01OnboardingSchema>;\nexport type Step01OnboardingFormInput = z.input<typeof step01OnboardingSchema>;\n"]}
|
package/dist/step-02.schema.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module udp-schema/step-02
|
|
7
7
|
*/
|
|
8
8
|
import { z } from 'zod';
|
|
9
|
-
import { optionalPhoneSchema } from './helpers.js';
|
|
9
|
+
import { optionalPhoneSchema } from './zod-helpers.js';
|
|
10
10
|
// ─── Sub-schemas ────────────────────────────────────────
|
|
11
11
|
/** Accepts a valid URL, an empty string, or undefined. */
|
|
12
12
|
export const optionalUrlSchema = z.union([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-02.schema.js","sourceRoot":"","sources":["../src/step-02.schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"step-02.schema.js","sourceRoot":"","sources":["../src/step-02.schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,2DAA2D;AAE3D,0DAA0D;AAC1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC;IACvC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACnC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACb,CAAC,CAAC,SAAS,EAAE;CACd,CAAC,CAAC;AAEH,2DAA2D;AAE3D,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,YAAY,EAAE,mBAAmB;IACjC,qBAAqB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC7C,cAAc,EAAE,mBAAmB;IACnC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,iBAAiB;QAC1B,SAAS,EAAE,iBAAiB;QAC5B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,iBAAiB;KAC3B,CAAC;IACF,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC;QACzB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QACzC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QAC7C,YAAY,EAAE,mBAAmB;KAClC,CAAC;CACH,CAAC,CAAC","sourcesContent":["/**\n * Step 02 — Contact Details Schema\n *\n * Single source of truth used by both frontend and backend.\n *\n * @module udp-schema/step-02\n */\n\nimport { z } from 'zod';\nimport { optionalPhoneSchema } from './zod-helpers.js';\n\n// ─── Sub-schemas ────────────────────────────────────────\n\n/** Accepts a valid URL, an empty string, or undefined. */\nexport const optionalUrlSchema = z.union([\n z.string().url('Enter a valid URL'),\n z.literal(''),\n z.undefined(),\n]);\n\n// ─── Main step-02 schema ────────────────────────────────\n\nexport const step02ContactDetailsSchema = z.object({\n phonePrimary: optionalPhoneSchema,\n whatsappSameAsPrimary: z.boolean().optional(),\n whatsappNumber: optionalPhoneSchema,\n socialMedia: z.object({\n facebook: optionalUrlSchema,\n twitter: optionalUrlSchema,\n instagram: optionalUrlSchema,\n linkedin: optionalUrlSchema,\n youtube: optionalUrlSchema,\n }),\n emergencyContact: z.object({\n contactName: z.string().trim().optional(),\n contactRelation: z.string().trim().optional(),\n contactPhone: optionalPhoneSchema,\n }),\n});\n\n// ─── Inferred types ─────────────────────────────────────\n\nexport type Step02ContactDetailsInput = z.infer<typeof step02ContactDetailsSchema>;\n"]}
|
package/dist/step-06.schema.d.ts
CHANGED
|
@@ -79,13 +79,13 @@ export declare const step06HouseholdSchema: z.ZodObject<{
|
|
|
79
79
|
lifeInsuranceDetails: z.ZodOptional<z.ZodString>;
|
|
80
80
|
annualPersonalIncomeRange: z.ZodEnum<{
|
|
81
81
|
PREFER_NOT_SAY: "PREFER_NOT_SAY";
|
|
82
|
+
NO_INCOME: "NO_INCOME";
|
|
82
83
|
BELOW_1L: "BELOW_1L";
|
|
83
84
|
"1_2L": "1_2L";
|
|
84
85
|
"2_3L": "2_3L";
|
|
85
86
|
"3_5L": "3_5L";
|
|
86
87
|
"5_10L": "5_10L";
|
|
87
88
|
ABOVE_10L: "ABOVE_10L";
|
|
88
|
-
NO_INCOME: "NO_INCOME";
|
|
89
89
|
}>;
|
|
90
90
|
annualHouseholdIncomeRange: z.ZodEnum<{
|
|
91
91
|
PREFER_NOT_SAY: "PREFER_NOT_SAY";
|
package/dist/step-07.schema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { optionalYearSchema } from './helpers.js';
|
|
2
|
+
import { optionalYearSchema } from './zod-helpers.js';
|
|
3
3
|
// ─── Step 07 — Education History ──────────────────────────────────────────────
|
|
4
4
|
//
|
|
5
5
|
// Covers: highest qualification level, Class 10 & 12 details,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-07.schema.js","sourceRoot":"","sources":["../src/step-07.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"step-07.schema.js","sourceRoot":"","sources":["../src/step-07.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,iFAAiF;AACjF,EAAE;AACF,8DAA8D;AAC9D,gEAAgE;AAChE,2DAA2D;AAC3D,gFAAgF;AAEhF,gFAAgF;AAEhF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACxC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAC7C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACxC,aAAa,EAAE,kBAAkB;IACjC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAC5C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAC1C,mBAAmB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAC5C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAC7C,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAC7C,gBAAgB,EAAE,kBAAkB;IACpC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAEH,gFAAgF;AAEhF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,6EAA6E;IAE7E,iEAAiE;IACjE,oBAAoB,EAAE,CAAC,CAAC,IAAI,CAC1B;QACE,UAAU;QACV,UAAU;QACV,SAAS;QACT,YAAY;QACZ,WAAW;QACX,KAAK;QACL,gBAAgB;QAChB,OAAO;KACR,EACD,EAAE,OAAO,EAAE,2CAA2C,EAAE,CACzD;IAED,6EAA6E;IAE7E,0CAA0C;IAC1C,aAAa,EAAE,CAAC;SACb,MAAM,CAAC;QACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QACnC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QACxC,aAAa,EAAE,kBAAkB;QACjC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QACtC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;KAC5C,CAAC;SACD,QAAQ,EAAE;IAEb,4EAA4E;IAE5E,0CAA0C;IAC1C,aAAa,EAAE,CAAC;SACb,MAAM,CAAC;QACN,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QAC7C,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QAC/C,aAAa,EAAE,kBAAkB;QACjC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QAC5C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;KAC3C,CAAC;SACD,QAAQ,EAAE;IAEb,6EAA6E;IAE7E,mDAAmD;IACnD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;IAE/C,4EAA4E;IAE5E,4DAA4D;IAC5D,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;IAElD,4EAA4E;IAE5E,+DAA+D;IAC/D,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;IAEtD,4EAA4E;IAE5E,6CAA6C;IAC7C,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;IAEjD,4EAA4E;IAE5E,oDAAoD;IACpD,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;IAErD,4EAA4E;IAE5E,wEAAwE;IACxE,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,QAAQ,EAAE;IAE7D,4EAA4E;IAE5E,sDAAsD;IACtD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\nimport { optionalYearSchema } from './zod-helpers.js';\n\n// ─── Step 07 — Education History ──────────────────────────────────────────────\n//\n// Covers: highest qualification level, Class 10 & 12 details,\n// and repeater fields for Diploma, Graduation, Post Graduation,\n// Doctorate (PhD), Post Doctorate, and Other Certificates.\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Reusable sub-schemas ────────────────────────────────────────────────────\n\nexport const degreeEntrySchema = z.object({\n degreeName: z.string().trim().optional(),\n institutionName: z.string().trim().optional(),\n university: z.string().trim().optional(),\n yearOfPassing: optionalYearSchema,\n courseOrStream: z.string().trim().optional(),\n marksOrGrade: z.string().trim().optional(),\n isCurrentlyStudying: z.boolean().optional(),\n});\n\nexport const certificateEntrySchema = z.object({\n certificateName: z.string().trim().optional(),\n institutionName: z.string().trim().optional(),\n yearOfCompletion: optionalYearSchema,\n fieldOrSubject: z.string().trim().optional(),\n});\n\n// ─── Main Step 07 Schema ─────────────────────────────────────────────────────\n\nexport const step07EducationSchema = z.object({\n // ── 7.1 Highest Qualification ─────────────────────────────────────────────\n\n /** Highest level of formal education completed or in progress */\n highestQualification: z.enum(\n [\n 'CLASS_10',\n 'CLASS_12',\n 'DIPLOMA',\n 'GRADUATION',\n 'POST_GRAD',\n 'PHD',\n 'POST_DOCTORATE',\n 'OTHER',\n ],\n { message: 'Please select your highest qualification.' },\n ),\n\n // ── 7.2 Class 10 / Secondary ──────────────────────────────────────────────\n\n /** Class 10 / Secondary school details */\n education10th: z\n .object({\n board: z.string().trim().optional(),\n schoolName: z.string().trim().optional(),\n yearOfPassing: optionalYearSchema,\n subjects: z.string().trim().optional(),\n marksObtained: z.string().trim().optional(),\n })\n .optional(),\n\n // ── 7.3 Class 12 / Higher Secondary ──────────────────────────────────────\n\n /** Class 12 / Higher Secondary details */\n education12th: z\n .object({\n institutionName: z.string().trim().optional(),\n boardOrUniversity: z.string().trim().optional(),\n yearOfPassing: optionalYearSchema,\n courseOrStream: z.string().trim().optional(),\n marksOrGrade: z.string().trim().optional(),\n })\n .optional(),\n\n // ── 7.4 Diplomas (repeater) ───────────────────────────────────────────────\n\n /** List of Diploma qualifications (one or more) */\n diplomas: z.array(degreeEntrySchema).optional(),\n\n // ── 7.5 Graduations (repeater) ───────────────────────────────────────────\n\n /** List of Graduation / Bachelor's degree qualifications */\n graduations: z.array(degreeEntrySchema).optional(),\n\n // ── 7.6 Post Graduations (repeater) ──────────────────────────────────────\n\n /** List of Post Graduation / Master's degree qualifications */\n postGraduations: z.array(degreeEntrySchema).optional(),\n\n // ── 7.7 Doctorates / PhD (repeater) ──────────────────────────────────────\n\n /** List of Doctorate / PhD qualifications */\n doctorates: z.array(degreeEntrySchema).optional(),\n\n // ── 7.8 Post Doctorates (repeater) ───────────────────────────────────────\n\n /** List of Post Doctoral research or fellowships */\n postDoctorates: z.array(degreeEntrySchema).optional(),\n\n // ── 7.9 Other Certificates (repeater) ────────────────────────────────────\n\n /** Other certificates, short courses, or professional qualifications */\n otherCertificates: z.array(certificateEntrySchema).optional(),\n\n // ── 7.10 Education Notes ─────────────────────────────────────────────────\n\n /** Any additional notes about education background */\n educationNotes: z.string().trim().optional(),\n});\n\n// ─── Inferred types ──────────────────────────────────────────────────────────\n\nexport type DegreeEntryInput = z.infer<typeof degreeEntrySchema>;\nexport type CertificateEntryInput = z.infer<typeof certificateEntrySchema>;\nexport type Step07EducationInput = z.infer<typeof step07EducationSchema>;\n"]}
|
package/dist/step-14.schema.d.ts
CHANGED
|
@@ -42,6 +42,8 @@ export declare const step14PrioritiesSchema: z.ZodObject<{
|
|
|
42
42
|
skillsWantToLearn: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
43
43
|
OTHER: "OTHER";
|
|
44
44
|
PUBLIC_SPEAKING: "PUBLIC_SPEAKING";
|
|
45
|
+
NEGOTIATION: "NEGOTIATION";
|
|
46
|
+
CONFLICT_RESOLUTION: "CONFLICT_RESOLUTION";
|
|
45
47
|
LEADERSHIP: "LEADERSHIP";
|
|
46
48
|
DIGITAL_MARKETING: "DIGITAL_MARKETING";
|
|
47
49
|
DATA_ANALYSIS: "DATA_ANALYSIS";
|
|
@@ -52,9 +54,7 @@ export declare const step14PrioritiesSchema: z.ZodObject<{
|
|
|
52
54
|
TECHNICAL_IT: "TECHNICAL_IT";
|
|
53
55
|
TEACHING_TRAINING: "TEACHING_TRAINING";
|
|
54
56
|
SOCIAL_MEDIA_CONTENT: "SOCIAL_MEDIA_CONTENT";
|
|
55
|
-
NEGOTIATION: "NEGOTIATION";
|
|
56
57
|
FIRST_AID_HEALTH: "FIRST_AID_HEALTH";
|
|
57
|
-
CONFLICT_RESOLUTION: "CONFLICT_RESOLUTION";
|
|
58
58
|
}>>>;
|
|
59
59
|
alignmentWithMovement: z.ZodOptional<z.ZodString>;
|
|
60
60
|
openToVolunteering: z.ZodOptional<z.ZodEnum<{
|
|
@@ -32,4 +32,4 @@ export declare const optionalYearSchema: z.ZodOptional<z.ZodString>;
|
|
|
32
32
|
* for full react-hook-form compatibility.
|
|
33
33
|
*/
|
|
34
34
|
export declare const optionalPhoneSchema: z.ZodOptional<z.ZodString>;
|
|
35
|
-
//# sourceMappingURL=helpers.d.ts.map
|
|
35
|
+
//# sourceMappingURL=zod-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-helpers.d.ts","sourceRoot":"","sources":["../src/zod-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,OAKvD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,yEAGjC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,4BAmB3B,CAAC;AAEL;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,4BAW5B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-helpers.js","sourceRoot":"","sources":["../src/zod-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAc,EAAW,EAAE;IAChE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,UAAU,CAC/C,sBAAsB,EACtB,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CACtC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,WAAW,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACxB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,CAAC,2BAA2B;IAClE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,wCAAwC;SAClD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;QACzB,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,oCAAoC;SAC9C,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEL;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,WAAW,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACxB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,CAAC,2BAA2B;IAClE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,2DAA2D;SACrE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Shared helper utilities for Zod schema preprocessing.\n *\n * @module udp-schema/helpers\n */\n\nimport { z } from 'zod';\n\n/**\n * Converts empty / whitespace-only strings to `undefined`\n * so Zod `.optional()` treats them as \"not provided\".\n */\nexport const emptyStringToUndefined = (value: unknown): unknown => {\n if (typeof value === 'string' && value.trim() === '') {\n return undefined;\n }\n return value;\n};\n\n/**\n * Optional trimmed string with 100-char max.\n * Empty strings are coerced to `undefined`.\n */\nexport const optionalTrimmedString = z.preprocess(\n emptyStringToUndefined,\n z.string().trim().max(100).optional(),\n);\n\n/**\n * Optional 4-digit year (1900–2099).\n * Empty strings and undefined are treated as \"not provided\".\n * Accepts strings like \"2020\". Rejects non-digits and out-of-range values.\n *\n * Uses superRefine (not preprocess) to keep input type as `string | undefined`\n * for full react-hook-form compatibility.\n */\nexport const optionalYearSchema = z\n .string()\n .optional()\n .superRefine((val, ctx) => {\n if (!val || val.trim() === '') return; // empty / undefined → skip\n if (!/^\\d{4}$/.test(val)) {\n ctx.addIssue({\n code: 'custom',\n message: 'Enter a valid 4-digit year (e.g. 2020)',\n });\n return;\n }\n const n = Number(val);\n if (n < 1900 || n > 2099) {\n ctx.addIssue({\n code: 'custom',\n message: 'Year must be between 1900 and 2099',\n });\n }\n });\n\n/**\n * Optional phone number — digits only, 7–15 characters.\n * Accepts an optional leading + for country code (e.g. +919876543210).\n * Empty strings and undefined are treated as \"not provided\".\n *\n * Uses superRefine (not preprocess) to keep input type as `string | undefined`\n * for full react-hook-form compatibility.\n */\nexport const optionalPhoneSchema = z\n .string()\n .optional()\n .superRefine((val, ctx) => {\n if (!val || val.trim() === '') return; // empty / undefined → skip\n if (!/^\\+?[0-9]{7,15}$/.test(val)) {\n ctx.addIssue({\n code: 'custom',\n message: 'Enter a valid phone number (digits only, 7–15 characters)',\n });\n }\n });\n"]}
|
package/package.json
CHANGED
package/dist/helpers.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,OAKvD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,yEAGjC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,4BAmB3B,CAAC;AAEL;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,4BAW5B,CAAC"}
|
package/dist/helpers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAc,EAAW,EAAE;IAChE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,UAAU,CAC/C,sBAAsB,EACtB,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CACtC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,WAAW,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACxB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,CAAC,2BAA2B;IAClE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,wCAAwC;SAClD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;QACzB,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,oCAAoC;SAC9C,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEL;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,WAAW,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACxB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,CAAC,2BAA2B;IAClE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,2DAA2D;SACrE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Shared helper utilities for Zod schema preprocessing.\n *\n * @module udp-schema/helpers\n */\n\nimport { z } from 'zod';\n\n/**\n * Converts empty / whitespace-only strings to `undefined`\n * so Zod `.optional()` treats them as \"not provided\".\n */\nexport const emptyStringToUndefined = (value: unknown): unknown => {\n if (typeof value === 'string' && value.trim() === '') {\n return undefined;\n }\n return value;\n};\n\n/**\n * Optional trimmed string with 100-char max.\n * Empty strings are coerced to `undefined`.\n */\nexport const optionalTrimmedString = z.preprocess(\n emptyStringToUndefined,\n z.string().trim().max(100).optional(),\n);\n\n/**\n * Optional 4-digit year (1900–2099).\n * Empty strings and undefined are treated as \"not provided\".\n * Accepts strings like \"2020\". Rejects non-digits and out-of-range values.\n *\n * Uses superRefine (not preprocess) to keep input type as `string | undefined`\n * for full react-hook-form compatibility.\n */\nexport const optionalYearSchema = z\n .string()\n .optional()\n .superRefine((val, ctx) => {\n if (!val || val.trim() === '') return; // empty / undefined → skip\n if (!/^\\d{4}$/.test(val)) {\n ctx.addIssue({\n code: 'custom',\n message: 'Enter a valid 4-digit year (e.g. 2020)',\n });\n return;\n }\n const n = Number(val);\n if (n < 1900 || n > 2099) {\n ctx.addIssue({\n code: 'custom',\n message: 'Year must be between 1900 and 2099',\n });\n }\n });\n\n/**\n * Optional phone number — digits only, 7–15 characters.\n * Accepts an optional leading + for country code (e.g. +919876543210).\n * Empty strings and undefined are treated as \"not provided\".\n *\n * Uses superRefine (not preprocess) to keep input type as `string | undefined`\n * for full react-hook-form compatibility.\n */\nexport const optionalPhoneSchema = z\n .string()\n .optional()\n .superRefine((val, ctx) => {\n if (!val || val.trim() === '') return; // empty / undefined → skip\n if (!/^\\+?[0-9]{7,15}$/.test(val)) {\n ctx.addIssue({\n code: 'custom',\n message: 'Enter a valid phone number (digits only, 7–15 characters)',\n });\n }\n });\n"]}
|