import {z} from 'zod' export type EnumGenres = 'bluegrass' | 'blues' | 'christian' | 'classical' | 'country-music' | 'edm' | 'folk' | 'hip-hop-rap' | 'indie' | 'jamband' | 'jazz' | 'kpop' | 'latin' | 'metal' | 'pop' | 'punk' | 'reggae' | 'rhythm-and-blues-soul' | 'rock' | 'tribute'; export type GetApiArtistsArgs = {page?: number | undefined, perPage?: number | undefined, artistId?: string | undefined, artistName?: string | undefined, genreSlug?: EnumGenres | undefined, artistHasUpcomingEvents?: boolean | undefined, dateModifiedFrom?: unknown | undefined, datePublishedFrom?: unknown | undefined, expandExternalIdentifiers?: boolean | undefined, expandArtistSameAs?: boolean | undefined}; export type GetApiArtistsOptions = {baseUrl?: string | undefined, BearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const success = z.boolean(); export const pagination = z.object({page: z.number().int().gte(0).optional(), perPage: z.number().int().gte(1).optional(), totalItems: z.number().int().gte(0).optional(), totalPages: z.number().int().gte(0).optional(), nextPage: z.string().optional(), previousPage: z.string().optional()}); export const enumUrlType = z.enum(["officialSite", "facebook", "twitter", "instagram", "youtube", "musicbrainz", "spotify", "androidApp", "iosApp"]); export const uRL = z.object({"@type": z.literal("URL").optional(), identifier: enumUrlType.optional(), url: z.string().optional()}); export const propDeletionStatus = z.enum(["deleted", "trashed", "merged"]); export const propDeletedAt = z.string(); export const propMergedInto = z.string(); export const enumGenres = z.enum(["bluegrass", "blues", "christian", "classical", "country-music", "edm", "folk", "hip-hop-rap", "indie", "jamband", "jazz", "kpop", "latin", "metal", "pop", "punk", "reggae", "rhythm-and-blues-soul", "rock", "tribute"]); export const enumEventStatus = z.enum(["scheduled", "postponed", "rescheduled", "cancelled"]); export const enumState = z.enum(["US-AL", "US-AK", "US-AZ", "US-AR", "US-CA", "US-CO", "US-CT", "US-DE", "US-FL", "US-GA", "US-HI", "US-ID", "US-IL", "US-IN", "US-IA", "US-KS", "US-KY", "US-LA", "US-ME", "US-MD", "US-MA", "US-MI", "US-MN", "US-MS", "US-MO", "US-MT", "US-NE", "US-NV", "US-NH", "US-NJ", "US-NM", "US-NY", "US-NC", "US-ND", "US-OH", "US-OK", "US-OR", "US-PA", "US-RI", "US-SC", "US-SD", "US-TN", "US-TX", "US-UT", "US-VT", "US-VA", "US-WA", "US-WV", "US-WI", "US-WY", "US-DC", "US-AS", "US-GU", "US-MP", "US-PR", "US-UM", "US-VI", "AU-ACT", "AU-NSW", "AU-NT", "AU-QLD", "AU-SA", "AU-TAS", "AU-VIC", "AU-WA", "CA-AB", "CA-BC", "CA-MB", "CA-NB", "CA-NL", "CA-NS", "CA-NT", "CA-NU", "CA-ON", "CA-PE", "CA-QC", "CA-SK", "CA-YT"]); export const enumCountryIso2 = z.enum(["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BR", "BS", "BT", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "US", "UY", "UZ", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "XD", "XG", "XK", "XP", "XR", "XS", "XW", "YE", "YT", "ZA", "ZM", "ZW"]); export const enumCountryIso3 = z.enum(["ABW", "AFG", "AGO", "AIA", "ALB", "AND", "ARE", "ARG", "ARM", "ASM", "ATF", "ATG", "AUS", "AZE", "BDI", "BEL", "BEN", "BFA", "BGD", "BGR", "BHR", "BHS", "BIH", "BLM", "BLR", "BLZ", "BMU", "BOL", "BRA", "BRB", "BRN", "BTN", "BWA", "CAF", "CAN", "CCK", "CHE", "CHL", "CHN", "CIV", "CMR", "COD", "COG", "COK", "COL", "COM", "CPV", "CRI", "CUB", "CUW", "CXR", "CYM", "CYP", "CZE", "DEU", "DJI", "DMA", "DNK", "DOM", "DZA", "ECU", "EGY", "ERI", "ESH", "ESP", "EST", "ETH", "FIN", "FJI", "FLK", "FRA", "FRO", "FSM", "GAB", "GBR", "GEO", "GGY", "GHA", "GIB", "GIN", "GLP", "GMB", "GNB", "GNQ", "GRC", "GRD", "GRL", "GTM", "GUF", "GUM", "GUY", "HKG", "HND", "HRV", "HTI", "HUN", "IDN", "IMN", "IND", "IOT", "IRL", "IRN", "IRQ", "ISL", "ISR", "ITA", "JAM", "JEY", "JOR", "JPN", "KAZ", "KEN", "KGZ", "KHM", "KIR", "KNA", "KOR", "KWT", "LAO", "LBN", "LBR", "LBY", "LCA", "LIE", "LKA", "LSO", "LTU", "LUX", "LVA", "MAC", "MAF", "MAR", "MCO", "MDA", "MDG", "MDV", "MEX", "MHL", "MKD", "MLI", "MLT", "MMR", "MNE", "MNG", "MNP", "MOZ", "MRT", "MSR", "MTQ", "MUS", "MWI", "MYS", "MYT", "NAM", "NCL", "NER", "NFK", "NGA", "NIC", "NIU", "NLD", "NOR", "NPL", "NRU", "NZL", "OMN", "PAK", "PAN", "PCN", "PER", "PHL", "PLW", "PNG", "POL", "PRI", "PRK", "PRT", "PRY", "PYF", "QAT", "REU", "ROU", "RUS", "RWA", "SAU", "SDN", "SEN", "SGP", "SGS", "SHN", "SLB", "SLE", "SLV", "SMR", "SOM", "SPM", "SRB", "SSD", "STP", "SUR", "SVK", "SVN", "SWE", "SWZ", "SXM", "SYC", "SYR", "TCA", "TCD", "TGO", "THA", "TJK", "TKL", "TKM", "TLS", "TON", "TTO", "TUN", "TUR", "TUV", "TWN", "TZA", "UGA", "UKR", "URY", "USA", "UZB", "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", "WLF", "WSM", "XGZ", "XKS", "XPR", "XQZ", "XSP", "XSV", "XWB", "XXD", "YEM", "ZAF", "ZMB", "ZWE"]); export const country = z.object({"@type": z.literal("Country").optional(), identifier: enumCountryIso2.optional(), name: z.string().optional(), alternateName: enumCountryIso3.optional(), "x-numUpcomingEvents": z.number().optional()}); export const state = z.object({"@type": z.literal("State").optional(), identifier: enumState.optional(), name: z.string().optional(), alternateName: z.string().optional(), country: country.optional(), "x-numUpcomingEvents": z.number().optional()}); export const postalAddress = z.object({"@type": z.literal("PostalAddress").optional(), streetAddress: z.string().optional(), addressLocality: z.string().optional(), postalCode: z.string().optional(), addressRegion: state.optional(), addressCountry: country.optional(), "x-streetAddress2": z.string().optional(), "x-timezone": z.string().optional(), "x-jamBaseMetroId": z.number().optional(), "x-jamBaseCityId": z.number().optional()}); export const propLatitude = z.number().gte(-90).lte(90); export const propLongitude = z.number().gte(-180).lte(180); export const geoCoordinates = z.object({"@type": z.literal("GeoCoordinates").optional(), latitude: propLatitude.optional(), longitude: propLongitude.optional()}); export const priceSpecification = z.object({"@type": z.literal("PriceSpecification").optional(), minPrice: z.number().optional(), maxPrice: z.number().optional(), price: z.number(), priceCurrency: z.string()}); export const organization = z.object({"@type": z.literal("Organization").optional(), identifier: z.string(), disambiguatingDescription: z.string(), name: z.string(), url: z.string().optional(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string(), dateModified: z.string()}); export const offer = z.object({name: z.string().optional(), identifier: z.string(), url: z.string(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), category: z.string(), priceSpecification: priceSpecification.optional(), seller: organization, validFrom: z.string()}); export const enumAttendanceMode = z.enum(["mixed", "offline", "online"]); export const stream: z.ZodType = z.object({name: z.string(), identifier: z.string(), url: z.string(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), eventStatus: enumEventStatus, startDate: z.string(), endDate: z.string().optional(), previousStartDate: z.string().optional(), doorTime: z.string().optional(), location: z.lazy(() => musicVenue), offers: z.array(offer).optional(), performer: z.array(z.object({name: z.string().optional(), identifier: z.string().optional(), url: z.string().optional(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), "@type": z.literal("MusicGroup").optional(), deletionStatus: propDeletionStatus.optional(), deletedAt: propDeletedAt.optional(), mergedInto: propMergedInto.optional(), member: z.array(z.object({type: z.literal("MusicGroup").optional(), name: z.string().optional(), identifier: z.string().optional(), image: z.string().optional(), url: z.string().optional()})).optional(), memberOf: z.array(z.object({"@type": z.literal("MusicGroup").optional(), name: z.string().optional(), identifier: z.string().optional(), image: z.string().optional(), url: z.string().optional()})).optional(), foundingLocation: z.object({"@type": z.literal("Place").optional(), name: z.string().optional()}).optional(), foundingDate: z.string().optional(), genre: z.array(enumGenres).optional(), events: z.array(z.union([z.lazy(() => concert), z.lazy(() => festival), z.lazy(() => stream)])).optional(), "x-bandOrMusician": z.enum(["band", "musician"]).optional(), "x-numUpcomingEvents": z.number().optional(), "x-externalIdentifiers": z.array(z.unknown()).optional(), "x-performanceDate": z.string().optional(), "x-performanceRank": z.number().optional(), "x-isHeadliner": z.boolean().optional(), "x-dateIsConfirmed": z.boolean().optional()})), eventAttendanceMode: enumAttendanceMode.optional(), isAccessibleForFree: z.boolean().optional(), "x-promoImage": z.string().optional(), "@type": z.literal("Stream"), deletionStatus: propDeletionStatus.optional(), deletedAt: propDeletedAt.optional(), mergedInto: propMergedInto.optional(), isLiveBroadcast: z.boolean().optional(), broadcastOfEvent: z.array(z.union([z.lazy(() => concert), z.lazy(() => festival)])).optional(), "x-customTitle": z.string().optional()}); export const enumFestivalLineupDisplayOption = z.enum(["full", "daybyday"]); export const festival: z.ZodType = z.object({name: z.string(), identifier: z.string(), url: z.string(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), eventStatus: enumEventStatus, startDate: z.string(), endDate: z.string(), previousStartDate: z.string().optional(), doorTime: z.string().optional(), location: z.lazy(() => musicVenue), offers: z.array(offer).optional(), performer: z.array(z.object({name: z.string().optional(), identifier: z.string().optional(), url: z.string().optional(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), "@type": z.literal("MusicGroup").optional(), deletionStatus: propDeletionStatus.optional(), deletedAt: propDeletedAt.optional(), mergedInto: propMergedInto.optional(), member: z.array(z.object({type: z.literal("MusicGroup").optional(), name: z.string().optional(), identifier: z.string().optional(), image: z.string().optional(), url: z.string().optional()})).optional(), memberOf: z.array(z.object({"@type": z.literal("MusicGroup").optional(), name: z.string().optional(), identifier: z.string().optional(), image: z.string().optional(), url: z.string().optional()})).optional(), foundingLocation: z.object({"@type": z.literal("Place").optional(), name: z.string().optional()}).optional(), foundingDate: z.string().optional(), genre: z.array(enumGenres).optional(), events: z.array(z.union([z.lazy(() => concert), z.lazy(() => festival), stream])).optional(), "x-bandOrMusician": z.enum(["band", "musician"]).optional(), "x-numUpcomingEvents": z.number().optional(), "x-externalIdentifiers": z.array(z.unknown()).optional(), "x-performanceDate": z.string().optional(), "x-performanceRank": z.number().optional(), "x-isHeadliner": z.boolean().optional(), "x-dateIsConfirmed": z.boolean().optional()})), eventAttendanceMode: enumAttendanceMode.optional(), isAccessibleForFree: z.boolean().optional(), "x-promoImage": z.string().optional(), "@type": z.literal("Festival"), deletionStatus: propDeletionStatus.optional(), deletedAt: propDeletedAt.optional(), mergedInto: propMergedInto.optional(), "x-lineupDisplayOption": enumFestivalLineupDisplayOption}); export const musicVenue: z.ZodType = z.object({name: z.string().optional(), identifier: z.string().optional(), url: z.string().optional(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), deletionStatus: propDeletionStatus.optional(), deletedAt: propDeletedAt.optional(), mergedInto: propMergedInto.optional(), maximumAttendeeCapacity: z.number().optional(), address: postalAddress.optional(), geo: geoCoordinates.optional(), events: z.array(z.union([z.lazy(() => concert), festival])).optional(), "x-isPermanentlyClosed": z.boolean().optional(), "x-numUpcomingEvents": z.number().optional(), "x-externalIdentifiers": z.array(z.unknown()).optional()}); export const concert: z.ZodType = z.object({name: z.string(), identifier: z.string(), url: z.string(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), eventStatus: enumEventStatus, startDate: z.string(), endDate: z.string().optional(), previousStartDate: z.string().optional(), doorTime: z.string().optional(), location: musicVenue, offers: z.array(offer).optional(), performer: z.array(z.object({name: z.string().optional(), identifier: z.string().optional(), url: z.string().optional(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), "@type": z.literal("MusicGroup").optional(), deletionStatus: propDeletionStatus.optional(), deletedAt: propDeletedAt.optional(), mergedInto: propMergedInto.optional(), member: z.array(z.object({type: z.literal("MusicGroup").optional(), name: z.string().optional(), identifier: z.string().optional(), image: z.string().optional(), url: z.string().optional()})).optional(), memberOf: z.array(z.object({"@type": z.literal("MusicGroup").optional(), name: z.string().optional(), identifier: z.string().optional(), image: z.string().optional(), url: z.string().optional()})).optional(), foundingLocation: z.object({"@type": z.literal("Place").optional(), name: z.string().optional()}).optional(), foundingDate: z.string().optional(), genre: z.array(enumGenres).optional(), events: z.array(z.union([z.lazy(() => concert), festival, stream])).optional(), "x-bandOrMusician": z.enum(["band", "musician"]).optional(), "x-numUpcomingEvents": z.number().optional(), "x-externalIdentifiers": z.array(z.unknown()).optional(), "x-performanceDate": z.string().optional(), "x-performanceRank": z.number().optional(), "x-isHeadliner": z.boolean().optional(), "x-dateIsConfirmed": z.boolean().optional()})), eventAttendanceMode: enumAttendanceMode.optional(), isAccessibleForFree: z.boolean().optional(), "x-promoImage": z.string().optional(), "@type": z.literal("Concert"), deletionStatus: propDeletionStatus.optional(), deletedAt: propDeletedAt.optional(), mergedInto: propMergedInto.optional(), "x-externalIdentifiers": z.array(z.unknown()).optional(), "x-customTitle": z.string().optional(), "x-subtitle": z.string().optional(), "x-headlinerInSupport": z.boolean().optional(), "x-streamIds": z.array(z.string()).optional()}); export const musicGroup = z.object({name: z.string().optional(), identifier: z.string().optional(), url: z.string().optional(), image: z.string().optional(), sameAs: z.array(uRL).optional(), datePublished: z.string().optional(), dateModified: z.string().optional(), "@type": z.literal("MusicGroup").optional(), deletionStatus: propDeletionStatus.optional(), deletedAt: propDeletedAt.optional(), mergedInto: propMergedInto.optional(), member: z.array(z.object({type: z.literal("MusicGroup").optional(), name: z.string().optional(), identifier: z.string().optional(), image: z.string().optional(), url: z.string().optional()})).optional(), memberOf: z.array(z.object({"@type": z.literal("MusicGroup").optional(), name: z.string().optional(), identifier: z.string().optional(), image: z.string().optional(), url: z.string().optional()})).optional(), foundingLocation: z.object({"@type": z.literal("Place").optional(), name: z.string().optional()}).optional(), foundingDate: z.string().optional(), genre: z.array(enumGenres).optional(), events: z.array(z.union([concert, festival, stream])).optional(), "x-bandOrMusician": z.enum(["band", "musician"]).optional(), "x-numUpcomingEvents": z.number().optional(), "x-externalIdentifiers": z.array(z.unknown()).optional()}); export const request = z.object({endpoint: z.string().optional(), method: z.string().optional(), params: z.array(z.unknown()).optional(), ip: z.union([z.string(), z.string()]).optional(), userAgent: z.string().optional()}); export const getApiArtistsResponse = z.object({success: success.optional(), pagination: pagination.optional(), artists: z.array(musicGroup).optional(), request: request.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 }; /** * Search Artists * * GET /artists */ export const getApiArtists = async (args: GetApiArtistsArgs, options?: GetApiArtistsOptions) => { const {baseUrl = "https://api.data.jambase.com/v3", fetch: fetchFn = fetch, BearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.page != null) query.append("page", String(args.page)) if (args.perPage != null) query.append("perPage", String(args.perPage)) if (args.artistId != null) query.append("artistId", String(args.artistId)) if (args.artistName != null) query.append("artistName", String(args.artistName)) if (args.genreSlug != null) query.append("genreSlug", String(args.genreSlug)) if (args.artistHasUpcomingEvents != null) query.append("artistHasUpcomingEvents", String(args.artistHasUpcomingEvents)) if (args.dateModifiedFrom != null) query.append("dateModifiedFrom", String(args.dateModifiedFrom)) if (args.datePublishedFrom != null) query.append("datePublishedFrom", String(args.datePublishedFrom)) if (args.expandExternalIdentifiers != null) query.append("expandExternalIdentifiers", String(args.expandExternalIdentifiers)) if (args.expandArtistSameAs != null) query.append("expandArtistSameAs", String(args.expandArtistSameAs)) if (BearerAuth !== undefined) headers.set('authorization', `Bearer ${BearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/artists${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(getApiArtistsResponse, await res.json()) };