import {z} from 'zod' export type GetApiExperimentalFlowInstancesInstanceIdArgs = {instance_id: string}; export type GetApiExperimentalFlowInstancesInstanceIdOptions = {baseUrl?: string | undefined, OAuth10?: string | undefined, fetch?: typeof fetch | undefined}; export const userName = z.string(); export const messageName = z.string(); export const notifyMethods = z.object({email: messageName.optional(), sms: messageName.optional(), "email-link-only": z.boolean().optional()}); export const notifyKind = z.enum(["standard", "confirmation"]); export const notifyDetails = z.object({users: z.array(userName), methods: notifyMethods, kind: notifyKind.optional()}); export const notifyAction = z.object({notify: notifyDetails}); export const documentName = z.string(); export const allowViewingDetails = z.object({users: z.array(userName), documents: z.array(documentName)}); export const allowViewingAction = z.object({"allow-viewing": allowViewingDetails}); export const denyViewingDetails = z.object({users: z.array(userName), documents: z.array(documentName)}); export const denyViewingAction = z.object({"deny-viewing": denyViewingDetails}); export const callbackName = z.string().max(128); export const callbackDetails = z.object({"callback-name": callbackName}); export const callbackAction = z.object({callback: callbackDetails}); export const systemAction = z.union([notifyAction, allowViewingAction, denyViewingAction, callbackAction]); export const approvedBy = z.object({documents: z.array(documentName), users: z.array(userName)}); export const approvedByGroupOf = z.object({"required-approvals": z.number().int().gte(0).lte(18446744073709552000), documents: z.array(documentName), users: z.array(userName)}); export const signedBy = z.object({documents: z.array(documentName), users: z.array(userName)}); export const signedByGroupOf = z.object({"required-signatures": z.number().int().gte(0).lte(18446744073709552000), documents: z.array(documentName), users: z.array(userName)}); export const viewedBy = z.object({documents: z.array(documentName), users: z.array(userName)}); export const url = z.string(); export const redirectTo = z.object({users: z.array(userName), url: url}); export const expect = z.object({"approved-by": approvedBy.optional(), "approved-by-group-of": approvedByGroupOf.optional(), "signed-by": signedBy.optional(), "signed-by-group-of": signedByGroupOf.optional(), "viewed-by": viewedBy.optional(), "redirect-to": redirectTo.optional()}); export const flowDSLStageRegular = z.record(z.string(), z.object({actions: z.array(systemAction), expect: expect})); export const confirmationAction = z.object({notify: z.object({users: z.array(userName), methods: notifyMethods, kind: z.literal("confirmation")})}); export const flowDSLStageConfirmation = z.record(z.string(), z.object({actions: z.array(confirmationAction), expect: z.object({})})); export const flowDSLStage = z.union([flowDSLStageRegular, flowDSLStageConfirmation]); export const dslVersion = z.string(); export const allowRejections = z.boolean(); export const timeOfDay = z.string(); export const reminderRelativeTime = z.object({time_of_day: timeOfDay, time_zone: z.string()}); export const reminderRepeat = z.enum(["never", "periodically"]); export const reminderDate = z.union([z.object({type: z.literal("absolute"), date_time: z.string()}), z.object({type: z.literal("relative"), days_delay: z.number().int().gte(1).lte(365), time: reminderRelativeTime.optional(), repeat: reminderRepeat.optional()})]); export const automaticReminderMethod = z.enum(["email", "sms", "email-and-sms"]); export const automaticReminder = z.object({"user-name": userName, date: reminderDate, method: automaticReminderMethod}); export const flowDSL = z.object({stages: z.array(flowDSLStage), "dsl-version": dslVersion, "allow-rejections": allowRejections.optional(), "automatic-reminders": z.array(automaticReminder).optional()}); export const documentID = z.string(); export const userIdType = z.enum(["email", "phone_number", "user_id", "full_name"]); export const onfidoMethod = z.enum(["document", "document_and_photo", "document_and_video", "document_and_motion"]); export const onfidoCountry = z.string(); export const onfidoDocumentType = z.enum(["national_identity_card", "driving_licence", "passport", "residence_permit"]); export const onfidoDocumentCapture = z.enum(["mobile_only", "mobile_or_desktop"]); export const onfidoAdditionalReportInfo = z.enum(["driving_licence_info", "address_info"]); export const nOUiLocale = z.enum(["nb", "en"]); export const uiLocale = z.enum(["nb-NO", "en-GB", "da-DK", "sv-SE", "fi-FI", "sv-FI"]); export const tupasBank = z.enum(["nordea", "opbank", "danske", "handelsbanken", "aland", "sbank", "aktia", "popbank", "savingsbank", "omasp", "mobileid"]); export const authenticationConfiguration = z.union([z.object({provider: z.literal("sms_otp"), max_failures: z.number().int().gte(0).lte(255), attempts_per_sms: z.number().int().gte(1).lte(5).optional()}), z.object({provider: z.literal("onfido"), max_failures: z.number().int().gte(0).lte(255), method: onfidoMethod.optional(), allowed_document_countries: z.array(onfidoCountry).optional(), allowed_document_types: z.array(onfidoDocumentType).optional(), document_capture: onfidoDocumentCapture.optional(), additional_report_info: onfidoAdditionalReportInfo.optional(), email: z.string().optional()}), z.object({provider: z.literal("se_bankid"), max_failures: z.number().int().gte(0).lte(255)}), z.object({provider: z.literal("dk_mitid"), max_failures: z.number().int().gte(0).lte(255)}), z.object({provider: z.literal("no_bankid"), max_failures: z.number().int().gte(0).lte(255), ui_locale: nOUiLocale.optional()}), z.object({provider: z.literal("ftn"), max_failures: z.number().int().gte(0).lte(255), ui_locale: uiLocale.optional(), force_bank: tupasBank.optional()})]); export const userConfiguration = z.object({id: z.string(), id_type: userIdType, auth_to_view: authenticationConfiguration.optional(), auth_to_view_archived: authenticationConfiguration.optional()}); export const message = z.string(); export const processParameters = z.object({documents: z.record(z.string(), documentID), users: z.record(z.string(), userConfiguration), messages: z.record(z.string(), message)}); export const instanceEventAction = z.enum(["approve", "sign", "view", "reject", "redirect"]); export const userID = z.string(); export const flowUserId = z.union([z.object({id_type: z.literal("email"), id: z.string()}), z.object({id_type: z.literal("phone_number"), id: z.string()}), z.object({id_type: z.literal("user_id"), id: userID}), z.object({id_type: z.literal("full_name"), id: z.string()})]); export const instanceUserActionForAuthor = z.object({type: instanceEventAction, user: flowUserId, document: documentID.optional()}); export const instanceState = z.object({available_actions: z.array(instanceUserActionForAuthor)}); export const authId = z.string(); export const authIdentifier = z.enum(["view", "view_archived", "sign"]); export const adminFormId = z.object({id: z.literal("participant_form"), participant_id: z.string()}); export const schema = z.object({}); export const uiSchema = z.object({}); export const formData = z.unknown(); export const invitationKind = z.enum(["email", "sms"]); export const adminApiAction = z.union([z.object({action: z.literal("notify_participant"), participant_id: z.string()}), z.object({action: z.literal("cancel_instance")}), z.object({action: z.literal("prolong_instance"), max_days: z.number().int().gte(1).lte(365)}), z.object({action: z.literal("reset_auth_attempts"), participant_id: z.string(), auth_label: authId.optional()}), z.object({action: z.literal("reset_authentication_attempts"), participant_id: z.string(), authentication: authIdentifier}), z.object({action: z.literal("admin_form"), form_id: adminFormId, schema: schema, ui_schema: uiSchema.optional(), default_value: formData.optional()}), z.object({action: z.literal("complete_redirect"), participant_id: z.string(), url: url}), z.object({action: z.literal("modify_reminder_settings"), participant_id: z.string()}), z.object({action: z.literal("delete_reminder_settings"), participant_id: z.string()}), z.object({action: z.literal("cancel_reminder"), participant_id: z.string()}), z.object({action: z.literal("modify_participant_info"), participant_id: z.string(), invitations_sent: z.array(invitationKind), authentication_modifiable: z.boolean()})]); export const getParticipantTag = z.object({category: z.string(), value: z.string()}); export const deprecatedAuthId = z.string(); export const onfidoReport = z.enum(["document", "document_and_photo", "document_and_video", "document_and_motion"]); export const onfidoApplicantNameField = z.string(); export const day = z.string(); export const mitIDCPR = z.string(); export const mitIdLanguage = z.enum(["en", "da", "kl"]); export const fIPersonalNumber = z.string(); export const standardParameters = z.union([z.object({provider: z.literal("sms_otp"), attempts_per_sms: z.number().int().gte(1).lte(5).optional(), mobile_number: z.string().optional()}), z.object({provider: z.literal("onfido"), report: onfidoReport.optional(), allowed_document_countries: z.array(onfidoCountry).optional(), allowed_document_types: z.array(onfidoDocumentType).optional(), force_cross_device: z.boolean().optional(), additional_report_info: onfidoAdditionalReportInfo.optional(), first_name: onfidoApplicantNameField.optional(), last_name: onfidoApplicantNameField.optional(), date_of_birth: day.optional(), email: z.string().optional()}), z.object({provider: z.literal("se_bank_id"), personal_number: z.string().optional()}), z.object({provider: z.literal("dk_mit_id"), personal_number: mitIDCPR.optional(), company_number: z.string().optional(), language: mitIdLanguage.optional(), employee_login: z.boolean().optional()}), z.object({provider: z.literal("no_bank_id"), personal_number: z.string().optional(), mobile_number: z.string().optional(), allow_substantial_level: z.boolean().optional(), ui_locale: nOUiLocale.optional()}), z.object({provider: z.literal("ftn"), force_bank: tupasBank.optional(), ui_locale: uiLocale.optional(), personal_number: fIPersonalNumber.optional()})]); export const sEPersonalNumber = z.string(); export const nOPersonalNumber = z.string(); export const signParameters = z.union([z.object({provider: z.literal("sms_otp"), attempts_per_sms: z.number().int().gte(1).lte(5).optional(), mobile_number: z.string().optional()}), z.object({provider: z.literal("se_bank_id"), personal_number: sEPersonalNumber.optional()}), z.object({provider: z.literal("dk_mit_id"), personal_number: mitIDCPR.optional(), company_number: z.string().optional(), language: mitIdLanguage.optional(), employee_login: z.boolean().optional()}), z.object({provider: z.literal("no_bank_id"), personal_number: nOPersonalNumber.optional(), mobile_number: z.string().optional(), ui_locale: nOUiLocale.optional()}), z.object({provider: z.literal("onfido"), report: onfidoReport.optional(), allowed_document_countries: z.array(onfidoCountry).optional(), allowed_document_types: z.array(onfidoDocumentType).optional(), force_cross_device: z.boolean().optional(), additional_report_info: onfidoAdditionalReportInfo.optional(), first_name: onfidoApplicantNameField.optional(), last_name: onfidoApplicantNameField.optional(), date_of_birth: day.optional(), email: z.string().optional()}), z.object({provider: z.literal("ftn"), force_bank: tupasBank.optional(), ui_locale: uiLocale.optional(), personal_number: fIPersonalNumber.optional()})]); export const participantAuthentication = z.union([z.object({type: z.literal("standard"), label: deprecatedAuthId.optional(), max_attempts_reached: z.boolean(), parameters: standardParameters}), z.object({type: z.literal("sign"), label: deprecatedAuthId.optional(), max_attempts_reached: z.boolean(), parameters: signParameters})]); export const reminderDeliveryMethod = z.enum(["email", "sms", "email_and_sms"]); export const participantReminderSettings = z.object({date: reminderDate, method: reminderDeliveryMethod}); export const automaticReminderDetail = z.object({date: z.string().optional(), settings: participantReminderSettings.optional()}); export const getParticipant = z.object({participant_id: z.string(), dsl_name: userName, tags: z.array(getParticipantTag), authentications: z.array(participantAuthentication), automatic_reminder: automaticReminderDetail, latest_reminder: z.string().optional()}); export const status = z.enum(["in_progress", "finalising", "canceled", "rejected", "completed", "failed", "timed_out"]); export const uTCTime = z.string(); export const callbackUrl = z.string(); export const flowCallbackAuthType = z.enum(["none", "basic"]); export const callbackVersion = z.literal("v1"); export const getCallback = z.object({url: callbackUrl, auth_type: flowCallbackAuthType, version: callbackVersion}); export const folderID = z.string(); export const initiator = z.enum(["flow_api", "id_check", "journey_service"]); export const getInstance = z.object({id: z.string(), title: z.string().optional(), process: flowDSL, process_parameters: processParameters, state: instanceState, access_links: z.record(z.string(), url), admin_actions: z.array(adminApiAction), participants: z.array(getParticipant), status: status, started: uTCTime, finished: uTCTime.optional(), last_event: uTCTime, trashed: uTCTime.optional(), callback: getCallback.optional(), author_id: userID, folder_id: folderID, timeout: z.string().optional(), documents: z.array(documentID), initiator: initiator, latest_reminder: z.string().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Get a Flow instance * * GET /experimental/flow/instances/{instance_id} * * Also accepts auth: OAuth2.0, SessionCookie + XToken */ export const getApiExperimentalFlowInstancesInstanceId = async (args: GetApiExperimentalFlowInstancesInstanceIdArgs, options?: GetApiExperimentalFlowInstancesInstanceIdOptions) => { const {baseUrl = "https://scrive.com", fetch: fetchFn = fetch, OAuth10} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json;charset=utf-8") if (OAuth10 !== undefined) headers.set('authorization', `oauth1 ${OAuth10}`) const url = `${baseUrl.replace(/\/+$/, '')}/experimental/flow/instances/${encodeURIComponent(String(args.instance_id))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(getInstance, await res.json()) };