@taddoo/sdk 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2
- package/index.d.ts +60 -4
- package/index.js +15 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Official SDK for the **Taddoo public website API**. Connect a tattoo artist's or tattoo studio's own website to [Taddoo](https://taddoo.com), the app tattoo artists use for requests, bookings, deposits, consent forms and bookkeeping.
|
|
4
4
|
|
|
5
|
-
With a few lines the website shows the artist's **flash** (designs, sizes, prices, free slots, booking with deposit via Stripe), their **tattoo request form** (every question exactly as configured, with reference images), **fixed services** like a booking menu (tattoo services such as "small tattoo, 1 h, CHF 250" or "medium tattoo, 4 h, 300 to 500", piercing, tooth gems, each with price, duration, deposit and reference images), **availability** (free days, guest spots), **waitlists** and **
|
|
5
|
+
With a few lines the website shows the artist's **flash** (designs, sizes, prices, free slots, booking with deposit via Stripe), their **tattoo request form** (every question exactly as configured, with reference images), **fixed services** like a booking menu (tattoo services such as "small tattoo, 1 h, CHF 250" or "medium tattoo, 4 h, 300 to 500", piercing, tooth gems, each with price, duration, deposit and reference images), **availability** (free days, guest spots), **waitlists**, **gift vouchers** and the **merch shop** (shirts, hoodies, prints with sizes, stock, shipping per country and checkout via Stripe), all in the website's own design. Everything a client sends lands in the artist's Taddoo app on iPhone, iPad, Android and Mac: requests as projects with a push notification, bookings in the calendar.
|
|
6
6
|
|
|
7
7
|
- Zero dependencies, ESM, TypeScript types included
|
|
8
8
|
- Browser, Node 18+, Deno, Bun, edge runtimes
|
|
@@ -77,6 +77,19 @@ if (res.status === "payment_required") window.location.href = res.checkoutUrl; /
|
|
|
77
77
|
|
|
78
78
|
Designs with `bookingMode: "request"` use `taddoo.flash.request(id, { variantId, name, email, wishDate })` instead.
|
|
79
79
|
|
|
80
|
+
## Merch shop
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
const shop = await taddoo.shop.get(); // products, variants, stock, shipping profiles
|
|
84
|
+
const cart = [{ variantId: shop.products[0].variants[0].id, quantity: 1 }];
|
|
85
|
+
const res = await taddoo.shop.checkout({ items: cart, country: "CH" });
|
|
86
|
+
localStorage.setItem("lastOrder", res.order.token);
|
|
87
|
+
window.location.href = res.checkoutUrl; // Stripe: address, phone, payment
|
|
88
|
+
// later: await taddoo.shop.order(token) -> { status: "paid" | "shipped" | ..., number }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Shipping works like on Etsy: each product has a shipping profile with rates per country (`"EU"` and `"*"` for the rest of the world), the piece with the highest first-item price pays it once, every further piece its additional price. The checkout computes the real totals and reserves the stock for 30 minutes; `out_of_stock` (409) tells you which `variantId` has how many pieces `available`.
|
|
92
|
+
|
|
80
93
|
## Questions and answers
|
|
81
94
|
|
|
82
95
|
Every question has `id`, `label`, `required` and `input.type`:
|
|
@@ -95,7 +108,7 @@ await taddoo.studio.submit(answers, { artist: "any" });
|
|
|
95
108
|
|
|
96
109
|
## Errors
|
|
97
110
|
|
|
98
|
-
Failed calls throw `TaddooError` with `code`, `status` and `message`. For `code === "rejected"` the message is already translated for the visitor: show it as is. Other codes: `card_required`, `account_inactive`, `page_not_live`, `origin_not_allowed`, `session_required`, `books_closed`, `rate_limited`, `network_error` and more, see the docs.
|
|
111
|
+
Failed calls throw `TaddooError` with `code`, `status` and `message`. For `code === "rejected"` the message is already translated for the visitor: show it as is. Other codes: `card_required`, `account_inactive`, `page_not_live`, `origin_not_allowed`, `session_required`, `books_closed`, `out_of_stock`, `cant_ship`, `rate_limited`, `network_error` and more, see the docs.
|
|
99
112
|
|
|
100
113
|
## Server-side use
|
|
101
114
|
|
package/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export interface Theme { preset: string; accent: string; background: string; mod
|
|
|
34
34
|
|
|
35
35
|
export interface Block {
|
|
36
36
|
id: string;
|
|
37
|
-
kind: "link" | "text" | "social" | "heading" | "address" | "form" | "flash" | "availability" | "waitlist" | "voucher" | "consultation" | "touchup" | "treatment";
|
|
37
|
+
kind: "link" | "text" | "social" | "heading" | "address" | "form" | "flash" | "availability" | "waitlist" | "voucher" | "shop" | "consultation" | "touchup" | "treatment";
|
|
38
38
|
title: string;
|
|
39
39
|
url: string | null;
|
|
40
40
|
imageUrl: string | null;
|
|
@@ -44,6 +44,7 @@ export interface Block {
|
|
|
44
44
|
handles?: Record<string, string | null>;
|
|
45
45
|
formId?: string;
|
|
46
46
|
amounts?: number[];
|
|
47
|
+
customAmount?: { min: number; max: number } | null;
|
|
47
48
|
currency?: string;
|
|
48
49
|
/** API endpoint that serves this block's content, if any. */
|
|
49
50
|
api?: string;
|
|
@@ -117,12 +118,15 @@ export interface Question { id: string; kind: string; label: string; hint: strin
|
|
|
117
118
|
export interface Form { id: string; title: string; url: string | null; intro: string | null; thanks: string | null; acceptsRequests: boolean; questions: Question[] }
|
|
118
119
|
export type Answers = Record<string, string | number | boolean | Array<string | number>>;
|
|
119
120
|
|
|
121
|
+
export interface FreeTime { full: boolean; windows: Array<{ from: string; to: string }> }
|
|
120
122
|
export interface Availability {
|
|
121
123
|
books: Books;
|
|
122
124
|
timezone: string;
|
|
123
125
|
horizonDays: number;
|
|
124
126
|
freeDays: string[];
|
|
125
|
-
|
|
127
|
+
/** Free hours per free day in local time; empty when the artist hides them. */
|
|
128
|
+
freeTimes: Record<string, FreeTime>;
|
|
129
|
+
studios: Array<{ id: string; name: string; address: string | null; freeDays: string[]; freeTimes: Record<string, FreeTime> }>;
|
|
126
130
|
guestSpots: Array<{ id: string; name: string; address: string | null; from: string; to: string }>;
|
|
127
131
|
timeOff: Array<{ from: string; to: string }>;
|
|
128
132
|
}
|
|
@@ -137,7 +141,52 @@ export interface Waitlist {
|
|
|
137
141
|
fields: Record<string, unknown>;
|
|
138
142
|
sizeUnit: "cm" | "in";
|
|
139
143
|
}
|
|
140
|
-
export interface Vouchers { available: boolean; url: string | null; amounts: number[]; currency: string; validityMonths: number | null; intro: string | null; terms: string | null }
|
|
144
|
+
export interface Vouchers { available: boolean; url: string | null; amounts: number[]; /** Own whole amount allowed between min and max, or null. */ customAmount: { min: number; max: number } | null; currency: string; validityMonths: number | null; intro: string | null; terms: string | null }
|
|
145
|
+
|
|
146
|
+
export interface ShopVariant {
|
|
147
|
+
id: string;
|
|
148
|
+
/** e.g. "M" or "Black / M"; empty for products without options. */
|
|
149
|
+
name: string;
|
|
150
|
+
price: number;
|
|
151
|
+
/** Pieces left; null = unlimited. */
|
|
152
|
+
stock: number | null;
|
|
153
|
+
available: boolean;
|
|
154
|
+
}
|
|
155
|
+
export interface ShopProduct {
|
|
156
|
+
id: string;
|
|
157
|
+
slug: string;
|
|
158
|
+
/** Product page on taddoo.com. */
|
|
159
|
+
url: string;
|
|
160
|
+
title: string;
|
|
161
|
+
description: string | null;
|
|
162
|
+
categoryId: string | null;
|
|
163
|
+
/** Name of the option, e.g. "Size"; null = no options. */
|
|
164
|
+
optionName: string | null;
|
|
165
|
+
priceMin: number;
|
|
166
|
+
priceMax: number;
|
|
167
|
+
soldOut: boolean;
|
|
168
|
+
shippingProfileId: string;
|
|
169
|
+
/** The first image is the cover. */
|
|
170
|
+
images: Array<{ url: string; cardUrl: string; width: number | null; height: number | null }>;
|
|
171
|
+
variants: ShopVariant[];
|
|
172
|
+
}
|
|
173
|
+
/** Shipping like on Etsy: country is an ISO code, "EU" or "*" (rest of the world); the most specific rate applies. The piece with the highest first price pays first once, every other piece its additional. */
|
|
174
|
+
export interface ShopRate { country: string; first: number; additional: number }
|
|
175
|
+
export interface ShopShippingProfile { id: string; deliveryNote: string | null; rates: ShopRate[] }
|
|
176
|
+
export interface Shop {
|
|
177
|
+
/** false: no shop, no product yet or online payments not set up. */
|
|
178
|
+
available: boolean;
|
|
179
|
+
url: string | null;
|
|
180
|
+
currency: string;
|
|
181
|
+
intro: string | null;
|
|
182
|
+
terms: string | null;
|
|
183
|
+
/** Fee the customer pays on top of items plus shipping (percent as a fraction, e.g. 0.049); null when the artist pays it. */
|
|
184
|
+
surcharge: { percent: number; fixed: number } | null;
|
|
185
|
+
categories: Array<{ id: string; name: string }>;
|
|
186
|
+
products: ShopProduct[];
|
|
187
|
+
shippingProfiles: ShopShippingProfile[];
|
|
188
|
+
}
|
|
189
|
+
export interface ShopOrderStatus { status: "pending" | "paid" | "shipped" | "canceled" | "refunded"; number: number; email: string | null }
|
|
141
190
|
|
|
142
191
|
export interface Studio {
|
|
143
192
|
type: "studio";
|
|
@@ -206,11 +255,18 @@ export interface TaddooClient {
|
|
|
206
255
|
join(id: string, data: { name: string; email: string; phone?: string; instagram?: string; preferredContact?: "email" | "instagram" | "whatsapp" | "sms"; wish?: string; bodyPart?: string; size?: number; sizeSecondary?: number }, opts?: { images?: File[] }): Promise<{ status: "joined" }>;
|
|
207
256
|
};
|
|
208
257
|
/** Fixed services: tattoo services, piercing, tooth gems, custom. */
|
|
209
|
-
services(): Promise<{ services: Service[] }>;
|
|
258
|
+
services(opts?: { locale?: string }): Promise<{ services: Service[] }>;
|
|
210
259
|
vouchers: {
|
|
211
260
|
get(): Promise<Vouchers>;
|
|
212
261
|
checkout(data: { amount: number; name: string; email: string; recipient?: string; message?: string }): Promise<{ checkoutUrl: string }>;
|
|
213
262
|
};
|
|
263
|
+
/** Merch shop: products, cart checkout via Stripe, order status. */
|
|
264
|
+
shop: {
|
|
265
|
+
get(opts?: CallOptions): Promise<Shop>;
|
|
266
|
+
/** country: ISO code of the delivery address. Errors: out_of_stock / changed (409, with variantId and available), cant_ship (422). */
|
|
267
|
+
checkout(data: { items: Array<{ variantId: string; quantity: number }>; country: string }, opts?: CallOptions): Promise<{ checkoutUrl: string; order: { number: number; token: string } }>;
|
|
268
|
+
order(token: string, opts?: CallOptions): Promise<ShopOrderStatus>;
|
|
269
|
+
};
|
|
214
270
|
studio: {
|
|
215
271
|
get(): Promise<Studio>;
|
|
216
272
|
form(): Promise<StudioForm>;
|
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @taddoo/sdk v1.0
|
|
2
|
+
* @taddoo/sdk v1.1.0 - official client for the Taddoo public website API.
|
|
3
3
|
* Connect a tattoo artist's or tattoo studio's own website to Taddoo:
|
|
4
|
-
* flash designs, fixed services, request forms, availability, waitlists
|
|
5
|
-
* gift vouchers.
|
|
4
|
+
* flash designs, fixed services, request forms, availability, waitlists,
|
|
5
|
+
* gift vouchers and the merch shop.
|
|
6
6
|
* Requests and bookings land in the artist's Taddoo app.
|
|
7
7
|
* Docs: https://taddoo.com/developers · Guide for coding agents: https://taddoo.com/developers/llms.txt
|
|
8
8
|
* No dependencies. Works in browsers, Node 18+, Deno, Bun and edge runtimes.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
export const DEFAULT_BASE_URL = "https://taddoo.com/api/v1";
|
|
14
|
-
export const SDK_VERSION = "1.0
|
|
14
|
+
export const SDK_VERSION = "1.1.0";
|
|
15
15
|
|
|
16
16
|
/** Error with the API's error code (e.g. "rejected", "card_required") and HTTP status. */
|
|
17
17
|
export class TaddooError extends Error {
|
|
@@ -219,6 +219,17 @@ export function createTaddoo(options = {}) {
|
|
|
219
219
|
/** { amount, name, email, recipient?, message? } -> { checkoutUrl } */
|
|
220
220
|
checkout: (data, o = {}) => request("POST", "/vouchers/checkout", { ...o, json: data }),
|
|
221
221
|
},
|
|
222
|
+
shop: {
|
|
223
|
+
/** Merch shop: { available, url, currency, intro, terms, surcharge, categories, products, shippingProfiles }. */
|
|
224
|
+
get: (o = {}) => request("GET", "/shop", o),
|
|
225
|
+
/**
|
|
226
|
+
* Pay a cart: { items: [{ variantId, quantity }], country } ->
|
|
227
|
+
* { checkoutUrl, order: { number, token } }. Redirect to checkoutUrl (Stripe).
|
|
228
|
+
*/
|
|
229
|
+
checkout: (data, o = {}) => request("POST", "/shop/checkout", { ...o, json: data }),
|
|
230
|
+
/** Status of an order from checkout: { status, number, email }. */
|
|
231
|
+
order: (token, o = {}) => request("GET", `/shop/orders/${encodeURIComponent(token)}`, o),
|
|
232
|
+
},
|
|
222
233
|
studio: {
|
|
223
234
|
/** Studio key only: studio page with artists, opening hours and flash. */
|
|
224
235
|
get: () => request("GET", "/studio", { artist: null }),
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taddoo/sdk",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Official Taddoo SDK: connect a tattoo artist's or tattoo studio's own website (built with Lovable, Bolt, v0, Cursor, Framer, Next.js, Astro...) to Taddoo. Flash gallery with booking and deposit, fixed services (tattoo services, piercing, tooth gems) with prices, tattoo request form, availability, waitlists and
|
|
5
|
-
"keywords": ["tattoo", "tattoo artist", "tattoo studio", "tattoo booking", "flash", "tattoo request form", "booking", "deposit", "link in bio", "taddoo", "website", "vibe coding", "lovable", "bolt", "v0", "cursor"],
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Official Taddoo SDK: connect a tattoo artist's or tattoo studio's own website (built with Lovable, Bolt, v0, Cursor, Framer, Next.js, Astro...) to Taddoo. Flash gallery with booking and deposit, fixed services (tattoo services, piercing, tooth gems) with prices, tattoo request form, availability, waitlists, gift vouchers and the merch shop; requests and orders land in the artist's Taddoo app.",
|
|
5
|
+
"keywords": ["tattoo", "tattoo artist", "tattoo studio", "tattoo booking", "flash", "tattoo request form", "booking", "deposit", "link in bio", "merch shop", "taddoo", "website", "vibe coding", "lovable", "bolt", "v0", "cursor"],
|
|
6
6
|
"homepage": "https://taddoo.com/developers",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": "Taddoo AG <hello@tattoomii.com> (https://taddoo.com)",
|