@pindownai/client-js 1.2.0 → 1.3.2

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 CHANGED
@@ -1,206 +1,140 @@
1
1
  # @pindownai/client-js
2
2
 
3
- Official TypeScript/JavaScript client for the [Pindown.ai](https://pindown.ai) API.
3
+ Official TypeScript/JavaScript client for the **[Pindown v1 Pins API](https://docs.pindown.ai)**.
4
+
5
+ Requires a **Workspace** plan API key (`pk_…`).
4
6
 
5
7
  ## Features
6
8
 
7
- - **Full TypeScript support** with IntelliSense
8
- - **All 36 API endpoints** (Pins, Pinboards, Datasets, Blocks, Collaborators)
9
- - **Built-in client-side rate limiting** with automatic token tracking
10
- - ✅ **Organized by API** - Clean folder structure (pins/, pinboards/, datasets/, etc.)
11
- - ✅ **Works everywhere** - Node.js, browsers, edge runtimes
12
- - ✅ **Dual format** - ESM and CommonJS support
13
- - ✅ **Zero dependencies** - Only uses native fetch API
9
+ - Typed **`pin_type` + `pin_config`** for all 27 pin shapes
10
+ - Full CRUD + batch + share on `/v1/pins`
11
+ - ESM + CJS, zero runtime dependencies (native `fetch`)
14
12
 
15
- ## Installation
13
+ ## Install
16
14
 
17
15
  ```bash
18
16
  npm install @pindownai/client-js
19
17
  ```
20
18
 
21
- ## Quick Start
19
+ ## Quick start
22
20
 
23
21
  ```typescript
24
22
  import { PindownClient } from '@pindownai/client-js'
23
+ import type { MarkdownPinConfig } from '@pindownai/client-js'
25
24
 
26
25
  const client = new PindownClient({
27
- apiKey: 'pk_live_...'
28
- // Tier is auto-detected from server!
26
+ apiKey: process.env.PINDOWN_API_KEY!,
29
27
  })
30
28
 
31
- // Create a pin
32
- const pin = await client.pins.create({
33
- metadata: {
34
- title: 'My First Pin'
35
- }
29
+ const created = await client.pins.create({
30
+ pin_type: 'markdown',
31
+ pin_config: { content: '# Hello\n\nCreated via API.' },
32
+ metadata: { title: 'My doc', tags: ['docs'] },
36
33
  })
37
34
 
38
- console.log(`Pin created: ${pin.id}`)
35
+ const pin = await client.pins.get(created.id)
36
+ const content = (pin.metadata?.pin_config as MarkdownPinConfig | undefined)?.content
39
37
 
40
- // Check your tier
41
- console.log(`Your tier: ${client.getTier()}`)
38
+ await client.pins.update(created.id, {
39
+ metadata: {
40
+ title: 'My doc (updated)',
41
+ pin_config: { content: '# Updated body' },
42
+ },
43
+ })
42
44
 
43
- // Check rate limits
44
- const info = client.getRateLimitInfo()
45
- if (info) {
46
- console.log(`Used: ${info.minute.used}/${info.minute.limit} tokens`)
47
- }
45
+ await client.pins.delete(created.id)
48
46
  ```
49
47
 
50
- ## API Reference
48
+ ## Pin types (importable interfaces)
51
49
 
52
- ### Pins API (`client.pins`)
50
+ Each pin type has its own `*PinConfig` interface:
53
51
 
54
52
  ```typescript
55
- // Create pin
56
- await client.pins.create({
57
- metadata: {
58
- title: 'My Pin'
59
- }
60
- })
61
-
62
- // Create with permissions
63
- await client.pins.create({
64
- is_public: true,
65
- allow_comments: true,
66
- metadata: {
67
- title: 'Public Pin',
68
- tags: ['docs']
69
- }
70
- })
71
-
72
- // CRUD operations
73
- await client.pins.get(pinId)
74
- await client.pins.list()
75
- await client.pins.update(pinId, {
76
- metadata: { title: 'Updated Title' }
77
- })
78
- await client.pins.delete(pinId)
79
- await client.pins.share(pinId, {
80
- is_public: true,
81
- allow_comments: true
82
- })
53
+ import type {
54
+ PinTypeId,
55
+ PinConfigByType,
56
+ MarkdownPinConfig,
57
+ TablePinConfig,
58
+ StatCardsPinConfig,
59
+ CreateTypedPinRequest,
60
+ } from '@pindownai/client-js'
83
61
  ```
84
62
 
85
- ### Pinboards API (`client.pinboards`)
63
+ Product types: `PRODUCT_PIN_TYPES` (same as `ALL_PIN_TYPES`)
64
+
65
+ ## Helpers
86
66
 
87
67
  ```typescript
88
- // Create & manage pinboards
89
- await client.pinboards.create({
90
- title: 'Dashboard',
91
- tags: ['analytics']
92
- })
93
- await client.pinboards.get(boardId)
94
- await client.pinboards.list()
95
- await client.pinboards.update(boardId, {
96
- title: 'New Title'
68
+ await client.pins.createMarkdown({
69
+ title: 'Notes',
70
+ content: '# Hello',
71
+ tags: ['api'],
97
72
  })
98
- await client.pinboards.delete(boardId)
99
73
 
100
- // Manage pins in pinboard
101
- await client.pinboards.addPin(boardId, {
102
- pin_id: pinId
103
- })
104
- await client.pinboards.removePin(boardId, pinId)
105
- await client.pinboards.updateLayout(boardId, {
106
- layout: { [pinId]: { x: 0, y: 0, w: 2, h: 1 } }
107
- })
108
- await client.pinboards.share(boardId, {
109
- is_public: true,
110
- allow_comments: true
74
+ await client.pins.createStatCards({
75
+ title: 'KPIs',
76
+ cards: [{ title: 'Revenue', value: '$1k', change: '+5%', trend: 'up' }],
111
77
  })
112
78
 
113
- // Custom roles
114
- await client.pinboards.createRole(boardId, {
115
- name: 'VIP',
116
- color: '#FFD700'
79
+ await client.pins.createTable({
80
+ title: 'Data',
81
+ columns: [{ id: 'name', name: 'Name', type: 'text' }],
82
+ rows: [{ id: 'r1', cells: { name: 'Item' } }],
117
83
  })
118
- await client.pinboards.listRoles(boardId)
119
- await client.pinboards.assignUserRoles(boardId, userId, {
120
- roleIds: ['role-123']
121
- })
122
- await client.pinboards.setPinRoleRequirements(boardId, pinId, {
123
- roleIds: ['role-123']
84
+
85
+ await client.pins.createEmbed({
86
+ title: 'Video',
87
+ url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
88
+ type: 'youtube',
124
89
  })
125
90
  ```
126
91
 
127
- ### Datasets API (`client.datasets`)
92
+ ## Pins API surface
128
93
 
129
- ```typescript
130
- // Create JSON dataset
131
- await client.datasets.create({
132
- name: 'Sales',
133
- type: 'json',
134
- data: { revenue: 125000, customers: 450 }
135
- })
94
+ | Method | Endpoint |
95
+ |--------|----------|
96
+ | `pins.create` | `POST /v1/pins` |
97
+ | `pins.get` | `GET /v1/pins/:id` |
98
+ | `pins.list` | `GET /v1/pins` |
99
+ | `pins.update` | `PUT /v1/pins/:id` |
100
+ | `pins.delete` | `DELETE /v1/pins/:id` |
101
+ | `pins.share` | `POST /v1/pins/:id/share` |
102
+ | `pins.batchGet` | `POST /v1/pins/batch/get` |
103
+ | `pins.batchCreate` | `POST /v1/pins/batch` |
104
+ | `pins.batchUpdate` | `PATCH /v1/pins/batch` |
105
+ | `pins.batchDelete` | `DELETE /v1/pins/batch` |
136
106
 
137
- // Create markdown dataset
138
- await client.datasets.create({
139
- name: 'Config',
140
- type: 'markdown',
141
- data: '# Company\nAcme Corp'
142
- })
107
+ ## Rate limits (server-enforced)
143
108
 
144
- // CRUD operations
145
- await client.datasets.get(datasetId)
146
- await client.datasets.list()
147
- await client.datasets.update(datasetId, {
148
- data: { revenue: 150000 }
149
- })
150
- await client.datasets.delete(datasetId)
109
+ The **server** applies rolling **60-second** buckets on `/v1/pins*` (scaled by subscription tier). When exceeded:
151
110
 
152
- // Share dataset
153
- await client.datasets.inviteCollaborator(datasetId, {
154
- email: 'user@example.com',
155
- role: 'editor'
156
- })
157
- ```
111
+ - HTTP **429**
112
+ - Error code **`RATE_LIMITED`**
113
+ - Thrown as **`RateLimitError`** in the client
158
114
 
159
- ### Blocks API (`client.blocks`)
115
+ Approximate base caps (before tier scaling):
160
116
 
161
- ```typescript
162
- await client.blocks.create(pinId, {
163
- title: 'Header',
164
- type: 'markdown',
165
- template: '# Title',
166
- order: 1
167
- })
168
- await client.blocks.get(pinId, blockId)
169
- await client.blocks.list(pinId)
170
- await client.blocks.update(pinId, blockId, {
171
- title: 'Updated Header',
172
- template: '# Updated'
173
- })
174
- await client.blocks.delete(pinId, blockId)
175
- ```
117
+ | Bucket | Methods | Base max / 60s |
118
+ |--------|---------|----------------|
119
+ | `read_standard` | `GET /pins`, `GET /pins/:id` | 120 |
120
+ | `read_batch` | `POST /pins/batch/get` | 60 |
121
+ | `write_core` | `POST`, `PUT`, `DELETE`, batch mutations, share | 90 |
176
122
 
177
- ### Collaborators API (`client.collaborators`)
123
+ ## Errors
178
124
 
179
125
  ```typescript
180
- // Pin collaborators
181
- await client.collaborators.listForPin(pinId)
182
- await client.collaborators.inviteToPin(pinId, { email: '...', role: 'editor' })
183
- await client.collaborators.updatePinRole(pinId, userId, { role: 'viewer' })
184
- await client.collaborators.removeFromPin(pinId, userId)
185
- await client.collaborators.getPinPermissions(pinId)
186
-
187
- // Pinboard collaborators
188
- await client.collaborators.listForPinboard(boardId)
189
- await client.collaborators.inviteToPinboard(boardId, { email: '...', role: 'editor' })
190
- await client.collaborators.updatePinboardRole(boardId, userId, { role: 'viewer' })
191
- await client.collaborators.removeFromPinboard(boardId, userId)
192
- await client.collaborators.getPinboardPermissions(boardId)
126
+ import {
127
+ AuthenticationError,
128
+ ForbiddenError,
129
+ NotFoundError,
130
+ ValidationError,
131
+ RateLimitError,
132
+ } from '@pindownai/client-js'
193
133
  ```
194
134
 
135
+ ## Docs
195
136
 
196
- ## Documentation
197
-
198
- Full API documentation: [docs.pindown.ai](https://docs.pindown.ai)
199
-
200
- ## Support
201
-
202
- - Discord: [discord.gg/pindown](https://discord.gg/bDuUNBq5eS)
203
- - Documentation: [docs.pindown.ai](https://docs.pindown.ai)
137
+ https://docs.pindown.ai
204
138
 
205
139
  ## License
206
140
 
package/dist/index.cjs CHANGED
@@ -1,3 +1,8 @@
1
- 'use strict';var E={starter:{tokensPerHour:16,tokensPerMinute:null},hobby:{tokensPerHour:6e3,tokensPerMinute:100},pro:{tokensPerHour:24e3,tokensPerMinute:400},teams:{tokensPerHour:6e4,tokensPerMinute:1e3},agency:{tokensPerHour:24e4,tokensPerMinute:4e3}};var v={GET:1,POST:1,PUT:1,DELETE:1,INVITE:3,SHARE:3,BATCH_1_10:3,BATCH_11_25:5,BATCH_26_50:10};var d=class extends Error{constructor(e){super(e),this.name="PindownError";}},p=class extends d{constructor(e="Authentication failed"){super(e),this.name="AuthenticationError";}},g=class extends d{constructor(e="Access forbidden"){super(e),this.name="ForbiddenError";}},P=class extends d{constructor(e){super(`${e} not found`),this.name="NotFoundError";}},c=class extends d{constructor(e,t){super(e),this.name="ValidationError",this.details=t;}},m=class extends d{constructor(e){super(`Rate limit exceeded: ${e.used}/${e.limit} tokens used in ${e.window} window. Resets at ${e.resetAt.toISOString()}`),this.name="RateLimitError",this.window=e.window,this.limit=e.limit,this.used=e.used,this.remaining=e.remaining,this.resetAt=e.resetAt,this.tier=e.tier;}},l=class extends d{constructor(e,t=500){super(e),this.name="ServerError",this.statusCode=t;}},h=class extends d{constructor(e="Network request failed"){super(e),this.name="NetworkError";}};var k=E,b=v,T=class{constructor(e){this.minuteTokens=new Map;this.hourTokens=new Map;this.tier=e,this.cleanupInterval=setInterval(()=>this.cleanup(),300*1e3);}checkLimit(e,t,i){let r=this.calculateTokenCost(e,t,i),s=this.getMinuteWindow(),o=this.getHourWindow(),n=k[this.tier];if(n.tokensPerMinute!==null){let y=this.minuteTokens.get(s)||0;if(y+r>n.tokensPerMinute)throw new m({window:"minute",limit:n.tokensPerMinute,used:y,remaining:Math.max(0,n.tokensPerMinute-y),resetAt:this.getMinuteResetTime(),tier:this.tier})}let u=this.hourTokens.get(o)||0;if(u+r>n.tokensPerHour)throw new m({window:"hour",limit:n.tokensPerHour,used:u,remaining:Math.max(0,n.tokensPerHour-u),resetAt:this.getHourResetTime(),tier:this.tier});this.incrementToken(s,r),this.incrementToken(o,r);}calculateTokenCost(e,t,i){if(t.includes("/batch")||t.includes("/sync")){if(i?.operations){let r=Array.isArray(i.operations)?i.operations.length:0;return r<=10?b.BATCH_1_10:r<=25?b.BATCH_11_25:(b.BATCH_26_50)}if(i?.pins){let r=Array.isArray(i.pins)?i.pins.length:0;return r<=16?5:(8)}}return t.includes("/collaborators")||t.includes("/invite")||t.includes("/share")?b.INVITE:b[e]||1}getMinuteWindow(){let e=new Date;return `minute_${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}-${String(e.getHours()).padStart(2,"0")}-${String(e.getMinutes()).padStart(2,"0")}`}getHourWindow(){let e=new Date;return `hour_${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}-${String(e.getHours()).padStart(2,"0")}`}incrementToken(e,t){if(e.startsWith("minute")){let i=this.minuteTokens.get(e)||0;this.minuteTokens.set(e,i+t);}else {let i=this.hourTokens.get(e)||0;this.hourTokens.set(e,i+t);}}getMinuteResetTime(){let e=new Date;return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes()+1,0,0)}getHourResetTime(){let e=new Date;return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours()+1,0,0,0)}getRateLimitInfo(){let e=k[this.tier],t=this.getMinuteWindow(),i=this.getHourWindow(),r=this.minuteTokens.get(t)||0,s=this.hourTokens.get(i)||0;return {tier:this.tier,minute:{limit:e.tokensPerMinute||0,used:r,remaining:e.tokensPerMinute?Math.max(0,e.tokensPerMinute-r):1/0,resetAt:this.getMinuteResetTime()},hour:{limit:e.tokensPerHour,used:s,remaining:Math.max(0,e.tokensPerHour-s),resetAt:this.getHourResetTime()}}}cleanup(){let t=Date.now()-7200*1e3;for(let[i]of this.minuteTokens)this.parseWindowTimestamp(i)<t&&this.minuteTokens.delete(i);for(let[i]of this.hourTokens)this.parseWindowTimestamp(i)<t&&this.hourTokens.delete(i);}parseWindowTimestamp(e){let t=e.split("_")[1].split("-"),i=parseInt(t[0]),r=parseInt(t[1])-1,s=parseInt(t[2]),o=parseInt(t[3]),n=e.startsWith("minute")?parseInt(t[4]):0;return new Date(i,r,s,o,n).getTime()}destroy(){this.cleanupInterval&&clearInterval(this.cleanupInterval);}};var f=class{constructor(e){this.client=e;}async create(e){return this.client.request("POST","/pins",e)}async get(e){return this.client.request("GET",`/pins/${e}`)}async list(e){let t=new URLSearchParams;e?.limit&&t.append("limit",e.limit.toString()),e?.offset&&t.append("offset",e.offset.toString());let i=t.toString(),r=i?`/pins?${i}`:"/pins";return this.client.request("GET",r)}async update(e,t){return this.client.request("PUT",`/pins/${e}`,t)}async delete(e){return this.client.request("DELETE",`/pins/${e}`)}async share(e,t){return this.client.request("POST",`/pins/${e}/share`,t)}async batchGet(e){return this.client.request("POST","/pins/batch/get",{pin_ids:e})}async batchCreate(e){return this.client.request("POST","/pins/batch",{pins:e})}async batchUpdate(e){return this.client.request("PATCH","/pins/batch",{updates:e})}async batchDelete(e){return this.client.request("DELETE","/pins/batch",{pin_ids:e})}async createMarkdown(e){let{content:t,title:i,tags:r,description:s,pin_layout:o,is_public:n,allow_edit:u,require_sign_in:y,allow_comments:_,pending_invites:S}=e;return this.create({pin_type:"markdown",pin_config:{content:t},pin_layout:o,is_public:n,allow_edit:u,require_sign_in:y,allow_comments:_,pending_invites:S,metadata:{title:i,tags:r,description:s}})}async createStatCards(e){let{cards:t,title:i,tags:r,description:s,pin_layout:o,is_public:n}=e;return this.create({pin_type:"stat-cards",pin_config:{cards:t},pin_layout:o,is_public:n,metadata:{title:i,tags:r,description:s}})}async createTable(e){let{columns:t,rows:i,title:r,tags:s,description:o,pin_layout:n,is_public:u}=e;return this.create({pin_type:"table",pin_config:{columns:t,rows:i},pin_layout:n,is_public:u,metadata:{title:r,tags:s,description:o}})}async createEmbed(e){let{url:t,type:i,title:r,tags:s,description:o,pin_layout:n,is_public:u}=e;return this.create({pin_type:"embed",pin_config:{url:t,type:i},pin_layout:n,is_public:u,metadata:{title:r,tags:s,description:o}})}async createMarkdownLegacy(e,t){return this.createMarkdown({title:e,content:"",...t})}};var C=class{constructor(e){this.client=e;}async create(e){return this.client.request("POST","/pinboards",e)}async get(e){return this.client.request("GET",`/pinboards/${e}`)}async list(){return this.client.request("GET","/pinboards")}async update(e,t){return this.client.request("PUT",`/pinboards/${e}`,t)}async delete(e){return this.client.request("DELETE",`/pinboards/${e}`)}async addPin(e,t){return this.client.request("POST",`/pinboards/${e}/pins`,t)}async removePin(e,t){return this.client.request("DELETE",`/pinboards/${e}/pins/${t}`)}async updateLayout(e,t){return this.client.request("PUT",`/pinboards/${e}/layout`,t)}async share(e,t){return this.client.request("POST",`/pinboards/${e}/share`,t)}async batchGet(e){return this.client.request("POST","/pinboards/batch/get",{pinboard_ids:e})}async batchAddPins(e,t,i){return this.client.request("POST",`/pinboards/${e}/pins/batch`,{pin_ids:t,layout:i})}async batchRemovePins(e,t){return this.client.request("DELETE",`/pinboards/${e}/pins/batch`,{pin_ids:t})}async createRole(e,t){return this.client.request("POST",`/pinboards/${e}/roles`,t)}async listRoles(e){return this.client.request("GET",`/pinboards/${e}/roles`)}async updateRole(e,t,i){return this.client.request("PUT",`/pinboards/${e}/roles/${t}`,i)}async deleteRole(e,t){return this.client.request("DELETE",`/pinboards/${e}/roles/${t}`)}async assignUserRoles(e,t,i){return this.client.request("PUT",`/pinboards/${e}/users/${t}/custom-roles`,{roleIds:i})}async setPinRoleRequirements(e,t,i){return this.client.request("PUT",`/pinboards/${e}/pins/${t}/required-roles`,{roleIds:i})}};var w=class{constructor(e){this.client=e;}async create(e){return this.client.request("POST","/pages",e)}async get(e){return this.client.request("GET",`/pages/${e}`)}async list(e){let t=new URLSearchParams;e?.limit&&t.append("limit",e.limit.toString()),e?.offset&&t.append("offset",e.offset.toString());let i=t.toString(),r=i?`/pages?${i}`:"/pages";return this.client.request("GET",r)}async listShared(e){let t=new URLSearchParams;e?.limit&&t.append("limit",e.limit.toString()),e?.offset&&t.append("offset",e.offset.toString());let i=t.toString(),r=i?`/pages/shared?${i}`:"/pages/shared";return this.client.request("GET",r)}async update(e,t){return this.client.request("PUT",`/pages/${e}`,t)}async delete(e){return this.client.request("DELETE",`/pages/${e}`)}async addPin(e,t){return this.client.request("POST",`/pages/${e}/pins`,t)}async removePin(e,t){return this.client.request("DELETE",`/pages/${e}/pins/${t}`)}async listPins(e){return this.client.request("GET",`/pages/${e}/pins`)}async batchGet(e){return this.client.request("POST","/pages/batch/get",{page_ids:e})}async batchCreate(e){return this.client.request("POST","/pages/batch",{pages:e})}async batchUpdate(e){return this.client.request("PATCH","/pages/batch",{updates:e})}async batchDelete(e){return this.client.request("DELETE","/pages/batch",{page_ids:e})}};var R=class{constructor(e){this.client=e;}async listForPin(e){return this.client.request("GET",`/pins/${e}/collaborators`)}async inviteToPin(e,t){return this.client.request("POST",`/pins/${e}/collaborators`,t)}async updatePinRole(e,t,i){return this.client.request("PUT",`/pins/${e}/collaborators/${t}`,i)}async removeFromPin(e,t){return this.client.request("DELETE",`/pins/${e}/collaborators/${t}`)}async getPinPermissions(e){return this.client.request("GET",`/pins/${e}/permissions`)}async listForPinboard(e){return this.client.request("GET",`/pinboards/${e}/collaborators`)}async inviteToPinboard(e,t){return this.client.request("POST",`/pinboards/${e}/collaborators`,t)}async updatePinboardRole(e,t,i){return this.client.request("PUT",`/pinboards/${e}/collaborators/${t}`,i)}async removeFromPinboard(e,t){return this.client.request("DELETE",`/pinboards/${e}/collaborators/${t}`)}async getPinboardPermissions(e){return this.client.request("GET",`/pinboards/${e}/permissions`)}};var q=class{constructor(e){this.tierDetected=false;if(!e.apiKey)throw new Error("API key is required");this.config={apiKey:e.apiKey,tier:e.tier,baseURL:e.baseURL||"https://api.pindown.ai/v1",enableRateLimitTracking:e.enableRateLimitTracking??true,maxRetries:e.maxRetries??3,timeout:e.timeout??3e4},this.config.tier&&(this.rateLimiter=new T(this.config.tier),this.tierDetected=true),this.pins=new f(this),this.pinboards=new C(this),this.pages=new w(this),this.collaborators=new R(this);}async request(e,t,i){this.config.enableRateLimitTracking&&this.rateLimiter&&this.rateLimiter.checkLimit(e,t,i);let r=`${this.config.baseURL}${t}`,s={Authorization:`Bearer ${this.config.apiKey}`};i&&(e==="POST"||e==="PUT"||e==="PATCH"||e==="DELETE")&&(s["Content-Type"]="application/json");let o={method:e,headers:s,signal:AbortSignal.timeout(this.config.timeout)};i&&(e==="POST"||e==="PUT"||e==="PATCH"||e==="DELETE")&&(o.body=JSON.stringify(i));try{let n=await fetch(r,o);return !this.tierDetected&&this.config.enableRateLimitTracking&&this.detectTierFromHeaders(n.headers),n.ok||await this.handleErrorResponse(n),(await n.json()).data}catch(n){throw n instanceof p||n instanceof g||n instanceof P||n instanceof c||n instanceof l?n:n.name==="AbortError"||n.name==="TimeoutError"?new h("Request timeout"):new h(n.message||"Network request failed")}}async handleErrorResponse(e){let t;try{t=await e.json();}catch{t={message:e.statusText};}let i=t.error?.message||t.message||"Unknown error";switch(e.status){case 401:throw new p(i);case 403:throw new g(i);case 404:throw new P(i);case 400:case 422:throw new c(i,t.error?.details);case 429:throw new c("Rate limit exceeded (server)",t);case 500:case 502:case 503:throw new l(i,e.status);default:throw new l(i,e.status)}}detectTierFromHeaders(e){let t=e.get("X-RateLimit-Tier");if(t&&!this.rateLimiter){let i=t.toLowerCase();console.log(`[Pindown Client] Auto-detected tier: ${i}`),this.config.tier=i,this.rateLimiter=new T(i),this.tierDetected=true;}}getRateLimitInfo(){return this.rateLimiter?this.rateLimiter.getRateLimitInfo():null}getTier(){return this.config.tier||null}destroy(){this.rateLimiter&&this.rateLimiter.destroy();}};
2
- exports.AuthenticationError=p;exports.ForbiddenError=g;exports.NetworkError=h;exports.NotFoundError=P;exports.PindownClient=q;exports.PindownError=d;exports.RateLimitError=m;exports.ServerError=l;exports.ValidationError=c;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var y=class{constructor(e){this.client=e;}async create(e){return this.client.request("POST","/pins",e)}async get(e){return this.client.request("GET",`/pins/${e}`)}async list(e){let i=new URLSearchParams;e?.limit&&i.append("limit",e.limit.toString()),e?.offset&&i.append("offset",e.offset.toString());let n=i.toString(),s=n?`/pins?${n}`:"/pins";return this.client.request("GET",s)}async update(e,i){return this.client.request("PUT",`/pins/${e}`,i)}async delete(e){return this.client.request("DELETE",`/pins/${e}`)}async share(e,i){return this.client.request("POST",`/pins/${e}/share`,i)}async batchGet(e){return this.client.request("POST","/pins/batch/get",{pin_ids:e})}async batchCreate(e){return this.client.request("POST","/pins/batch",{pins:e})}async batchUpdate(e){return this.client.request("PATCH","/pins/batch",{updates:e})}async batchDelete(e){return this.client.request("DELETE","/pins/batch",{pin_ids:e})}async createMarkdown(e){let{content:i,title:n,tags:s,description:a,pin_layout:o,is_public:t,allow_edit:d,require_sign_in:w,allow_comments:b,pending_invites:_}=e;return this.create({pin_type:"markdown",pin_config:{content:i},pin_layout:o,is_public:t,allow_edit:d,require_sign_in:w,allow_comments:b,pending_invites:_,metadata:{title:n,tags:s,description:a}})}async createStatCards(e){let{cards:i,title:n,tags:s,description:a,pin_layout:o,is_public:t}=e;return this.create({pin_type:"stat-cards",pin_config:{cards:i},pin_layout:o,is_public:t,metadata:{title:n,tags:s,description:a}})}async createTable(e){let{columns:i,rows:n,title:s,tags:a,description:o,pin_layout:t,is_public:d}=e;return this.create({pin_type:"table",pin_config:{columns:i,rows:n},pin_layout:t,is_public:d,metadata:{title:s,tags:a,description:o}})}async updateTable(e,i){let{columns:n,rows:s,title:a,tags:o,description:t}=i,d={};return n!==void 0&&(d.columns=n),s!==void 0&&(d.rows=s),this.update(e,{pin_config:d,...a!==void 0||o!==void 0||t!==void 0?{metadata:{...a!==void 0&&{title:a},...o!==void 0&&{tags:o},...t!==void 0&&{description:t}}}:{}})}async createEmbed(e){let{url:i,type:n,title:s,tags:a,description:o,pin_layout:t,is_public:d}=e;return this.create({pin_type:"embed",pin_config:{url:i,type:n},pin_layout:t,is_public:d,metadata:{title:s,tags:a,description:o}})}async createMarkdownLegacy(e,i){return this.createMarkdown({title:e,content:"",...i})}};var p=class extends Error{constructor(e){super(e),this.name="PindownError";}},u=class extends p{constructor(e="Authentication failed"){super(e),this.name="AuthenticationError";}},l=class extends p{constructor(e="Access forbidden"){super(e),this.name="ForbiddenError";}},P=class extends p{constructor(e){super(`${e} not found`),this.name="NotFoundError";}},f=class extends p{constructor(e,i){super(e),this.name="ValidationError",this.details=i;}},g=class extends p{constructor(e="Rate limit exceeded (429 RATE_LIMITED)"){super(e),this.name="RateLimitError";}},c=class extends p{constructor(e,i=500){super(e),this.name="ServerError",this.statusCode=i;}},m=class extends p{constructor(e="Network request failed"){super(e),this.name="NetworkError";}};var C=class{constructor(e){if(!e.apiKey)throw new Error("API key is required");this.config={apiKey:e.apiKey,baseURL:e.baseURL||"https://api.pindown.ai/v1",maxRetries:e.maxRetries??3,timeout:e.timeout??3e4},this.pins=new y(this);}async request(e,i,n){let s=`${this.config.baseURL}${i}`,a={Authorization:`Bearer ${this.config.apiKey}`};n&&(e==="POST"||e==="PUT"||e==="PATCH"||e==="DELETE")&&(a["Content-Type"]="application/json");let o={method:e,headers:a,signal:AbortSignal.timeout(this.config.timeout)};n&&(e==="POST"||e==="PUT"||e==="PATCH"||e==="DELETE")&&(o.body=JSON.stringify(n));try{let t=await fetch(s,o);return t.ok||await this.handleErrorResponse(t),(await t.json()).data}catch(t){throw t instanceof u||t instanceof l||t instanceof P||t instanceof f||t instanceof g||t instanceof c?t:t instanceof Error&&(t.name==="AbortError"||t.name==="TimeoutError")?new m("Request timeout"):new m(t instanceof Error?t.message:"Network request failed")}}async handleErrorResponse(e){let i;try{i=await e.json();}catch{i={message:e.statusText};}let n=i.error?.message||i.message||"Unknown error";switch(e.status){case 401:throw new u(n);case 403:throw new l(n);case 404:throw new P(n);case 400:case 422:throw new f(n,i.error?.details);case 429:throw new g(n);case 500:case 502:case 503:throw new c(n,e.status);default:throw new c(n,e.status)}}};var x={pin_type:"table",summary:"Spreadsheet-style pin. columns is required; rows are optional but needed for visible data.",required_fields:["columns"],optional_fields:["rows"],fields:[{path:"columns",type:"TableColumn[]",required:true,description:"At least one column. Each column needs id + name (type optional, e.g. text | number)."},{path:"columns[].id",type:"string",required:true,description:"Stable column key used in row.cells."},{path:"columns[].name",type:"string",required:true,description:"Column header label."},{path:"rows",type:"TableRow[]",required:false,description:"Table data. Each row: { id, cells: { [columnId]: value } }."}],example_config:{columns:[{id:"col1",name:"Name",type:"text"},{id:"col2",name:"Value",type:"number"}],rows:[{id:"row1",cells:{col1:"Item",col2:1}}]},example_update:{pin_config:{columns:[{id:"col1",name:"Name",type:"text"},{id:"col2",name:"Value",type:"number"}],rows:[{id:"row1",cells:{col1:"Updated",col2:42}}]}}},T={table:x,markdown:{pin_type:"markdown",summary:"Rich text / markdown body.",required_fields:[],optional_fields:["content","collaboration"],fields:[{path:"content",type:"string",required:false,description:"Markdown source. Server seeds Yjs when set on create."}],example_config:{content:`# Hello
2
+
3
+ Body text.`},example_update:{pin_config:{content:`# Updated
4
+
5
+ New body.`}}},"stat-cards":{pin_type:"stat-cards",summary:"KPI cards grid.",required_fields:["cards"],optional_fields:[],fields:[{path:"cards",type:"StatCardItem[]",required:true,description:"Each card: title, value; optional change, trend (up|down|neutral)."}],example_config:{cards:[{title:"Revenue",value:"1000",change:"+5%",trend:"up"}]},example_update:{pin_config:{cards:[{title:"Revenue",value:"1234",change:"+8%",trend:"up"}]}}}};function h(r){return T[r]}function I(r){let e=h(r);return e?[`Pin type: ${e.pin_type}`,e.summary,"","Required pin_config fields:",...e.required_fields.map(n=>` - ${n}`),"","Optional pin_config fields:",...e.optional_fields.length?e.optional_fields.map(n=>` - ${n}`):[" (none documented)"],"","Field reference:",...e.fields.map(n=>` ${n.path} (${n.type}${n.required?", required":""}): ${n.description}`),"","Example update payload:",JSON.stringify(e.example_update,null,2)].join(`
6
+ `):[`No built-in hint for pin type "${r}".`,"Use CreatePinRequest<typeof pinType> / PinConfigByType[typeof pinType] in TypeScript,","or client.pins.create({ pin_type, pin_config, metadata }) with typed pin_config."].join(`
7
+ `)}exports.AuthenticationError=u;exports.ForbiddenError=l;exports.NetworkError=m;exports.NotFoundError=P;exports.PIN_CONFIG_HINTS=T;exports.PindownClient=C;exports.PindownError=p;exports.RateLimitError=g;exports.ServerError=c;exports.ValidationError=f;exports.formatPinConfigHint=I;exports.getPinConfigHint=h;//# sourceMappingURL=index.cjs.map
3
8
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/tier-limits.json","../src/config/token-costs.json","../src/errors/index.ts","../src/utils/RateLimiter.ts","../src/client/pins/index.ts","../src/client/pinboards/index.ts","../src/client/pages/index.ts","../src/client/collaborators/index.ts","../src/client/PindownClient.ts"],"names":["tier_limits_default","token_costs_default","PindownError","message","AuthenticationError","ForbiddenError","NotFoundError","resource","ValidationError","details","RateLimitError","params","ServerError","statusCode","NetworkError","TIER_LIMITS","TOKEN_COSTS","RateLimiter","tier","method","endpoint","body","cost","minuteWindow","hourWindow","limits","used","hourUsed","ops","pins","now","window","current","minuteUsed","twoHoursAgo","key","windowKey","parts","year","month","day","hour","minute","PinsMethods","client","request","pinId","options","query","pinIds","updates","input","content","title","tags","description","pin_layout","is_public","allow_edit","require_sign_in","allow_comments","pending_invites","cards","columns","rows","url","type","additionalMetadata","PinboardsMethods","boardId","pinboardIds","layout","roleId","userId","roleIds","PagesMethods","pageId","pageIds","pages","CollaboratorsMethods","PindownClient","config","data","headers","requestOptions","response","error","errorData","tierHeader"],"mappings":"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","file":"index.cjs","sourcesContent":["{\r\n \"starter\": {\r\n \"tokensPerHour\": 16,\r\n \"tokensPerMinute\": null\r\n },\r\n \"hobby\": {\r\n \"tokensPerHour\": 6000,\r\n \"tokensPerMinute\": 100\r\n },\r\n \"pro\": {\r\n \"tokensPerHour\": 24000,\r\n \"tokensPerMinute\": 400\r\n },\r\n \"teams\": {\r\n \"tokensPerHour\": 60000,\r\n \"tokensPerMinute\": 1000\r\n },\r\n \"agency\": {\r\n \"tokensPerHour\": 240000,\r\n \"tokensPerMinute\": 4000\r\n }\r\n}\r\n\r\n","{\r\n \"GET\": 1,\r\n \"POST\": 1,\r\n \"PUT\": 1,\r\n \"DELETE\": 1,\r\n \"INVITE\": 3,\r\n \"SHARE\": 3,\r\n \"BATCH_1_10\": 3,\r\n \"BATCH_11_25\": 5,\r\n \"BATCH_26_50\": 10\r\n}\r\n","/**\r\n * Error classes for Pindown API Client\r\n */\r\n\r\nimport type { Tier } from '../types/config'\r\n\r\nexport class PindownError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = 'PindownError'\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PindownError {\r\n constructor(message: string = 'Authentication failed') {\r\n super(message)\r\n this.name = 'AuthenticationError'\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends PindownError {\r\n constructor(message: string = 'Access forbidden') {\r\n super(message)\r\n this.name = 'ForbiddenError'\r\n }\r\n}\r\n\r\nexport class NotFoundError extends PindownError {\r\n constructor(resource: string) {\r\n super(`${resource} not found`)\r\n this.name = 'NotFoundError'\r\n }\r\n}\r\n\r\nexport class ValidationError extends PindownError {\r\n public details?: any\r\n\r\n constructor(message: string, details?: any) {\r\n super(message)\r\n this.name = 'ValidationError'\r\n this.details = details\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PindownError {\r\n public window: 'minute' | 'hour'\r\n public limit: number\r\n public used: number\r\n public remaining: number\r\n public resetAt: Date\r\n public tier: Tier\r\n\r\n constructor(params: {\r\n window: 'minute' | 'hour'\r\n limit: number\r\n used: number\r\n remaining: number\r\n resetAt: Date\r\n tier: Tier\r\n }) {\r\n super(\r\n `Rate limit exceeded: ${params.used}/${params.limit} tokens used in ${params.window} window. ` +\r\n `Resets at ${params.resetAt.toISOString()}`\r\n )\r\n this.name = 'RateLimitError'\r\n this.window = params.window\r\n this.limit = params.limit\r\n this.used = params.used\r\n this.remaining = params.remaining\r\n this.resetAt = params.resetAt\r\n this.tier = params.tier\r\n }\r\n}\r\n\r\nexport class ServerError extends PindownError {\r\n public statusCode: number\r\n\r\n constructor(message: string, statusCode: number = 500) {\r\n super(message)\r\n this.name = 'ServerError'\r\n this.statusCode = statusCode\r\n }\r\n}\r\n\r\nexport class NetworkError extends PindownError {\r\n constructor(message: string = 'Network request failed') {\r\n super(message)\r\n this.name = 'NetworkError'\r\n }\r\n}\r\n\r\n","/**\r\n * Rate Limiter - Client-side rate limiting with in-memory counters\r\n */\r\n\r\nimport tierLimitsJson from '../config/tier-limits.json'\r\nimport tokenCostsJson from '../config/token-costs.json'\r\nimport { RateLimitError } from '../errors'\r\nimport type { Tier } from '../types/config'\r\nimport type { RateLimitInfo } from '../types/api'\r\n\r\nconst TIER_LIMITS = tierLimitsJson as Record<Tier, { tokensPerHour: number; tokensPerMinute: number | null }>\r\nconst TOKEN_COSTS = tokenCostsJson as Record<string, number>\r\n\r\nexport class RateLimiter {\r\n private tier: Tier\r\n private minuteTokens = new Map<string, number>()\r\n private hourTokens = new Map<string, number>()\r\n private cleanupInterval: NodeJS.Timeout | number\r\n\r\n constructor(tier: Tier) {\r\n this.tier = tier\r\n \r\n // Auto-cleanup expired windows every 5 minutes\r\n this.cleanupInterval = setInterval(() => this.cleanup(), 5 * 60 * 1000)\r\n }\r\n\r\n /**\r\n * Check if request is allowed, throw RateLimitError if limit reached\r\n */\r\n checkLimit(method: string, endpoint: string, body?: any): void {\r\n const cost = this.calculateTokenCost(method, endpoint, body)\r\n const minuteWindow = this.getMinuteWindow()\r\n const hourWindow = this.getHourWindow()\r\n \r\n const limits = TIER_LIMITS[this.tier]\r\n \r\n // Check minute limit (if exists)\r\n if (limits.tokensPerMinute !== null) {\r\n const used = this.minuteTokens.get(minuteWindow) || 0\r\n if (used + cost > limits.tokensPerMinute) {\r\n throw new RateLimitError({\r\n window: 'minute',\r\n limit: limits.tokensPerMinute,\r\n used,\r\n remaining: Math.max(0, limits.tokensPerMinute - used),\r\n resetAt: this.getMinuteResetTime(),\r\n tier: this.tier\r\n })\r\n }\r\n }\r\n \r\n // Check hour limit\r\n const hourUsed = this.hourTokens.get(hourWindow) || 0\r\n if (hourUsed + cost > limits.tokensPerHour) {\r\n throw new RateLimitError({\r\n window: 'hour',\r\n limit: limits.tokensPerHour,\r\n used: hourUsed,\r\n remaining: Math.max(0, limits.tokensPerHour - hourUsed),\r\n resetAt: this.getHourResetTime(),\r\n tier: this.tier\r\n })\r\n }\r\n \r\n // Increment counters\r\n this.incrementToken(minuteWindow, cost)\r\n this.incrementToken(hourWindow, cost)\r\n }\r\n\r\n /**\r\n * Calculate token cost for a request\r\n */\r\n private calculateTokenCost(method: string, endpoint: string, body?: any): number {\r\n // Check for batch endpoints\r\n if (endpoint.includes('/batch') || endpoint.includes('/sync')) {\r\n if (body?.operations) {\r\n const ops = Array.isArray(body.operations) ? body.operations.length : 0\r\n if (ops <= 10) return TOKEN_COSTS.BATCH_1_10\r\n if (ops <= 25) return TOKEN_COSTS.BATCH_11_25\r\n if (ops <= 50) return TOKEN_COSTS.BATCH_26_50\r\n return TOKEN_COSTS.BATCH_26_50 // Cap at 50\r\n }\r\n // For /sync endpoints, check pins array\r\n if (body?.pins) {\r\n const pins = Array.isArray(body.pins) ? body.pins.length : 0\r\n if (pins <= 16) return 5 // As per RATE_LIMITING_STRATEGY.md\r\n if (pins <= 32) return 8\r\n return 8 // Cap at 32\r\n }\r\n }\r\n \r\n // Check for invite/share endpoints\r\n if (endpoint.includes('/collaborators') || endpoint.includes('/invite') || endpoint.includes('/share')) {\r\n return TOKEN_COSTS.INVITE\r\n }\r\n \r\n // Standard methods (all cost 1 token)\r\n return TOKEN_COSTS[method] || 1\r\n }\r\n\r\n /**\r\n * Get current minute window key\r\n */\r\n private getMinuteWindow(): string {\r\n const now = new Date()\r\n return `minute_${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}-${String(now.getMinutes()).padStart(2, '0')}`\r\n }\r\n\r\n /**\r\n * Get current hour window key\r\n */\r\n private getHourWindow(): string {\r\n const now = new Date()\r\n return `hour_${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}`\r\n }\r\n\r\n /**\r\n * Increment token count for a window\r\n */\r\n private incrementToken(window: string, cost: number): void {\r\n if (window.startsWith('minute')) {\r\n const current = this.minuteTokens.get(window) || 0\r\n this.minuteTokens.set(window, current + cost)\r\n } else {\r\n const current = this.hourTokens.get(window) || 0\r\n this.hourTokens.set(window, current + cost)\r\n }\r\n }\r\n\r\n /**\r\n * Get reset time for current minute window\r\n */\r\n private getMinuteResetTime(): Date {\r\n const now = new Date()\r\n return new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes() + 1, 0, 0)\r\n }\r\n\r\n /**\r\n * Get reset time for current hour window\r\n */\r\n private getHourResetTime(): Date {\r\n const now = new Date()\r\n return new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours() + 1, 0, 0, 0)\r\n }\r\n\r\n /**\r\n * Get current rate limit info\r\n */\r\n getRateLimitInfo(): RateLimitInfo {\r\n const limits = TIER_LIMITS[this.tier]\r\n const minuteWindow = this.getMinuteWindow()\r\n const hourWindow = this.getHourWindow()\r\n \r\n const minuteUsed = this.minuteTokens.get(minuteWindow) || 0\r\n const hourUsed = this.hourTokens.get(hourWindow) || 0\r\n \r\n return {\r\n tier: this.tier,\r\n minute: {\r\n limit: limits.tokensPerMinute || 0,\r\n used: minuteUsed,\r\n remaining: limits.tokensPerMinute \r\n ? Math.max(0, limits.tokensPerMinute - minuteUsed)\r\n : Infinity,\r\n resetAt: this.getMinuteResetTime()\r\n },\r\n hour: {\r\n limit: limits.tokensPerHour,\r\n used: hourUsed,\r\n remaining: Math.max(0, limits.tokensPerHour - hourUsed),\r\n resetAt: this.getHourResetTime()\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup expired windows (older than 2 hours)\r\n */\r\n private cleanup(): void {\r\n const now = Date.now()\r\n const twoHoursAgo = now - 2 * 60 * 60 * 1000\r\n \r\n // Parse and remove old minute windows\r\n for (const [key] of this.minuteTokens) {\r\n if (this.parseWindowTimestamp(key) < twoHoursAgo) {\r\n this.minuteTokens.delete(key)\r\n }\r\n }\r\n \r\n // Parse and remove old hour windows\r\n for (const [key] of this.hourTokens) {\r\n if (this.parseWindowTimestamp(key) < twoHoursAgo) {\r\n this.hourTokens.delete(key)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Parse timestamp from window key\r\n */\r\n private parseWindowTimestamp(windowKey: string): number {\r\n const parts = windowKey.split('_')[1].split('-')\r\n const year = parseInt(parts[0])\r\n const month = parseInt(parts[1]) - 1\r\n const day = parseInt(parts[2])\r\n const hour = parseInt(parts[3])\r\n const minute = windowKey.startsWith('minute') ? parseInt(parts[4]) : 0\r\n \r\n return new Date(year, month, day, hour, minute).getTime()\r\n }\r\n\r\n /**\r\n * Destroy the rate limiter (cleanup interval)\r\n */\r\n destroy(): void {\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval as NodeJS.Timeout)\r\n }\r\n }\r\n}\r\n\r\n","/**\n * Pins API Methods\n */\n\nimport type { PindownClient } from '../PindownClient'\nimport type {\n Pin,\n PinTypeId,\n CreatePinRequest,\n UpdatePinRequest,\n SharePinRequest,\n ListPinsOptions,\n CreateMarkdownPinInput,\n CreateStatCardsPinInput,\n CreateTablePinInput,\n CreateEmbedPinInput,\n} from '../../types/pins'\nimport type { PaginatedResponse } from '../../types/api'\n\nexport class PinsMethods {\n constructor(private client: PindownClient) {}\n\n /** Create a pin (typed via CreatePinRequest&lt;T&gt;) */\n async create<T extends PinTypeId>(request: CreatePinRequest<T>): Promise<Pin<T>> {\n return this.client.request<Pin<T>>('POST', '/pins', request)\n }\n\n async get<T extends PinTypeId = PinTypeId>(pinId: string): Promise<Pin<T>> {\n return this.client.request<Pin<T>>('GET', `/pins/${pinId}`)\n }\n\n async list(options?: ListPinsOptions): Promise<PaginatedResponse<Pin>> {\n const params = new URLSearchParams()\n if (options?.limit) params.append('limit', options.limit.toString())\n if (options?.offset) params.append('offset', options.offset.toString())\n\n const query = params.toString()\n const endpoint = query ? `/pins?${query}` : '/pins'\n\n return this.client.request<PaginatedResponse<Pin>>('GET', endpoint)\n }\n\n async update<T extends PinTypeId = PinTypeId>(pinId: string, request: UpdatePinRequest<T>): Promise<Pin<T>> {\n return this.client.request<Pin<T>>('PUT', `/pins/${pinId}`, request)\n }\n\n async delete(pinId: string): Promise<void> {\n return this.client.request<void>('DELETE', `/pins/${pinId}`)\n }\n\n async share(pinId: string, request: SharePinRequest): Promise<Pin> {\n return this.client.request<Pin>('POST', `/pins/${pinId}/share`, request)\n }\n\n async batchGet(pinIds: string[]): Promise<{\n found: Pin[]\n not_found: string[]\n permission_denied: string[]\n }> {\n return this.client.request('POST', '/pins/batch/get', { pin_ids: pinIds })\n }\n\n async batchCreate(pins: CreatePinRequest[]): Promise<{\n created: Array<{ id: string; index: number; created_at: number }>\n failed: Array<{ index: number; error: string }>\n }> {\n return this.client.request('POST', '/pins/batch', { pins })\n }\n\n async batchUpdate(updates: Array<{ id: string } & UpdatePinRequest>): Promise<{\n updated: string[]\n failed: Array<{ id: string; error: string }>\n updated_at: number\n }> {\n return this.client.request('PATCH', '/pins/batch', { updates })\n }\n\n async batchDelete(pinIds: string[]): Promise<{\n deleted: string[]\n failed: Array<{ id: string; error: string }>\n }> {\n return this.client.request('DELETE', '/pins/batch', { pin_ids: pinIds })\n }\n\n /** Create a markdown pin with pin_config.content (seeds Yjs on the server). */\n async createMarkdown(input: CreateMarkdownPinInput): Promise<Pin<'markdown'>> {\n const { content, title, tags, description, pin_layout, is_public, allow_edit, require_sign_in, allow_comments, pending_invites } = input\n return this.create({\n pin_type: 'markdown',\n pin_config: { content },\n pin_layout,\n is_public,\n allow_edit,\n require_sign_in,\n allow_comments,\n pending_invites,\n metadata: { title, tags, description },\n })\n }\n\n async createStatCards(input: CreateStatCardsPinInput): Promise<Pin<'stat-cards'>> {\n const { cards, title, tags, description, pin_layout, is_public } = input\n return this.create({\n pin_type: 'stat-cards',\n pin_config: { cards },\n pin_layout,\n is_public,\n metadata: { title, tags, description },\n })\n }\n\n async createTable(input: CreateTablePinInput): Promise<Pin<'table'>> {\n const { columns, rows, title, tags, description, pin_layout, is_public } = input\n return this.create({\n pin_type: 'table',\n pin_config: { columns, rows },\n pin_layout,\n is_public,\n metadata: { title, tags, description },\n })\n }\n\n async createEmbed(input: CreateEmbedPinInput): Promise<Pin<'embed'>> {\n const { url, type, title, tags, description, pin_layout, is_public } = input\n return this.create({\n pin_type: 'embed',\n pin_config: { url, type },\n pin_layout,\n is_public,\n metadata: { title, tags, description },\n })\n }\n\n /**\n * @deprecated Use createMarkdown({ title, content, ... }) — old signature ignored content in title\n */\n async createMarkdownLegacy(title: string, additionalMetadata?: Record<string, unknown>): Promise<Pin<'markdown'>> {\n return this.createMarkdown({\n title,\n content: '',\n ...(additionalMetadata as Partial<CreateMarkdownPinInput>),\n })\n }\n}\n","/**\n * Pinboards API Methods\n */\n\nimport type { PindownClient } from '../PindownClient'\nimport type {\n Pinboard,\n CreatePinboardRequest,\n UpdatePinboardRequest,\n AddPinToPinboardRequest,\n UpdatePinboardLayoutRequest\n} from '../../types/api'\n\nexport class PinboardsMethods {\n constructor(private client: PindownClient) {}\n\n /**\n * Create a new pinboard\n */\n async create(request: CreatePinboardRequest): Promise<Pinboard> {\n return this.client.request<Pinboard>('POST', '/pinboards', request)\n }\n\n /**\n * Get a pinboard by ID\n */\n async get(boardId: string): Promise<Pinboard> {\n return this.client.request<Pinboard>('GET', `/pinboards/${boardId}`)\n }\n\n /**\n * List all pinboards\n */\n async list(): Promise<Pinboard[]> {\n return this.client.request<Pinboard[]>('GET', '/pinboards')\n }\n\n /**\n * Update a pinboard\n */\n async update(boardId: string, request: UpdatePinboardRequest): Promise<Pinboard> {\n return this.client.request<Pinboard>('PUT', `/pinboards/${boardId}`, request)\n }\n\n /**\n * Delete a pinboard\n */\n async delete(boardId: string): Promise<void> {\n return this.client.request<void>('DELETE', `/pinboards/${boardId}`)\n }\n\n /**\n * Add a pin to a pinboard\n */\n async addPin(boardId: string, request: AddPinToPinboardRequest): Promise<Pinboard> {\n return this.client.request<Pinboard>('POST', `/pinboards/${boardId}/pins`, request)\n }\n\n /**\n * Remove a pin from a pinboard\n */\n async removePin(boardId: string, pinId: string): Promise<void> {\n return this.client.request<void>('DELETE', `/pinboards/${boardId}/pins/${pinId}`)\n }\n\n /**\n * Update pinboard layout\n */\n async updateLayout(boardId: string, request: UpdatePinboardLayoutRequest): Promise<Pinboard> {\n return this.client.request<Pinboard>('PUT', `/pinboards/${boardId}/layout`, request)\n }\n\n /**\n * Update pinboard sharing settings\n */\n async share(boardId: string, request: {\n is_public?: boolean\n require_sign_in?: boolean\n allow_comments?: boolean\n }): Promise<Pinboard> {\n return this.client.request<Pinboard>('POST', `/pinboards/${boardId}/share`, request)\n }\n\n // ============================================\n // Batch Operations\n // ============================================\n\n /**\n * Get multiple pinboards by IDs in a single request (max 100 pinboards)\n */\n async batchGet(pinboardIds: string[]): Promise<{\n found: Pinboard[]\n not_found: string[]\n permission_denied: string[]\n }> {\n return this.client.request<{\n found: Pinboard[]\n not_found: string[]\n permission_denied: string[]\n }>('POST', '/pinboards/batch/get', {\n pinboard_ids: pinboardIds\n })\n }\n\n /**\n * Add multiple pins to a pinboard with layout in a single request (max 50 pins)\n */\n async batchAddPins(boardId: string, pinIds: string[], layout?: Record<string, {\n x: number\n y: number\n w: number\n h: number\n }>): Promise<{\n added: string[]\n failed: Array<{ id: string; error: string }>\n layout_updated: boolean\n }> {\n return this.client.request<{\n added: string[]\n failed: Array<{ id: string; error: string }>\n layout_updated: boolean\n }>('POST', `/pinboards/${boardId}/pins/batch`, {\n pin_ids: pinIds,\n layout\n })\n }\n\n /**\n * Remove multiple pins from a pinboard in a single request (max 50 pins)\n */\n async batchRemovePins(boardId: string, pinIds: string[]): Promise<{\n removed: string[]\n failed: Array<{ id: string; error: string }>\n }> {\n return this.client.request<{\n removed: string[]\n failed: Array<{ id: string; error: string }>\n }>('DELETE', `/pinboards/${boardId}/pins/batch`, {\n pin_ids: pinIds\n })\n }\n\n // ============================================\n // Custom Roles\n // ============================================\n\n /**\n * Create a custom role for a pinboard (max 5 roles per pinboard)\n */\n async createRole(boardId: string, request: {\n name: string\n color: string\n permissions?: Record<string, any>\n }): Promise<{ roleId: string; name: string; color: string }> {\n return this.client.request<{ roleId: string; name: string; color: string }>('POST', `/pinboards/${boardId}/roles`, request)\n }\n\n /**\n * List custom roles for a pinboard\n */\n async listRoles(boardId: string): Promise<Record<string, any>> {\n return this.client.request<Record<string, any>>('GET', `/pinboards/${boardId}/roles`)\n }\n\n /**\n * Update a custom role\n */\n async updateRole(boardId: string, roleId: string, request: {\n name?: string\n color?: string\n permissions?: Record<string, any>\n }): Promise<void> {\n return this.client.request<void>('PUT', `/pinboards/${boardId}/roles/${roleId}`, request)\n }\n\n /**\n * Delete a custom role\n */\n async deleteRole(boardId: string, roleId: string): Promise<void> {\n return this.client.request<void>('DELETE', `/pinboards/${boardId}/roles/${roleId}`)\n }\n\n /**\n * Assign custom roles to a user (user must be a collaborator first)\n */\n async assignUserRoles(boardId: string, userId: string, roleIds: string[]): Promise<void> {\n return this.client.request<void>('PUT', `/pinboards/${boardId}/users/${userId}/custom-roles`, { roleIds })\n }\n\n /**\n * Set role requirements for a pin (only users with these roles can see the pin)\n */\n async setPinRoleRequirements(boardId: string, pinId: string, roleIds: string[]): Promise<void> {\n return this.client.request<void>('PUT', `/pinboards/${boardId}/pins/${pinId}/required-roles`, { roleIds })\n }\n}\n\n","/**\r\n * Pages API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Page,\r\n CreatePageRequest,\r\n UpdatePageRequest,\r\n AddPinToPageRequest,\r\n ListPagesOptions\r\n} from '../../types/api'\r\n\r\nexport class PagesMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new page\r\n */\r\n async create(request: CreatePageRequest): Promise<Page> {\r\n return this.client.request<Page>('POST', '/pages', request)\r\n }\r\n\r\n /**\r\n * Get a page by ID\r\n */\r\n async get(pageId: string): Promise<Page> {\r\n return this.client.request<Page>('GET', `/pages/${pageId}`)\r\n }\r\n\r\n /**\r\n * List all pages\r\n */\r\n async list(options?: ListPagesOptions): Promise<{\r\n pages: Page[]\r\n total: number\r\n }> {\r\n const params = new URLSearchParams()\r\n if (options?.limit) params.append('limit', options.limit.toString())\r\n if (options?.offset) params.append('offset', options.offset.toString())\r\n\r\n const query = params.toString()\r\n const endpoint = query ? `/pages?${query}` : '/pages'\r\n\r\n return this.client.request<{\r\n pages: Page[]\r\n total: number\r\n }>('GET', endpoint)\r\n }\r\n\r\n /**\r\n * List pages shared with user\r\n */\r\n async listShared(options?: ListPagesOptions): Promise<{\r\n pages: Page[]\r\n total: number\r\n }> {\r\n const params = new URLSearchParams()\r\n if (options?.limit) params.append('limit', options.limit.toString())\r\n if (options?.offset) params.append('offset', options.offset.toString())\r\n\r\n const query = params.toString()\r\n const endpoint = query ? `/pages/shared?${query}` : '/pages/shared'\r\n\r\n return this.client.request<{\r\n pages: Page[]\r\n total: number\r\n }>('GET', endpoint)\r\n }\r\n\r\n /**\r\n * Update a page\r\n */\r\n async update(pageId: string, request: UpdatePageRequest): Promise<Page> {\r\n return this.client.request<Page>('PUT', `/pages/${pageId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a page\r\n */\r\n async delete(pageId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pages/${pageId}`)\r\n }\r\n\r\n /**\r\n * Add a pin to a page\r\n */\r\n async addPin(pageId: string, request: AddPinToPageRequest): Promise<void> {\r\n return this.client.request<void>('POST', `/pages/${pageId}/pins`, request)\r\n }\r\n\r\n /**\r\n * Remove a pin from a page\r\n */\r\n async removePin(pageId: string, pinId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pages/${pageId}/pins/${pinId}`)\r\n }\r\n\r\n /**\r\n * List pins in a page\r\n */\r\n async listPins(pageId: string): Promise<{\r\n pins: string[]\r\n total: number\r\n }> {\r\n return this.client.request<{\r\n pins: string[]\r\n total: number\r\n }>('GET', `/pages/${pageId}/pins`)\r\n }\r\n\r\n // ============================================\r\n // Batch Operations\r\n // ============================================\r\n\r\n /**\r\n * Get multiple pages by IDs in a single request (max 100 pages)\r\n */\r\n async batchGet(pageIds: string[]): Promise<{\r\n found: Page[]\r\n not_found: string[]\r\n permission_denied: string[]\r\n }> {\r\n return this.client.request<{\r\n found: Page[]\r\n not_found: string[]\r\n permission_denied: string[]\r\n }>('POST', '/pages/batch/get', {\r\n page_ids: pageIds\r\n })\r\n }\r\n\r\n /**\r\n * Create multiple pages in a single request (max 50 pages)\r\n */\r\n async batchCreate(pages: CreatePageRequest[]): Promise<{\r\n created: Array<{ id: string; index: number; created_at: number }>\r\n failed: Array<{ index: number; error: string }>\r\n }> {\r\n return this.client.request<{\r\n created: Array<{ id: string; index: number; created_at: number }>\r\n failed: Array<{ index: number; error: string }>\r\n }>('POST', '/pages/batch', {\r\n pages\r\n })\r\n }\r\n\r\n /**\r\n * Update multiple pages in a single request (max 50 pages)\r\n */\r\n async batchUpdate(updates: Array<{ id: string } & UpdatePageRequest>): Promise<{\r\n updated: string[]\r\n failed: Array<{ id: string; error: string }>\r\n updated_at: number\r\n }> {\r\n return this.client.request<{\r\n updated: string[]\r\n failed: Array<{ id: string; error: string }>\r\n updated_at: number\r\n }>('PATCH', '/pages/batch', {\r\n updates\r\n })\r\n }\r\n\r\n /**\r\n * Delete multiple pages in a single request (max 50 pages)\r\n */\r\n async batchDelete(pageIds: string[]): Promise<{\r\n deleted: string[]\r\n failed: Array<{ id: string; error: string }>\r\n }> {\r\n return this.client.request<{\r\n deleted: string[]\r\n failed: Array<{ id: string; error: string }>\r\n }>('DELETE', '/pages/batch', {\r\n page_ids: pageIds\r\n })\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n","/**\r\n * Collaborators API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Collaborator,\r\n InviteCollaboratorRequest,\r\n UpdateCollaboratorRoleRequest,\r\n Permissions\r\n} from '../../types/api'\r\n\r\nexport class CollaboratorsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n // ============================================\r\n // Pin Collaborators\r\n // ============================================\r\n\r\n /**\r\n * List collaborators for a pin\r\n */\r\n async listForPin(pinId: string): Promise<{\r\n owner: Collaborator\r\n collaborators: Collaborator[]\r\n pending_invites: Array<{ email: string; role: string; invited_at: string }>\r\n }> {\r\n return this.client.request('GET', `/pins/${pinId}/collaborators`)\r\n }\r\n\r\n /**\r\n * Invite a collaborator to a pin\r\n */\r\n async inviteToPin(pinId: string, request: InviteCollaboratorRequest): Promise<void> {\r\n return this.client.request('POST', `/pins/${pinId}/collaborators`, request)\r\n }\r\n\r\n /**\r\n * Update a pin collaborator's role\r\n */\r\n async updatePinRole(pinId: string, userId: string, request: UpdateCollaboratorRoleRequest): Promise<void> {\r\n return this.client.request('PUT', `/pins/${pinId}/collaborators/${userId}`, request)\r\n }\r\n\r\n /**\r\n * Remove a collaborator from a pin\r\n */\r\n async removeFromPin(pinId: string, userId: string): Promise<void> {\r\n return this.client.request('DELETE', `/pins/${pinId}/collaborators/${userId}`)\r\n }\r\n\r\n /**\r\n * Get current user's permissions for a pin\r\n */\r\n async getPinPermissions(pinId: string): Promise<Permissions> {\r\n return this.client.request('GET', `/pins/${pinId}/permissions`)\r\n }\r\n\r\n // ============================================\r\n // Pinboard Collaborators\r\n // ============================================\r\n\r\n /**\r\n * List collaborators for a pinboard\r\n */\r\n async listForPinboard(boardId: string): Promise<{\r\n owner: Collaborator\r\n collaborators: Collaborator[]\r\n pending_invites: Array<{ email: string; role: string; invited_at: string }>\r\n }> {\r\n return this.client.request('GET', `/pinboards/${boardId}/collaborators`)\r\n }\r\n\r\n /**\r\n * Invite a collaborator to a pinboard\r\n */\r\n async inviteToPinboard(boardId: string, request: InviteCollaboratorRequest): Promise<void> {\r\n return this.client.request('POST', `/pinboards/${boardId}/collaborators`, request)\r\n }\r\n\r\n /**\r\n * Update a pinboard collaborator's role\r\n */\r\n async updatePinboardRole(boardId: string, userId: string, request: UpdateCollaboratorRoleRequest): Promise<void> {\r\n return this.client.request('PUT', `/pinboards/${boardId}/collaborators/${userId}`, request)\r\n }\r\n\r\n /**\r\n * Remove a collaborator from a pinboard\r\n */\r\n async removeFromPinboard(boardId: string, userId: string): Promise<void> {\r\n return this.client.request('DELETE', `/pinboards/${boardId}/collaborators/${userId}`)\r\n }\r\n\r\n /**\r\n * Get current user's permissions for a pinboard\r\n */\r\n async getPinboardPermissions(boardId: string): Promise<Permissions> {\r\n return this.client.request('GET', `/pinboards/${boardId}/permissions`)\r\n }\r\n}\r\n\r\n","/**\n * Pindown API Client\n */\n\nimport { RateLimiter } from '../utils/RateLimiter'\nimport { PinsMethods } from './pins'\nimport { PinboardsMethods } from './pinboards'\nimport { PagesMethods } from './pages'\nimport { CollaboratorsMethods } from './collaborators'\nimport type { PindownConfig, Tier } from '../types/config'\nimport type { RateLimitInfo } from '../types/api'\nimport {\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n ServerError,\n NetworkError\n} from '../errors'\n\nexport class PindownClient {\n private config: Omit<Required<PindownConfig>, 'tier'> & { tier?: Tier }\n private rateLimiter?: RateLimiter\n private tierDetected: boolean = false\n\n public readonly pins: PinsMethods\n public readonly pinboards: PinboardsMethods\n public readonly pages: PagesMethods\n public readonly collaborators: CollaboratorsMethods\n\n constructor(config: PindownConfig) {\n // Validate required config\n if (!config.apiKey) {\n throw new Error('API key is required')\n }\n\n // Set defaults\n this.config = {\n apiKey: config.apiKey,\n tier: config.tier, // Optional - will be auto-detected\n baseURL: config.baseURL || 'https://api.pindown.ai/v1',\n enableRateLimitTracking: config.enableRateLimitTracking ?? true,\n maxRetries: config.maxRetries ?? 3,\n timeout: config.timeout ?? 30000\n }\n\n // Initialize rate limiter if tier is provided\n if (this.config.tier) {\n this.rateLimiter = new RateLimiter(this.config.tier)\n this.tierDetected = true\n }\n\n // Initialize API methods\n this.pins = new PinsMethods(this)\n this.pinboards = new PinboardsMethods(this)\n this.pages = new PagesMethods(this)\n this.collaborators = new CollaboratorsMethods(this)\n }\n\n /**\n * Core request method\n */\n async request<T = any>(\n method: string,\n endpoint: string,\n data?: any\n ): Promise<T> {\n // Check rate limit BEFORE making request (if tier is detected)\n if (this.config.enableRateLimitTracking && this.rateLimiter) {\n this.rateLimiter.checkLimit(method, endpoint, data)\n }\n\n const url = `${this.config.baseURL}${endpoint}`\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.config.apiKey}`\n }\n\n // Only set Content-Type for methods with body\n if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE')) {\n headers['Content-Type'] = 'application/json'\n }\n\n const requestOptions: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.config.timeout)\n }\n\n if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE')) {\n requestOptions.body = JSON.stringify(data)\n }\n\n try {\n const response = await fetch(url, requestOptions)\n\n // Auto-detect tier from response headers (if not already detected)\n if (!this.tierDetected && this.config.enableRateLimitTracking) {\n this.detectTierFromHeaders(response.headers)\n }\n\n // Handle error responses\n if (!response.ok) {\n await this.handleErrorResponse(response)\n }\n\n // Parse JSON response\n const result = await response.json()\n return result.data as T\n } catch (error: any) {\n // Re-throw our custom errors\n if (\n error instanceof AuthenticationError ||\n error instanceof ForbiddenError ||\n error instanceof NotFoundError ||\n error instanceof ValidationError ||\n error instanceof ServerError\n ) {\n throw error\n }\n\n // Network or timeout errors\n if (error.name === 'AbortError' || error.name === 'TimeoutError') {\n throw new NetworkError('Request timeout')\n }\n\n throw new NetworkError(error.message || 'Network request failed')\n }\n }\n\n /**\n * Handle error responses from API\n */\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorData: any\n\n try {\n errorData = await response.json()\n } catch {\n errorData = { message: response.statusText }\n }\n\n const message = errorData.error?.message || errorData.message || 'Unknown error'\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message)\n case 403:\n throw new ForbiddenError(message)\n case 404:\n throw new NotFoundError(message)\n case 400:\n case 422:\n throw new ValidationError(message, errorData.error?.details)\n case 429:\n // Rate limit error from server (should rarely happen with client-side limiting)\n throw new ValidationError('Rate limit exceeded (server)', errorData)\n case 500:\n case 502:\n case 503:\n throw new ServerError(message, response.status)\n default:\n throw new ServerError(message, response.status)\n }\n }\n\n /**\n * Detect tier from response headers\n */\n private detectTierFromHeaders(headers: Headers): void {\n const tierHeader = headers.get('X-RateLimit-Tier')\n if (tierHeader && !this.rateLimiter) {\n const tier = tierHeader.toLowerCase() as Tier\n console.log(`[Pindown Client] Auto-detected tier: ${tier}`)\n this.config.tier = tier\n this.rateLimiter = new RateLimiter(tier)\n this.tierDetected = true\n }\n }\n\n /**\n * Get current rate limit info\n */\n getRateLimitInfo(): RateLimitInfo | null {\n if (!this.rateLimiter) {\n return null\n }\n return this.rateLimiter.getRateLimitInfo()\n }\n\n /**\n * Get current tier\n */\n getTier(): Tier | null {\n return this.config.tier || null\n }\n\n /**\n * Destroy the client (cleanup resources)\n */\n destroy(): void {\n if (this.rateLimiter) {\n this.rateLimiter.destroy()\n }\n }\n}\n\n"]}
1
+ {"version":3,"sources":["../src/client/pins/index.ts","../src/errors/index.ts","../src/client/PindownClient.ts","../src/pin-config-hints.ts"],"names":["PinsMethods","client","request","pinId","options","params","query","endpoint","pinIds","pins","updates","input","content","title","tags","description","pin_layout","is_public","allow_edit","require_sign_in","allow_comments","pending_invites","cards","columns","rows","pin_config","url","type","additionalMetadata","PindownError","message","AuthenticationError","ForbiddenError","NotFoundError","resource","ValidationError","details","RateLimitError","ServerError","statusCode","NetworkError","PindownClient","config","method","data","headers","requestOptions","response","error","errorData","TABLE_HINT","PIN_CONFIG_HINTS","getPinConfigHint","pinType","formatPinConfigHint","hint","f"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Pins API Methods\n */\n\nimport type { PindownClient } from '../PindownClient'\nimport type {\n Pin,\n PinTypeId,\n CreatePinRequest,\n UpdatePinRequest,\n SharePinRequest,\n ListPinsOptions,\n CreateMarkdownPinInput,\n CreateStatCardsPinInput,\n CreateTablePinInput,\n UpdateTablePinInput,\n CreateEmbedPinInput,\n TablePinConfig,\n} from '../../types/pins'\nimport type { PaginatedResponse } from '../../types/api'\n\nexport class PinsMethods {\n constructor(private client: PindownClient) {}\n\n /** Create a pin (typed via CreatePinRequest&lt;T&gt;) */\n async create<T extends PinTypeId>(request: CreatePinRequest<T>): Promise<Pin<T>> {\n return this.client.request<Pin<T>>('POST', '/pins', request)\n }\n\n async get<T extends PinTypeId = PinTypeId>(pinId: string): Promise<Pin<T>> {\n return this.client.request<Pin<T>>('GET', `/pins/${pinId}`)\n }\n\n async list(options?: ListPinsOptions): Promise<PaginatedResponse<Pin>> {\n const params = new URLSearchParams()\n if (options?.limit) params.append('limit', options.limit.toString())\n if (options?.offset) params.append('offset', options.offset.toString())\n\n const query = params.toString()\n const endpoint = query ? `/pins?${query}` : '/pins'\n\n return this.client.request<PaginatedResponse<Pin>>('GET', endpoint)\n }\n\n async update<T extends PinTypeId = PinTypeId>(pinId: string, request: UpdatePinRequest<T>): Promise<Pin<T>> {\n return this.client.request<Pin<T>>('PUT', `/pins/${pinId}`, request)\n }\n\n async delete(pinId: string): Promise<void> {\n return this.client.request<void>('DELETE', `/pins/${pinId}`)\n }\n\n async share(pinId: string, request: SharePinRequest): Promise<Pin> {\n return this.client.request<Pin>('POST', `/pins/${pinId}/share`, request)\n }\n\n async batchGet(pinIds: string[]): Promise<{\n found: Pin[]\n not_found: string[]\n permission_denied: string[]\n }> {\n return this.client.request('POST', '/pins/batch/get', { pin_ids: pinIds })\n }\n\n async batchCreate(pins: CreatePinRequest[]): Promise<{\n created: Array<{ id: string; index: number; created_at: number }>\n failed: Array<{ index: number; error: string }>\n }> {\n return this.client.request('POST', '/pins/batch', { pins })\n }\n\n async batchUpdate(updates: Array<{ id: string } & UpdatePinRequest>): Promise<{\n updated: string[]\n failed: Array<{ id: string; error: string }>\n updated_at: number\n }> {\n return this.client.request('PATCH', '/pins/batch', { updates })\n }\n\n async batchDelete(pinIds: string[]): Promise<{\n deleted: string[]\n failed: Array<{ id: string; error: string }>\n }> {\n return this.client.request('DELETE', '/pins/batch', { pin_ids: pinIds })\n }\n\n /** Create a markdown pin with pin_config.content (seeds Yjs on the server). */\n async createMarkdown(input: CreateMarkdownPinInput): Promise<Pin<'markdown'>> {\n const { content, title, tags, description, pin_layout, is_public, allow_edit, require_sign_in, allow_comments, pending_invites } = input\n return this.create({\n pin_type: 'markdown',\n pin_config: { content },\n pin_layout,\n is_public,\n allow_edit,\n require_sign_in,\n allow_comments,\n pending_invites,\n metadata: { title, tags, description },\n })\n }\n\n async createStatCards(input: CreateStatCardsPinInput): Promise<Pin<'stat-cards'>> {\n const { cards, title, tags, description, pin_layout, is_public } = input\n return this.create({\n pin_type: 'stat-cards',\n pin_config: { cards },\n pin_layout,\n is_public,\n metadata: { title, tags, description },\n })\n }\n\n async createTable(input: CreateTablePinInput): Promise<Pin<'table'>> {\n const { columns, rows, title, tags, description, pin_layout, is_public } = input\n return this.create({\n pin_type: 'table',\n pin_config: { columns, rows },\n pin_layout,\n is_public,\n metadata: { title, tags, description },\n })\n }\n\n /** Partial table pin_config update with typed columns/rows. */\n async updateTable(pinId: string, input: UpdateTablePinInput): Promise<Pin<'table'>> {\n const { columns, rows, title, tags, description } = input\n const pin_config: Partial<TablePinConfig> = {}\n if (columns !== undefined) pin_config.columns = columns\n if (rows !== undefined) pin_config.rows = rows\n\n return this.update<'table'>(pinId, {\n pin_config: pin_config as TablePinConfig,\n ...(title !== undefined || tags !== undefined || description !== undefined\n ? { metadata: { ...(title !== undefined && { title }), ...(tags !== undefined && { tags }), ...(description !== undefined && { description }) } }\n : {}),\n })\n }\n\n async createEmbed(input: CreateEmbedPinInput): Promise<Pin<'embed'>> {\n const { url, type, title, tags, description, pin_layout, is_public } = input\n return this.create({\n pin_type: 'embed',\n pin_config: { url, type },\n pin_layout,\n is_public,\n metadata: { title, tags, description },\n })\n }\n\n /**\n * @deprecated Use createMarkdown({ title, content, ... }) — old signature ignored content in title\n */\n async createMarkdownLegacy(title: string, additionalMetadata?: Record<string, unknown>): Promise<Pin<'markdown'>> {\n return this.createMarkdown({\n title,\n content: '',\n ...(additionalMetadata as Partial<CreateMarkdownPinInput>),\n })\n }\n}\n","/**\n * Error classes for the v1 Pins API client\n */\n\nexport class PindownError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PindownError'\n }\n}\n\nexport class AuthenticationError extends PindownError {\n constructor(message: string = 'Authentication failed') {\n super(message)\n this.name = 'AuthenticationError'\n }\n}\n\nexport class ForbiddenError extends PindownError {\n constructor(message: string = 'Access forbidden') {\n super(message)\n this.name = 'ForbiddenError'\n }\n}\n\nexport class NotFoundError extends PindownError {\n constructor(resource: string) {\n super(`${resource} not found`)\n this.name = 'NotFoundError'\n }\n}\n\nexport class ValidationError extends PindownError {\n public details?: unknown\n\n constructor(message: string, details?: unknown) {\n super(message)\n this.name = 'ValidationError'\n this.details = details\n }\n}\n\nexport class RateLimitError extends PindownError {\n constructor(message: string = 'Rate limit exceeded (429 RATE_LIMITED)') {\n super(message)\n this.name = 'RateLimitError'\n }\n}\n\nexport class ServerError extends PindownError {\n public statusCode: number\n\n constructor(message: string, statusCode: number = 500) {\n super(message)\n this.name = 'ServerError'\n this.statusCode = statusCode\n }\n}\n\nexport class NetworkError extends PindownError {\n constructor(message: string = 'Network request failed') {\n super(message)\n this.name = 'NetworkError'\n }\n}\n","/**\n * Pindown API Client — v1 Pins API only\n */\n\nimport { PinsMethods } from './pins'\nimport type { PindownConfig } from '../types/config'\nimport {\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n ServerError,\n NetworkError,\n} from '../errors'\n\nexport class PindownClient {\n private config: Required<Omit<PindownConfig, 'baseURL'>> & { baseURL: string }\n\n public readonly pins: PinsMethods\n\n constructor(config: PindownConfig) {\n if (!config.apiKey) {\n throw new Error('API key is required')\n }\n\n this.config = {\n apiKey: config.apiKey,\n baseURL: config.baseURL || 'https://api.pindown.ai/v1',\n maxRetries: config.maxRetries ?? 3,\n timeout: config.timeout ?? 30000,\n }\n\n this.pins = new PinsMethods(this)\n }\n\n async request<T = unknown>(method: string, endpoint: string, data?: unknown): Promise<T> {\n const url = `${this.config.baseURL}${endpoint}`\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.config.apiKey}`,\n }\n\n if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE')) {\n headers['Content-Type'] = 'application/json'\n }\n\n const requestOptions: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.config.timeout),\n }\n\n if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE')) {\n requestOptions.body = JSON.stringify(data)\n }\n\n try {\n const response = await fetch(url, requestOptions)\n\n if (!response.ok) {\n await this.handleErrorResponse(response)\n }\n\n const result = await response.json()\n return result.data as T\n } catch (error: unknown) {\n if (\n error instanceof AuthenticationError ||\n error instanceof ForbiddenError ||\n error instanceof NotFoundError ||\n error instanceof ValidationError ||\n error instanceof RateLimitError ||\n error instanceof ServerError\n ) {\n throw error\n }\n\n if (error instanceof Error && (error.name === 'AbortError' || error.name === 'TimeoutError')) {\n throw new NetworkError('Request timeout')\n }\n\n throw new NetworkError(error instanceof Error ? error.message : 'Network request failed')\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorData: { error?: { code?: string; message?: string; details?: unknown }; message?: string }\n\n try {\n errorData = await response.json()\n } catch {\n errorData = { message: response.statusText }\n }\n\n const message = errorData.error?.message || errorData.message || 'Unknown error'\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message)\n case 403:\n throw new ForbiddenError(message)\n case 404:\n throw new NotFoundError(message)\n case 400:\n case 422:\n throw new ValidationError(message, errorData.error?.details)\n case 429:\n throw new RateLimitError(message)\n case 500:\n case 502:\n case 503:\n throw new ServerError(message, response.status)\n default:\n throw new ServerError(message, response.status)\n }\n }\n}\n","/**\n * Runtime hints + minimal examples per pin type.\n * Use when building API payloads without opening the docs every time.\n */\n\nimport type { PinConfigByType, PinTypeId, UpdatePinRequest } from './types/pins'\n\nexport interface PinConfigFieldHint {\n path: string\n type: string\n required: boolean\n description: string\n}\n\nexport interface PinConfigHint<T extends PinTypeId = PinTypeId> {\n pin_type: T\n summary: string\n required_fields: string[]\n optional_fields: string[]\n fields: PinConfigFieldHint[]\n /** Minimal valid pin_config for create/update */\n example_config: PinConfigByType[T]\n /** Typical PUT /v1/pins/:id body (root-level pin_config) */\n example_update: UpdatePinRequest<T>\n}\n\nconst TABLE_HINT: PinConfigHint<'table'> = {\n pin_type: 'table',\n summary: 'Spreadsheet-style pin. columns is required; rows are optional but needed for visible data.',\n required_fields: ['columns'],\n optional_fields: ['rows'],\n fields: [\n {\n path: 'columns',\n type: 'TableColumn[]',\n required: true,\n description: 'At least one column. Each column needs id + name (type optional, e.g. text | number).',\n },\n {\n path: 'columns[].id',\n type: 'string',\n required: true,\n description: 'Stable column key used in row.cells.',\n },\n {\n path: 'columns[].name',\n type: 'string',\n required: true,\n description: 'Column header label.',\n },\n {\n path: 'rows',\n type: 'TableRow[]',\n required: false,\n description: 'Table data. Each row: { id, cells: { [columnId]: value } }.',\n },\n ],\n example_config: {\n columns: [\n { id: 'col1', name: 'Name', type: 'text' },\n { id: 'col2', name: 'Value', type: 'number' },\n ],\n rows: [{ id: 'row1', cells: { col1: 'Item', col2: 1 } }],\n },\n example_update: {\n pin_config: {\n columns: [\n { id: 'col1', name: 'Name', type: 'text' },\n { id: 'col2', name: 'Value', type: 'number' },\n ],\n rows: [{ id: 'row1', cells: { col1: 'Updated', col2: 42 } }],\n },\n },\n}\n\n/** Per-type hints (expand over time; table is fully documented). */\nexport const PIN_CONFIG_HINTS: Partial<Record<PinTypeId, PinConfigHint>> = {\n table: TABLE_HINT,\n markdown: {\n pin_type: 'markdown',\n summary: 'Rich text / markdown body.',\n required_fields: [],\n optional_fields: ['content', 'collaboration'],\n fields: [\n {\n path: 'content',\n type: 'string',\n required: false,\n description: 'Markdown source. Server seeds Yjs when set on create.',\n },\n ],\n example_config: { content: '# Hello\\n\\nBody text.' },\n example_update: { pin_config: { content: '# Updated\\n\\nNew body.' } },\n },\n 'stat-cards': {\n pin_type: 'stat-cards',\n summary: 'KPI cards grid.',\n required_fields: ['cards'],\n optional_fields: [],\n fields: [\n {\n path: 'cards',\n type: 'StatCardItem[]',\n required: true,\n description: 'Each card: title, value; optional change, trend (up|down|neutral).',\n },\n ],\n example_config: {\n cards: [{ title: 'Revenue', value: '1000', change: '+5%', trend: 'up' }],\n },\n example_update: {\n pin_config: {\n cards: [{ title: 'Revenue', value: '1234', change: '+8%', trend: 'up' }],\n },\n },\n },\n}\n\nexport function getPinConfigHint<T extends PinTypeId>(pinType: T): PinConfigHint<T> | undefined {\n return PIN_CONFIG_HINTS[pinType] as PinConfigHint<T> | undefined\n}\n\n/** Pretty-print field hints for CLI / logging. */\nexport function formatPinConfigHint(pinType: PinTypeId): string {\n const hint = getPinConfigHint(pinType)\n if (!hint) {\n return [\n `No built-in hint for pin type \"${pinType}\".`,\n 'Use CreatePinRequest<typeof pinType> / PinConfigByType[typeof pinType] in TypeScript,',\n 'or client.pins.create({ pin_type, pin_config, metadata }) with typed pin_config.',\n ].join('\\n')\n }\n\n const lines = [\n `Pin type: ${hint.pin_type}`,\n hint.summary,\n '',\n 'Required pin_config fields:',\n ...hint.required_fields.map((f) => ` - ${f}`),\n '',\n 'Optional pin_config fields:',\n ...(hint.optional_fields.length ? hint.optional_fields.map((f) => ` - ${f}`) : [' (none documented)']),\n '',\n 'Field reference:',\n ...hint.fields.map(\n (f) => ` ${f.path} (${f.type}${f.required ? ', required' : ''}): ${f.description}`,\n ),\n '',\n 'Example update payload:',\n JSON.stringify(hint.example_update, null, 2),\n ]\n return lines.join('\\n')\n}\n"]}