@@ -32,6 +32,8 @@ export type ValidationModificationInfo = {
3232 valid ?: boolean
3333}
3434
35+ type ValidationSignatureFlow = ValidationFileRecord [ 'signatureFlow' ]
36+
3537type ValidationMetadataDimension = {
3638 w : number
3739 h : number
@@ -64,15 +66,12 @@ function isOptionalField(record: UnknownRecord, key: string, guard: (value: unkn
6466}
6567
6668function toNumber ( value : unknown ) : number | null {
67- if ( typeof value === 'number' && Number . isFinite ( value ) ) {
68- return value
69- }
70-
71- if ( typeof value === 'string' && / ^ - ? \d + $ / . test ( value ) ) {
72- return Number . parseInt ( value , 10 )
73- }
69+ return typeof value === 'number' && Number . isFinite ( value ) ? value : null
70+ }
7471
75- return null
72+ function toInteger ( value : unknown ) : number | null {
73+ const normalized = toNumber ( value )
74+ return normalized !== null && Number . isInteger ( normalized ) ? normalized : null
7675}
7776
7877function isString ( value : unknown ) : value is string {
@@ -84,7 +83,7 @@ function isNullableString(value: unknown): value is string | null {
8483}
8584
8685function isValidationStatus ( value : unknown ) : value is ValidationStatus {
87- const normalizedValue = toNumber ( value )
86+ const normalizedValue = toInteger ( value )
8887 return normalizedValue === FILE_STATUS . DRAFT
8988 || normalizedValue === FILE_STATUS . ABLE_TO_SIGN
9089 || normalizedValue === FILE_STATUS . PARTIAL_SIGNED
@@ -93,27 +92,30 @@ function isValidationStatus(value: unknown): value is ValidationStatus {
9392}
9493
9594function isSignerStatus ( value : unknown ) : value is SignerDetailRecord [ 'status' ] {
96- const normalizedValue = toNumber ( value )
95+ const normalizedValue = toInteger ( value )
9796 return normalizedValue === SIGN_REQUEST_STATUS . DRAFT
9897 || normalizedValue === SIGN_REQUEST_STATUS . ABLE_TO_SIGN
9998 || normalizedValue === SIGN_REQUEST_STATUS . SIGNED
10099}
101100
102- function isValidationSignatureFlow ( value : unknown ) : boolean {
103- if ( value === 'none' || value === 'parallel' || value === 'ordered_numeric' ) {
104- return true
101+ function isValidationSignatureFlow ( value : unknown ) : value is ValidationSignatureFlow {
102+ return value === 0 || value === 1 || value === 2
103+ }
104+
105+ function normalizeValidationSignatureFlow ( value : unknown ) : ValidationSignatureFlow | null {
106+ if ( isValidationSignatureFlow ( value ) ) {
107+ return value
105108 }
106109
107- const normalizedValue = toNumber ( value )
108- return normalizedValue === 0 || normalizedValue === 1 || normalizedValue === 2
110+ return null
109111}
110112
111113function isValidationStatusInfo ( value : unknown ) : value is ValidationStatusInfo {
112114 if ( ! isRecord ( value ) ) {
113115 return false
114116 }
115117
116- return isOptionalField ( value , 'id' , fieldValue => typeof fieldValue === 'number' )
118+ return isOptionalField ( value , 'id' , fieldValue => toInteger ( fieldValue ) !== null )
117119 && isOptionalField ( value , 'label' , isString )
118120}
119121
@@ -153,7 +155,7 @@ function isValidationMetadata(value: unknown): value is NonNullable<ValidationFi
153155 return false
154156 }
155157
156- if ( ! isString ( value . extension ) || typeof value . p !== 'number' ) {
158+ if ( ! isString ( value . extension ) || toInteger ( value . p ) === null ) {
157159 return false
158160 }
159161
@@ -181,9 +183,9 @@ function isSignerDetailRecord(value: unknown): value is SignerDetailRecord {
181183 return false
182184 }
183185
184- return typeof value . signRequestId === 'number'
186+ return toInteger ( value . signRequestId ) !== null
185187 && isString ( value . displayName )
186- && isString ( value . email )
188+ && isOptionalField ( value , ' email' , isNullableString )
187189 && isNullableString ( value . signed )
188190 && isSignerStatus ( value . status )
189191 && isString ( value . statusText )
@@ -203,13 +205,13 @@ function isValidatedChildFileRecord(value: unknown): value is ValidatedChildFile
203205 return false
204206 }
205207
206- return typeof value . id === 'number'
208+ return toInteger ( value . id ) !== null
207209 && isString ( value . uuid )
208210 && isString ( value . name )
209211 && isValidationStatus ( value . status )
210212 && isString ( value . statusText )
211- && typeof value . nodeId === 'number'
212- && typeof value . size === 'number'
213+ && toInteger ( value . nodeId ) !== null
214+ && toInteger ( value . size ) !== null
213215 && Array . isArray ( value . signers )
214216 && isString ( value . file )
215217 && isValidationMetadata ( value . metadata )
@@ -220,19 +222,19 @@ function isValidationDocumentRecord(data: unknown): data is ValidationFileRecord
220222 return false
221223 }
222224 if (
223- typeof data . id !== 'number'
225+ toInteger ( data . id ) === null
224226 || ! isString ( data . uuid )
225227 || ! isString ( data . name )
226228 || ! isValidationStatus ( data . status )
227229 || ! isString ( data . statusText )
228- || typeof data . nodeId !== 'number'
230+ || toInteger ( data . nodeId ) === null
229231 || ( data . nodeType !== 'file' && data . nodeType !== 'envelope' )
230- || ! isValidationSignatureFlow ( data . signatureFlow )
231- || toNumber ( data . docmdpLevel ) === null
232- || toNumber ( data . filesCount ) === null
232+ || normalizeValidationSignatureFlow ( data . signatureFlow ) === null
233+ || toInteger ( data . docmdpLevel ) === null
234+ || toInteger ( data . filesCount ) === null
233235 || ! Array . isArray ( data . files )
234- || toNumber ( data . totalPages ) === null
235- || toNumber ( data . size ) === null
236+ || toInteger ( data . totalPages ) === null
237+ || toInteger ( data . size ) === null
236238 || ! isString ( data . pdfVersion )
237239 || ! isString ( data . created_at )
238240 || ! isRequestedBy ( data . requested_by )
@@ -278,24 +280,113 @@ export function toValidationDocument(data: unknown): ValidationDocumentState | n
278280 return null
279281 }
280282
283+ const id = toInteger ( data . id )
284+ const nodeId = toInteger ( data . nodeId )
285+ const docmdpLevel = toInteger ( data . docmdpLevel )
286+ const filesCount = toInteger ( data . filesCount )
287+ const totalPages = toInteger ( data . totalPages )
288+ const size = toInteger ( data . size )
289+ const signatureFlow = normalizeValidationSignatureFlow ( data . signatureFlow )
290+
291+ if (
292+ id === null
293+ || nodeId === null
294+ || docmdpLevel === null
295+ || filesCount === null
296+ || totalPages === null
297+ || size === null
298+ || signatureFlow === null
299+ ) {
300+ return null
301+ }
302+
303+ const files = data . files . map ( ( file ) => {
304+ const childId = toInteger ( file . id )
305+ const childNodeId = toInteger ( file . nodeId )
306+ const childSize = toInteger ( file . size )
307+ const childStatus = toInteger ( file . status )
308+ const metadataPages = toInteger ( file . metadata . p )
309+
310+ if (
311+ childId === null
312+ || childNodeId === null
313+ || childSize === null
314+ || childStatus === null
315+ || metadataPages === null
316+ ) {
317+ return null
318+ }
319+
320+ return {
321+ ...file ,
322+ id : childId ,
323+ nodeId : childNodeId ,
324+ size : childSize ,
325+ status : childStatus ,
326+ metadata : {
327+ ...file . metadata ,
328+ p : metadataPages ,
329+ } ,
330+ }
331+ } )
332+
333+ if ( files . some ( file => file === null ) ) {
334+ return null
335+ }
336+ const normalizedFiles = files . filter ( ( file ) : file is ValidatedChildFileRecord => file !== null )
337+
281338 const metadata = isValidationMetadata ( data . metadata )
282339 ? data . metadata
283340 : {
284341 ...DEFAULT_VALIDATION_METADATA ,
285- p : data . totalPages ,
342+ p : totalPages ,
286343 }
287344
345+ const metadataPages = toInteger ( metadata . p )
346+ if ( metadataPages === null ) {
347+ return null
348+ }
349+
288350 const settings = isValidationSettings ( data . settings )
289351 ? data . settings
290352 : DEFAULT_VALIDATION_SETTINGS
291353
292- const signers = Array . isArray ( data . signers ) ? data . signers : [ ]
354+ const signers = ( Array . isArray ( data . signers ) ? data . signers : [ ] ) . map ( ( signer ) => {
355+ const signRequestId = toInteger ( signer . signRequestId )
356+ const status = toInteger ( signer . status )
357+
358+ if ( signRequestId === null || status === null ) {
359+ return null
360+ }
361+
362+ return {
363+ ...signer ,
364+ signRequestId,
365+ status,
366+ }
367+ } )
368+
369+ if ( signers . some ( signer => signer === null ) ) {
370+ return null
371+ }
372+ const normalizedSigners = signers . filter ( ( signer ) : signer is SignerDetailRecord => signer !== null )
293373
294374 return {
295375 ...data ,
296- metadata,
376+ id,
377+ nodeId,
378+ signatureFlow,
379+ docmdpLevel,
380+ filesCount,
381+ totalPages,
382+ size,
383+ files : normalizedFiles ,
384+ metadata : {
385+ ...metadata ,
386+ p : metadataPages ,
387+ } ,
297388 settings,
298- signers,
389+ signers : normalizedSigners ,
299390 }
300391}
301392
0 commit comments