@vibelyster/depop-cli 0.1.0 → 0.2.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/cli.js +18 -13
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Impit as
|
|
2
|
+
import{Impit as F}from"impit";var i="https://webapi.depop.com",v=new F({browser:"chrome"});function c(e){return{Accept:"*/*","Content-Type":"application/json",Authorization:`Bearer ${e}`,Origin:"https://www.depop.com",Referer:"https://www.depop.com/"}}async function l(e,t={}){let a=await v.fetch(e,t);if(!a.ok){let o=await a.text(),s;try{s=JSON.parse(o)}catch{s=o}throw new Error(`Depop API error ${a.status}: ${JSON.stringify(s)}`)}return a.status===204?null:a.json()}async function h(e){try{return{loggedIn:!0,user:await l(`${i}/api/v1/sellerOnboarding/sellerStatus/`,{headers:c(e)})}}catch(t){return{loggedIn:!1,error:t.message}}}async function $(e){let t=await l(`${i}/api/v1/addresses/`,{headers:c(e)});if(t?.length>0)return String(t[0].userId);throw new Error("Could not resolve userId \u2014 no addresses found on account")}async function k(e,t){let{readFile:a}=await import("node:fs/promises"),{extname:o}=await import("node:path"),s=o(e).slice(1).toLowerCase()||"jpg",n=s==="png"?"image/png":"image/jpeg",r=await l(`${i}/api/v2/pictures/`,{method:"POST",headers:c(t),body:JSON.stringify({type:"PRODUCT",extension:s})}),p=await a(e),u=await v.fetch(r.url,{method:"PUT",headers:{"Content-Type":n},body:p});if(!u.ok){let g=await u.text();throw new Error(`S3 upload failed ${u.status}: ${g}`)}return{id:r.id,url:r.url.split("?")[0]}}async function b(e,t){return l(`${i}/api/v2/drafts/`,{method:"POST",headers:c(t),body:JSON.stringify(e)})}async function I(e,t,a){return l(`${i}/api/v2/drafts/${e}/`,{method:"PUT",headers:c(a),body:JSON.stringify({id:e,...t})})}async function S(e){return l(`${i}/api/v2/drafts/`,{headers:c(e)})}async function x(e,t){return l(`${i}/api/v1/drafts/${e}/`,{method:"DELETE",headers:c(t)})}async function T(e,t,a){return l(`${i}/api/v2/products/${e}/`,{method:"PUT",headers:{...c(a),Referer:`https://www.depop.com/products/edit/${e}/`},body:JSON.stringify(t)})}async function D(e,t){return l(`${i}/api/v1/products/${e}/`,{method:"DELETE",headers:c(t)})}async function O(e,t){return l(`${i}/api/v1/product/by-slug/${e}/user/?camel_case=true`,{headers:c(t)})}async function C(e,t){return l(`${i}/api/v3/shop/${t}/products/?limit=200&force_fee_calculation=false`,{headers:c(e)})}async function P(e){return l(`${i}/api/v1/addresses/`,{headers:c(e)})}async function N(e){return l(`${i}/presentation/api/v1/attributes/groups/`,{headers:c(e)})}async function U(e){return l(`${i}/api/v2/search/filters/productAttributes/?country=en`,{headers:c(e)})}async function A(e,t="USPS"){return l(`${i}/api/v1/shipping-providers/?ids=${t}`,{headers:c(e)})}import{readFile as w,writeFile as R,mkdir as q,unlink as z}from"node:fs/promises";import{createInterface as B}from"node:readline";import{homedir as G}from"node:os";import{join as L}from"node:path";var m="https://www.depop.com",j=L(G(),".vibelyster"),f=L(j,"depop.json");function K(e){let t=B({input:process.stdin,output:process.stdout});return new Promise(a=>{t.question(e,o=>{t.close(),a(o.trim())})})}async function y(){try{let e=JSON.parse(await w(f,"utf-8"));if(e.accessToken)return e}catch{}return null}async function _(e){await q(j,{recursive:!0}),await R(f,JSON.stringify(e,null,2))}async function V(){try{await z(f)}catch{}}async function d(e){let t=H(e,"--access-token")||process.env.DEPOP_ACCESS_TOKEN;if(t)return t;let a=await y();if(a)return a.accessToken;console.error("Error: Not logged in. Run `depop login` or set DEPOP_ACCESS_TOKEN env var."),process.exit(1)}async function E(e){let t=await y();if(t?.userId)return t.userId;let a=await d(e),o=await $(a);return t&&(t.userId=o,await _(t)),o}function H(e,t){let a=e.indexOf(t);return a!==-1&&a+1<e.length?e[a+1]:null}function M(e){let t=[],a=["--access-token","--status"],o=0;for(;o<e.length;)a.includes(e[o])?o+=2:(t.push(e[o]),o++);return t}async function Q(){let e=process.argv.slice(2),t=M(e),a=t[0];if(!a||a==="--help"||a==="-h"){console.log(`Depop CLI \u2014 VibeLyster
|
|
3
3
|
|
|
4
4
|
Commands:
|
|
5
5
|
login Save your access token
|
|
@@ -8,6 +8,9 @@ Commands:
|
|
|
8
8
|
listings List your products
|
|
9
9
|
listing <slug> Get product details
|
|
10
10
|
addresses List shipping addresses
|
|
11
|
+
categories List categories (group \u2192 productType)
|
|
12
|
+
conditions List valid condition values and colors
|
|
13
|
+
shipping List shipping providers and parcel sizes
|
|
11
14
|
upload <image-path> Upload a square image, returns {id, url}
|
|
12
15
|
create <json-file> Create a draft listing
|
|
13
16
|
drafts List draft listings
|
|
@@ -22,16 +25,18 @@ Auth:
|
|
|
22
25
|
Or set DEPOP_ACCESS_TOKEN env var.
|
|
23
26
|
|
|
24
27
|
Note: Images must be square. Crop before uploading.
|
|
25
|
-
`);return}try{switch(
|
|
28
|
+
`);return}try{switch(a){case"login":{console.log(`Depop Login
|
|
26
29
|
`),console.log("To get your access token:"),console.log(" 1. Log in to depop.com in your browser"),console.log(" 2. Open DevTools \u2192 Application \u2192 Cookies \u2192 depop.com"),console.log(` 3. Copy the 'access_token' cookie value
|
|
27
|
-
`);let o=await
|
|
28
|
-
Verifying...`);let s=await h(o);s.loggedIn||(console.error("Login failed:",s.error),process.exit(1)),console.log("Resolving user ID...");let n=await
|
|
29
|
-
Logged in! canSell: ${s.user.canSell}`),console.log(`User ID: ${n}`),console.log(`Credentials saved to ${f}`);break}case"auth":{let o=await
|
|
30
|
-
`)[0].slice(0,60),g=
|
|
31
|
-
Total: ${
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
`);let o=await K("access_token: ");o||(console.error("access_token is required."),process.exit(1)),console.log(`
|
|
31
|
+
Verifying...`);let s=await h(o);s.loggedIn||(console.error("Login failed:",s.error),process.exit(1)),console.log("Resolving user ID...");let n=await $(o);await _({accessToken:o,userId:n,savedAt:new Date().toISOString()}),console.log(`
|
|
32
|
+
Logged in! canSell: ${s.user.canSell}`),console.log(`User ID: ${n}`),console.log(`Credentials saved to ${f}`);break}case"auth":{let o=await d(e),s=await h(o);if(s.loggedIn){let n=await E(e);console.log("Logged in. User ID:",n),console.log("canSell:",s.user.canSell),console.log("stripe:",s.user.stripe?.isConnected?"connected":"not connected");let r=await y();r?(console.log(`Credentials: ${f}`),r.savedAt&&console.log("Saved at:",r.savedAt)):console.log("Credentials: environment variables")}else console.error("Not logged in:",s.error),process.exit(1);break}case"logout":{await V(),console.log("Logged out. Credentials removed from",f);break}case"listings":{let o=await d(e),s=await E(e),n=await C(o,s),r=n.products||n.objects||[];if(!r.length){console.log("No listings found.");break}for(let p of r){let u=(p.description||"(no title)").split(`
|
|
33
|
+
`)[0].slice(0,60),g=p.slug||p.id;console.log(`[${g}] ${u} \u2014 ${p.status}`),console.log(` ${m}/products/${g}/`)}console.log(`
|
|
34
|
+
Total: ${r.length} listings`);break}case"listing":{let o=t[1];o||(console.error("Usage: depop listing <slug>"),process.exit(1));let s=await d(e),n=await O(o,s);console.log(JSON.stringify(n,null,2));break}case"addresses":{let o=await d(e),s=await P(o);console.log(JSON.stringify(s,null,2));break}case"categories":{let o=await d(e),s=await N(o);for(let[n,r]of Object.entries(s)){if(!r.product_types?.length)continue;let p=(r.department||[]).join(", ");console.log(`
|
|
35
|
+
${n} (${p}):`);for(let u of r.product_types){let g=u.name_i18n?.["en-US"]||u.name_i18n?.en||u.id;console.log(` ${u.id} \u2014 ${g}`)}}break}case"conditions":{let o=await d(e),s=await U(o);console.log("Conditions:");for(let n of s.condition||[])console.log(` ${n.id} \u2014 ${n.nameI18N} (${n.descriptionI18N})`);console.log(`
|
|
36
|
+
Colors (max `+(s.settings?.maxColours||2)+"):");for(let n of s.colour||[])console.log(` ${n.id} \u2014 ${n.nameI18N}`);break}case"shipping":{let o=await d(e),s=await A(o);for(let n of s){console.log(`${n.id}:`);for(let r of n.parcelSizes||[])console.log(` ${r.id} \u2014 ${r.title} (${r.subtitle}) $${r.cost?.amount}`)}break}case"upload":{let o=t[1];o||(console.error("Usage: depop upload <image-path>"),console.error(`
|
|
37
|
+
Image must be square. Depop will reject non-square images.`),process.exit(1));let s=await d(e),n=await k(o,s);console.log("Uploaded:"),console.log(" ID:",n.id),console.log(" URL:",n.url||n.imageUrl||JSON.stringify(n));break}case"create":{let o=t[1];o||(console.error("Usage: depop create <json-file>"),console.error(`
|
|
38
|
+
See examples/draft.json for the payload format.`),process.exit(1));let s=await d(e),n=JSON.parse(await w(o,"utf-8"));console.log("Creating draft...");let r=await b(n,s);console.log("Draft created:",r.id),console.log(`
|
|
39
|
+
To publish, open the draft in your browser:`),console.log(` ${m}/sellinghub/drafts/edit/${r.id}/`),console.log(`
|
|
40
|
+
Or update it via: depop draft-update <draft-id> <json-file>`);break}case"drafts":{let o=await d(e),n=(await S(o)).drafts||[];if(!n.length){console.log("No drafts found.");break}for(let r of n){let p=(r.description||"(no description)").split(`
|
|
41
|
+
`)[0].slice(0,60),u=r.priceAmount?`$${r.priceAmount}`:"?",g=r.missingFields?.length?` [missing: ${r.missingFields.join(", ")}]`:" [ready]";console.log(`[${r.id}] ${p} \u2014 ${u}${g}`)}console.log(`
|
|
42
|
+
Total: ${n.length} drafts`);break}case"draft-update":{let o=t[1],s=t[2];(!o||!s)&&(console.error("Usage: depop draft-update <draft-id> <json-file>"),process.exit(1));let n=await d(e),r=JSON.parse(await w(s,"utf-8"));await I(o,r,n),console.log("Draft updated:",o),console.log(` ${m}/sellinghub/drafts/edit/${o}/`);break}case"draft-delete":{let o=t[1];o||(console.error("Usage: depop draft-delete <draft-id>"),process.exit(1));let s=await d(e);await x(o,s),console.log("Draft deleted:",o);break}case"edit":{let o=t[1],s=t[2];(!o||!s)&&(console.error("Usage: depop edit <product-id> <json-file>"),process.exit(1));let n=await d(e),r=JSON.parse(await w(s,"utf-8")),p=await T(o,r,n);console.log("Updated listing:"),console.log(" ID:",p.id),console.log(" URL:",`${m}/products/${p.slug||p.id}/`);break}case"delete":{let o=t[1];o||(console.error("Usage: depop delete <product-id>"),process.exit(1));let s=await d(e);await D(o,s),console.log(`Deleted product ${o}`);break}default:console.error(`Unknown command: ${a}`),console.error('Run "depop --help" for usage.'),process.exit(1)}}catch(o){console.error("Error:",o.message),process.exit(1)}}Q();
|