UNPKG

printify-effect

Version:

Effect-ts wrapper for Printify REST API — still in early development, use at your own risk!

424 lines (378 loc) 11.4 kB
import { pipe, Schema } from "effect"; import { CurrencyCode, EmailString, MoneyAmount, NonEmptyString, NonnegativeInteger, NonnegativeNumber, PrintifyDateString, UrlString, } from "../common/schemas"; import { ImageIdSchema, ProductIdSchema, WebhookIdSchema } from "./brands"; export const Shop = Schema.Struct({ id: NonnegativeInteger, title: NonEmptyString, sales_channel: NonEmptyString, }); export const ListShopsResponse = Schema.Array(Shop); // Address schema export const Address = Schema.Struct({ first_name: NonEmptyString, last_name: NonEmptyString, email: Schema.optional(Schema.NullOr(EmailString)), phone: NonEmptyString, country: Schema.optional(Schema.NullOr(Schema.String)), region: Schema.String, address1: NonEmptyString, address2: Schema.optional(Schema.String), city: NonEmptyString, zip: NonEmptyString, company: Schema.optional(Schema.NullOr(Schema.String)), }); // Order schemas export const OrderShipment = Schema.Struct({ carrier: NonEmptyString, number: NonEmptyString, url: UrlString, delivered_at: PrintifyDateString, }); export const PrintifyConnection = Schema.Struct({ id: NonEmptyString, url: UrlString, }); export const LineItemMetadata = Schema.Struct({ title: NonEmptyString, price: MoneyAmount, variant_label: NonEmptyString, sku: NonEmptyString, country: NonEmptyString, }); export const LineItem = Schema.Struct({ product_id: NonEmptyString, quantity: NonnegativeInteger, variant_id: NonnegativeInteger, print_provider_id: NonnegativeInteger, cost: MoneyAmount, shipping_cost: MoneyAmount, status: NonEmptyString, metadata: LineItemMetadata, sent_to_production_at: Schema.optional(PrintifyDateString), fulfilled_at: Schema.optional(PrintifyDateString), }); export const OrderMetadata = Schema.Struct({ order_type: NonEmptyString, shop_order_id: NonEmptyString, shop_order_label: Schema.String, shop_fulfilled_at: Schema.optional(PrintifyDateString), }); export const Order = Schema.Struct({ id: NonEmptyString, address_to: Address, line_items: Schema.Array(LineItem), external: Schema.optional( Schema.Array( Schema.Struct({ id: NonEmptyString, handle: NonEmptyString, shipping_template_id: NonEmptyString, }) ) ), metadata: OrderMetadata, total_price: MoneyAmount, total_shipping: MoneyAmount, total_tax: MoneyAmount, status: NonEmptyString, shipping_method: NonnegativeInteger, is_printify_express: Schema.optional(Schema.Boolean), is_economy_shipping: Schema.optional(Schema.Boolean), shipments: Schema.optional(Schema.Array(OrderShipment)), created_at: PrintifyDateString, sent_to_production_at: Schema.optional(PrintifyDateString), fulfilled_at: Schema.optional(PrintifyDateString), printify_connect: PrintifyConnection, }); export const ListOrdersResponse = Schema.Struct({ current_page: NonnegativeInteger, data: Schema.Array(Order), }); export const GetOrderResponse = Order; export const SubmitOrderResponse = Schema.Struct({ id: NonEmptyString, }); export const SubmitExpressOrderResponse = Schema.Struct({ ordinary: Schema.optional( Schema.Struct({ id: NonEmptyString, }) ), express: Schema.optional( Schema.Struct({ id: NonEmptyString, }) ), }); export const SendOrderToProductionResponse = Order; export const CalculateShippingResponse = Schema.Struct({ standard: MoneyAmount, express: MoneyAmount, priority: MoneyAmount, printify_express: MoneyAmount, economy: MoneyAmount, }); export const CancelUnpaidOrderResponse = Order; // Product schemas export const ProductOption = Schema.Struct({ name: NonEmptyString, type: NonEmptyString, values: Schema.Array( Schema.Struct({ id: NonnegativeInteger, title: NonEmptyString, }) ), }); export const ProductVariant = Schema.Struct({ id: NonnegativeInteger, sku: NonEmptyString, cost: MoneyAmount, price: MoneyAmount, title: NonEmptyString, grams: NonnegativeNumber, is_enabled: Schema.Boolean, is_default: Schema.Boolean, is_available: Schema.Boolean, is_printify_express_eligible: Schema.Boolean, options: Schema.Array(NonnegativeInteger), }); export const ProductImage = Schema.Struct({ src: UrlString, variant_ids: Schema.Array(NonnegativeInteger), position: NonEmptyString, is_default: Schema.Boolean, }); export const PlaceholderImage = Schema.Struct({ id: NonEmptyString, name: NonEmptyString, type: NonEmptyString, height: NonnegativeNumber, width: NonnegativeNumber, x: Schema.Number, y: Schema.Number, scale: NonnegativeNumber, angle: Schema.Number, }); export const PrintAreaPlaceholder = Schema.Struct({ position: NonEmptyString, images: Schema.Array(PlaceholderImage), }); export const PrintArea = Schema.Struct({ variant_ids: Schema.Array(NonnegativeInteger), placeholders: Schema.Array(PrintAreaPlaceholder), background: Schema.String, }); export const ExternalProductData = Schema.Struct({ id: NonEmptyString, handle: NonEmptyString, }); const PrintDetails = Schema.Struct({ print_on_side: Schema.optional(Schema.Literal("regular", "mirror", "off")), }); export const Product = Schema.Struct({ id: ProductIdSchema, title: NonEmptyString, description: NonEmptyString, safety_information: Schema.optional(NonEmptyString), tags: Schema.optional(Schema.Array(NonEmptyString)), options: Schema.optional(Schema.Array(ProductOption)), variants: Schema.Array(ProductVariant), images: Schema.Array(ProductImage), created_at: PrintifyDateString, updated_at: PrintifyDateString, visible: Schema.optional(Schema.Boolean), blueprint_id: NonnegativeInteger, print_provider_id: NonnegativeInteger, user_id: NonnegativeInteger, shop_id: NonnegativeInteger, print_areas: Schema.Array(PrintArea), print_details: Schema.optional( Schema.Union(PrintDetails, Schema.Array(PrintDetails)) ), external: Schema.optional(Schema.Array(ExternalProductData)), is_locked: Schema.optional(Schema.Boolean), is_printify_express_eligible: Schema.optional(Schema.Boolean), is_printify_express_enabled: Schema.optional(Schema.Boolean), is_economy_shipping_eligible: Schema.optional(Schema.Boolean), is_economy_shipping_enabled: Schema.optional(Schema.Boolean), sales_channel_properties: Schema.optional( Schema.Union( Schema.Record({ key: Schema.String, value: Schema.Unknown }), Schema.Array(Schema.Record({ key: Schema.String, value: Schema.Unknown })) ) ), views: Schema.optional( Schema.Array(Schema.Record({ key: Schema.String, value: Schema.Unknown })) ), }); export const ListProductsResponse = Schema.Struct({ current_page: NonnegativeInteger, data: Schema.Array(Product), first_page_url: Schema.String, from: NonnegativeInteger, last_page: NonnegativeInteger, last_page_url: Schema.String, next_page_url: Schema.NullOr(Schema.String), path: Schema.String, per_page: NonnegativeInteger, prev_page_url: Schema.NullOr(Schema.String), to: NonnegativeInteger, total: NonnegativeInteger, }); export const GetProductResponse = Product; export const CreateProductResponse = Product; export const UpdateProductResponse = Product; // Catalog schemas export const Location = Schema.Struct({ address1: NonEmptyString, address2: Schema.NullOr(NonEmptyString), city: NonEmptyString, country: NonEmptyString, region: NonEmptyString, zip: NonEmptyString, }); export const PrintProvider = Schema.Struct({ id: NonnegativeInteger, title: NonEmptyString, location: Schema.optional(Location), }); export const Placeholder = Schema.Struct({ position: NonEmptyString, height: NonnegativeInteger, width: NonnegativeInteger, }); export const Variant = Schema.Struct({ id: NonnegativeInteger, title: NonEmptyString, options: Schema.Struct({ color: Schema.String, size: Schema.String, }), placeholders: Schema.Array(Placeholder), }); export const Blueprint = Schema.Struct({ id: NonnegativeInteger, title: NonEmptyString, description: Schema.optional(NonEmptyString), brand: NonEmptyString, model: NonEmptyString, images: Schema.Array(UrlString), }); export const ListBlueprintsResponse = Schema.Array(Blueprint); export const ListProvidersResponse = Schema.Array(PrintProvider); export const GetBlueprintResponse = Blueprint; export const GetBlueprintVariantsResponse = Schema.Struct({ id: NonnegativeInteger, title: NonEmptyString, variants: Schema.Array(Variant), }); export const GetProviderResponse = Schema.Struct({ id: NonnegativeInteger, title: NonEmptyString, location: Location, blueprints: Schema.Array(Blueprint), }); export const GetBlueprintProviderResponse = Schema.Array(PrintProvider); export const ShippingProfile = Schema.Struct({ variant_ids: Schema.Array(NonnegativeInteger), first_item: Schema.Struct({ cost: MoneyAmount, currency: CurrencyCode, }), additional_items: Schema.Struct({ cost: MoneyAmount, currency: CurrencyCode, }), countries: Schema.Array(NonEmptyString), }); export const GetVariantShippingResponse = Schema.Struct({ handling_time: Schema.Struct({ value: NonnegativeInteger, unit: Schema.Literal("day", "business_day"), }), profiles: Schema.Array(ShippingProfile), }); // Upload schemas export const ImageUpload = Schema.Struct({ file_name: NonEmptyString, height: NonnegativeInteger, width: NonnegativeInteger, size: NonnegativeInteger, mime_type: NonEmptyString, preview_url: UrlString, upload_time: PrintifyDateString, }); export const Image = Schema.extend( ImageUpload, Schema.Struct({ id: ImageIdSchema, }) ); export const ListUploadsResponse = Schema.Struct({ current_page: NonnegativeInteger, data: Schema.Array(ImageUpload), first_page_url: Schema.String, from: Schema.NullOr(NonnegativeInteger), last_page: NonnegativeInteger, last_page_url: Schema.String, next_page_url: Schema.NullOr(Schema.String), path: Schema.String, per_page: NonnegativeInteger, prev_page_url: Schema.NullOr(Schema.String), to: Schema.NullOr(NonnegativeInteger), total: NonnegativeInteger, }); export const UploadImageResponse = Image; export const GetUploadByIdResponse = Image; // Webhook schemas export const Webhook = Schema.Struct({ id: WebhookIdSchema, topic: NonEmptyString, url: UrlString, shop_id: NonEmptyString, }); export const ListWebhooksResponse = Schema.Array(Webhook); export const CreateWebhookResponse = Schema.Struct({ topic: NonEmptyString, url: UrlString, shop_id: NonEmptyString, id: NonEmptyString, }); export const UpdateWebhookResponse = Schema.Struct({ topic: NonEmptyString, url: UrlString, shop_id: NonEmptyString, id: NonEmptyString, }); export const DeleteWebhookResponse = Schema.Struct({ message: NonEmptyString, }); // Empty response schema for operations that return empty objects/void export const EmptyResponse = Schema.Struct({}); const HasId = Schema.Struct({ id: Schema.String }); type HasId = typeof HasId.Type; export const withId = <A extends HasId, I extends HasId, R>( originalSchema: Schema.Schema<A, I, R>, id: string ) => pipe( originalSchema, Schema.omit("id"), Schema.extend( Schema.Struct({ id: Schema.optional(Schema.String).pipe( Schema.withDecodingDefault(() => id) ), }) ) );