import {z} from 'zod' export type GetApiV2ApplicationsApplicationIdCampaignsCampaignIdRulesetsRulesetIdArgs = {applicationId: number, campaignId: number, rulesetId: number}; export type GetApiV2ApplicationsApplicationIdCampaignsCampaignIdRulesetsRulesetIdOptions = {baseUrl?: string | undefined, managerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const groupBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["all", "atLeastOne", "none"]), blocks: z.array(z.lazy(() => block)), onFailure: z.array(z.lazy(() => block)).optional(), onError: z.record(z.string(), z.array(z.lazy(() => block))).optional()}); export const awardDiscountCartTarget = z.object({type: z.literal("cart")}); export const awardDiscountAllItemsTarget = z.object({type: z.literal("allItems"), prorated: z.boolean().optional()}); export const awardDiscountGlobalFilterTarget = z.object({type: z.literal("globalFilter"), name: z.string(), prorated: z.boolean().optional()}); export const awardDiscountSelectorTarget = z.object({type: z.literal("selector"), name: z.string(), prorated: z.boolean().optional()}); export const awardDiscountBundleItemByIndex = z.object({type: z.literal("byIndex"), value: z.number().int()}); export const awardDiscountBundleItemByAttribute = z.object({type: z.literal("byAttribute"), attribute: z.string(), direction: z.enum(["highest", "lowest"])}); export const awardDiscountBundleItem = z.discriminatedUnion("type", [awardDiscountBundleItemByIndex, awardDiscountBundleItemByAttribute]); export const awardDiscountBundleTarget = z.object({type: z.literal("bundle"), name: z.string(), item: awardDiscountBundleItem.optional(), prorated: z.boolean().optional()}); export const additionalCostReference = z.object({id: z.number().int(), name: z.string(), title: z.string().optional()}); export const awardDiscountAdditionalCostTarget = z.object({type: z.literal("additionalCost"), additionalCost: additionalCostReference, target: z.discriminatedUnion("type", [awardDiscountCartTarget, awardDiscountAllItemsTarget, awardDiscountGlobalFilterTarget, awardDiscountSelectorTarget])}); export const awardDiscountTarget = z.discriminatedUnion("type", [awardDiscountCartTarget, awardDiscountAllItemsTarget, awardDiscountGlobalFilterTarget, awardDiscountSelectorTarget, awardDiscountBundleTarget, awardDiscountAdditionalCostTarget]); export const awardDiscountBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), name: z.string(), value: z.union([z.number(), z.string()]), partial: z.boolean(), target: awardDiscountTarget}); export const passthroughBlock = z.object({id: z.string().optional(), type: z.literal("passthrough"), expression: z.array(z.unknown())}); export const showNotificationBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), notificationType: z.string(), title: z.string(), body: z.string(), onError: z.record(z.string(), z.array(z.lazy(() => block))).optional()}); export const awardItemBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), sku: z.string(), name: z.string(), quantity: z.string(), partial: z.boolean().optional(), onFailure: z.array(z.lazy(() => block)).optional(), onError: z.record(z.string(), z.array(z.lazy(() => block))).optional()}); export const giveawayPoolBlockReference = z.object({id: z.number().int(), name: z.string().optional()}); export const awardGiveawayBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), giveawayPool: giveawayPoolBlockReference, profile: z.enum(["Current", "Advocate"]), onError: z.record(z.string(), z.array(z.lazy(() => block))).optional()}); export const geoJSONPoint = z.object({type: z.literal("Point"), coordinates: z.array(z.number())}); export const geoJSONPolygon = z.object({type: z.literal("Polygon"), coordinates: z.array(z.array(z.array(z.number())))}); export const geoJSONMultiPolygon = z.object({type: z.literal("MultiPolygon"), coordinates: z.array(z.array(z.array(z.array(z.number()))))}); export const geoJSONGeometryCollection = z.object({type: z.literal("GeometryCollection"), geometries: z.array(z.lazy(() => geoJSONGeometry))}); export const geoJSONGeometry: z.ZodType = z.discriminatedUnion("type", [geoJSONPoint, geoJSONPolygon, geoJSONMultiPolygon, geoJSONGeometryCollection]); export const checkAttributeBlock = z.union([z.object({id: z.string().optional(), type: z.literal("checkAttribute"), tags: z.array(z.string()).optional(), operator: z.enum(["equals", "not(equals)", "lessThan", "lessThanOrEqual", "greaterThan", "greaterThanOrEqual", "contains", "not(contains)", "matchesRegexp", "startsWith", "endsWith", "oneOf", "not(oneOf)", "inCollection", "not(inCollection)", "after", "before"]), attribute: z.string(), value: z.unknown(), min: z.unknown(), max: z.unknown(), start: z.string().optional(), end: z.string().optional(), startInclusive: z.boolean().optional(), endInclusive: z.boolean().optional(), timezoneInsensitive: z.boolean().optional(), values: z.unknown(), count: z.unknown(), onFailure: z.array(z.lazy(() => block)).optional()}), z.object({id: z.string().optional(), type: z.literal("checkAttribute"), tags: z.array(z.string()).optional(), operator: z.literal("between"), attribute: z.string(), value: z.unknown(), min: z.unknown(), max: z.unknown(), start: z.string().optional(), end: z.string().optional(), startInclusive: z.boolean().optional(), endInclusive: z.boolean().optional(), timezoneInsensitive: z.boolean().optional(), values: z.unknown(), count: z.unknown(), onFailure: z.array(z.lazy(() => block)).optional()}), z.object({id: z.string().optional(), type: z.literal("checkAttribute"), tags: z.array(z.string()).optional(), operator: z.enum(["containsOneOf", "containsNoneOf", "containsAllOf"]), attribute: z.string(), value: z.unknown(), min: z.unknown(), max: z.unknown(), start: z.string().optional(), end: z.string().optional(), startInclusive: z.boolean().optional(), endInclusive: z.boolean().optional(), timezoneInsensitive: z.boolean().optional(), values: z.unknown(), count: z.unknown(), onFailure: z.array(z.lazy(() => block)).optional()}), z.object({id: z.string().optional(), type: z.literal("checkAttribute"), tags: z.array(z.string()).optional(), operator: z.enum(["containsAtLeast", "containsExactly"]), attribute: z.string(), value: z.unknown(), min: z.unknown(), max: z.unknown(), start: z.string().optional(), end: z.string().optional(), startInclusive: z.boolean().optional(), endInclusive: z.boolean().optional(), timezoneInsensitive: z.boolean().optional(), values: z.unknown(), count: z.unknown(), onFailure: z.array(z.lazy(() => block)).optional()}), z.object({id: z.string().optional(), type: z.literal("checkAttribute"), tags: z.array(z.string()).optional(), operator: z.enum(["empty", "not(empty)", "exists", "not(exists)", "isTrue", "isFalse"]), attribute: z.string(), value: z.unknown(), min: z.unknown(), max: z.unknown(), start: z.string().optional(), end: z.string().optional(), startInclusive: z.boolean().optional(), endInclusive: z.boolean().optional(), timezoneInsensitive: z.boolean().optional(), values: z.unknown(), count: z.unknown(), onFailure: z.array(z.lazy(() => block)).optional()}), z.object({id: z.string().optional(), type: z.literal("checkAttribute"), tags: z.array(z.string()).optional(), operator: z.enum(["within", "not(within)"]), attribute: z.string(), value: z.unknown(), min: z.unknown(), max: z.unknown(), start: z.string(), end: z.string(), startInclusive: z.boolean().optional(), endInclusive: z.boolean().optional(), timezoneInsensitive: z.boolean().optional(), values: z.unknown(), count: z.unknown(), onFailure: z.array(z.lazy(() => block)).optional()}), z.object({id: z.string().optional(), type: z.literal("checkAttribute"), tags: z.array(z.string()).optional(), operator: z.enum(["in", "not(in)"]), attribute: z.string(), value: z.unknown(), min: z.unknown(), max: z.unknown(), start: z.string().optional(), end: z.string().optional(), startInclusive: z.boolean().optional(), endInclusive: z.boolean().optional(), timezoneInsensitive: z.boolean().optional(), values: z.union([z.array(z.object({name: z.string().optional(), geometry: geoJSONGeometry})), z.string()]), count: z.unknown(), onFailure: z.array(z.lazy(() => block)).optional()})]); export const audienceBlockReference = z.object({id: z.number().int(), name: z.string().optional(), integration: z.string().optional(), integrationId: z.string().optional()}); export const checkAudienceBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["member", "not(member)", "justJoined", "justLeft"]), profile: z.enum(["Current", "Advocate"]).optional(), audience: audienceBlockReference, onFailure: z.array(z.lazy(() => block)).optional()}); export const checkLoyaltyBalanceBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["equals", "not(equals)", "lessThan", "lessThanOrEqual", "greaterThan", "greaterThanOrEqual"]), program: z.object({id: z.number().int(), name: z.string().optional(), title: z.string().optional()}), subledger: z.string(), balance: z.enum(["current", "pending", "negative", "tentativeCurrent"]), value: z.number(), onFailure: z.array(z.lazy(() => block)).optional()}); export const checkCouponBlock = z.object({id: z.string().optional(), type: z.literal("checkCoupon"), tags: z.array(z.string()).optional(), redeem: z.boolean(), onFailure: z.array(z.lazy(() => block)).optional()}); export const checkReferralBlock = z.object({id: z.string().optional(), type: z.literal("checkReferral"), tags: z.array(z.string()).optional(), redeem: z.boolean(), onFailure: z.array(z.lazy(() => block)).optional()}); export const updateAudienceMembershipBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["add", "remove"]), profile: z.enum(["Current", "Advocate"]), audience: audienceBlockReference}); export const achievementBlockReference = z.object({id: z.number().int(), title: z.string().optional(), name: z.string().optional(), target: z.number().optional()}); export const updateAchievementProgressBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.literal("increaseBy"), value: z.union([z.number(), z.string()]), achievement: achievementBlockReference}); export const attributeBlockReference = z.object({id: z.number().int(), entity: z.string(), name: z.string(), title: z.string().optional(), type: z.string().optional()}); export const updateAttributeValueBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["setTo", "increaseBy", "decreaseBy", "multiplyBy", "divideBy", "toggle", "laterBy", "earlierBy"]), attribute: attributeBlockReference, value: z.unknown(), target: z.object({type: z.enum(["session", "profile", "advocateProfile", "coupon", "referral", "event", "loyaltyCard", "allItems", "selector", "globalFilter"]), name: z.string().optional()})}); export const webhookBlockReference = z.object({id: z.number().int(), title: z.string().optional()}); export const triggerWebhookBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), webhook: webhookBlockReference, params: z.record(z.string(), z.unknown()).optional(), onError: z.record(z.string(), z.array(z.lazy(() => block))).optional()}); export const customEffectBlockReference = z.object({id: z.number().int(), name: z.string().optional(), title: z.string().optional()}); export const triggerCustomEffectBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), customEffect: customEffectBlockReference, params: z.record(z.string(), z.unknown()).optional(), target: z.object({type: z.enum(["cart", "allItems", "selector", "globalFilter", "bundle"]), name: z.string().optional()}), onError: z.record(z.string(), z.array(z.lazy(() => block))).optional()}); export const checkEventBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), eventType: z.string(), matchers: z.array(z.lazy(() => block)).optional(), onFailure: z.array(z.lazy(() => block)).optional()}); export const checkAchievementBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["justCompleted", "started", "not(started)", "inProgress", "not(inProgress)", "completed", "not(completed)"]), achievement: achievementBlockReference, onFailure: z.array(z.lazy(() => block)).optional()}); export const checkBudgetBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["available", "enoughFor"]), action: z.enum(["redeemCoupon", "redeemReferral", "setDiscount", "createCoupon", "createReferral", "setDiscountEffect", "createLoyaltyPoints", "createLoyaltyPointsEffect", "redeemLoyaltyPoints", "redeemLoyaltyPointsEffect", "awardGiveaway", "addFreeItemEffect", "customEffect", "callApi"]), value: z.number().optional(), onFailure: z.array(z.lazy(() => block)).optional()}); export const createCouponBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), campaignId: z.union([z.number(), z.string()]), recipientId: z.string(), storeInSession: z.boolean(), usageLimit: z.union([z.number(), z.string()]).optional(), discountLimit: z.union([z.number(), z.string()]).optional(), startDate: z.string().optional(), expiryDate: z.string().optional(), attributes: z.unknown(), validCharacters: z.string().optional(), pattern: z.string().optional()}); export const createReferralBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), campaignId: z.union([z.number(), z.string()]), friendId: z.string(), storeInSession: z.boolean(), usageLimit: z.union([z.number(), z.string()]).optional(), startDate: z.string().optional(), expiryDate: z.string().optional(), attributes: z.unknown(), validCharacters: z.string().optional(), pattern: z.string().optional()}); export const reserveCouponBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional()}); export const updateLoyaltyPointsExpiryBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["setTo", "laterBy"]), program: z.object({id: z.number().int(), name: z.string().optional(), title: z.string().optional()}), recipient: z.enum(["Current", "Advocate"]), subledger: z.string(), value: z.string(), onFailure: z.array(z.lazy(() => block)).optional()}); export const checkLoyaltyCardBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["linked", "not(linked)"]), onFailure: z.array(z.lazy(() => block)).optional()}); export const tierBlockReference = z.object({id: z.number().int(), name: z.string(), minPoints: z.number(), upperLimit: z.number().optional()}); export const checkTierBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), operator: z.enum(["member", "not(member)"]), subledger: z.string(), tier: tierBlockReference, onFailure: z.array(z.lazy(() => block)).optional()}); export const awardLoyaltyPointsCartTarget = z.object({type: z.literal("cart")}); export const awardLoyaltyPointsAllItemsTarget = z.object({type: z.literal("allItems")}); export const awardLoyaltyPointsGlobalFilterTarget = z.object({type: z.literal("globalFilter"), name: z.string()}); export const awardLoyaltyPointsSelectorTarget = z.object({type: z.literal("selector"), name: z.string()}); export const awardLoyaltyPointsBundleTarget = z.object({type: z.literal("bundle"), name: z.string()}); export const awardLoyaltyPointsTarget = z.discriminatedUnion("type", [awardLoyaltyPointsCartTarget, awardLoyaltyPointsAllItemsTarget, awardLoyaltyPointsGlobalFilterTarget, awardLoyaltyPointsSelectorTarget, awardLoyaltyPointsBundleTarget]); export const awardLoyaltyPointsBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), name: z.string(), program: z.object({id: z.number().int(), name: z.string().optional(), title: z.string().optional()}), recipient: z.enum(["Current", "Advocate"]), subledger: z.string(), target: awardLoyaltyPointsTarget, value: z.union([z.number(), z.string()]), partial: z.boolean().optional(), awaitsActivation: z.boolean().optional(), startDate: z.string().optional(), validityDuration: z.string().optional(), expiryDate: z.string().optional(), pendingDuration: z.string().optional()}); export const redeemLoyaltyPointsBlock = z.object({id: z.string().optional(), type: z.string(), tags: z.array(z.string()).optional(), program: z.object({id: z.number().int(), name: z.string().optional(), title: z.string().optional()}), subledger: z.string(), value: z.union([z.number(), z.string()]), name: z.string().optional()}); export const block: z.ZodType = z.discriminatedUnion("type", [groupBlock, awardDiscountBlock, passthroughBlock, showNotificationBlock, awardItemBlock, awardGiveawayBlock, checkAttributeBlock, checkAudienceBlock, checkLoyaltyBalanceBlock, checkCouponBlock, checkReferralBlock, updateAudienceMembershipBlock, updateAchievementProgressBlock, updateAttributeValueBlock, triggerWebhookBlock, triggerCustomEffectBlock, checkEventBlock, checkAchievementBlock, checkBudgetBlock, createCouponBlock, createReferralBlock, reserveCouponBlock, updateLoyaltyPointsExpiryBlock, checkLoyaltyCardBlock, checkTierBlock, awardLoyaltyPointsBlock, redeemLoyaltyPointsBlock]); export const ruleV2 = z.object({id: z.string().optional(), parentId: z.string().optional(), title: z.string(), description: z.string().optional(), blocks: z.array(block)}); export const filterSelectorStep = z.object({type: z.literal("filter"), predicate: block}); export const sortSelectorStepField = z.object({expression: z.string(), direction: z.enum(["asc", "desc"])}); export const sortSelectorStep = z.object({type: z.literal("sort"), fields: z.array(sortSelectorStepField)}); export const selectSelectorStep = z.object({type: z.literal("select"), operator: z.enum(["many", "between", "one"]), from: z.union([z.enum(["start", "end"]), z.number().int()]).optional(), to: z.number().int().optional(), count: z.number().int().optional(), index: z.number().int().optional(), partial: z.boolean().optional()}); export const mapSelectorStep = z.object({type: z.literal("map"), expression: z.string()}); export const reduceSelectorStep = z.object({type: z.literal("reduce"), operator: z.enum(["max", "min", "sum", "count", "empty"])}); export const reverseSelectorStep = z.object({type: z.literal("reverse")}); export const selectorValueMapRef = z.object({id: z.number().int()}); export const filterAndMapValuesSelectorStep = z.object({type: z.literal("filterAndMapValues"), valueMap: selectorValueMapRef}); export const selectorStep = z.discriminatedUnion("type", [filterSelectorStep, sortSelectorStep, selectSelectorStep, mapSelectorStep, reduceSelectorStep, reverseSelectorStep, filterAndMapValuesSelectorStep]); export const selector = z.object({name: z.string(), type: z.literal("selector"), source: z.string(), steps: z.array(selectorStep)}); export const bundle = z.object({id: z.string().optional(), name: z.string(), type: z.literal("bundle"), sources: z.array(z.string()), counts: z.array(z.number().int()), matchers: z.array(z.string()).optional()}); export const templateParameter = z.object({name: z.string(), value: z.unknown(), valueType: z.string(), minValue: z.number().optional(), maxValue: z.number().optional(), description: z.string(), attribute: z.number().int().optional()}); export const rulesetV2 = z.object({id: z.number().int().optional(), created: z.string().optional(), userId: z.number().int().optional(), campaignId: z.number().int().optional(), templateId: z.number().int().optional(), activatedAt: z.string().optional(), promotionRules: z.array(ruleV2), strikethroughRules: z.array(ruleV2).optional(), selectors: z.array(selector).optional(), bundles: z.array(bundle).optional(), parameters: z.array(templateParameter).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 ruleset (V2) * * GET /v2/applications/{applicationId}/campaigns/{campaignId}/rulesets/{rulesetId} * * Also accepts auth: management_key */ export const getApiV2ApplicationsApplicationIdCampaignsCampaignIdRulesetsRulesetId = async (args: GetApiV2ApplicationsApplicationIdCampaignsCampaignIdRulesetsRulesetIdArgs, options?: GetApiV2ApplicationsApplicationIdCampaignsCampaignIdRulesetsRulesetIdOptions) => { const {baseUrl = "https://yourbaseurl.talon.one", fetch: fetchFn = fetch, managerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (managerAuth !== undefined) headers.set("Authorization", managerAuth) const url = `${baseUrl.replace(/\/+$/, '')}/v2/applications/${encodeURIComponent(String(args.applicationId))}/campaigns/${encodeURIComponent(String(args.campaignId))}/rulesets/${encodeURIComponent(String(args.rulesetId))}${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(rulesetV2, await res.json()) };