@pindownai/client-js 0.6.0 → 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/dist/index.d.cts CHANGED
@@ -127,6 +127,53 @@ interface UpdateDatasetRequest {
127
127
  type?: DatasetType;
128
128
  data?: any;
129
129
  }
130
+ interface Page {
131
+ id: string;
132
+ owner_id: string;
133
+ is_public: boolean;
134
+ metadata: {
135
+ title: string;
136
+ description?: string;
137
+ tags: string[];
138
+ created_at: string;
139
+ updated_at?: string;
140
+ };
141
+ pins: string[];
142
+ layout?: Record<string, any>;
143
+ created_at: number;
144
+ updated_at: number;
145
+ }
146
+ interface CreatePageRequest {
147
+ metadata: {
148
+ title: string;
149
+ description?: string;
150
+ tags?: string[];
151
+ };
152
+ pins?: string[];
153
+ layout?: Record<string, any>;
154
+ is_public?: boolean;
155
+ allow_comments?: boolean;
156
+ require_sign_in?: boolean;
157
+ include_datasets?: boolean;
158
+ }
159
+ interface UpdatePageRequest {
160
+ metadata?: {
161
+ title?: string;
162
+ description?: string;
163
+ tags?: string[];
164
+ };
165
+ is_public?: boolean;
166
+ allow_comments?: boolean;
167
+ require_sign_in?: boolean;
168
+ include_datasets?: boolean;
169
+ }
170
+ interface AddPinToPageRequest {
171
+ pin_id: string;
172
+ }
173
+ interface ListPagesOptions {
174
+ limit?: number;
175
+ offset?: number;
176
+ }
130
177
  type BlockType = 'markdown' | 'mermaid' | 'conditional' | 'image' | 'stat-cards' | 'line-chart' | 'flexible-table' | 'embed';
131
178
  interface Block {
132
179
  id: string;
@@ -413,6 +460,105 @@ declare class PinboardsMethods {
413
460
  setPinRoleRequirements(boardId: string, pinId: string, roleIds: string[]): Promise<void>;
414
461
  }
415
462
 
463
+ /**
464
+ * Pages API Methods
465
+ */
466
+
467
+ declare class PagesMethods {
468
+ private client;
469
+ constructor(client: PindownClient);
470
+ /**
471
+ * Create a new page
472
+ */
473
+ create(request: CreatePageRequest): Promise<Page>;
474
+ /**
475
+ * Get a page by ID
476
+ */
477
+ get(pageId: string): Promise<Page>;
478
+ /**
479
+ * List all pages
480
+ */
481
+ list(options?: ListPagesOptions): Promise<{
482
+ pages: Page[];
483
+ total: number;
484
+ }>;
485
+ /**
486
+ * List pages shared with user
487
+ */
488
+ listShared(options?: ListPagesOptions): Promise<{
489
+ pages: Page[];
490
+ total: number;
491
+ }>;
492
+ /**
493
+ * Update a page
494
+ */
495
+ update(pageId: string, request: UpdatePageRequest): Promise<Page>;
496
+ /**
497
+ * Delete a page
498
+ */
499
+ delete(pageId: string): Promise<void>;
500
+ /**
501
+ * Add a pin to a page
502
+ */
503
+ addPin(pageId: string, request: AddPinToPageRequest): Promise<void>;
504
+ /**
505
+ * Remove a pin from a page
506
+ */
507
+ removePin(pageId: string, pinId: string): Promise<void>;
508
+ /**
509
+ * List pins in a page
510
+ */
511
+ listPins(pageId: string): Promise<{
512
+ pins: string[];
513
+ total: number;
514
+ }>;
515
+ /**
516
+ * Get multiple pages by IDs in a single request (max 100 pages)
517
+ */
518
+ batchGet(pageIds: string[]): Promise<{
519
+ found: Page[];
520
+ not_found: string[];
521
+ permission_denied: string[];
522
+ }>;
523
+ /**
524
+ * Create multiple pages in a single request (max 50 pages)
525
+ */
526
+ batchCreate(pages: CreatePageRequest[]): Promise<{
527
+ created: Array<{
528
+ id: string;
529
+ index: number;
530
+ created_at: number;
531
+ }>;
532
+ failed: Array<{
533
+ index: number;
534
+ error: string;
535
+ }>;
536
+ }>;
537
+ /**
538
+ * Update multiple pages in a single request (max 50 pages)
539
+ */
540
+ batchUpdate(updates: Array<{
541
+ id: string;
542
+ } & UpdatePageRequest>): Promise<{
543
+ updated: string[];
544
+ failed: Array<{
545
+ id: string;
546
+ error: string;
547
+ }>;
548
+ updated_at: number;
549
+ }>;
550
+ /**
551
+ * Delete multiple pages in a single request (max 50 pages)
552
+ */
553
+ batchDelete(pageIds: string[]): Promise<{
554
+ deleted: string[];
555
+ failed: Array<{
556
+ id: string;
557
+ error: string;
558
+ }>;
559
+ }>;
560
+ }
561
+
416
562
  /**
417
563
  * Datasets API Methods
418
564
  */
@@ -530,6 +676,76 @@ declare class BlocksMethods {
530
676
  * Delete a block
531
677
  */
532
678
  delete(pinId: string, blockId: string): Promise<void>;
679
+ /**
680
+ * Get multiple blocks by IDs in a single request (max 100 blocks)
681
+ */
682
+ batchGet(blockIds: Array<{
683
+ pin_id: string;
684
+ block_id: string;
685
+ }>): Promise<{
686
+ found: Block[];
687
+ not_found: Array<{
688
+ pin_id: string;
689
+ block_id: string;
690
+ }>;
691
+ permission_denied: Array<{
692
+ pin_id: string;
693
+ block_id: string;
694
+ }>;
695
+ }>;
696
+ /**
697
+ * Create multiple blocks for a pin in a single request (max 50 blocks)
698
+ */
699
+ batchCreate(pinId: string, blocks: Array<{
700
+ title: string;
701
+ type?: 'markdown' | 'code' | 'text' | 'image';
702
+ template?: string;
703
+ order?: number;
704
+ }>): Promise<{
705
+ created: Block[];
706
+ failed: Array<{
707
+ index: number;
708
+ error: string;
709
+ }>;
710
+ }>;
711
+ /**
712
+ * Update multiple blocks in a single request (max 50 blocks)
713
+ */
714
+ batchUpdate(updates: Array<{
715
+ pin_id: string;
716
+ block_id: string;
717
+ title?: string;
718
+ type?: 'markdown' | 'code' | 'text' | 'image';
719
+ template?: string;
720
+ order?: number;
721
+ }>): Promise<{
722
+ updated: Array<{
723
+ pin_id: string;
724
+ block_id: string;
725
+ }>;
726
+ failed: Array<{
727
+ pin_id: string;
728
+ block_id: string;
729
+ error: string;
730
+ }>;
731
+ }>;
732
+ /**
733
+ * Delete multiple blocks in a single request (max 50 blocks)
734
+ */
735
+ batchDelete(blockIds: Array<{
736
+ pin_id: string;
737
+ block_id: string;
738
+ }>): Promise<{
739
+ deleted: Array<{
740
+ pin_id: string;
741
+ block_id: string;
742
+ }>;
743
+ failed: Array<{
744
+ pin_id: string;
745
+ block_id: string;
746
+ error: string;
747
+ }>;
748
+ }>;
533
749
  }
534
750
 
535
751
  /**
@@ -643,6 +859,7 @@ declare class PindownClient {
643
859
  private tierDetected;
644
860
  readonly pins: PinsMethods;
645
861
  readonly pinboards: PinboardsMethods;
862
+ readonly pages: PagesMethods;
646
863
  readonly datasets: DatasetsMethods;
647
864
  readonly blocks: BlocksMethods;
648
865
  readonly collaborators: CollaboratorsMethods;
@@ -717,4 +934,4 @@ declare class NetworkError extends PindownError {
717
934
  constructor(message?: string);
718
935
  }
719
936
 
720
- export { type AddPinToPinboardRequest, type ApiResponse, AuthenticationError, type Block, type BlockType, type Collaborator, type CollaboratorRole, type CreateBlockRequest, type CreateDatasetRequest, type CreatePinRequest, type CreatePinboardRequest, type Dataset, type DatasetType, ForbiddenError, type InviteCollaboratorRequest, type ListPinsOptions, NetworkError, NotFoundError, type PaginatedResponse, type Permissions, type Pin, type PinCardType, type PinDataType, type Pinboard, PindownClient, type PindownConfig, PindownError, RateLimitError, type RateLimitInfo, ServerError, type SharePinRequest, type Tier, type UpdateBlockRequest, type UpdateCollaboratorRoleRequest, type UpdateDatasetRequest, type UpdatePinRequest, type UpdatePinboardLayoutRequest, type UpdatePinboardRequest, ValidationError };
937
+ export { type AddPinToPageRequest, type AddPinToPinboardRequest, type ApiResponse, AuthenticationError, type Block, type BlockType, type Collaborator, type CollaboratorRole, type CreateBlockRequest, type CreateDatasetRequest, type CreatePageRequest, type CreatePinRequest, type CreatePinboardRequest, type Dataset, type DatasetType, ForbiddenError, type InviteCollaboratorRequest, type ListPagesOptions, type ListPinsOptions, NetworkError, NotFoundError, type Page, type PaginatedResponse, type Permissions, type Pin, type PinCardType, type PinDataType, type Pinboard, PindownClient, type PindownConfig, PindownError, RateLimitError, type RateLimitInfo, ServerError, type SharePinRequest, type Tier, type UpdateBlockRequest, type UpdateCollaboratorRoleRequest, type UpdateDatasetRequest, type UpdatePageRequest, type UpdatePinRequest, type UpdatePinboardLayoutRequest, type UpdatePinboardRequest, ValidationError };
package/dist/index.d.ts CHANGED
@@ -127,6 +127,53 @@ interface UpdateDatasetRequest {
127
127
  type?: DatasetType;
128
128
  data?: any;
129
129
  }
130
+ interface Page {
131
+ id: string;
132
+ owner_id: string;
133
+ is_public: boolean;
134
+ metadata: {
135
+ title: string;
136
+ description?: string;
137
+ tags: string[];
138
+ created_at: string;
139
+ updated_at?: string;
140
+ };
141
+ pins: string[];
142
+ layout?: Record<string, any>;
143
+ created_at: number;
144
+ updated_at: number;
145
+ }
146
+ interface CreatePageRequest {
147
+ metadata: {
148
+ title: string;
149
+ description?: string;
150
+ tags?: string[];
151
+ };
152
+ pins?: string[];
153
+ layout?: Record<string, any>;
154
+ is_public?: boolean;
155
+ allow_comments?: boolean;
156
+ require_sign_in?: boolean;
157
+ include_datasets?: boolean;
158
+ }
159
+ interface UpdatePageRequest {
160
+ metadata?: {
161
+ title?: string;
162
+ description?: string;
163
+ tags?: string[];
164
+ };
165
+ is_public?: boolean;
166
+ allow_comments?: boolean;
167
+ require_sign_in?: boolean;
168
+ include_datasets?: boolean;
169
+ }
170
+ interface AddPinToPageRequest {
171
+ pin_id: string;
172
+ }
173
+ interface ListPagesOptions {
174
+ limit?: number;
175
+ offset?: number;
176
+ }
130
177
  type BlockType = 'markdown' | 'mermaid' | 'conditional' | 'image' | 'stat-cards' | 'line-chart' | 'flexible-table' | 'embed';
131
178
  interface Block {
132
179
  id: string;
@@ -413,6 +460,105 @@ declare class PinboardsMethods {
413
460
  setPinRoleRequirements(boardId: string, pinId: string, roleIds: string[]): Promise<void>;
414
461
  }
415
462
 
463
+ /**
464
+ * Pages API Methods
465
+ */
466
+
467
+ declare class PagesMethods {
468
+ private client;
469
+ constructor(client: PindownClient);
470
+ /**
471
+ * Create a new page
472
+ */
473
+ create(request: CreatePageRequest): Promise<Page>;
474
+ /**
475
+ * Get a page by ID
476
+ */
477
+ get(pageId: string): Promise<Page>;
478
+ /**
479
+ * List all pages
480
+ */
481
+ list(options?: ListPagesOptions): Promise<{
482
+ pages: Page[];
483
+ total: number;
484
+ }>;
485
+ /**
486
+ * List pages shared with user
487
+ */
488
+ listShared(options?: ListPagesOptions): Promise<{
489
+ pages: Page[];
490
+ total: number;
491
+ }>;
492
+ /**
493
+ * Update a page
494
+ */
495
+ update(pageId: string, request: UpdatePageRequest): Promise<Page>;
496
+ /**
497
+ * Delete a page
498
+ */
499
+ delete(pageId: string): Promise<void>;
500
+ /**
501
+ * Add a pin to a page
502
+ */
503
+ addPin(pageId: string, request: AddPinToPageRequest): Promise<void>;
504
+ /**
505
+ * Remove a pin from a page
506
+ */
507
+ removePin(pageId: string, pinId: string): Promise<void>;
508
+ /**
509
+ * List pins in a page
510
+ */
511
+ listPins(pageId: string): Promise<{
512
+ pins: string[];
513
+ total: number;
514
+ }>;
515
+ /**
516
+ * Get multiple pages by IDs in a single request (max 100 pages)
517
+ */
518
+ batchGet(pageIds: string[]): Promise<{
519
+ found: Page[];
520
+ not_found: string[];
521
+ permission_denied: string[];
522
+ }>;
523
+ /**
524
+ * Create multiple pages in a single request (max 50 pages)
525
+ */
526
+ batchCreate(pages: CreatePageRequest[]): Promise<{
527
+ created: Array<{
528
+ id: string;
529
+ index: number;
530
+ created_at: number;
531
+ }>;
532
+ failed: Array<{
533
+ index: number;
534
+ error: string;
535
+ }>;
536
+ }>;
537
+ /**
538
+ * Update multiple pages in a single request (max 50 pages)
539
+ */
540
+ batchUpdate(updates: Array<{
541
+ id: string;
542
+ } & UpdatePageRequest>): Promise<{
543
+ updated: string[];
544
+ failed: Array<{
545
+ id: string;
546
+ error: string;
547
+ }>;
548
+ updated_at: number;
549
+ }>;
550
+ /**
551
+ * Delete multiple pages in a single request (max 50 pages)
552
+ */
553
+ batchDelete(pageIds: string[]): Promise<{
554
+ deleted: string[];
555
+ failed: Array<{
556
+ id: string;
557
+ error: string;
558
+ }>;
559
+ }>;
560
+ }
561
+
416
562
  /**
417
563
  * Datasets API Methods
418
564
  */
@@ -530,6 +676,76 @@ declare class BlocksMethods {
530
676
  * Delete a block
531
677
  */
532
678
  delete(pinId: string, blockId: string): Promise<void>;
679
+ /**
680
+ * Get multiple blocks by IDs in a single request (max 100 blocks)
681
+ */
682
+ batchGet(blockIds: Array<{
683
+ pin_id: string;
684
+ block_id: string;
685
+ }>): Promise<{
686
+ found: Block[];
687
+ not_found: Array<{
688
+ pin_id: string;
689
+ block_id: string;
690
+ }>;
691
+ permission_denied: Array<{
692
+ pin_id: string;
693
+ block_id: string;
694
+ }>;
695
+ }>;
696
+ /**
697
+ * Create multiple blocks for a pin in a single request (max 50 blocks)
698
+ */
699
+ batchCreate(pinId: string, blocks: Array<{
700
+ title: string;
701
+ type?: 'markdown' | 'code' | 'text' | 'image';
702
+ template?: string;
703
+ order?: number;
704
+ }>): Promise<{
705
+ created: Block[];
706
+ failed: Array<{
707
+ index: number;
708
+ error: string;
709
+ }>;
710
+ }>;
711
+ /**
712
+ * Update multiple blocks in a single request (max 50 blocks)
713
+ */
714
+ batchUpdate(updates: Array<{
715
+ pin_id: string;
716
+ block_id: string;
717
+ title?: string;
718
+ type?: 'markdown' | 'code' | 'text' | 'image';
719
+ template?: string;
720
+ order?: number;
721
+ }>): Promise<{
722
+ updated: Array<{
723
+ pin_id: string;
724
+ block_id: string;
725
+ }>;
726
+ failed: Array<{
727
+ pin_id: string;
728
+ block_id: string;
729
+ error: string;
730
+ }>;
731
+ }>;
732
+ /**
733
+ * Delete multiple blocks in a single request (max 50 blocks)
734
+ */
735
+ batchDelete(blockIds: Array<{
736
+ pin_id: string;
737
+ block_id: string;
738
+ }>): Promise<{
739
+ deleted: Array<{
740
+ pin_id: string;
741
+ block_id: string;
742
+ }>;
743
+ failed: Array<{
744
+ pin_id: string;
745
+ block_id: string;
746
+ error: string;
747
+ }>;
748
+ }>;
533
749
  }
534
750
 
535
751
  /**
@@ -643,6 +859,7 @@ declare class PindownClient {
643
859
  private tierDetected;
644
860
  readonly pins: PinsMethods;
645
861
  readonly pinboards: PinboardsMethods;
862
+ readonly pages: PagesMethods;
646
863
  readonly datasets: DatasetsMethods;
647
864
  readonly blocks: BlocksMethods;
648
865
  readonly collaborators: CollaboratorsMethods;
@@ -717,4 +934,4 @@ declare class NetworkError extends PindownError {
717
934
  constructor(message?: string);
718
935
  }
719
936
 
720
- export { type AddPinToPinboardRequest, type ApiResponse, AuthenticationError, type Block, type BlockType, type Collaborator, type CollaboratorRole, type CreateBlockRequest, type CreateDatasetRequest, type CreatePinRequest, type CreatePinboardRequest, type Dataset, type DatasetType, ForbiddenError, type InviteCollaboratorRequest, type ListPinsOptions, NetworkError, NotFoundError, type PaginatedResponse, type Permissions, type Pin, type PinCardType, type PinDataType, type Pinboard, PindownClient, type PindownConfig, PindownError, RateLimitError, type RateLimitInfo, ServerError, type SharePinRequest, type Tier, type UpdateBlockRequest, type UpdateCollaboratorRoleRequest, type UpdateDatasetRequest, type UpdatePinRequest, type UpdatePinboardLayoutRequest, type UpdatePinboardRequest, ValidationError };
937
+ export { type AddPinToPageRequest, type AddPinToPinboardRequest, type ApiResponse, AuthenticationError, type Block, type BlockType, type Collaborator, type CollaboratorRole, type CreateBlockRequest, type CreateDatasetRequest, type CreatePageRequest, type CreatePinRequest, type CreatePinboardRequest, type Dataset, type DatasetType, ForbiddenError, type InviteCollaboratorRequest, type ListPagesOptions, type ListPinsOptions, NetworkError, NotFoundError, type Page, type PaginatedResponse, type Permissions, type Pin, type PinCardType, type PinDataType, type Pinboard, PindownClient, type PindownConfig, PindownError, RateLimitError, type RateLimitInfo, ServerError, type SharePinRequest, type Tier, type UpdateBlockRequest, type UpdateCollaboratorRoleRequest, type UpdateDatasetRequest, type UpdatePageRequest, type UpdatePinRequest, type UpdatePinboardLayoutRequest, type UpdatePinboardRequest, ValidationError };
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- 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 C={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 a=class extends Error{constructor(e){super(e),this.name="PindownError";}},l=class extends a{constructor(e="Authentication failed"){super(e),this.name="AuthenticationError";}},m=class extends a{constructor(e="Access forbidden"){super(e),this.name="ForbiddenError";}},p=class extends a{constructor(e){super(`${e} not found`),this.name="NotFoundError";}},d=class extends a{constructor(e,t){super(e),this.name="ValidationError",this.details=t;}},g=class extends a{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;}},c=class extends a{constructor(e,t=500){super(e),this.name="ServerError",this.statusCode=t;}},P=class extends a{constructor(e="Network request failed"){super(e),this.name="NetworkError";}};var _=E,h=C,b=class{constructor(e){this.minuteTokens=new Map;this.hourTokens=new Map;this.tier=e,this.cleanupInterval=setInterval(()=>this.cleanup(),300*1e3);}checkLimit(e,t,r){let n=this.calculateTokenCost(e,t,r),o=this.getMinuteWindow(),u=this.getHourWindow(),i=_[this.tier];if(i.tokensPerMinute!==null){let k=this.minuteTokens.get(o)||0;if(k+n>i.tokensPerMinute)throw new g({window:"minute",limit:i.tokensPerMinute,used:k,remaining:Math.max(0,i.tokensPerMinute-k),resetAt:this.getMinuteResetTime(),tier:this.tier})}let y=this.hourTokens.get(u)||0;if(y+n>i.tokensPerHour)throw new g({window:"hour",limit:i.tokensPerHour,used:y,remaining:Math.max(0,i.tokensPerHour-y),resetAt:this.getHourResetTime(),tier:this.tier});this.incrementToken(o,n),this.incrementToken(u,n);}calculateTokenCost(e,t,r){if(t.includes("/batch")||t.includes("/sync")){if(r?.operations){let n=Array.isArray(r.operations)?r.operations.length:0;return n<=10?h.BATCH_1_10:n<=25?h.BATCH_11_25:(h.BATCH_26_50)}if(r?.pins){let n=Array.isArray(r.pins)?r.pins.length:0;return n<=16?5:(8)}}return t.includes("/collaborators")||t.includes("/invite")||t.includes("/share")?h.INVITE:h[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 r=this.minuteTokens.get(e)||0;this.minuteTokens.set(e,r+t);}else {let r=this.hourTokens.get(e)||0;this.hourTokens.set(e,r+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=_[this.tier],t=this.getMinuteWindow(),r=this.getHourWindow(),n=this.minuteTokens.get(t)||0,o=this.hourTokens.get(r)||0;return {tier:this.tier,minute:{limit:e.tokensPerMinute||0,used:n,remaining:e.tokensPerMinute?Math.max(0,e.tokensPerMinute-n):1/0,resetAt:this.getMinuteResetTime()},hour:{limit:e.tokensPerHour,used:o,remaining:Math.max(0,e.tokensPerHour-o),resetAt:this.getHourResetTime()}}}cleanup(){let t=Date.now()-7200*1e3;for(let[r]of this.minuteTokens)this.parseWindowTimestamp(r)<t&&this.minuteTokens.delete(r);for(let[r]of this.hourTokens)this.parseWindowTimestamp(r)<t&&this.hourTokens.delete(r);}parseWindowTimestamp(e){let t=e.split("_")[1].split("-"),r=parseInt(t[0]),n=parseInt(t[1])-1,o=parseInt(t[2]),u=parseInt(t[3]),i=e.startsWith("minute")?parseInt(t[4]):0;return new Date(r,n,o,u,i).getTime()}destroy(){this.cleanupInterval&&clearInterval(this.cleanupInterval);}};var T=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 r=t.toString(),n=r?`/pins?${r}`:"/pins";return this.client.request("GET",n)}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,t){return this.create({data_type:"markdown",metadata:{title:e,...t}})}async createStatCard(e,t,r){return this.create({data_type:"pin-card",metadata:{title:t,pin_card_type:"stat-cards",pin_card_config:[e],...r}})}async createTable(e,t,r){return this.create({data_type:"pin-card",metadata:{title:t,pin_card_type:"flexible-table",pin_card_config:e,...r}})}async createEmbed(e,t,r){return this.create({data_type:"pin-card",metadata:{title:t,pin_card_type:"embed",pin_card_config:{url:e},...r}})}};var f=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,r){return this.client.request("POST",`/pinboards/${e}/pins/batch`,{pin_ids:t,layout:r})}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,r){return this.client.request("PUT",`/pinboards/${e}/roles/${t}`,r)}async deleteRole(e,t){return this.client.request("DELETE",`/pinboards/${e}/roles/${t}`)}async assignUserRoles(e,t,r){return this.client.request("PUT",`/pinboards/${e}/users/${t}/custom-roles`,{roleIds:r})}async setPinRoleRequirements(e,t,r){return this.client.request("PUT",`/pinboards/${e}/pins/${t}/required-roles`,{roleIds:r})}};var R=class{constructor(e){this.client=e;}async create(e){return this.client.request("POST","/datasets",e)}async get(e){return this.client.request("GET",`/datasets/${e}`)}async list(){return this.client.request("GET","/datasets")}async update(e,t){return this.client.request("PUT",`/datasets/${e}`,t)}async delete(e){return this.client.request("DELETE",`/datasets/${e}`)}async inviteCollaborator(e,t){return this.client.request("POST",`/datasets/${e}/collaborators`,t)}async batchGet(e){return this.client.request("POST","/datasets/batch/get",{dataset_ids:e})}async batchCreate(e){return this.client.request("POST","/datasets/batch",{datasets:e})}async batchUpdate(e){return this.client.request("PATCH","/datasets/batch",{updates:e})}async batchDelete(e){return this.client.request("DELETE","/datasets/batch",{dataset_ids:e})}};var q=class{constructor(e){this.client=e;}async create(e,t){return this.client.request("POST",`/pins/${e}/blocks`,t)}async get(e,t){return this.client.request("GET",`/pins/${e}/blocks/${t}`)}async list(e){return this.client.request("GET",`/pins/${e}/blocks`)}async update(e,t,r){return this.client.request("PUT",`/pins/${e}/blocks/${t}`,r)}async delete(e,t){return this.client.request("DELETE",`/pins/${e}/blocks/${t}`)}};var w=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,r){return this.client.request("PUT",`/pins/${e}/collaborators/${t}`,r)}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,r){return this.client.request("PUT",`/pinboards/${e}/collaborators/${t}`,r)}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 v=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 b(this.config.tier),this.tierDetected=true),this.pins=new T(this),this.pinboards=new f(this),this.datasets=new R(this),this.blocks=new q(this),this.collaborators=new w(this);}async request(e,t,r){this.config.enableRateLimitTracking&&this.rateLimiter&&this.rateLimiter.checkLimit(e,t,r);let n=`${this.config.baseURL}${t}`,o={Authorization:`Bearer ${this.config.apiKey}`};r&&(e==="POST"||e==="PUT"||e==="PATCH"||e==="DELETE")&&(o["Content-Type"]="application/json");let u={method:e,headers:o,signal:AbortSignal.timeout(this.config.timeout)};r&&(e==="POST"||e==="PUT"||e==="PATCH"||e==="DELETE")&&(u.body=JSON.stringify(r));try{let i=await fetch(n,u);return !this.tierDetected&&this.config.enableRateLimitTracking&&this.detectTierFromHeaders(i.headers),i.ok||await this.handleErrorResponse(i),(await i.json()).data}catch(i){throw i instanceof l||i instanceof m||i instanceof p||i instanceof d||i instanceof c?i:i.name==="AbortError"||i.name==="TimeoutError"?new P("Request timeout"):new P(i.message||"Network request failed")}}async handleErrorResponse(e){let t;try{t=await e.json();}catch{t={message:e.statusText};}let r=t.error?.message||t.message||"Unknown error";switch(e.status){case 401:throw new l(r);case 403:throw new m(r);case 404:throw new p(r);case 400:case 422:throw new d(r,t.error?.details);case 429:throw new d("Rate limit exceeded (server)",t);case 500:case 502:case 503:throw new c(r,e.status);default:throw new c(r,e.status)}}detectTierFromHeaders(e){let t=e.get("X-RateLimit-Tier");if(t&&!this.rateLimiter){let r=t.toLowerCase();console.log(`[Pindown Client] Auto-detected tier: ${r}`),this.config.tier=r,this.rateLimiter=new b(r),this.tierDetected=true;}}getRateLimitInfo(){return this.rateLimiter?this.rateLimiter.getRateLimitInfo():null}getTier(){return this.config.tier||null}destroy(){this.rateLimiter&&this.rateLimiter.destroy();}};/**
1
+ 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 o=class extends Error{constructor(e){super(e),this.name="PindownError";}},l=class extends o{constructor(e="Authentication failed"){super(e),this.name="AuthenticationError";}},g=class extends o{constructor(e="Access forbidden"){super(e),this.name="ForbiddenError";}},p=class extends o{constructor(e){super(`${e} not found`),this.name="NotFoundError";}},u=class extends o{constructor(e,t){super(e),this.name="ValidationError",this.details=t;}},m=class extends o{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;}},c=class extends o{constructor(e,t=500){super(e),this.name="ServerError",this.statusCode=t;}},P=class extends o{constructor(e="Network request failed"){super(e),this.name="NetworkError";}};var C=E,h=v,b=class{constructor(e){this.minuteTokens=new Map;this.hourTokens=new Map;this.tier=e,this.cleanupInterval=setInterval(()=>this.cleanup(),300*1e3);}checkLimit(e,t,r){let i=this.calculateTokenCost(e,t,r),a=this.getMinuteWindow(),d=this.getHourWindow(),n=C[this.tier];if(n.tokensPerMinute!==null){let k=this.minuteTokens.get(a)||0;if(k+i>n.tokensPerMinute)throw new m({window:"minute",limit:n.tokensPerMinute,used:k,remaining:Math.max(0,n.tokensPerMinute-k),resetAt:this.getMinuteResetTime(),tier:this.tier})}let y=this.hourTokens.get(d)||0;if(y+i>n.tokensPerHour)throw new m({window:"hour",limit:n.tokensPerHour,used:y,remaining:Math.max(0,n.tokensPerHour-y),resetAt:this.getHourResetTime(),tier:this.tier});this.incrementToken(a,i),this.incrementToken(d,i);}calculateTokenCost(e,t,r){if(t.includes("/batch")||t.includes("/sync")){if(r?.operations){let i=Array.isArray(r.operations)?r.operations.length:0;return i<=10?h.BATCH_1_10:i<=25?h.BATCH_11_25:(h.BATCH_26_50)}if(r?.pins){let i=Array.isArray(r.pins)?r.pins.length:0;return i<=16?5:(8)}}return t.includes("/collaborators")||t.includes("/invite")||t.includes("/share")?h.INVITE:h[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 r=this.minuteTokens.get(e)||0;this.minuteTokens.set(e,r+t);}else {let r=this.hourTokens.get(e)||0;this.hourTokens.set(e,r+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=C[this.tier],t=this.getMinuteWindow(),r=this.getHourWindow(),i=this.minuteTokens.get(t)||0,a=this.hourTokens.get(r)||0;return {tier:this.tier,minute:{limit:e.tokensPerMinute||0,used:i,remaining:e.tokensPerMinute?Math.max(0,e.tokensPerMinute-i):1/0,resetAt:this.getMinuteResetTime()},hour:{limit:e.tokensPerHour,used:a,remaining:Math.max(0,e.tokensPerHour-a),resetAt:this.getHourResetTime()}}}cleanup(){let t=Date.now()-7200*1e3;for(let[r]of this.minuteTokens)this.parseWindowTimestamp(r)<t&&this.minuteTokens.delete(r);for(let[r]of this.hourTokens)this.parseWindowTimestamp(r)<t&&this.hourTokens.delete(r);}parseWindowTimestamp(e){let t=e.split("_")[1].split("-"),r=parseInt(t[0]),i=parseInt(t[1])-1,a=parseInt(t[2]),d=parseInt(t[3]),n=e.startsWith("minute")?parseInt(t[4]):0;return new Date(r,i,a,d,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 r=t.toString(),i=r?`/pins?${r}`:"/pins";return this.client.request("GET",i)}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,t){return this.create({data_type:"markdown",metadata:{title:e,...t}})}async createStatCard(e,t,r){return this.create({data_type:"pin-card",metadata:{title:t,pin_card_type:"stat-cards",pin_card_config:[e],...r}})}async createTable(e,t,r){return this.create({data_type:"pin-card",metadata:{title:t,pin_card_type:"flexible-table",pin_card_config:e,...r}})}async createEmbed(e,t,r){return this.create({data_type:"pin-card",metadata:{title:t,pin_card_type:"embed",pin_card_config:{url:e},...r}})}};var T=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,r){return this.client.request("POST",`/pinboards/${e}/pins/batch`,{pin_ids:t,layout:r})}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,r){return this.client.request("PUT",`/pinboards/${e}/roles/${t}`,r)}async deleteRole(e,t){return this.client.request("DELETE",`/pinboards/${e}/roles/${t}`)}async assignUserRoles(e,t,r){return this.client.request("PUT",`/pinboards/${e}/users/${t}/custom-roles`,{roleIds:r})}async setPinRoleRequirements(e,t,r){return this.client.request("PUT",`/pinboards/${e}/pins/${t}/required-roles`,{roleIds:r})}};var q=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 r=t.toString(),i=r?`/pages?${r}`:"/pages";return this.client.request("GET",i)}async listShared(e){let t=new URLSearchParams;e?.limit&&t.append("limit",e.limit.toString()),e?.offset&&t.append("offset",e.offset.toString());let r=t.toString(),i=r?`/pages/shared?${r}`:"/pages/shared";return this.client.request("GET",i)}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 create(e){return this.client.request("POST","/datasets",e)}async get(e){return this.client.request("GET",`/datasets/${e}`)}async list(){return this.client.request("GET","/datasets")}async update(e,t){return this.client.request("PUT",`/datasets/${e}`,t)}async delete(e){return this.client.request("DELETE",`/datasets/${e}`)}async inviteCollaborator(e,t){return this.client.request("POST",`/datasets/${e}/collaborators`,t)}async batchGet(e){return this.client.request("POST","/datasets/batch/get",{dataset_ids:e})}async batchCreate(e){return this.client.request("POST","/datasets/batch",{datasets:e})}async batchUpdate(e){return this.client.request("PATCH","/datasets/batch",{updates:e})}async batchDelete(e){return this.client.request("DELETE","/datasets/batch",{dataset_ids:e})}};var w=class{constructor(e){this.client=e;}async create(e,t){return this.client.request("POST",`/pins/${e}/blocks`,t)}async get(e,t){return this.client.request("GET",`/pins/${e}/blocks/${t}`)}async list(e){return this.client.request("GET",`/pins/${e}/blocks`)}async update(e,t,r){return this.client.request("PUT",`/pins/${e}/blocks/${t}`,r)}async delete(e,t){return this.client.request("DELETE",`/pins/${e}/blocks/${t}`)}async batchGet(e){return this.client.request("POST","/blocks/batch/get",{block_ids:e})}async batchCreate(e,t){return this.client.request("POST","/blocks/batch",{pin_id:e,blocks:t})}async batchUpdate(e){return this.client.request("PATCH","/blocks/batch",{updates:e})}async batchDelete(e){return this.client.request("DELETE","/blocks/batch",{block_ids:e})}};var _=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,r){return this.client.request("PUT",`/pins/${e}/collaborators/${t}`,r)}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,r){return this.client.request("PUT",`/pinboards/${e}/collaborators/${t}`,r)}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 A=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 b(this.config.tier),this.tierDetected=true),this.pins=new f(this),this.pinboards=new T(this),this.pages=new q(this),this.datasets=new R(this),this.blocks=new w(this),this.collaborators=new _(this);}async request(e,t,r){this.config.enableRateLimitTracking&&this.rateLimiter&&this.rateLimiter.checkLimit(e,t,r);let i=`${this.config.baseURL}${t}`,a={Authorization:`Bearer ${this.config.apiKey}`};r&&(e==="POST"||e==="PUT"||e==="PATCH"||e==="DELETE")&&(a["Content-Type"]="application/json");let d={method:e,headers:a,signal:AbortSignal.timeout(this.config.timeout)};r&&(e==="POST"||e==="PUT"||e==="PATCH"||e==="DELETE")&&(d.body=JSON.stringify(r));try{let n=await fetch(i,d);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 l||n instanceof g||n instanceof p||n instanceof u||n instanceof c?n:n.name==="AbortError"||n.name==="TimeoutError"?new P("Request timeout"):new P(n.message||"Network request failed")}}async handleErrorResponse(e){let t;try{t=await e.json();}catch{t={message:e.statusText};}let r=t.error?.message||t.message||"Unknown error";switch(e.status){case 401:throw new l(r);case 403:throw new g(r);case 404:throw new p(r);case 400:case 422:throw new u(r,t.error?.details);case 429:throw new u("Rate limit exceeded (server)",t);case 500:case 502:case 503:throw new c(r,e.status);default:throw new c(r,e.status)}}detectTierFromHeaders(e){let t=e.get("X-RateLimit-Tier");if(t&&!this.rateLimiter){let r=t.toLowerCase();console.log(`[Pindown Client] Auto-detected tier: ${r}`),this.config.tier=r,this.rateLimiter=new b(r),this.tierDetected=true;}}getRateLimitInfo(){return this.rateLimiter?this.rateLimiter.getRateLimitInfo():null}getTier(){return this.config.tier||null}destroy(){this.rateLimiter&&this.rateLimiter.destroy();}};/**
2
2
  * @pindownai/client-js
3
3
  *
4
4
  * Official TypeScript/JavaScript client for Pindown.ai API
5
5
  *
6
6
  * @author Pindown.ai
7
7
  * @license MIT
8
- */export{l as AuthenticationError,m as ForbiddenError,P as NetworkError,p as NotFoundError,v as PindownClient,a as PindownError,g as RateLimitError,c as ServerError,d as ValidationError};//# sourceMappingURL=index.js.map
8
+ */export{l as AuthenticationError,g as ForbiddenError,P as NetworkError,p as NotFoundError,A as PindownClient,o as PindownError,m as RateLimitError,c as ServerError,u as ValidationError};//# sourceMappingURL=index.js.map
9
9
  //# sourceMappingURL=index.js.map