import {z} from 'zod' export type DesignStandard = 'Generic' | 'Navigatr'; export type BadgeType = 'Experience' | 'Learning' | 'Validation' | 'Certification' | 'Attendance' | 'Work_Experience' | 'Volunteering' | 'Job' | 'Apprenticeship' | 'Course' | 'Internship' | 'Workshop' | 'Campaigning' | 'Activism' | 'Other' | 'Informal_Learning' | 'Training' | 'Certified' | 'Qualification' | 'Membership'; export type Language = 'Arabic_Modern_Standard' | 'Bengali' | 'Bulgarian' | 'Chinese_Cantonese' | 'Chinese_Mandarin' | 'Chinese_Simplified' | 'Chinese_Traditional' | 'Croatian' | 'Czech' | 'Dutch' | 'English' | 'French' | 'German' | 'Greek' | 'Hungarian' | 'Irish_Gaeilge' | 'Italian' | 'Kurdish_Kurmanji' | 'Kurdish_Sorani' | 'Latvian' | 'Lithuanian' | 'Pashto' | 'Persian' | 'Polish' | 'Portuguese' | 'Punjabi' | 'Romanian' | 'Scottish_Gaelic_Gaidhlig' | 'Slovak' | 'Somali' | 'Spanish' | 'Tigrinya' | 'Turkish' | 'Ukrainian' | 'Urdu' | 'Welsh_Cymraeg'; export type RecipientType = 'User' | 'Organisation'; export type SourceType = 'Internal' | 'Credly' | 'Open_University' | 'Imported'; export type BadgeCost = 'Free' | 'Paid' | 'Other'; export type BadgeLevel = 'Foundational' | 'Intermediate' | 'Advanced' | 'Other' | 'Explore' | 'Deepen' | 'Apply' | 'Teach' | 'Lead'; export type TimeToEarn = 'Hours' | 'Days' | 'Weeks' | 'Months' | 'Years' | 'Other'; export type ParticipationType = 'Online' | 'Hybrid' | 'In_Person'; export type QualificationType = 'Award' | 'Certificate' | 'Diploma'; export type QualificationFramework = 'RQF' | 'CQFW' | 'SCQF' | 'EQF' | 'QFEmirates'; export type BadgeGrade = 'Pass' | 'Merit' | 'Distinction' | 'Distinction*'; export type BadgeCriteriaType = 'Application' | 'Assessment' | 'Award' | 'Badge' | 'Course' | 'Credential' | 'Education_Experience' | 'Leadership' | 'Member' | 'Participant' | 'Pathway' | 'Payment' | 'Portfolio' | 'Presenter' | 'Project' | 'Professional_Experience' | 'Schedule_Registration' | 'Volunteer' | 'Other'; export type BadgeCriteriaCreate = {external_id?: (string | null) | undefined, description: string, type: BadgeCriteriaType, external_url?: (string | null) | undefined, badge_id?: (number | null) | undefined}; export type BadgeAlignmentCreate = {external_id?: (string | null) | undefined, name: string, description: string, url: string, framework?: (string | null) | undefined, code?: (string | null) | undefined}; export type BadgeEndorsementCreate = {external_id?: (string | null) | undefined, name: string, description: string, url?: (string | null) | undefined, image_url?: (string | null) | undefined, image_url_2x?: (string | null) | undefined, image_url_original?: (string | null) | undefined}; export type BadgeTagCreate = {name: string, external_id?: (string | null) | undefined, type?: (string | null) | undefined, source?: (string | null) | undefined}; export type BadgeCreate = {name: string, design_standard?: (DesignStandard | null) | undefined, type: BadgeType, language?: Language | undefined, provider_ids?: (Array | null) | undefined, community_ids?: (Array | null) | undefined, recipient_type?: RecipientType | undefined, description: string, issuer_id?: (number | null) | undefined, image_url?: (string | null) | undefined, image_url_2x?: (string | null) | undefined, image_url_original?: (string | null) | undefined, design_parameters: unknown, source?: (SourceType | null) | undefined, earn_url?: (string | null) | undefined, external_url?: (string | null) | undefined, information_url?: (string | null) | undefined, embed?: (string | null) | undefined, external_id?: (string | null) | undefined, latitude?: (number | null) | undefined, longitude?: (number | null) | undefined, city?: (string | null) | undefined, country?: (string | null) | undefined, config: unknown, address?: (string | null) | undefined, available_to_all?: boolean | undefined, availability?: (string | null) | undefined, end_date?: (string | null) | undefined, cost?: (BadgeCost | null) | undefined, level?: (BadgeLevel | null) | undefined, time_to_earn?: (TimeToEarn | null) | undefined, participation_type?: ParticipationType | undefined, qa_locked?: (boolean | null) | undefined, job_titles?: (Array | null) | undefined, specialized_occupations?: (Array | null) | undefined, title_names?: (Array | null) | undefined, is_demo?: (boolean | null) | undefined, certificates_enabled?: boolean | undefined, industries?: (Array | null) | undefined, occupation_groups?: (Array | null) | undefined, skill_category_names?: (Array | null) | undefined, edu_levels?: (Array | null) | undefined, qualification_code?: (string | null) | undefined, credits_available?: (number | null) | undefined, credits_unit?: (string | null) | undefined, qualification_type?: (QualificationType | null) | undefined, qualification_framework?: (QualificationFramework | null) | undefined, qualification_level?: (string | null) | undefined, grade?: (BadgeGrade | null) | undefined, field_of_study_id?: (number | null) | undefined, featured?: boolean | undefined, ai_generated?: boolean | undefined, time_created?: string | undefined, criteria?: (Array | null) | undefined, alignments?: (Array | null) | undefined, endorsements?: (Array | null) | undefined, tags?: (Array | null) | undefined}; export type CreateApiV1BadgeArgs = {provider_id?: number | undefined, generate_image?: boolean | undefined, title?: (string | null) | undefined, subtitle?: (string | null) | undefined, 'X-Access-Token'?: (string | null) | undefined, body: BadgeCreate}; export type CreateApiV1BadgeOptions = {baseUrl: string, OAuth2PasswordBearer?: string | undefined, fetch?: typeof fetch | undefined}; export const designStandard = z.enum(["Generic", "Navigatr"]); export const badgeType = z.enum(["Experience", "Learning", "Validation", "Certification", "Attendance", "Work_Experience", "Volunteering", "Job", "Apprenticeship", "Course", "Internship", "Workshop", "Campaigning", "Activism", "Other", "Informal_Learning", "Training", "Certified", "Qualification", "Membership"]); export const language = z.enum(["Arabic_Modern_Standard", "Bengali", "Bulgarian", "Chinese_Cantonese", "Chinese_Mandarin", "Chinese_Simplified", "Chinese_Traditional", "Croatian", "Czech", "Dutch", "English", "French", "German", "Greek", "Hungarian", "Irish_Gaeilge", "Italian", "Kurdish_Kurmanji", "Kurdish_Sorani", "Latvian", "Lithuanian", "Pashto", "Persian", "Polish", "Portuguese", "Punjabi", "Romanian", "Scottish_Gaelic_Gaidhlig", "Slovak", "Somali", "Spanish", "Tigrinya", "Turkish", "Ukrainian", "Urdu", "Welsh_Cymraeg"]); export const recipientType = z.enum(["User", "Organisation"]); export const sourceType = z.enum(["Internal", "Credly", "Open_University", "Imported"]); export const badgeCost = z.enum(["Free", "Paid", "Other"]); export const badgeLevel = z.enum(["Foundational", "Intermediate", "Advanced", "Other", "Explore", "Deepen", "Apply", "Teach", "Lead"]); export const timeToEarn = z.enum(["Hours", "Days", "Weeks", "Months", "Years", "Other"]); export const participationType = z.enum(["Online", "Hybrid", "In_Person"]); export const qualificationType = z.enum(["Award", "Certificate", "Diploma"]); export const qualificationFramework = z.enum(["RQF", "CQFW", "SCQF", "EQF", "QFEmirates"]); export const badgeGrade = z.enum(["Pass", "Merit", "Distinction", "Distinction*"]); export const badgeStatus = z.enum(["Initialising", "Draft", "Awaiting_Approval", "Published", "Deleted", "Expired"]); export const userVisibility = z.enum(["Public", "Private"]); export const userDetailPublic = z.object({id: z.number().int().optional(), firstname: z.string().nullable(), lastname: z.string().nullable(), avatar_url: z.string().nullable().optional(), avatar_url_2x: z.string().nullable().optional(), avatar_url_original: z.string().nullable().optional(), interests: z.array(z.string()).nullable().optional(), noindex_enabled: z.boolean().nullable().optional(), visibility: userVisibility.optional(), time_created: z.string().optional(), time_updated: z.string().nullable().optional(), seo_keywords: z.array(z.string()).nullable().optional(), seo_title: z.string().nullable().optional(), seo_description: z.string().nullable().optional(), social_handle_linkedin: z.string().nullable().optional(), social_handle_twitter: z.string().nullable().optional(), social_handle_facebook: z.string().nullable().optional(), social_handle_instagram: z.string().nullable().optional()}); export const badgeIssuerType = z.enum(["Employer", "Learning_Provider", "Other"]); export const badgeIssuerStatus = z.enum(["Active", "Suspended", "Deleted"]); export const badgeIssuerPublic = z.object({id: z.number().int().optional(), name: z.string().nullable().optional(), type: badgeIssuerType.nullable().optional(), status: badgeIssuerStatus.optional(), external_url: z.string().nullable().optional(), email: z.string().nullable().optional(), image_url: z.string().nullable().optional(), banner_url: z.string().nullable().optional(), image_url_2x: z.string().nullable().optional(), banner_url_2x: z.string().nullable().optional()}); export const address = z.object({full_address: z.string().nullable().optional(), name: z.string().nullable().optional(), number: z.string().nullable().optional(), street: z.string().nullable().optional(), postcode: z.string().nullable().optional(), locality: z.string().nullable().optional(), city: z.string().nullable().optional(), district: z.string().nullable().optional(), region: z.string().nullable().optional(), country: z.string().nullable().optional()}); export const badgeCriteriaType = z.enum(["Application", "Assessment", "Award", "Badge", "Course", "Credential", "Education_Experience", "Leadership", "Member", "Participant", "Pathway", "Payment", "Portfolio", "Presenter", "Project", "Professional_Experience", "Schedule_Registration", "Volunteer", "Other"]); export const badgeCriteria = z.object({external_id: z.string().nullable().optional(), description: z.string().nullable().optional(), type: badgeCriteriaType.nullable().optional(), external_url: z.string().nullable().optional(), badge_id: z.number().int().nullable().optional(), id: z.number().int().nullable().optional()}); export const badgeTag = z.object({name: z.string().nullable().optional(), external_id: z.string().nullable().optional(), type: z.string().nullable().optional(), source: z.string().nullable().optional()}); export const badgeAlignment = z.object({external_id: z.string().nullable().optional(), name: z.string().nullable().optional(), description: z.string().nullable().optional(), url: z.string().nullable().optional(), framework: z.string().nullable().optional(), code: z.string().nullable().optional(), id: z.number().int().nullable().optional(), badge_id: z.number().int().nullable().optional()}); export const badgeEndorsement = z.object({external_id: z.string().nullable().optional(), name: z.string().nullable().optional(), description: z.string().nullable().optional(), url: z.string().nullable().optional(), image_url: z.string().nullable().optional(), image_url_2x: z.string().nullable().optional(), image_url_original: z.string().nullable().optional(), id: z.number().int().nullable().optional(), badge_id: z.number().int().nullable().optional()}); export const collectionLight = z.object({id: z.number().int(), name: z.string().nullable().optional(), badge_issuer_id: z.number().int().nullable().optional()}); export const providerStatus = z.enum(["Active", "Suspended", "Deleted"]); export const providerType = z.enum(["Learning_Provider", "Training_Provider", "Awarding_Body", "Employer", "Local_Authority", "University", "College", "Charity", "Department", "Project", "Other"]); export const communityStatus = z.enum(["Active", "Suspended", "Deleted"]); export const communityType = z.enum(["City", "Region", "Local_Authority", "Membership_Organisation", "Awarding_Body", "Partnership", "Corporate", "Association", "University", "College", "Charity", "Other"]); export const communityLight = z.object({id: z.number().int(), status: communityStatus.optional(), type: communityType.nullable().optional(), name: z.string().nullable().optional(), short_name: z.string().max(12).nullable().optional(), is_verified: z.boolean().nullable().optional(), image_url: z.string().nullable().optional(), image_url_2x: z.string().nullable().optional(), image_url_original: z.string().nullable().optional(), linkedin_organisation_id: z.number().int().nullable().optional(), social_handle_linkedin: z.string().nullable().optional(), social_handle_twitter: z.string().nullable().optional(), social_handle_facebook: z.string().nullable().optional(), social_handle_instagram: z.string().nullable().optional(), url: z.string().nullable().optional()}); export const providerLight = z.object({id: z.number().int(), status: providerStatus.optional(), type: providerType.nullable().optional(), name: z.string().nullable().optional(), short_name: z.string().max(12).nullable().optional(), external_url: z.string().nullable().optional(), is_verified: z.boolean().nullable().optional(), verification_text: z.string().nullable().optional(), verification_url: z.string().nullable().optional(), is_demo: z.boolean().nullable().optional(), open_access: z.boolean().optional(), community_id: z.number().int().nullable().optional(), community: communityLight.nullable(), image_url: z.string().nullable().optional(), banner_url: z.string().nullable().optional(), image_url_2x: z.string().nullable().optional(), banner_url_2x: z.string().nullable().optional(), image_url_original: z.string().nullable().optional(), banner_url_original: z.string().nullable().optional(), qa_community_id: z.number().int().nullable().optional(), linkedin_organisation_id: z.number().int().nullable().optional(), social_handle_linkedin: z.string().nullable().optional(), social_handle_twitter: z.string().nullable().optional(), social_handle_facebook: z.string().nullable().optional(), social_handle_instagram: z.string().nullable().optional(), url: z.string().nullable().optional()}); export const sectorSubjectAreaEmbedded = z.object({id: z.number().int(), code: z.string(), name: z.string(), tier_1_name: z.string().nullable().optional(), image_label: z.string().nullable().optional()}); export const badge = z.object({name: z.string().nullable().optional(), design_standard: designStandard.nullable().optional(), type: badgeType.nullable().optional(), language: language.nullable().optional(), provider_ids: z.array(z.number().int()).nullable().optional(), community_ids: z.array(z.number().int()).nullable().optional(), recipient_type: recipientType.nullable().optional(), description: z.string().nullable().optional(), issuer_id: z.number().int().nullable().optional(), image_url: z.string().nullable().optional(), image_url_2x: z.string().nullable().optional(), image_url_original: z.string().nullable().optional(), design_parameters: z.unknown(), source: sourceType.nullable().optional(), earn_url: z.string().nullable().optional(), external_url: z.string().nullable().optional(), information_url: z.string().nullable().optional(), embed: z.string().nullable().optional(), external_id: z.string().nullable().optional(), latitude: z.number().nullable().optional(), longitude: z.number().nullable().optional(), city: z.string().nullable().optional(), country: z.string().nullable().optional(), config: z.unknown(), address: z.string().nullable().optional(), available_to_all: z.boolean().nullable().optional(), availability: z.string().nullable().optional(), end_date: z.string().nullable().optional(), cost: badgeCost.nullable().optional(), level: badgeLevel.nullable().optional(), time_to_earn: timeToEarn.nullable().optional(), participation_type: participationType.nullable().optional(), qa_locked: z.boolean().nullable().optional(), job_titles: z.array(z.string()).nullable().optional(), specialized_occupations: z.array(z.string()).nullable().optional(), title_names: z.array(z.string()).nullable().optional(), is_demo: z.boolean().nullable().optional(), certificates_enabled: z.boolean().optional(), industries: z.array(z.string()).nullable().optional(), occupation_groups: z.array(z.string()).nullable().optional(), skill_category_names: z.array(z.string()).nullable().optional(), edu_levels: z.array(z.string()).nullable().optional(), qualification_code: z.string().max(100).nullable().optional(), credits_available: z.number().gte(0).nullable().optional(), credits_unit: z.string().max(20).nullable().optional(), qualification_type: qualificationType.nullable().optional(), qualification_framework: qualificationFramework.nullable().optional(), qualification_level: z.string().max(50).nullable().optional(), grade: badgeGrade.nullable().optional(), field_of_study_id: z.number().int().nullable().optional(), id: z.number().int().optional(), status: badgeStatus.optional(), created_by: userDetailPublic.nullable().optional(), submitted_by: userDetailPublic.nullable().optional(), published_by: userDetailPublic.nullable().optional(), updated_by: userDetailPublic.nullable().optional(), issuer: badgeIssuerPublic.nullable().optional(), ranking: z.number().int().nullable().optional(), time_created: z.string().optional(), time_updated: z.string().nullable().optional(), time_submitted: z.string().nullable().optional(), time_published: z.string().nullable().optional(), quality_assured_at: z.string().nullable().optional(), time_issued: z.string().nullable().optional(), postal_address: address.nullable().optional(), created_by_id: z.number().int().nullable().optional(), submitted_by_id: z.number().int().nullable().optional(), published_by_id: z.number().int().nullable().optional(), updated_by_id: z.number().int().nullable().optional(), criteria: z.array(badgeCriteria).nullable().optional(), tags: z.array(badgeTag).nullable().optional(), alignments: z.array(badgeAlignment).nullable().optional(), endorsements: z.array(badgeEndorsement).nullable().optional(), collections: z.array(collectionLight).nullable().optional(), providers: z.array(providerLight).nullable().optional(), interacted_with: z.boolean().nullable().optional(), featured: z.boolean().optional(), ai_generated: z.boolean().optional(), url: z.string().optional(), seo_keywords: z.array(z.string()).nullable().optional(), seo_title: z.string().nullable().optional(), seo_description: z.string().nullable().optional(), field_of_study: sectorSubjectAreaEmbedded.nullable().optional(), display_level: z.string().nullable()}); 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 }; /** * Create Badge * * POST /v1/badge/ */ export const createApiV1Badge = async (args: CreateApiV1BadgeArgs, options: CreateApiV1BadgeOptions) => { const {baseUrl, fetch: fetchFn = fetch, OAuth2PasswordBearer} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args.provider_id != null) query.append("provider_id", String(args.provider_id)) if (args.generate_image != null) query.append("generate_image", String(args.generate_image)) if (args.title != null) query.append("title", String(args.title)) if (args.subtitle != null) query.append("subtitle", String(args.subtitle)) if (args['X-Access-Token'] != null) headers.set("X-Access-Token", String(args['X-Access-Token'])) if (OAuth2PasswordBearer !== undefined) headers.set('authorization', `Bearer ${OAuth2PasswordBearer}`) const url = `${baseUrl.replace(/\/+$/, '')}/v1/badge/${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(badge, await res.json()) };