@cprice70/etsy-cli 0.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.
@@ -0,0 +1,5 @@
1
+ export declare const CALLBACK_PORT = 3003;
2
+ export declare const REDIRECT_URI = "http://localhost:3003/callback";
3
+ export declare function openBrowser(url: string): void;
4
+ export declare function waitForCallback(expectedState: string): Promise<string>;
5
+ //# sourceMappingURL=auth-callback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-callback.d.ts","sourceRoot":"","sources":["../../src/commands/auth-callback.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,OAAO,CAAC;AAClC,eAAO,MAAM,YAAY,mCAA+C,CAAC;AAEzE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAM7C;AAED,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCtE"}
@@ -0,0 +1,39 @@
1
+ import http from "http";
2
+ import { exec } from "child_process";
3
+ export const CALLBACK_PORT = 3003;
4
+ export const REDIRECT_URI = `http://localhost:${CALLBACK_PORT}/callback`;
5
+ export function openBrowser(url) {
6
+ const cmd = process.platform === "darwin" ? "open" :
7
+ process.platform === "win32" ? "start" :
8
+ "xdg-open";
9
+ exec(`${cmd} "${url}"`);
10
+ }
11
+ export function waitForCallback(expectedState) {
12
+ return new Promise((resolve, reject) => {
13
+ const server = http.createServer((req, res) => {
14
+ const url = new URL(req.url ?? "/", `http://localhost:${CALLBACK_PORT}`);
15
+ const code = url.searchParams.get("code");
16
+ const returnedState = url.searchParams.get("state");
17
+ const html = (title, body) => `<html><head><meta charset="UTF-8"></head><body style="font-family:sans-serif;max-width:500px;margin:80px auto;text-align:center"><h2>${title}</h2><p>${body}</p></body></html>`;
18
+ if (!code || returnedState !== expectedState) {
19
+ res.writeHead(400, { "Content-Type": "text/html" });
20
+ res.end(html("Authorization failed", "Missing code or state mismatch. Please try again."));
21
+ server.close();
22
+ reject(new Error("Authorization failed: missing code or state mismatch"));
23
+ return;
24
+ }
25
+ res.writeHead(200, { "Content-Type": "text/html" });
26
+ res.end(html("✅ Authorized!", "You can close this tab and return to the terminal."));
27
+ server.close();
28
+ resolve(code);
29
+ });
30
+ server.on("error", (err) => reject(new Error(`Callback server error: ${err.message}`)));
31
+ server.listen(CALLBACK_PORT);
32
+ const timeout = setTimeout(() => {
33
+ server.close();
34
+ reject(new Error("Timed out waiting for authorization (5 min limit)"));
35
+ }, 5 * 60 * 1000);
36
+ server.on("close", () => clearTimeout(timeout));
37
+ });
38
+ }
39
+ //# sourceMappingURL=auth-callback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-callback.js","sourceRoot":"","sources":["../../src/commands/auth-callback.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,aAAa,WAAW,CAAC;AAEzE,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,GAAG,GACP,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACxC,UAAU,CAAC;IACb,IAAI,CAAC,GAAG,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,aAAqB;IACnD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,aAAa,EAAE,CAAC,CAAC;YACzE,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,aAAa,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAEpD,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,IAAY,EAAE,EAAE,CAC3C,wIAAwI,KAAK,WAAW,IAAI,oBAAoB,CAAC;YAEnL,IAAI,CAAC,IAAI,IAAI,aAAa,KAAK,aAAa,EAAE,CAAC;gBAC7C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;gBACpD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,mDAAmD,CAAC,CAAC,CAAC;gBAC3F,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC,CAAC;gBAC1E,OAAO;YACT,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,oDAAoD,CAAC,CAAC,CAAC;YACrF,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QACxF,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAE7B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;QACzE,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAElB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { Command } from "commander";
2
+ export declare function generateCodeVerifier(): string;
3
+ export declare function generateCodeChallenge(verifier: string): string;
4
+ export declare function registerAuthCommands(program: Command): void;
5
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D;AAsFD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmK3D"}
@@ -0,0 +1,227 @@
1
+ import readline from "readline/promises";
2
+ import crypto from "crypto";
3
+ import { loadConfig, saveConfig, deleteConfig, getConfigPath } from "../config.js";
4
+ import { printSuccess, printError, printWarning } from "../output.js";
5
+ import { CALLBACK_PORT, REDIRECT_URI, openBrowser, waitForCallback } from "./auth-callback.js";
6
+ const OAUTH_SCOPES = "listings_r listings_w transactions_r shops_r";
7
+ const TOKEN_URL = "https://api.etsy.com/v3/public/oauth/token";
8
+ export function generateCodeVerifier() {
9
+ return crypto.randomBytes(32).toString("base64url");
10
+ }
11
+ export function generateCodeChallenge(verifier) {
12
+ return crypto.createHash("sha256").update(verifier).digest("base64url");
13
+ }
14
+ function maskSecret(value) {
15
+ if (!value)
16
+ return "(not set)";
17
+ if (value.length <= 8)
18
+ return "****";
19
+ return value.slice(0, 4) + "****" + value.slice(-4);
20
+ }
21
+ async function exchangeCodeForTokens(code, clientId, codeVerifier) {
22
+ const body = new URLSearchParams({
23
+ grant_type: "authorization_code",
24
+ client_id: clientId,
25
+ redirect_uri: REDIRECT_URI,
26
+ code,
27
+ code_verifier: codeVerifier,
28
+ });
29
+ const response = await fetch(TOKEN_URL, {
30
+ method: "POST",
31
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
32
+ body: body.toString(),
33
+ });
34
+ if (!response.ok) {
35
+ const err = await response.json().catch(() => ({}));
36
+ throw new Error(`Token exchange failed: ${err.error_description ?? err.error ?? response.status}`);
37
+ }
38
+ const data = await response.json();
39
+ if (typeof data.access_token !== "string" || !data.access_token ||
40
+ typeof data.refresh_token !== "string" || !data.refresh_token) {
41
+ throw new Error("Invalid token response: missing access_token or refresh_token");
42
+ }
43
+ return data;
44
+ }
45
+ async function detectShopId(accessToken, xApiKey, userId) {
46
+ try {
47
+ let resolvedUserId = userId;
48
+ // If user_id not provided, fetch current user via /application/users/me
49
+ if (!resolvedUserId) {
50
+ const meRes = await fetch(`https://openapi.etsy.com/v3/application/users/me`, {
51
+ headers: {
52
+ "Authorization": `Bearer ${accessToken}`,
53
+ "x-api-key": xApiKey,
54
+ },
55
+ });
56
+ if (!meRes.ok)
57
+ return undefined;
58
+ const me = await meRes.json();
59
+ resolvedUserId = me.user_id;
60
+ if (!resolvedUserId)
61
+ return undefined;
62
+ }
63
+ // Get shops for user
64
+ const shopsRes = await fetch(`https://openapi.etsy.com/v3/application/users/${resolvedUserId}/shops`, {
65
+ headers: {
66
+ "Authorization": `Bearer ${accessToken}`,
67
+ "x-api-key": xApiKey,
68
+ },
69
+ });
70
+ if (!shopsRes.ok)
71
+ return undefined;
72
+ const shops = await shopsRes.json();
73
+ return shops.shop_id ? String(shops.shop_id) : undefined;
74
+ }
75
+ catch {
76
+ return undefined;
77
+ }
78
+ }
79
+ export function registerAuthCommands(program) {
80
+ const auth = program.command("auth").description("Manage authentication");
81
+ auth
82
+ .command("login")
83
+ .description("Store Etsy credentials interactively")
84
+ .action(async () => {
85
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
86
+ try {
87
+ const apiKey = await rl.question("API Key (keystring): ");
88
+ if (!apiKey.trim()) {
89
+ printError("API Key is required");
90
+ process.exit(1);
91
+ return;
92
+ }
93
+ const sharedSecret = await rl.question("Shared Secret: ");
94
+ if (!sharedSecret.trim()) {
95
+ printError("Shared Secret is required");
96
+ process.exit(1);
97
+ return;
98
+ }
99
+ const clientId = await rl.question("Client ID (same as API Key / keystring): ");
100
+ if (!clientId.trim()) {
101
+ printError("Client ID is required");
102
+ process.exit(1);
103
+ return;
104
+ }
105
+ const currentConfig = loadConfig();
106
+ const partialConfig = {
107
+ ...currentConfig,
108
+ apiKey: apiKey.trim(),
109
+ sharedSecret: sharedSecret.trim(),
110
+ clientId: clientId.trim(),
111
+ };
112
+ // Save API key and client ID immediately for public read access
113
+ saveConfig(partialConfig);
114
+ const doOAuth = await rl.question("Complete OAuth for full access? (y/N): ");
115
+ if (doOAuth.trim().toLowerCase() === "y") {
116
+ const codeVerifier = generateCodeVerifier();
117
+ const codeChallenge = generateCodeChallenge(codeVerifier);
118
+ const state = crypto.randomBytes(16).toString("hex");
119
+ const authUrl = `https://www.etsy.com/oauth/connect` +
120
+ `?response_type=code` +
121
+ `&client_id=${encodeURIComponent(clientId.trim())}` +
122
+ `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
123
+ `&scope=${encodeURIComponent(OAUTH_SCOPES)}` +
124
+ `&state=${state}` +
125
+ `&code_challenge=${codeChallenge}` +
126
+ `&code_challenge_method=S256`;
127
+ console.log("\nOpening browser for authorization...");
128
+ console.log("(If it doesn't open, visit this URL manually:)\n");
129
+ console.log(authUrl);
130
+ console.log(`\nWaiting for callback on http://localhost:${CALLBACK_PORT}...\n`);
131
+ openBrowser(authUrl);
132
+ const code = await waitForCallback(state);
133
+ process.stdout.write("Exchanging code for tokens... ");
134
+ const tokens = await exchangeCodeForTokens(code, clientId.trim(), codeVerifier);
135
+ process.stdout.write("done\n");
136
+ partialConfig.accessToken = tokens.access_token;
137
+ partialConfig.refreshToken = tokens.refresh_token;
138
+ partialConfig.accessTokenExpiresAt =
139
+ Math.floor(Date.now() / 1000) + tokens.expires_in;
140
+ process.stdout.write("Detecting shop ID... ");
141
+ const xApiKey = sharedSecret.trim()
142
+ ? `${apiKey.trim()}:${sharedSecret.trim()}`
143
+ : apiKey.trim();
144
+ const shopId = await detectShopId(tokens.access_token, xApiKey, tokens.user_id);
145
+ if (shopId) {
146
+ process.stdout.write(`found: ${shopId}\n`);
147
+ partialConfig.shopId = shopId;
148
+ }
149
+ else {
150
+ process.stdout.write("not found\n");
151
+ const manualShopId = await rl.question("Enter your Shop ID manually (or press Enter to skip): ");
152
+ if (manualShopId.trim()) {
153
+ partialConfig.shopId = manualShopId.trim();
154
+ }
155
+ }
156
+ }
157
+ saveConfig(partialConfig);
158
+ printSuccess(`Config saved to ${getConfigPath()}`);
159
+ }
160
+ catch (err) {
161
+ printError(`Login failed: ${err instanceof Error ? err.message : String(err)}`);
162
+ process.exit(1);
163
+ }
164
+ finally {
165
+ rl.close();
166
+ process.stdin.destroy();
167
+ }
168
+ });
169
+ auth
170
+ .command("status")
171
+ .description("Show current authentication status")
172
+ .action(() => {
173
+ try {
174
+ const config = loadConfig();
175
+ const configPath = getConfigPath();
176
+ const hasOAuth = !!(config.accessToken && config.refreshToken);
177
+ const statusLabel = config.apiKey ? "Configured" : "Not configured";
178
+ const printStatus = config.apiKey ? printSuccess : printWarning;
179
+ let expiryStr = "(not set)";
180
+ if (config.accessTokenExpiresAt) {
181
+ expiryStr = new Date(config.accessTokenExpiresAt * 1000).toISOString();
182
+ }
183
+ console.log("");
184
+ console.log("Etsy CLI Status:");
185
+ console.log(" API Key: " + maskSecret(config.apiKey));
186
+ console.log(" Shared Secret: " + maskSecret(config.sharedSecret));
187
+ console.log(" Client ID: " + maskSecret(config.clientId));
188
+ console.log(" OAuth: " + (hasOAuth ? "configured" : "not configured"));
189
+ console.log(" Access Token: " + maskSecret(config.accessToken));
190
+ console.log(" Token Expiry: " + expiryStr);
191
+ console.log(" Refresh Token: " + maskSecret(config.refreshToken));
192
+ console.log(" Shop ID: " + (config.shopId || "(not set)"));
193
+ console.log(" Config File: " + configPath);
194
+ console.log("");
195
+ printStatus(statusLabel);
196
+ console.log("");
197
+ }
198
+ catch (err) {
199
+ printError(`Status check failed: ${err instanceof Error ? err.message : String(err)}`);
200
+ process.exit(1);
201
+ }
202
+ });
203
+ auth
204
+ .command("logout")
205
+ .description("Delete stored credentials")
206
+ .action(async () => {
207
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
208
+ try {
209
+ const answer = await rl.question("This will delete all stored credentials and require full re-setup. Continue? (y/N): ");
210
+ if (answer.trim().toLowerCase() !== "y") {
211
+ console.log("Aborted.");
212
+ return;
213
+ }
214
+ deleteConfig();
215
+ printSuccess("Logged out. Config file deleted.");
216
+ }
217
+ catch (err) {
218
+ printError(`Logout failed: ${err instanceof Error ? err.message : String(err)}`);
219
+ process.exit(1);
220
+ }
221
+ finally {
222
+ rl.close();
223
+ process.stdin.destroy();
224
+ }
225
+ });
226
+ }
227
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Command } from "commander";
2
+ import type { EtsyClient } from "../etsy-client.js";
3
+ export declare function registerListingsCommands(program: Command, client: EtsyClient, resolveShopId: (opts: {
4
+ shop?: string;
5
+ }) => string): void;
6
+ //# sourceMappingURL=listings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listings.d.ts","sourceRoot":"","sources":["../../src/commands/listings.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkCpD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,GACjD,IAAI,CAiON"}
@@ -0,0 +1,213 @@
1
+ import readline from "readline/promises";
2
+ import { printTable, printJson, printError, printSuccess, colorState, isAuthError } from "../output.js";
3
+ const STATE_ENDPOINTS = {
4
+ active: "active",
5
+ draft: "draft",
6
+ inactive: "inactive",
7
+ };
8
+ function formatPrice(price) {
9
+ if (!price)
10
+ return "";
11
+ const amount = price.amount / price.divisor;
12
+ return `${price.currency_code ?? "$"}${amount.toFixed(2)}`;
13
+ }
14
+ export function registerListingsCommands(program, client, resolveShopId) {
15
+ const listings = program.command("listings").description("Manage listings");
16
+ listings
17
+ .command("list")
18
+ .description("List shop listings")
19
+ .option("--state <state>", "Listing state: active, draft, inactive", "active")
20
+ .option("--limit <n>", "Number of results (max 100)", "25")
21
+ .option("--offset <n>", "Pagination offset", "0")
22
+ .option("--shop <id>", "Shop ID override")
23
+ .option("--json", "Output raw JSON")
24
+ .action(async (opts) => {
25
+ try {
26
+ const shopId = resolveShopId({ shop: opts.shop });
27
+ const endpoint = STATE_ENDPOINTS[opts.state] ?? "active";
28
+ const limit = Math.min(parseInt(opts.limit, 10) || 25, 100);
29
+ const result = await client.call("GET", `/application/shops/${shopId}/listings/${endpoint}`, { query: { limit: String(limit), offset: opts.offset } });
30
+ const items = result.results ?? [];
31
+ if (opts.json) {
32
+ printJson(items);
33
+ return;
34
+ }
35
+ if (items.length === 0) {
36
+ console.log("No listings found.");
37
+ return;
38
+ }
39
+ const rows = items.map((l) => [
40
+ String(l.listing_id ?? ""),
41
+ l.title ?? "",
42
+ formatPrice(l.price),
43
+ String(l.quantity ?? ""),
44
+ colorState(l.state ?? ""),
45
+ ]);
46
+ printTable(["ID", "Title", "Price", "Qty", "State"], rows);
47
+ }
48
+ catch (err) {
49
+ const message = err instanceof Error ? err.message : String(err);
50
+ printError(`Failed to list listings: ${message}`);
51
+ if (isAuthError(err)) {
52
+ printError("Hint: run 'etsy auth login' to re-authenticate.");
53
+ }
54
+ process.exit(1);
55
+ return;
56
+ }
57
+ });
58
+ listings
59
+ .command("get")
60
+ .description("Get a listing by ID")
61
+ .requiredOption("--id <id>", "Listing ID")
62
+ .option("--json", "Output raw JSON")
63
+ .action(async (opts) => {
64
+ try {
65
+ const result = await client.call("GET", `/application/listings/${opts.id}`, {});
66
+ if (opts.json) {
67
+ printJson(result);
68
+ return;
69
+ }
70
+ console.log("");
71
+ for (const [key, value] of Object.entries(result)) {
72
+ if (value !== null && value !== undefined) {
73
+ const display = typeof value === "object" ? JSON.stringify(value) : String(value);
74
+ console.log(` ${key}: ${display}`);
75
+ }
76
+ }
77
+ console.log("");
78
+ }
79
+ catch (err) {
80
+ const message = err instanceof Error ? err.message : String(err);
81
+ printError(`Failed to get listing: ${message}`);
82
+ if (isAuthError(err)) {
83
+ printError("Hint: run 'etsy auth login' to re-authenticate.");
84
+ }
85
+ process.exit(1);
86
+ return;
87
+ }
88
+ });
89
+ listings
90
+ .command("create")
91
+ .description("Create a new listing (interactive)")
92
+ .option("--shop <id>", "Shop ID override")
93
+ .action(async (opts) => {
94
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
95
+ try {
96
+ const shopId = resolveShopId({ shop: opts.shop });
97
+ const title = await rl.question("Title: ");
98
+ const description = await rl.question("Description: ");
99
+ const priceStr = await rl.question("Price (e.g. 19.99): ");
100
+ const quantityStr = await rl.question("Quantity: ");
101
+ const type = await rl.question("Type (physical/digital/download): ");
102
+ const taxonomyIdStr = await rl.question("Taxonomy ID (see https://developer.etsy.com): ");
103
+ const shippingProfileIdStr = await rl.question("Shipping Profile ID (physical only, or press Enter to skip): ");
104
+ const whoMade = await rl.question("Who made it? (i_did/someone_else/collective): ");
105
+ const whenMade = await rl.question("When made? (e.g. 2020_2024): ");
106
+ const isSupplyStr = await rl.question("Is supply? (y/N): ");
107
+ const price = parseFloat(priceStr);
108
+ if (isNaN(price)) {
109
+ printError("Invalid price: must be a number (e.g. 19.99)");
110
+ process.exit(1);
111
+ return;
112
+ }
113
+ const quantity = parseInt(quantityStr, 10);
114
+ if (isNaN(quantity)) {
115
+ printError("Invalid quantity: must be an integer");
116
+ process.exit(1);
117
+ return;
118
+ }
119
+ const taxonomyId = parseInt(taxonomyIdStr, 10);
120
+ if (isNaN(taxonomyId)) {
121
+ printError("Invalid taxonomy ID: must be an integer");
122
+ process.exit(1);
123
+ return;
124
+ }
125
+ const body = {
126
+ title: title.trim(),
127
+ description: description.trim(),
128
+ price,
129
+ quantity,
130
+ type: type.trim(),
131
+ taxonomy_id: taxonomyId,
132
+ who_made: whoMade.trim(),
133
+ when_made: whenMade.trim(),
134
+ is_supply: isSupplyStr.trim().toLowerCase() === "y",
135
+ };
136
+ if (shippingProfileIdStr.trim()) {
137
+ const shippingProfileId = parseInt(shippingProfileIdStr.trim(), 10);
138
+ if (isNaN(shippingProfileId)) {
139
+ printError("Invalid shipping profile ID: must be an integer");
140
+ process.exit(1);
141
+ return;
142
+ }
143
+ body.shipping_profile_id = shippingProfileId;
144
+ }
145
+ const result = await client.call("POST", `/application/shops/${shopId}/listings`, { body, oauth: true });
146
+ printSuccess(`Created listing ID: ${result.listing_id}`);
147
+ }
148
+ catch (err) {
149
+ const message = err instanceof Error ? err.message : String(err);
150
+ printError(`Failed to create listing: ${message}`);
151
+ if (isAuthError(err)) {
152
+ printError("Hint: run 'etsy auth login' to re-authenticate.");
153
+ }
154
+ process.exit(1);
155
+ return;
156
+ }
157
+ finally {
158
+ rl.close();
159
+ process.stdin.destroy();
160
+ }
161
+ });
162
+ listings
163
+ .command("update")
164
+ .description("Update a listing")
165
+ .requiredOption("--id <id>", "Listing ID")
166
+ .option("--title <text>", "New title")
167
+ .option("--price <amount>", "New price")
168
+ .option("--quantity <n>", "New quantity")
169
+ .option("--state <state>", "New state: active, inactive, draft")
170
+ .action(async (opts) => {
171
+ try {
172
+ const validStates = ["active", "inactive", "draft"];
173
+ if (opts.state !== undefined && !validStates.includes(opts.state)) {
174
+ printError(`Invalid state: "${opts.state}". Must be one of: active, inactive, draft`);
175
+ process.exit(1);
176
+ return;
177
+ }
178
+ const body = {};
179
+ if (opts.title !== undefined)
180
+ body.title = opts.title;
181
+ if (opts.price !== undefined) {
182
+ const price = parseFloat(opts.price);
183
+ if (isNaN(price)) {
184
+ printError("Invalid price: must be a number (e.g. 19.99)");
185
+ process.exit(1);
186
+ return;
187
+ }
188
+ body.price = price;
189
+ }
190
+ if (opts.quantity !== undefined)
191
+ body.quantity = parseInt(opts.quantity, 10);
192
+ if (opts.state !== undefined)
193
+ body.state = opts.state;
194
+ if (Object.keys(body).length === 0) {
195
+ printError("No fields to update. Provide at least one of: --title, --price, --quantity, --state");
196
+ process.exit(1);
197
+ return;
198
+ }
199
+ const result = await client.call("PATCH", `/application/listings/${opts.id}`, { body, oauth: true });
200
+ console.log(`Updated listing ${result.listing_id ?? opts.id}`);
201
+ }
202
+ catch (err) {
203
+ const message = err instanceof Error ? err.message : String(err);
204
+ printError(`Failed to update listing: ${message}`);
205
+ if (isAuthError(err)) {
206
+ printError("Hint: run 'etsy auth login' to re-authenticate.");
207
+ }
208
+ process.exit(1);
209
+ return;
210
+ }
211
+ });
212
+ }
213
+ //# sourceMappingURL=listings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listings.js","sourceRoot":"","sources":["../../src/commands/listings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Command } from "commander";
2
+ import type { EtsyClient } from "../etsy-client.js";
3
+ export declare function registerOrdersCommands(program: Command, client: EtsyClient, resolveShopId: (opts: {
4
+ shop?: string;
5
+ }) => string): void;
6
+ //# sourceMappingURL=orders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orders.d.ts","sourceRoot":"","sources":["../../src/commands/orders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAoCpD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,GACjD,IAAI,CA2HN"}
@@ -0,0 +1,111 @@
1
+ import { printTable, printJson, printError, colorState, isAuthError } from "../output.js";
2
+ function formatTotal(total) {
3
+ if (!total)
4
+ return "";
5
+ const amount = total.amount / total.divisor;
6
+ return `${total.currency_code ?? "$"}${amount.toFixed(2)}`;
7
+ }
8
+ export function registerOrdersCommands(program, client, resolveShopId) {
9
+ const orders = program.command("orders").description("View orders (receipts)");
10
+ orders
11
+ .command("list")
12
+ .description("List orders")
13
+ .option("--limit <n>", "Number of results (max 100)", "25")
14
+ .option("--offset <n>", "Pagination offset", "0")
15
+ .option("--start <date>", "ISO 8601 start date (e.g. 2024-01-01)")
16
+ .option("--end <date>", "ISO 8601 end date")
17
+ .option("--shop <id>", "Shop ID override")
18
+ .option("--json", "Output raw JSON")
19
+ .action(async (opts) => {
20
+ try {
21
+ const shopId = resolveShopId({ shop: opts.shop });
22
+ const limit = Math.min(parseInt(opts.limit, 10) || 25, 100);
23
+ const query = {
24
+ limit: String(limit),
25
+ offset: String(parseInt(opts.offset, 10) || 0),
26
+ };
27
+ if (opts.start) {
28
+ const ts = Math.floor(new Date(opts.start).getTime() / 1000);
29
+ if (isNaN(ts)) {
30
+ printError(`Invalid --start date: "${opts.start}". Use ISO 8601 format (e.g. 2024-01-01)`);
31
+ process.exit(1);
32
+ return;
33
+ }
34
+ query.min_created = String(ts);
35
+ }
36
+ if (opts.end) {
37
+ const ts = Math.floor(new Date(opts.end).getTime() / 1000);
38
+ if (isNaN(ts)) {
39
+ printError(`Invalid --end date: "${opts.end}". Use ISO 8601 format (e.g. 2024-12-31)`);
40
+ process.exit(1);
41
+ return;
42
+ }
43
+ query.max_created = String(ts);
44
+ }
45
+ const result = await client.call("GET", `/application/shops/${shopId}/receipts`, { query, oauth: true });
46
+ const receipts = result.results ?? [];
47
+ if (opts.json) {
48
+ printJson(receipts);
49
+ return;
50
+ }
51
+ if (receipts.length === 0) {
52
+ console.log("No orders found.");
53
+ return;
54
+ }
55
+ const rows = receipts.map((r) => [
56
+ String(r.receipt_id ?? ""),
57
+ r.name ?? "",
58
+ r.create_timestamp ? new Date(r.create_timestamp * 1000).toISOString().split("T")[0] : "",
59
+ formatTotal(r.grandtotal),
60
+ colorState(r.status ?? ""),
61
+ ]);
62
+ printTable(["Receipt ID", "Buyer", "Date", "Total", "Status"], rows);
63
+ }
64
+ catch (err) {
65
+ const message = err instanceof Error ? err.message : String(err);
66
+ printError(`Failed to list orders: ${message}`);
67
+ if (isAuthError(err)) {
68
+ printError("Hint: run 'etsy auth login' to re-authenticate.");
69
+ }
70
+ process.exit(1);
71
+ }
72
+ });
73
+ orders
74
+ .command("get")
75
+ .description("Get a single order by receipt ID")
76
+ .requiredOption("--id <id>", "Receipt ID")
77
+ .option("--shop <id>", "Shop ID override")
78
+ .option("--json", "Output raw JSON")
79
+ .action(async (opts) => {
80
+ try {
81
+ const shopId = resolveShopId({ shop: opts.shop });
82
+ const result = await client.call("GET", `/application/shops/${shopId}/receipts/${opts.id}`, { oauth: true });
83
+ if (opts.json) {
84
+ printJson(result);
85
+ return;
86
+ }
87
+ console.log("");
88
+ console.log(` Receipt ID: ${result.receipt_id ?? opts.id}`);
89
+ console.log(` Buyer: ${result.name ?? ""}`);
90
+ console.log(` Status: ${colorState(result.status ?? "")}`);
91
+ console.log(` Total: ${formatTotal(result.grandtotal)}`);
92
+ if (result.transactions && result.transactions.length > 0) {
93
+ console.log("\n Line Items:");
94
+ for (const txn of result.transactions) {
95
+ const price = txn.price ? formatTotal(txn.price) : "";
96
+ console.log(` - ${txn.title ?? ""} (x${txn.quantity ?? 1}) ${price}`);
97
+ }
98
+ }
99
+ console.log("");
100
+ }
101
+ catch (err) {
102
+ const message = err instanceof Error ? err.message : String(err);
103
+ printError(`Failed to get order: ${message}`);
104
+ if (isAuthError(err)) {
105
+ printError("Hint: run 'etsy auth login' to re-authenticate.");
106
+ }
107
+ process.exit(1);
108
+ }
109
+ });
110
+ }
111
+ //# sourceMappingURL=orders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orders.js","sourceRoot":"","sources":["../../src/commands/orders.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Command } from "commander";
2
+ import type { EtsyClient } from "../etsy-client.js";
3
+ export declare function registerShopCommands(program: Command, client: EtsyClient, resolveShopId: (opts: {
4
+ shop?: string;
5
+ }) => string): void;
6
+ //# sourceMappingURL=shop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shop.d.ts","sourceRoot":"","sources":["../../src/commands/shop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAYpD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,GACjD,IAAI,CAkCN"}
@@ -0,0 +1,35 @@
1
+ import { printJson, printError, isAuthError } from "../output.js";
2
+ export function registerShopCommands(program, client, resolveShopId) {
3
+ const shop = program.command("shop").description("View shop information");
4
+ shop
5
+ .command("get")
6
+ .description("Get your shop details")
7
+ .option("--shop <id>", "Shop ID override")
8
+ .option("--json", "Output raw JSON")
9
+ .action(async (opts) => {
10
+ try {
11
+ const shopId = resolveShopId({ shop: opts.shop });
12
+ const result = await client.call("GET", `/application/shops/${shopId}`, {});
13
+ if (opts.json) {
14
+ printJson(result);
15
+ return;
16
+ }
17
+ console.log("");
18
+ console.log(` Shop Name: ${result.shop_name ?? ""}`);
19
+ console.log(` Shop ID: ${result.shop_id ?? shopId}`);
20
+ console.log(` Currency: ${result.currency_code ?? ""}`);
21
+ console.log(` Active Listings: ${result.listing_active_count ?? 0}`);
22
+ console.log(` On Vacation: ${result.is_vacation ? "yes" : "no"}`);
23
+ console.log("");
24
+ }
25
+ catch (err) {
26
+ const message = err instanceof Error ? err.message : String(err);
27
+ printError(`Failed to get shop: ${message}`);
28
+ if (isAuthError(err)) {
29
+ printError("Hint: run 'etsy auth login' to re-authenticate.");
30
+ }
31
+ process.exit(1);
32
+ }
33
+ });
34
+ }
35
+ //# sourceMappingURL=shop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shop.js","sourceRoot":"","sources":["../../src/commands/shop.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAWlE,MAAM,UAAU,oBAAoB,CAClC,OAAgB,EAChB,MAAkB,EAClB,aAAkD;IAElD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAE1E,IAAI;SACD,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,uBAAuB,CAAC;SACpC,MAAM,CAAC,aAAa,EAAE,kBAAkB,CAAC;SACzC,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,KAAK,EAAE,IAAuC,EAAE,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,sBAAsB,MAAM,EAAE,EAAE,EAAE,CAAe,CAAC;YAE1F,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,SAAS,CAAC,MAAM,CAAC,CAAC;gBAClB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC,CAAC;YAC9D,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,oBAAoB,IAAI,CAAC,EAAE,CAAC,CAAC;YACtE,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,UAAU,CAAC,uBAAuB,OAAO,EAAE,CAAC,CAAC;YAC7C,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,UAAU,CAAC,iDAAiD,CAAC,CAAC;YAChE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface Config {
2
+ apiKey: string;
3
+ sharedSecret: string;
4
+ clientId: string;
5
+ accessToken: string;
6
+ refreshToken: string;
7
+ accessTokenExpiresAt: number;
8
+ shopId: string;
9
+ }
10
+ export declare function getConfigPath(): string;
11
+ export declare function loadConfig(): Partial<Config>;
12
+ export declare function saveConfig(config: Partial<Config>): void;
13
+ export declare function deleteConfig(): void;
14
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAoB5C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAKxD;AAED,wBAAgB,YAAY,IAAI,IAAI,CAOnC"}
@@ -0,0 +1,45 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import os from "os";
4
+ export function getConfigPath() {
5
+ return path.join(os.homedir(), ".config", "etsy-cli", "config.json");
6
+ }
7
+ export function loadConfig() {
8
+ const configPath = getConfigPath();
9
+ let fileConfig = {};
10
+ try {
11
+ const raw = fs.readFileSync(configPath, "utf-8");
12
+ fileConfig = JSON.parse(raw);
13
+ }
14
+ catch {
15
+ // File doesn't exist or is invalid
16
+ }
17
+ const config = { ...fileConfig };
18
+ if (process.env.ETSY_API_KEY)
19
+ config.apiKey = process.env.ETSY_API_KEY;
20
+ if (process.env.ETSY_SHARED_SECRET)
21
+ config.sharedSecret = process.env.ETSY_SHARED_SECRET;
22
+ if (process.env.ETSY_ACCESS_TOKEN)
23
+ config.accessToken = process.env.ETSY_ACCESS_TOKEN;
24
+ if (process.env.ETSY_REFRESH_TOKEN)
25
+ config.refreshToken = process.env.ETSY_REFRESH_TOKEN;
26
+ if (process.env.ETSY_SHOP_ID)
27
+ config.shopId = process.env.ETSY_SHOP_ID;
28
+ return config;
29
+ }
30
+ export function saveConfig(config) {
31
+ const configPath = getConfigPath();
32
+ const configDir = path.dirname(configPath);
33
+ fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
34
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 0o600 });
35
+ }
36
+ export function deleteConfig() {
37
+ const configPath = getConfigPath();
38
+ try {
39
+ fs.unlinkSync(configPath);
40
+ }
41
+ catch {
42
+ // File doesn't exist — ignore
43
+ }
44
+ }
45
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAYpB,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,IAAI,UAAU,GAAoB,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;IACrC,CAAC;IAED,MAAM,MAAM,GAAoB,EAAE,GAAG,UAAU,EAAE,CAAC;IAElD,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IACvE,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAAE,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IACzF,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAAE,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACtF,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAAE,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IACzF,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAEvE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAuB;IAChD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type Config } from "./config.js";
2
+ interface CallOptions {
3
+ query?: Record<string, string>;
4
+ body?: unknown;
5
+ oauth?: boolean;
6
+ }
7
+ export declare class EtsyClient {
8
+ private config;
9
+ constructor(config: Partial<Config>);
10
+ call(method: string, path: string, options?: CallOptions): Promise<unknown>;
11
+ private makeRequest;
12
+ private handleResponse;
13
+ private doRefresh;
14
+ }
15
+ export declare function createClient(config: Partial<Config>): EtsyClient;
16
+ export {};
17
+ //# sourceMappingURL=etsy-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"etsy-client.d.ts","sourceRoot":"","sources":["../src/etsy-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAMtD,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;IAI7B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;YA+BvE,WAAW;YA8BX,cAAc;YAmBd,SAAS;CAwCxB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,UAAU,CAEhE"}
@@ -0,0 +1,110 @@
1
+ import { saveConfig } from "./config.js";
2
+ const BASE_URL = "https://openapi.etsy.com/v3";
3
+ const TOKEN_URL = "https://api.etsy.com/v3/public/oauth/token";
4
+ const REFRESH_THRESHOLD_SECONDS = 60;
5
+ export class EtsyClient {
6
+ config;
7
+ constructor(config) {
8
+ this.config = config;
9
+ }
10
+ async call(method, path, options = {}) {
11
+ if (options.oauth && !this.config.accessToken) {
12
+ throw new Error("This command requires OAuth. Run `etsy auth login` and complete the OAuth step.");
13
+ }
14
+ // Proactive refresh: if expiresAt known and within threshold
15
+ if (this.config.accessToken &&
16
+ this.config.accessTokenExpiresAt !== undefined &&
17
+ !process.env.ETSY_ACCESS_TOKEN // skip if env-var-supplied
18
+ ) {
19
+ const secondsUntilExpiry = this.config.accessTokenExpiresAt - Math.floor(Date.now() / 1000);
20
+ if (secondsUntilExpiry < REFRESH_THRESHOLD_SECONDS) {
21
+ await this.doRefresh();
22
+ }
23
+ }
24
+ const response = await this.makeRequest(method, path, options);
25
+ // Reactive refresh on 401
26
+ if (response.status === 401 && this.config.accessToken && this.config.refreshToken) {
27
+ await this.doRefresh();
28
+ const retryResponse = await this.makeRequest(method, path, options);
29
+ return this.handleResponse(retryResponse);
30
+ }
31
+ return this.handleResponse(response);
32
+ }
33
+ async makeRequest(method, path, options) {
34
+ const url = new URL(`${BASE_URL}${path}`);
35
+ if (options.query) {
36
+ for (const [k, v] of Object.entries(options.query)) {
37
+ url.searchParams.set(k, v);
38
+ }
39
+ }
40
+ const headers = {};
41
+ if (this.config.accessToken) {
42
+ headers["Authorization"] = `Bearer ${this.config.accessToken}`;
43
+ }
44
+ if (this.config.apiKey) {
45
+ headers["x-api-key"] = this.config.sharedSecret
46
+ ? `${this.config.apiKey}:${this.config.sharedSecret}`
47
+ : this.config.apiKey;
48
+ }
49
+ const init = { method, headers };
50
+ if (options.body !== undefined) {
51
+ headers["Content-Type"] = "application/json";
52
+ init.body = JSON.stringify(options.body);
53
+ }
54
+ return fetch(url.toString(), init);
55
+ }
56
+ async handleResponse(response) {
57
+ if (!response.ok) {
58
+ let message = `HTTP ${response.status}`;
59
+ try {
60
+ const body = await response.json();
61
+ if (body.error)
62
+ message += `: ${body.error}`;
63
+ else if (body.message)
64
+ message += `: ${body.message}`;
65
+ }
66
+ catch {
67
+ // ignore parse errors
68
+ }
69
+ throw new Error(message);
70
+ }
71
+ // 204 No Content has no body to parse
72
+ if (response.status === 204) {
73
+ return {};
74
+ }
75
+ return response.json();
76
+ }
77
+ async doRefresh() {
78
+ if (!this.config.refreshToken || !this.config.clientId) {
79
+ throw new Error("Cannot refresh: missing refresh token or client ID. Run `etsy auth login`.");
80
+ }
81
+ const body = new URLSearchParams({
82
+ grant_type: "refresh_token",
83
+ client_id: this.config.clientId,
84
+ refresh_token: this.config.refreshToken,
85
+ });
86
+ const response = await fetch(TOKEN_URL, {
87
+ method: "POST",
88
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
89
+ body: body.toString(),
90
+ });
91
+ if (!response.ok) {
92
+ throw new Error("Token refresh failed. Run `etsy auth login` to re-authenticate.");
93
+ }
94
+ const tokens = await response.json();
95
+ if (typeof tokens.access_token !== "string" || !tokens.access_token ||
96
+ typeof tokens.refresh_token !== "string" || !tokens.refresh_token) {
97
+ throw new Error("Token refresh failed: invalid response from server. Run `etsy auth login` to re-authenticate.");
98
+ }
99
+ this.config.accessToken = tokens.access_token;
100
+ this.config.refreshToken = tokens.refresh_token;
101
+ this.config.accessTokenExpiresAt = typeof tokens.expires_in === "number"
102
+ ? Math.floor(Date.now() / 1000) + tokens.expires_in
103
+ : undefined;
104
+ saveConfig(this.config);
105
+ }
106
+ }
107
+ export function createClient(config) {
108
+ return new EtsyClient(config);
109
+ }
110
+ //# sourceMappingURL=etsy-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"etsy-client.js","sourceRoot":"","sources":["../src/etsy-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAe,MAAM,aAAa,CAAC;AAEtD,MAAM,QAAQ,GAAG,6BAA6B,CAAC;AAC/C,MAAM,SAAS,GAAG,4CAA4C,CAAC;AAC/D,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAQrC,MAAM,OAAO,UAAU;IACb,MAAM,CAAkB;IAEhC,YAAY,MAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,IAAY,EAAE,UAAuB,EAAE;QAChE,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;QACJ,CAAC;QAED,6DAA6D;QAC7D,IACE,IAAI,CAAC,MAAM,CAAC,WAAW;YACvB,IAAI,CAAC,MAAM,CAAC,oBAAoB,KAAK,SAAS;YAC9C,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,2BAA2B;UAC1D,CAAC;YACD,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAC5F,IAAI,kBAAkB,GAAG,yBAAyB,EAAE,CAAC;gBACnD,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACzB,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAE/D,0BAA0B;QAC1B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACnF,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACvB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,IAAY,EAAE,OAAoB;QAC1E,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,QAAQ,GAAG,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAA2B,EAAE,CAAC;QAE3C,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5B,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACjE,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY;gBAC7C,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;gBACrD,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QACzB,CAAC;QAED,MAAM,IAAI,GAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAE9C,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,QAAkB;QAC7C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,OAAO,GAAG,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6B,CAAC;gBAC9D,IAAI,IAAI,CAAC,KAAK;oBAAE,OAAO,IAAI,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;qBACxC,IAAI,IAAI,CAAC,OAAO;oBAAE,OAAO,IAAI,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,sBAAsB;YACxB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QACD,sCAAsC;QACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAChG,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;YAC/B,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC/B,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;SACxC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;YACtC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAIjC,CAAC;QAEF,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,YAAY;YAC/D,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;QACnH,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;YACtE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,UAAU;YACnD,CAAC,CAAC,SAAS,CAAC;QAEd,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,UAAU,YAAY,CAAC,MAAuB;IAClD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/build/index.js ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ import { program } from "commander";
3
+ import { loadConfig } from "./config.js";
4
+ import { createClient } from "./etsy-client.js";
5
+ import { printError } from "./output.js";
6
+ import { registerAuthCommands } from "./commands/auth.js";
7
+ import { registerShopCommands } from "./commands/shop.js";
8
+ import { registerListingsCommands } from "./commands/listings.js";
9
+ import { registerOrdersCommands } from "./commands/orders.js";
10
+ import { createRequire } from "module";
11
+ const require = createRequire(import.meta.url);
12
+ const { version } = require("../package.json");
13
+ const config = loadConfig();
14
+ program
15
+ .name("etsy")
16
+ .description("Etsy Open API v3 CLI")
17
+ .version(version);
18
+ // Auth commands don't need a client
19
+ registerAuthCommands(program);
20
+ // For all other commands, try to create the client.
21
+ // If config is missing credentials, commands that need the client error at runtime.
22
+ let client = null;
23
+ try {
24
+ client = createClient(config);
25
+ }
26
+ catch {
27
+ // Config incomplete — auth commands still work
28
+ }
29
+ // Proxy defers the "not configured" error to runtime
30
+ const clientProxy = new Proxy({}, {
31
+ get(_target, prop) {
32
+ if (!client) {
33
+ printError('Not configured. Run "etsy auth login" to set up credentials.');
34
+ process.exit(1);
35
+ }
36
+ const val = client[prop];
37
+ return typeof val === "function" ? val.bind(client) : val;
38
+ },
39
+ });
40
+ function resolveShopId(opts) {
41
+ const shopId = opts.shop ?? config.shopId;
42
+ if (!shopId) {
43
+ printError('Shop ID is required. Use --shop <id>, set ETSY_SHOP_ID, or run "etsy auth login".');
44
+ process.exit(1);
45
+ }
46
+ return shopId;
47
+ }
48
+ registerShopCommands(program, clientProxy, resolveShopId);
49
+ registerListingsCommands(program, clientProxy, resolveShopId);
50
+ registerOrdersCommands(program, clientProxy, resolveShopId);
51
+ program.parse();
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAE5B,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,sBAAsB,CAAC;KACnC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oCAAoC;AACpC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAE9B,oDAAoD;AACpD,oFAAoF;AACpF,IAAI,MAAM,GAAsB,IAAI,CAAC;AAErC,IAAI,CAAC;IACH,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAAC,MAAM,CAAC;IACP,+CAA+C;AACjD,CAAC;AAED,qDAAqD;AACrD,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,EAAgB,EAAE;IAC9C,GAAG,CAAC,OAAO,EAAE,IAAI;QACf,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,UAAU,CAAC,8DAA8D,CAAC,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,GAAI,MAAc,CAAC,IAAc,CAAC,CAAC;QAC5C,OAAO,OAAO,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5D,CAAC;CACF,CAAC,CAAC;AAEH,SAAS,aAAa,CAAC,IAAuB;IAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,UAAU,CACR,mFAAmF,CACpF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAC1D,wBAAwB,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAC9D,sBAAsB,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAE5D,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function printTable(headers: string[], rows: (string | number)[][]): void;
2
+ export declare function printJson(data: unknown): void;
3
+ export declare function printSuccess(message: string): void;
4
+ export declare function printError(message: string): void;
5
+ export declare function printWarning(message: string): void;
6
+ export declare function isAuthError(err: unknown): boolean;
7
+ export declare function colorState(state: string): string;
8
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,GAAG,IAAI,CAS/E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAE7C;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMjD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBhD"}
@@ -0,0 +1,49 @@
1
+ import chalk from "chalk";
2
+ import Table from "cli-table3";
3
+ export function printTable(headers, rows) {
4
+ const table = new Table({
5
+ head: headers.map((h) => chalk.cyan.bold(h)),
6
+ style: { head: [] },
7
+ });
8
+ for (const row of rows) {
9
+ table.push(row.map(String));
10
+ }
11
+ console.log(table.toString());
12
+ }
13
+ export function printJson(data) {
14
+ console.log(JSON.stringify(data, null, 2));
15
+ }
16
+ export function printSuccess(message) {
17
+ console.log(chalk.green(message));
18
+ }
19
+ export function printError(message) {
20
+ console.error(chalk.red(message));
21
+ }
22
+ export function printWarning(message) {
23
+ console.warn(chalk.yellow(message));
24
+ }
25
+ export function isAuthError(err) {
26
+ if (err instanceof Error) {
27
+ const msg = err.message.toLowerCase();
28
+ return msg.includes("401") || msg.includes("403") || msg.includes("unauthorized") || msg.includes("forbidden");
29
+ }
30
+ return false;
31
+ }
32
+ export function colorState(state) {
33
+ switch (state.toLowerCase()) {
34
+ // Listing states
35
+ case "active": return chalk.green(state);
36
+ case "draft": return chalk.yellow(state);
37
+ case "inactive": return chalk.dim(state);
38
+ case "expired": return chalk.red(state);
39
+ case "sold_out": return chalk.red(state);
40
+ // Receipt/order states
41
+ case "paid": return chalk.green(state);
42
+ case "completed": return chalk.green(state);
43
+ case "open": return chalk.yellow(state);
44
+ case "payment_processing": return chalk.yellow(state);
45
+ case "canceled": return chalk.red(state);
46
+ default: return state;
47
+ }
48
+ }
49
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@cprice70/etsy-cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for the Etsy Open API v3",
5
+ "type": "module",
6
+ "main": "build/index.js",
7
+ "bin": {
8
+ "etsy": "build/index.js"
9
+ },
10
+ "files": ["build"],
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsx watch src/index.ts",
14
+ "watch": "tsc --watch",
15
+ "start": "node build/index.js",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/cprice70/etsy-cli"
22
+ },
23
+ "author": "cprice70",
24
+ "license": "MIT",
25
+ "engines": { "node": ">=18" },
26
+ "dependencies": {
27
+ "chalk": "^5.4.1",
28
+ "cli-table3": "^0.6.5",
29
+ "commander": "^12.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0",
33
+ "tsx": "^4.7.0",
34
+ "typescript": "^5.7.0",
35
+ "vitest": "^3.0.0"
36
+ }
37
+ }