@@ -129,6 +129,14 @@ import { openDocument } from '../utils/viewer.js'
129129import { getStatusLabel } from ' ../utils/fileStatus.js'
130130import { getSigningRouteUuid } from ' ../utils/signRequestUuid.ts'
131131import { FILE_STATUS , SIGN_REQUEST_STATUS } from ' ../constants.js'
132+ import {
133+ isLoadedValidationEnvelopeDocument ,
134+ isLoadedValidationFileDocument ,
135+ MODIFICATION_ALLOWED ,
136+ MODIFICATION_UNMODIFIED ,
137+ MODIFICATION_VIOLATION ,
138+ toValidationDocument ,
139+ } from ' ../services/validationDocument'
132140import logger from ' ../logger.js'
133141import { useFilesStore } from ' ../store/files.js'
134142import { useSignStore } from ' ../store/sign.js'
@@ -138,6 +146,13 @@ import type {
138146 ValidatedChildFileRecord ,
139147 ValidationFileRecord ,
140148} from ' ../types/index'
149+ import type {
150+ LoadedValidationEnvelopeDocumentState ,
151+ LoadedValidationFileDocumentState ,
152+ ValidationDocumentState ,
153+ ValidationModificationInfo ,
154+ ValidationStatusInfo ,
155+ } from ' ../services/validationDocument'
141156
142157defineOptions ({
143158 name: ' Validation' ,
@@ -161,25 +176,7 @@ type RouterState = {
161176}
162177
163178type ToggleOpenState = Record <number , boolean >
164- type ValidationStatus = ValidationFileRecord [' status' ]
165- type ValidationStatusInfo = {
166- id? : number
167- label? : string
168- }
169-
170- const MODIFICATION_UNMODIFIED = 1
171- const MODIFICATION_ALLOWED = 2
172- const MODIFICATION_VIOLATION = 3
173179
174- type ModificationValidationStatus =
175- typeof MODIFICATION_UNMODIFIED
176- | typeof MODIFICATION_ALLOWED
177- | typeof MODIFICATION_VIOLATION
178-
179- type ValidationModificationInfo = {
180- status? : ModificationValidationStatus
181- valid? : boolean
182- }
183180type ValidationDisplaySigner = SignerDetailRecord & {
184181 signature_validation? : ValidationStatusInfo
185182 certificate_validation? : ValidationStatusInfo
@@ -209,41 +206,8 @@ type ValidationErrorResponse = {
209206 }
210207}
211208
212- type ValidationMetadataDimension = {
213- w: number
214- h: number
215- }
216-
217- type ValidationDocumentState = ValidationFileRecord & {
218- signers: SignerDetailRecord []
219- metadata: NonNullable <ValidationFileRecord [' metadata' ]>
220- settings: NonNullable <ValidationFileRecord [' settings' ]>
221- }
222-
223- type LoadedValidationEnvelopeDocumentState = ValidationDocumentState & {
224- nodeType: ' envelope'
225- }
226-
227- type LoadedValidationFileDocumentState = ValidationDocumentState & {
228- nodeType: ' file'
229- }
230-
231- type UnknownRecord = Record <string , unknown >
232-
233- function isRecord(value : unknown ): value is Record <string , unknown > {
234- return typeof value === ' object' && value !== null
235- }
236-
237- function hasOwn(record : UnknownRecord , key : string ): boolean {
238- return Object .prototype .hasOwnProperty .call (record , key )
239- }
240-
241- function isOptionalField(record : UnknownRecord , key : string , guard : (value : unknown ) => boolean ): boolean {
242- return ! hasOwn (record , key ) || guard (record [key ])
243- }
244-
245209function normalizeRouteRecord(value : unknown , source : ' params' | ' query' ): Record <string , string > {
246- if (! isRecord ( value ) ) {
210+ if (typeof value !== ' object ' || value === null ) {
247211 return {}
248212 }
249213
@@ -271,22 +235,6 @@ function toNumber(value: unknown): number | null {
271235 return typeof value === ' number' && Number .isFinite (value ) ? value : null
272236}
273237
274- function isValidationStatus(value : unknown ): value is ValidationStatus {
275- const normalizedValue = toNumber (value )
276- return normalizedValue === FILE_STATUS .DRAFT
277- || normalizedValue === FILE_STATUS .ABLE_TO_SIGN
278- || normalizedValue === FILE_STATUS .PARTIAL_SIGNED
279- || normalizedValue === FILE_STATUS .SIGNED
280- || normalizedValue === FILE_STATUS .DELETED
281- }
282-
283- function isSignerStatus(value : unknown ): value is SignerDetailRecord [' status' ] {
284- const normalizedValue = toNumber (value )
285- return normalizedValue === SIGN_REQUEST_STATUS .DRAFT
286- || normalizedValue === SIGN_REQUEST_STATUS .ABLE_TO_SIGN
287- || normalizedValue === SIGN_REQUEST_STATUS .SIGNED
288- }
289-
290238function isValidationRouteName(value : RouteState [' name' ]): value is ValidationRouteName {
291239 return value === ' validation'
292240 || value === ' ValidationFile'
@@ -298,220 +246,13 @@ function isSignedDocumentStatus(status: unknown): boolean {
298246 return Number (status ) === FILE_STATUS .SIGNED
299247}
300248
301- function isString(value : unknown ): value is string {
302- return typeof value === ' string'
303- }
304-
305- function isNullableString(value : unknown ): value is string | null {
306- return value === null || typeof value === ' string'
307- }
308-
309- function isValidationStatusInfo(value : unknown ): value is ValidationStatusInfo {
310- if (! isRecord (value )) {
311- return false
312- }
313-
314- return isOptionalField (value , ' id' , fieldValue => typeof fieldValue === ' number' )
315- && isOptionalField (value , ' label' , isString )
316- }
317-
318- function isValidationModificationInfo(value : unknown ): value is ValidationModificationInfo {
319- if (! isRecord (value )) {
320- return false
321- }
322-
323- return isOptionalField (value , ' status' , isModificationValidationStatus )
324- && isOptionalField (value , ' valid' , fieldValue => typeof fieldValue === ' boolean' )
325- }
326-
327- function isModificationValidationStatus(value : unknown ): value is ModificationValidationStatus {
328- return value === MODIFICATION_UNMODIFIED
329- || value === MODIFICATION_ALLOWED
330- || value === MODIFICATION_VIOLATION
331- }
332-
333- function isValidationMetadataDimension(value : unknown ): value is ValidationMetadataDimension {
334- if (! isRecord (value )) {
335- return false
336- }
337-
338- return typeof value .w === ' number' && Number .isFinite (value .w )
339- && typeof value .h === ' number' && Number .isFinite (value .h )
340- }
341-
342- function isRequestedBy(value : unknown ): value is ValidationFileRecord [' requested_by' ] {
343- if (! isRecord (value )) {
344- return false
345- }
346- return isString (value .userId ) && isString (value .displayName )
347- }
348-
349- function isValidationMetadata(value : unknown ): value is NonNullable <ValidationFileRecord [' metadata' ]> {
350- if (! isRecord (value )) {
351- return false
352- }
353-
354- if (! isString (value .extension ) || typeof value .p !== ' number' ) {
355- return false
356- }
357-
358- return isOptionalField (value , ' d' , fieldValue => Array .isArray (fieldValue ) && fieldValue .every (isValidationMetadataDimension ))
359- && isOptionalField (value , ' original_file_deleted' , fieldValue => typeof fieldValue === ' boolean' )
360- && isOptionalField (value , ' pdfVersion' , isString )
361- && isOptionalField (value , ' status_changed_at' , isString )
362- }
363-
364- function isValidationSettings(value : unknown ): value is NonNullable <ValidationFileRecord [' settings' ]> {
365- if (! isRecord (value )) {
366- return false
367- }
368- return typeof value .canSign === ' boolean'
369- && typeof value .canRequestSign === ' boolean'
370- && typeof value .phoneNumber === ' string'
371- && typeof value .hasSignatureFile === ' boolean'
372- && typeof value .needIdentificationDocuments === ' boolean'
373- && typeof value .identificationDocumentsWaitingApproval === ' boolean'
374- && isOptionalField (value , ' isApprover' , fieldValue => typeof fieldValue === ' boolean' )
375- }
376-
377- function isSignerDetailRecord(value : unknown ): value is SignerDetailRecord {
378- if (! isRecord (value )) {
379- return false
380- }
381-
382- return typeof value .signRequestId === ' number'
383- && isString (value .displayName )
384- && isString (value .email )
385- && isNullableString (value .signed )
386- && isSignerStatus (value .status )
387- && isString (value .statusText )
388- && isNullableString (value .description )
389- && isString (value .request_sign_date )
390- && typeof value .me === ' boolean'
391- && Array .isArray (value .visibleElements )
392- && isOptionalField (value , ' signature_validation' , isValidationStatusInfo )
393- && isOptionalField (value , ' certificate_validation' , isValidationStatusInfo )
394- && isOptionalField (value , ' modification_validation' , isValidationModificationInfo )
395- && isOptionalField (value , ' crl_validation' , isString )
396- && isOptionalField (value , ' isLibreSignRootCA' , fieldValue => typeof fieldValue === ' boolean' )
397- }
398-
399- function isValidatedChildFileRecord(value : unknown ): value is ValidatedChildFileRecord {
400- if (! isRecord (value )) {
401- return false
402- }
403-
404- return typeof value .id === ' number'
405- && isString (value .uuid )
406- && isString (value .name )
407- && isValidationStatus (value .status )
408- && isString (value .statusText )
409- && typeof value .nodeId === ' number'
410- && typeof value .size === ' number'
411- && Array .isArray (value .signers )
412- && isString (value .file )
413- && isValidationMetadata (value .metadata )
414- }
415-
416- function isValidationDocumentRecord(data : unknown ): data is ValidationFileRecord {
417- if (! isRecord (data )) {
418- return false
419- }
420- if (
421- typeof data .id !== ' number'
422- || ! isString (data .uuid )
423- || ! isString (data .name )
424- || ! isValidationStatus (data .status )
425- || ! isString (data .statusText )
426- || typeof data .nodeId !== ' number'
427- || (data .nodeType !== ' file' && data .nodeType !== ' envelope' )
428- || typeof data .signatureFlow !== ' number'
429- || typeof data .docmdpLevel !== ' number'
430- || typeof data .filesCount !== ' number'
431- || ! Array .isArray (data .files )
432- || typeof data .totalPages !== ' number'
433- || typeof data .size !== ' number'
434- || ! isString (data .pdfVersion )
435- || ! isString (data .created_at )
436- || ! isRequestedBy (data .requested_by )
437- ) {
438- return false
439- }
440-
441- if (! data .files .every (isValidatedChildFileRecord )) {
442- return false
443- }
444-
445- if (hasOwn (data , ' signers' ) && (! Array .isArray (data .signers ) || ! data .signers .every (isSignerDetailRecord ))) {
446- return false
447- }
448-
449- if (hasOwn (data , ' metadata' ) && ! isValidationMetadata (data .metadata )) {
450- return false
451- }
452-
453- if (hasOwn (data , ' settings' ) && ! isValidationSettings (data .settings )) {
454- return false
455- }
456-
457- return true
458- }
459-
460- const DEFAULT_VALIDATION_METADATA: NonNullable <ValidationFileRecord [' metadata' ]> = {
461- extension: ' pdf' ,
462- p: 0 ,
463- }
464-
465- const DEFAULT_VALIDATION_SETTINGS: NonNullable <ValidationFileRecord [' settings' ]> = {
466- canSign: false ,
467- canRequestSign: false ,
468- phoneNumber: ' ' ,
469- hasSignatureFile: false ,
470- needIdentificationDocuments: false ,
471- identificationDocumentsWaitingApproval: false ,
472- }
473-
474- function toValidationDocument(data : unknown ): ValidationDocumentState | null {
475- if (! isValidationDocumentRecord (data )) {
476- return null
477- }
478-
479- const metadata = isValidationMetadata (data .metadata )
480- ? data .metadata
481- : {
482- ... DEFAULT_VALIDATION_METADATA ,
483- p: data .totalPages ,
484- }
485-
486- const settings = isValidationSettings (data .settings )
487- ? data .settings
488- : DEFAULT_VALIDATION_SETTINGS
489-
490- const signers = Array .isArray (data .signers ) ? data .signers : []
491-
492- return {
493- ... data ,
494- metadata ,
495- settings ,
496- signers ,
497- }
498- }
499-
500249function getValidationErrorMessage(response : ValidationErrorResponse | undefined , fallback : string ): string {
501250 if (response ?.data ?.ocs ?.data ?.errors ?.length ) {
502251 return response .data .ocs .data .errors [0 ]?.message || fallback
503252 }
504253 return fallback
505254}
506255
507- function isLoadedValidationEnvelopeDocument(document : ValidationDocumentState | null ): document is LoadedValidationEnvelopeDocumentState {
508- return document ?.nodeType === ' envelope'
509- }
510-
511- function isLoadedValidationFileDocument(document : ValidationDocumentState | null ): document is LoadedValidationFileDocumentState {
512- return document ?.nodeType === ' file'
513- }
514-
515256const signStore = useSignStore ()
516257const sidebarStore = useSidebarStore ()
517258const filesStore = useFilesStore ()
@@ -974,7 +715,7 @@ function syncValidatedDocumentToFilesStore(validationDocument: ValidationFileRec
974715 ? currentFile .files
975716 : []
976717 if (nestedFiles .length > 0 ) {
977- pendingFiles .push (... nestedFiles .filter ((file ): file is ValidatedChildFileRecord => isRecord ( file ) ))
718+ pendingFiles .push (... nestedFiles .filter ((file ): file is ValidatedChildFileRecord => typeof file === ' object ' && file !== null ))
978719 }
979720 }
980721}
0 commit comments