@profplum700/etsy-nextjs 2.3.1

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 ADDED
@@ -0,0 +1,338 @@
1
+ # @profplum700/etsy-nextjs
2
+
3
+ Next.js integration for the Etsy v3 API client. Seamlessly integrate Etsy into your Next.js applications with Server Components, API Routes, and more.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @profplum700/etsy-nextjs @profplum700/etsy-v3-api-client
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - Server Components support
14
+ - API Routes helpers
15
+ - Automatic rate limiting
16
+ - Built-in caching
17
+ - Cookie-based token storage
18
+ - Edge Runtime compatibility
19
+ - TypeScript support
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Configure the Server Client
24
+
25
+ Create a configuration file (e.g., `lib/etsy-server.ts`):
26
+
27
+ ```typescript
28
+ import { configureEtsyServerClient } from '@profplum700/etsy-nextjs/server';
29
+
30
+ configureEtsyServerClient({
31
+ apiKey: process.env.ETSY_API_KEY!,
32
+ redirectUri: process.env.ETSY_REDIRECT_URI!,
33
+ scopes: ['listings_r', 'listings_w', 'shops_r'],
34
+ });
35
+ ```
36
+
37
+ ### 2. Use in Server Components
38
+
39
+ ```typescript
40
+ // app/shop/[shopId]/page.tsx
41
+ import { getEtsyServerClient } from '@profplum700/etsy-nextjs/server';
42
+
43
+ export default async function ShopPage({ params }: { params: { shopId: string } }) {
44
+ const client = await getEtsyServerClient();
45
+ const shop = await client.getShop(params.shopId);
46
+
47
+ return (
48
+ <div>
49
+ <h1>{shop.title}</h1>
50
+ <p>{shop.announcement}</p>
51
+ </div>
52
+ );
53
+ }
54
+ ```
55
+
56
+ ### 3. Create API Routes
57
+
58
+ ```typescript
59
+ // app/api/etsy/[...path]/route.ts
60
+ import { createEtsyApiRoute } from '@profplum700/etsy-nextjs';
61
+
62
+ export const { GET, POST, PUT, DELETE } = createEtsyApiRoute({
63
+ apiKey: process.env.ETSY_API_KEY!,
64
+ rateLimit: {
65
+ requests: 100,
66
+ window: 60000, // 1 minute
67
+ },
68
+ cache: {
69
+ enabled: true,
70
+ ttl: 300, // 5 minutes
71
+ },
72
+ });
73
+ ```
74
+
75
+ ### 4. Use in Client Components
76
+
77
+ ```typescript
78
+ 'use client';
79
+
80
+ import { EtsyNextClientProvider, useEtsyNextClient } from '@profplum700/etsy-nextjs';
81
+ import { EtsyClient } from '@profplum700/etsy-v3-api-client';
82
+
83
+ const client = new EtsyClient({
84
+ apiKey: process.env.NEXT_PUBLIC_ETSY_API_KEY!,
85
+ });
86
+
87
+ export default function App({ children }) {
88
+ return (
89
+ <EtsyNextClientProvider client={client} apiEndpoint="/api/etsy">
90
+ {children}
91
+ </EtsyNextClientProvider>
92
+ );
93
+ }
94
+
95
+ function MyComponent() {
96
+ const { client } = useEtsyNextClient();
97
+
98
+ // Use the client in your component
99
+ const handleFetch = async () => {
100
+ const shop = await client.getShop('123');
101
+ console.log(shop);
102
+ };
103
+
104
+ return <button onClick={handleFetch}>Fetch Shop</button>;
105
+ }
106
+ ```
107
+
108
+ ## API Reference
109
+
110
+ ### Server-Side
111
+
112
+ #### `configureEtsyServerClient(config)`
113
+
114
+ Configure the global Etsy server client.
115
+
116
+ ```typescript
117
+ interface EtsyServerClientConfig {
118
+ apiKey: string;
119
+ redirectUri?: string;
120
+ scopes?: string[];
121
+ cookieName?: string;
122
+ encryptionKey?: string;
123
+ }
124
+ ```
125
+
126
+ #### `getEtsyServerClient()`
127
+
128
+ Get the configured Etsy server client instance. Use in Server Components and Server Actions.
129
+
130
+ ```typescript
131
+ const client = await getEtsyServerClient();
132
+ ```
133
+
134
+ #### `createEtsyServerClient(config)`
135
+
136
+ Create a new Etsy server client with custom configuration.
137
+
138
+ ```typescript
139
+ const client = createEtsyServerClient({
140
+ apiKey: process.env.ETSY_API_KEY!,
141
+ redirectUri: process.env.ETSY_REDIRECT_URI!,
142
+ });
143
+ ```
144
+
145
+ #### `createEtsyApiRoute(config)`
146
+
147
+ Create API route handlers with built-in rate limiting and caching.
148
+
149
+ ```typescript
150
+ interface EtsyApiRouteConfig {
151
+ apiKey: string;
152
+ redirectUri?: string;
153
+ scopes?: string[];
154
+ rateLimit?: {
155
+ requests: number;
156
+ window: number; // in milliseconds
157
+ };
158
+ cache?: {
159
+ enabled: boolean;
160
+ ttl: number; // in seconds
161
+ };
162
+ }
163
+ ```
164
+
165
+ ### Client-Side
166
+
167
+ #### `<EtsyNextClientProvider>`
168
+
169
+ Provider component for client-side Etsy client.
170
+
171
+ ```tsx
172
+ <EtsyNextClientProvider client={client} apiEndpoint="/api/etsy">
173
+ {children}
174
+ </EtsyNextClientProvider>
175
+ ```
176
+
177
+ #### `useEtsyNextClient()`
178
+
179
+ Hook to access the Etsy client in client components.
180
+
181
+ ```typescript
182
+ const { client, apiEndpoint } = useEtsyNextClient();
183
+ ```
184
+
185
+ ## Usage Examples
186
+
187
+ ### Server Component with Data Fetching
188
+
189
+ ```typescript
190
+ // app/listings/page.tsx
191
+ import { getEtsyServerClient } from '@profplum700/etsy-nextjs/server';
192
+
193
+ export default async function ListingsPage() {
194
+ const client = await getEtsyServerClient();
195
+ const response = await client.getListingsByShop('123', {
196
+ state: 'active',
197
+ limit: 25,
198
+ });
199
+
200
+ return (
201
+ <div>
202
+ <h1>Listings</h1>
203
+ <ul>
204
+ {response.results.map((listing) => (
205
+ <li key={listing.listing_id}>{listing.title}</li>
206
+ ))}
207
+ </ul>
208
+ </div>
209
+ );
210
+ }
211
+ ```
212
+
213
+ ### API Route with Rate Limiting
214
+
215
+ ```typescript
216
+ // app/api/shop/[shopId]/route.ts
217
+ import { NextRequest, NextResponse } from 'next/server';
218
+ import { getEtsyServerClient } from '@profplum700/etsy-nextjs/server';
219
+
220
+ export async function GET(
221
+ request: NextRequest,
222
+ { params }: { params: { shopId: string } }
223
+ ) {
224
+ try {
225
+ const client = await getEtsyServerClient();
226
+ const shop = await client.getShop(params.shopId);
227
+
228
+ return NextResponse.json(shop);
229
+ } catch (error) {
230
+ return NextResponse.json(
231
+ { error: 'Failed to fetch shop' },
232
+ { status: 500 }
233
+ );
234
+ }
235
+ }
236
+ ```
237
+
238
+ ### Server Action
239
+
240
+ ```typescript
241
+ 'use server';
242
+
243
+ import { getEtsyServerClient } from '@profplum700/etsy-nextjs/server';
244
+ import { revalidatePath } from 'next/cache';
245
+
246
+ export async function updateListing(shopId: string, listingId: string, updates: any) {
247
+ const client = await getEtsyServerClient();
248
+ const result = await client.updateListing(shopId, listingId, updates);
249
+
250
+ // Revalidate the page to show updated data
251
+ revalidatePath(`/listings/${listingId}`);
252
+
253
+ return result;
254
+ }
255
+ ```
256
+
257
+ ### Static Site Generation (SSG)
258
+
259
+ ```typescript
260
+ // app/shop/[shopId]/page.tsx
261
+ import { getEtsyServerClient } from '@profplum700/etsy-nextjs/server';
262
+
263
+ export async function generateStaticParams() {
264
+ // Generate paths for your shops
265
+ return [
266
+ { shopId: '123' },
267
+ { shopId: '456' },
268
+ ];
269
+ }
270
+
271
+ export default async function ShopPage({ params }: { params: { shopId: string } }) {
272
+ const client = await getEtsyServerClient();
273
+ const shop = await client.getShop(params.shopId);
274
+
275
+ return <div>{shop.title}</div>;
276
+ }
277
+ ```
278
+
279
+ ### Incremental Static Regeneration (ISR)
280
+
281
+ ```typescript
282
+ // app/listings/page.tsx
283
+ import { getEtsyServerClient } from '@profplum700/etsy-nextjs/server';
284
+
285
+ export const revalidate = 3600; // Revalidate every hour
286
+
287
+ export default async function ListingsPage() {
288
+ const client = await getEtsyServerClient();
289
+ const response = await client.getListingsByShop('123');
290
+
291
+ return <div>{/* Render listings */}</div>;
292
+ }
293
+ ```
294
+
295
+ ## Environment Variables
296
+
297
+ ```env
298
+ # Required
299
+ ETSY_API_KEY=your_api_key
300
+
301
+ # Optional
302
+ ETSY_REDIRECT_URI=http://localhost:3000/auth/callback
303
+ ETSY_SCOPES=listings_r,listings_w,shops_r
304
+ ```
305
+
306
+ ## TypeScript Support
307
+
308
+ All functions and components are fully typed with TypeScript.
309
+
310
+ ```typescript
311
+ import type {
312
+ EtsyServerClientConfig,
313
+ EtsyApiRouteConfig,
314
+ } from '@profplum700/etsy-nextjs';
315
+ ```
316
+
317
+ ## Best Practices
318
+
319
+ 1. **Use Server Components for Data Fetching**: Fetch data on the server to reduce client bundle size and improve performance.
320
+
321
+ 2. **Implement Rate Limiting**: Use the built-in rate limiting in API routes to prevent abuse.
322
+
323
+ 3. **Cache Responses**: Enable caching for frequently accessed data to reduce API calls.
324
+
325
+ 4. **Secure Your Keys**: Never expose your API key in client-side code. Use server-side rendering or API routes.
326
+
327
+ 5. **Handle Errors Gracefully**: Always wrap API calls in try-catch blocks and provide user feedback.
328
+
329
+ ## License
330
+
331
+ MIT
332
+
333
+ ## Related Packages
334
+
335
+ - [@profplum700/etsy-v3-api-client](../etsy-v3-api-client) - Core API client
336
+ - [@profplum700/etsy-react](../etsy-react) - React hooks
337
+ - [@profplum700/etsy-cli](../etsy-cli) - CLI tool
338
+ - [@profplum700/etsy-admin-ui](../etsy-admin-ui) - Admin dashboard components
package/dist/index.cjs ADDED
@@ -0,0 +1,206 @@
1
+ 'use strict';
2
+
3
+ var etsyV3ApiClient = require('@profplum700/etsy-v3-api-client');
4
+ var headers = require('next/headers');
5
+ var server = require('next/server');
6
+ var React = require('react');
7
+
8
+ let serverClientInstance = null;
9
+ let serverClientConfig = null;
10
+ function configureEtsyServerClient(config) {
11
+ serverClientConfig = config;
12
+ }
13
+ async function getEtsyServerClient() {
14
+ if (!serverClientConfig) {
15
+ throw new Error('Etsy server client not configured. Call configureEtsyServerClient() first.');
16
+ }
17
+ if (!serverClientInstance) {
18
+ const { apiKey } = serverClientConfig;
19
+ const cookieStore = await headers.cookies();
20
+ const cookieName = serverClientConfig.cookieName || 'etsy-tokens';
21
+ const tokenData = cookieStore.get(cookieName);
22
+ if (!tokenData) {
23
+ throw new Error('No authentication tokens found in cookies');
24
+ }
25
+ let tokens;
26
+ try {
27
+ tokens = JSON.parse(tokenData.value);
28
+ }
29
+ catch {
30
+ throw new Error('Invalid token data in cookies');
31
+ }
32
+ const refreshSave = async (accessToken, refreshToken, expiresAt) => {
33
+ const cookieStore = await headers.cookies();
34
+ const cookieName = serverClientConfig?.cookieName || 'etsy-tokens';
35
+ cookieStore.set(cookieName, JSON.stringify({
36
+ accessToken,
37
+ refreshToken,
38
+ expiresAt: expiresAt.toISOString(),
39
+ }), {
40
+ httpOnly: true,
41
+ secure: process.env.NODE_ENV === 'production',
42
+ sameSite: 'lax',
43
+ maxAge: 60 * 60 * 24 * 90,
44
+ });
45
+ };
46
+ serverClientInstance = new etsyV3ApiClient.EtsyClient({
47
+ keystring: apiKey,
48
+ accessToken: tokens.accessToken,
49
+ refreshToken: tokens.refreshToken,
50
+ expiresAt: new Date(tokens.expiresAt),
51
+ refreshSave,
52
+ });
53
+ }
54
+ return serverClientInstance;
55
+ }
56
+ async function createEtsyServerClient(config) {
57
+ const { apiKey, cookieName } = config;
58
+ const cookieStore = await headers.cookies();
59
+ const tokenCookieName = cookieName || 'etsy-tokens';
60
+ const tokenData = cookieStore.get(tokenCookieName);
61
+ if (!tokenData) {
62
+ throw new Error('No authentication tokens found in cookies');
63
+ }
64
+ let tokens;
65
+ try {
66
+ tokens = JSON.parse(tokenData.value);
67
+ }
68
+ catch {
69
+ throw new Error('Invalid token data in cookies');
70
+ }
71
+ const refreshSave = async (accessToken, refreshToken, expiresAt) => {
72
+ const cookieStore = await headers.cookies();
73
+ cookieStore.set(tokenCookieName, JSON.stringify({
74
+ accessToken,
75
+ refreshToken,
76
+ expiresAt: expiresAt.toISOString(),
77
+ }), {
78
+ httpOnly: true,
79
+ secure: process.env.NODE_ENV === 'production',
80
+ sameSite: 'lax',
81
+ maxAge: 60 * 60 * 24 * 90,
82
+ });
83
+ };
84
+ return new etsyV3ApiClient.EtsyClient({
85
+ keystring: apiKey,
86
+ accessToken: tokens.accessToken,
87
+ refreshToken: tokens.refreshToken,
88
+ expiresAt: new Date(tokens.expiresAt),
89
+ refreshSave,
90
+ });
91
+ }
92
+
93
+ const rateLimitStore = new Map();
94
+ function createEtsyApiRoute(config) {
95
+ const { rateLimit, cache } = config;
96
+ function checkRateLimit(identifier) {
97
+ if (!rateLimit)
98
+ return true;
99
+ const now = Date.now();
100
+ const entry = rateLimitStore.get(identifier);
101
+ if (!entry || now > entry.resetTime) {
102
+ rateLimitStore.set(identifier, {
103
+ count: 1,
104
+ resetTime: now + rateLimit.window,
105
+ });
106
+ return true;
107
+ }
108
+ if (entry.count >= rateLimit.requests) {
109
+ return false;
110
+ }
111
+ entry.count++;
112
+ return true;
113
+ }
114
+ async function handleRequest(request, handler) {
115
+ try {
116
+ if (rateLimit) {
117
+ const identifier = request.headers.get('x-forwarded-for') || 'anonymous';
118
+ if (!checkRateLimit(identifier)) {
119
+ return server.NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 });
120
+ }
121
+ }
122
+ const client = await getEtsyServerClient();
123
+ const result = await handler(client, request);
124
+ const response = server.NextResponse.json(result);
125
+ if (cache?.enabled) {
126
+ response.headers.set('Cache-Control', `public, s-maxage=${cache.ttl}, stale-while-revalidate`);
127
+ }
128
+ return response;
129
+ }
130
+ catch (error) {
131
+ console.error('Etsy API route error:', error);
132
+ if (error instanceof Error) {
133
+ return server.NextResponse.json({ error: error.message }, { status: 500 });
134
+ }
135
+ return server.NextResponse.json({ error: 'Internal server error' }, { status: 500 });
136
+ }
137
+ }
138
+ return {
139
+ GET: async (request) => {
140
+ return handleRequest(request, async (_client) => {
141
+ const { searchParams } = new URL(request.url);
142
+ const endpoint = searchParams.get('endpoint');
143
+ if (!endpoint) {
144
+ throw new Error('Endpoint parameter is required');
145
+ }
146
+ const params = {};
147
+ searchParams.forEach((value, key) => {
148
+ if (key !== 'endpoint') {
149
+ params[key] = value;
150
+ }
151
+ });
152
+ return { message: 'GET endpoint', endpoint, params };
153
+ });
154
+ },
155
+ POST: async (request) => {
156
+ return handleRequest(request, async (_client) => {
157
+ const body = await request.json();
158
+ const { endpoint, data } = body;
159
+ if (!endpoint) {
160
+ throw new Error('Endpoint parameter is required');
161
+ }
162
+ return { message: 'POST endpoint', endpoint, data };
163
+ });
164
+ },
165
+ PUT: async (request) => {
166
+ return handleRequest(request, async (_client) => {
167
+ const body = await request.json();
168
+ const { endpoint, data } = body;
169
+ if (!endpoint) {
170
+ throw new Error('Endpoint parameter is required');
171
+ }
172
+ return { message: 'PUT endpoint', endpoint, data };
173
+ });
174
+ },
175
+ DELETE: async (request) => {
176
+ return handleRequest(request, async (_client) => {
177
+ const { searchParams } = new URL(request.url);
178
+ const endpoint = searchParams.get('endpoint');
179
+ if (!endpoint) {
180
+ throw new Error('Endpoint parameter is required');
181
+ }
182
+ return { message: 'DELETE endpoint', endpoint };
183
+ });
184
+ },
185
+ };
186
+ }
187
+
188
+ const EtsyNextClientContext = React.createContext(undefined);
189
+ function EtsyNextClientProvider({ client, apiEndpoint, children }) {
190
+ return (React.createElement(EtsyNextClientContext.Provider, { value: { client, apiEndpoint } }, children));
191
+ }
192
+ function useEtsyNextClient() {
193
+ const context = React.useContext(EtsyNextClientContext);
194
+ if (!context) {
195
+ throw new Error('useEtsyNextClient must be used within an EtsyNextClientProvider');
196
+ }
197
+ return context;
198
+ }
199
+
200
+ exports.EtsyNextClientProvider = EtsyNextClientProvider;
201
+ exports.configureEtsyServerClient = configureEtsyServerClient;
202
+ exports.createEtsyApiRoute = createEtsyApiRoute;
203
+ exports.createEtsyServerClient = createEtsyServerClient;
204
+ exports.getEtsyServerClient = getEtsyServerClient;
205
+ exports.useEtsyNextClient = useEtsyNextClient;
206
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../../src/server/client.ts","../../src/server/route.ts","../../src/client/provider.tsx"],"sourcesContent":[null,null,null],"names":["cookies","EtsyClient","NextResponse","createContext","useContext"],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { EtsyClient } from '@profplum700/etsy-v3-api-client';
2
+ import { NextRequest, NextResponse } from 'next/server';
3
+ import React, { ReactNode } from 'react';
4
+
5
+ interface EtsyServerClientConfig {
6
+ apiKey: string;
7
+ redirectUri?: string;
8
+ scopes?: string[];
9
+ cookieName?: string;
10
+ encryptionKey?: string;
11
+ }
12
+ declare function configureEtsyServerClient(config: EtsyServerClientConfig): void;
13
+ declare function getEtsyServerClient(): Promise<EtsyClient>;
14
+ declare function createEtsyServerClient(config: EtsyServerClientConfig): Promise<EtsyClient>;
15
+
16
+ interface EtsyApiRouteConfig {
17
+ apiKey: string;
18
+ redirectUri?: string;
19
+ scopes?: string[];
20
+ rateLimit?: {
21
+ requests: number;
22
+ window: number;
23
+ };
24
+ cache?: {
25
+ enabled: boolean;
26
+ ttl: number;
27
+ };
28
+ }
29
+ declare function createEtsyApiRoute(config: EtsyApiRouteConfig): {
30
+ GET: (request: NextRequest) => Promise<NextResponse>;
31
+ POST: (request: NextRequest) => Promise<NextResponse>;
32
+ PUT: (request: NextRequest) => Promise<NextResponse>;
33
+ DELETE: (request: NextRequest) => Promise<NextResponse>;
34
+ };
35
+
36
+ interface EtsyNextClientContextValue {
37
+ client: EtsyClient;
38
+ apiEndpoint?: string;
39
+ }
40
+ interface EtsyNextClientProviderProps {
41
+ client: EtsyClient;
42
+ apiEndpoint?: string;
43
+ children: ReactNode;
44
+ }
45
+ declare function EtsyNextClientProvider({ client, apiEndpoint, children }: EtsyNextClientProviderProps): React.JSX.Element;
46
+ declare function useEtsyNextClient(): EtsyNextClientContextValue;
47
+
48
+ export { EtsyNextClientProvider, configureEtsyServerClient, createEtsyApiRoute, createEtsyServerClient, getEtsyServerClient, useEtsyNextClient };
49
+ export type { EtsyApiRouteConfig, EtsyServerClientConfig };
@@ -0,0 +1,199 @@
1
+ import { EtsyClient } from '@profplum700/etsy-v3-api-client';
2
+ import { cookies } from 'next/headers';
3
+ import { NextResponse } from 'next/server';
4
+ import React, { createContext, useContext } from 'react';
5
+
6
+ let serverClientInstance = null;
7
+ let serverClientConfig = null;
8
+ function configureEtsyServerClient(config) {
9
+ serverClientConfig = config;
10
+ }
11
+ async function getEtsyServerClient() {
12
+ if (!serverClientConfig) {
13
+ throw new Error('Etsy server client not configured. Call configureEtsyServerClient() first.');
14
+ }
15
+ if (!serverClientInstance) {
16
+ const { apiKey } = serverClientConfig;
17
+ const cookieStore = await cookies();
18
+ const cookieName = serverClientConfig.cookieName || 'etsy-tokens';
19
+ const tokenData = cookieStore.get(cookieName);
20
+ if (!tokenData) {
21
+ throw new Error('No authentication tokens found in cookies');
22
+ }
23
+ let tokens;
24
+ try {
25
+ tokens = JSON.parse(tokenData.value);
26
+ }
27
+ catch {
28
+ throw new Error('Invalid token data in cookies');
29
+ }
30
+ const refreshSave = async (accessToken, refreshToken, expiresAt) => {
31
+ const cookieStore = await cookies();
32
+ const cookieName = serverClientConfig?.cookieName || 'etsy-tokens';
33
+ cookieStore.set(cookieName, JSON.stringify({
34
+ accessToken,
35
+ refreshToken,
36
+ expiresAt: expiresAt.toISOString(),
37
+ }), {
38
+ httpOnly: true,
39
+ secure: process.env.NODE_ENV === 'production',
40
+ sameSite: 'lax',
41
+ maxAge: 60 * 60 * 24 * 90,
42
+ });
43
+ };
44
+ serverClientInstance = new EtsyClient({
45
+ keystring: apiKey,
46
+ accessToken: tokens.accessToken,
47
+ refreshToken: tokens.refreshToken,
48
+ expiresAt: new Date(tokens.expiresAt),
49
+ refreshSave,
50
+ });
51
+ }
52
+ return serverClientInstance;
53
+ }
54
+ async function createEtsyServerClient(config) {
55
+ const { apiKey, cookieName } = config;
56
+ const cookieStore = await cookies();
57
+ const tokenCookieName = cookieName || 'etsy-tokens';
58
+ const tokenData = cookieStore.get(tokenCookieName);
59
+ if (!tokenData) {
60
+ throw new Error('No authentication tokens found in cookies');
61
+ }
62
+ let tokens;
63
+ try {
64
+ tokens = JSON.parse(tokenData.value);
65
+ }
66
+ catch {
67
+ throw new Error('Invalid token data in cookies');
68
+ }
69
+ const refreshSave = async (accessToken, refreshToken, expiresAt) => {
70
+ const cookieStore = await cookies();
71
+ cookieStore.set(tokenCookieName, JSON.stringify({
72
+ accessToken,
73
+ refreshToken,
74
+ expiresAt: expiresAt.toISOString(),
75
+ }), {
76
+ httpOnly: true,
77
+ secure: process.env.NODE_ENV === 'production',
78
+ sameSite: 'lax',
79
+ maxAge: 60 * 60 * 24 * 90,
80
+ });
81
+ };
82
+ return new EtsyClient({
83
+ keystring: apiKey,
84
+ accessToken: tokens.accessToken,
85
+ refreshToken: tokens.refreshToken,
86
+ expiresAt: new Date(tokens.expiresAt),
87
+ refreshSave,
88
+ });
89
+ }
90
+
91
+ const rateLimitStore = new Map();
92
+ function createEtsyApiRoute(config) {
93
+ const { rateLimit, cache } = config;
94
+ function checkRateLimit(identifier) {
95
+ if (!rateLimit)
96
+ return true;
97
+ const now = Date.now();
98
+ const entry = rateLimitStore.get(identifier);
99
+ if (!entry || now > entry.resetTime) {
100
+ rateLimitStore.set(identifier, {
101
+ count: 1,
102
+ resetTime: now + rateLimit.window,
103
+ });
104
+ return true;
105
+ }
106
+ if (entry.count >= rateLimit.requests) {
107
+ return false;
108
+ }
109
+ entry.count++;
110
+ return true;
111
+ }
112
+ async function handleRequest(request, handler) {
113
+ try {
114
+ if (rateLimit) {
115
+ const identifier = request.headers.get('x-forwarded-for') || 'anonymous';
116
+ if (!checkRateLimit(identifier)) {
117
+ return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 });
118
+ }
119
+ }
120
+ const client = await getEtsyServerClient();
121
+ const result = await handler(client, request);
122
+ const response = NextResponse.json(result);
123
+ if (cache?.enabled) {
124
+ response.headers.set('Cache-Control', `public, s-maxage=${cache.ttl}, stale-while-revalidate`);
125
+ }
126
+ return response;
127
+ }
128
+ catch (error) {
129
+ console.error('Etsy API route error:', error);
130
+ if (error instanceof Error) {
131
+ return NextResponse.json({ error: error.message }, { status: 500 });
132
+ }
133
+ return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
134
+ }
135
+ }
136
+ return {
137
+ GET: async (request) => {
138
+ return handleRequest(request, async (_client) => {
139
+ const { searchParams } = new URL(request.url);
140
+ const endpoint = searchParams.get('endpoint');
141
+ if (!endpoint) {
142
+ throw new Error('Endpoint parameter is required');
143
+ }
144
+ const params = {};
145
+ searchParams.forEach((value, key) => {
146
+ if (key !== 'endpoint') {
147
+ params[key] = value;
148
+ }
149
+ });
150
+ return { message: 'GET endpoint', endpoint, params };
151
+ });
152
+ },
153
+ POST: async (request) => {
154
+ return handleRequest(request, async (_client) => {
155
+ const body = await request.json();
156
+ const { endpoint, data } = body;
157
+ if (!endpoint) {
158
+ throw new Error('Endpoint parameter is required');
159
+ }
160
+ return { message: 'POST endpoint', endpoint, data };
161
+ });
162
+ },
163
+ PUT: async (request) => {
164
+ return handleRequest(request, async (_client) => {
165
+ const body = await request.json();
166
+ const { endpoint, data } = body;
167
+ if (!endpoint) {
168
+ throw new Error('Endpoint parameter is required');
169
+ }
170
+ return { message: 'PUT endpoint', endpoint, data };
171
+ });
172
+ },
173
+ DELETE: async (request) => {
174
+ return handleRequest(request, async (_client) => {
175
+ const { searchParams } = new URL(request.url);
176
+ const endpoint = searchParams.get('endpoint');
177
+ if (!endpoint) {
178
+ throw new Error('Endpoint parameter is required');
179
+ }
180
+ return { message: 'DELETE endpoint', endpoint };
181
+ });
182
+ },
183
+ };
184
+ }
185
+
186
+ const EtsyNextClientContext = createContext(undefined);
187
+ function EtsyNextClientProvider({ client, apiEndpoint, children }) {
188
+ return (React.createElement(EtsyNextClientContext.Provider, { value: { client, apiEndpoint } }, children));
189
+ }
190
+ function useEtsyNextClient() {
191
+ const context = useContext(EtsyNextClientContext);
192
+ if (!context) {
193
+ throw new Error('useEtsyNextClient must be used within an EtsyNextClientProvider');
194
+ }
195
+ return context;
196
+ }
197
+
198
+ export { EtsyNextClientProvider, configureEtsyServerClient, createEtsyApiRoute, createEtsyServerClient, getEtsyServerClient, useEtsyNextClient };
199
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../../src/server/client.ts","../../src/server/route.ts","../../src/client/provider.tsx"],"sourcesContent":[null,null,null],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@profplum700/etsy-nextjs",
3
+ "version": "2.3.1",
4
+ "type": "module",
5
+ "description": "Next.js integration for Etsy v3 API client",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.esm.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist/**/*",
11
+ "README.md"
12
+ ],
13
+ "keywords": [
14
+ "etsy",
15
+ "api",
16
+ "v3",
17
+ "nextjs",
18
+ "next.js",
19
+ "react",
20
+ "typescript",
21
+ "javascript"
22
+ ],
23
+ "author": {
24
+ "name": "profplum700",
25
+ "email": "profplum700@users.noreply.github.com"
26
+ },
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/profplum700/etsy-v3-api-client.git",
31
+ "directory": "packages/etsy-nextjs"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/profplum700/etsy-v3-api-client/issues"
35
+ },
36
+ "homepage": "https://github.com/profplum700/etsy-v3-api-client/tree/main/packages/etsy-nextjs#readme",
37
+ "engines": {
38
+ "node": ">=20.0.0"
39
+ },
40
+ "peerDependencies": {
41
+ "@profplum700/etsy-v3-api-client": "^2.0.0",
42
+ "next": "^14.0.0 || ^15.0.0",
43
+ "react": "^18.0.0 || ^19.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "@rollup/plugin-commonjs": "^28.0.6",
47
+ "@rollup/plugin-node-resolve": "^16.0.1",
48
+ "@rollup/plugin-typescript": "^12.1.4",
49
+ "@types/jest": "^30.0.0",
50
+ "@types/node": "^24.1.0",
51
+ "@types/react": "^18.3.18",
52
+ "jest": "^30.0.5",
53
+ "next": "^15.1.4",
54
+ "react": "^18.3.1",
55
+ "rollup": "^4.45.1",
56
+ "rollup-plugin-dts": "^6.1.1",
57
+ "ts-jest": "^29.4.0",
58
+ "typescript": "^5.5.3",
59
+ "@profplum700/etsy-v3-api-client": "2.3.1"
60
+ },
61
+ "publishConfig": {
62
+ "access": "public"
63
+ },
64
+ "scripts": {
65
+ "build": "rollup -c",
66
+ "build:watch": "rollup -c --watch",
67
+ "test": "jest --passWithNoTests",
68
+ "test:watch": "jest --watch",
69
+ "test:coverage": "jest --coverage",
70
+ "lint": "eslint --config ../../eslint.config.mjs .",
71
+ "lint:fix": "eslint --fix --config ../../eslint.config.mjs .",
72
+ "type-check": "tsc --noEmit"
73
+ }
74
+ }