1688-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.
- package/AGENTS.md +118 -0
- package/README.md +48 -0
- package/dist/auth/cookies.js +31 -0
- package/dist/auth/cookies.js.map +1 -0
- package/dist/auth/verify.js +25 -0
- package/dist/auth/verify.js.map +1 -0
- package/dist/cli.js +373 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/cart-add.js +199 -0
- package/dist/commands/cart-add.js.map +1 -0
- package/dist/commands/cart-list.js +168 -0
- package/dist/commands/cart-list.js.map +1 -0
- package/dist/commands/cart-remove.js +119 -0
- package/dist/commands/cart-remove.js.map +1 -0
- package/dist/commands/checkout-confirm.js +407 -0
- package/dist/commands/checkout-confirm.js.map +1 -0
- package/dist/commands/checkout-prepare.js +244 -0
- package/dist/commands/checkout-prepare.js.map +1 -0
- package/dist/commands/doctor.js +246 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/image-search.js +210 -0
- package/dist/commands/image-search.js.map +1 -0
- package/dist/commands/login.js +209 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +59 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/offer.js +185 -0
- package/dist/commands/offer.js.map +1 -0
- package/dist/commands/order-get.js +76 -0
- package/dist/commands/order-get.js.map +1 -0
- package/dist/commands/order-list.js +176 -0
- package/dist/commands/order-list.js.map +1 -0
- package/dist/commands/order-logistics.js +152 -0
- package/dist/commands/order-logistics.js.map +1 -0
- package/dist/commands/search.js +250 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/seller-chat.js +213 -0
- package/dist/commands/seller-chat.js.map +1 -0
- package/dist/commands/seller-inquire.js +110 -0
- package/dist/commands/seller-inquire.js.map +1 -0
- package/dist/commands/seller-lookup-ww.js +6 -0
- package/dist/commands/seller-lookup-ww.js.map +1 -0
- package/dist/commands/seller-messages.js +181 -0
- package/dist/commands/seller-messages.js.map +1 -0
- package/dist/commands/whoami.js +53 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/commands/workflows.js +264 -0
- package/dist/commands/workflows.js.map +1 -0
- package/dist/daemon/client.js +75 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/manager.js +128 -0
- package/dist/daemon/manager.js.map +1 -0
- package/dist/daemon/protocol.js +5 -0
- package/dist/daemon/protocol.js.map +1 -0
- package/dist/daemon/server.js +197 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/throttle.js +17 -0
- package/dist/daemon/throttle.js.map +1 -0
- package/dist/io/errors.js +10 -0
- package/dist/io/errors.js.map +1 -0
- package/dist/io/output.js +17 -0
- package/dist/io/output.js.map +1 -0
- package/dist/io/prompt.js +17 -0
- package/dist/io/prompt.js.map +1 -0
- package/dist/session/context.js +91 -0
- package/dist/session/context.js.map +1 -0
- package/dist/session/dispatch.js +50 -0
- package/dist/session/dispatch.js.map +1 -0
- package/dist/session/lock.js +23 -0
- package/dist/session/lock.js.map +1 -0
- package/dist/session/paths.js +31 -0
- package/dist/session/paths.js.map +1 -0
- package/dist/session/shared.js +104 -0
- package/dist/session/shared.js.map +1 -0
- package/dist/session/state.js +27 -0
- package/dist/session/state.js.map +1 -0
- package/dist/util/time.js +17 -0
- package/dist/util/time.js.map +1 -0
- package/package.json +44 -0
- package/scripts/postinstall.mjs +49 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { dispatch } from '../session/dispatch.js';
|
|
2
|
+
import { emit, info } from '../io/output.js';
|
|
3
|
+
import { CliError } from '../io/errors.js';
|
|
4
|
+
import { execute as offerExecute, } from './offer.js';
|
|
5
|
+
import { execute as cartListExecute, } from './cart-list.js';
|
|
6
|
+
export async function execute(ctx, args) {
|
|
7
|
+
if (!/^\d+$/.test(args.offerId)) {
|
|
8
|
+
throw new CliError(2, 'BAD_INPUT', `Invalid offerId: ${args.offerId}`);
|
|
9
|
+
}
|
|
10
|
+
if (!/^\d+$/.test(args.skuId)) {
|
|
11
|
+
throw new CliError(2, 'BAD_INPUT', `Invalid skuId: ${args.skuId}`);
|
|
12
|
+
}
|
|
13
|
+
if (!Number.isFinite(args.quantity) || args.quantity < 1) {
|
|
14
|
+
throw new CliError(2, 'BAD_INPUT', `Invalid quantity: ${args.quantity}`);
|
|
15
|
+
}
|
|
16
|
+
// 1. Look up SKU spec text via offer execute (reuses cached daemon page).
|
|
17
|
+
info('Looking up SKU spec...');
|
|
18
|
+
const offer = await offerExecute(ctx, { offerId: args.offerId });
|
|
19
|
+
const sku = offer.skus.find((s) => s.skuId === args.skuId);
|
|
20
|
+
if (!sku) {
|
|
21
|
+
throw new CliError(12, 'SKU_NOT_FOUND', `SKU ${args.skuId} not found in offer ${args.offerId}. ` +
|
|
22
|
+
`Run \`1688 offer ${args.offerId}\` to list available SKUs.`);
|
|
23
|
+
}
|
|
24
|
+
if (sku.stock !== null && args.quantity > sku.stock) {
|
|
25
|
+
throw new CliError(2, 'OUT_OF_STOCK', `Quantity ${args.quantity} exceeds available stock (${sku.stock}).`);
|
|
26
|
+
}
|
|
27
|
+
// 2. Open detail page; find the row matching this SKU; fill qty; click 加采购车.
|
|
28
|
+
info(`Adding ${args.quantity}× ${sku.specs.slice(0, 30)} (¥${sku.price?.toFixed(2) ?? '?'})...`);
|
|
29
|
+
const page = await ctx.newPage();
|
|
30
|
+
try {
|
|
31
|
+
await page.goto(`https://detail.1688.com/offer/${args.offerId}.html`, {
|
|
32
|
+
waitUntil: 'domcontentloaded',
|
|
33
|
+
timeout: 30000,
|
|
34
|
+
});
|
|
35
|
+
if (/login\.1688\.com|login\.taobao\.com/.test(page.url())) {
|
|
36
|
+
throw new CliError(3, 'NOT_LOGGED_IN', 'Session expired. Run `1688 login`.');
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
await page.waitForSelector('input.ant-input-number-input', {
|
|
40
|
+
timeout: 15000,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
throw new CliError(11, 'SKU_TABLE_NOT_LOADED', 'SKU quantity inputs did not render.');
|
|
45
|
+
}
|
|
46
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
47
|
+
// Find the SMALLEST ancestor that contains both an input AND our exact
|
|
48
|
+
// spec text. Tag that input so Playwright can drive it.
|
|
49
|
+
const tagged = await page.evaluate((specHint) => {
|
|
50
|
+
const cleanHint = specHint.replace(/\s+/g, '').slice(0, 20);
|
|
51
|
+
// Find leaf elements with text matching our spec hint exactly.
|
|
52
|
+
const all = Array.from(document.querySelectorAll('*'));
|
|
53
|
+
const specEls = all.filter((el) => el.children.length === 0 &&
|
|
54
|
+
el.textContent !== null &&
|
|
55
|
+
el.textContent.replace(/\s+/g, '').includes(cleanHint));
|
|
56
|
+
for (const specEl of specEls) {
|
|
57
|
+
// Walk up; the FIRST ancestor that contains an input is our row.
|
|
58
|
+
let cur = specEl;
|
|
59
|
+
for (let d = 0; d < 10 && cur; d++) {
|
|
60
|
+
cur = cur.parentElement;
|
|
61
|
+
if (!cur)
|
|
62
|
+
break;
|
|
63
|
+
const inp = cur.querySelector('input.ant-input-number-input');
|
|
64
|
+
if (inp) {
|
|
65
|
+
inp.setAttribute('data-bb-target', '1');
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}, sku.specs);
|
|
72
|
+
if (!tagged) {
|
|
73
|
+
throw new CliError(14, 'SKU_ROW_NOT_FOUND', `Could not locate qty input row for SKU "${sku.specs.slice(0, 30)}".`);
|
|
74
|
+
}
|
|
75
|
+
// Zero out ALL other qty inputs so the bulk-add only picks up our row.
|
|
76
|
+
await page.evaluate(() => {
|
|
77
|
+
const inputs = Array.from(document.querySelectorAll('input.ant-input-number-input'));
|
|
78
|
+
for (const inp of inputs) {
|
|
79
|
+
if (inp.dataset.bbTarget === '1')
|
|
80
|
+
continue;
|
|
81
|
+
if (!inp.value || inp.value === '0' || inp.value === '')
|
|
82
|
+
continue;
|
|
83
|
+
const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;
|
|
84
|
+
setter?.call(inp, '');
|
|
85
|
+
inp.dispatchEvent(new Event('input', { bubbles: true }));
|
|
86
|
+
inp.dispatchEvent(new Event('change', { bubbles: true }));
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
90
|
+
// Drive the React-controlled input via fill() (proper event sequence).
|
|
91
|
+
const qtyInput = page.locator('input[data-bb-target="1"]');
|
|
92
|
+
await qtyInput.click({ timeout: 3000 });
|
|
93
|
+
await qtyInput.fill(''); // clear first
|
|
94
|
+
await qtyInput.fill(String(args.quantity));
|
|
95
|
+
// Press Tab to blur + commit
|
|
96
|
+
await page.keyboard.press('Tab');
|
|
97
|
+
await new Promise((r) => setTimeout(r, 2500));
|
|
98
|
+
if (process.env.BB1688_DEBUG === '1') {
|
|
99
|
+
const valueNow = await qtyInput.inputValue();
|
|
100
|
+
const cartButtons = await page.evaluate(() => {
|
|
101
|
+
return Array.from(document.querySelectorAll('button')).filter(b => /加.*采购车/.test(b.textContent ?? '')).map(b => ({
|
|
102
|
+
text: (b.textContent ?? '').trim(),
|
|
103
|
+
disabled: b.disabled,
|
|
104
|
+
cls: (b.className?.toString?.() || '').slice(0, 80),
|
|
105
|
+
visible: b.offsetParent !== null,
|
|
106
|
+
}));
|
|
107
|
+
});
|
|
108
|
+
process.stderr.write(`[debug] input value after typing: "${valueNow}"\n` +
|
|
109
|
+
`[debug] 加采购车 buttons: ${JSON.stringify(cartButtons)}\n`);
|
|
110
|
+
}
|
|
111
|
+
// Capture mtop calls during click
|
|
112
|
+
const cartWrites = [];
|
|
113
|
+
page.on('request', (req) => {
|
|
114
|
+
if (req.method() === 'POST' && /purchaseastoreservice|addcart|cart\.add/i.test(req.url())) {
|
|
115
|
+
const m = req.url().match(/mtop\.[^/?]+/);
|
|
116
|
+
if (m)
|
|
117
|
+
cartWrites.push(m[0]);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
// Click "加采购车" button (the primary add-to-cart trigger).
|
|
121
|
+
await page
|
|
122
|
+
.locator('button:has-text("加采购车"):not([disabled])')
|
|
123
|
+
.first()
|
|
124
|
+
.click({ force: true, timeout: 5000 });
|
|
125
|
+
await new Promise((r) => setTimeout(r, 2500));
|
|
126
|
+
// 1688 typically pops a confirmation modal — find + click it.
|
|
127
|
+
const dialogState = await page.evaluate(() => {
|
|
128
|
+
const out = [];
|
|
129
|
+
document
|
|
130
|
+
.querySelectorAll('div[role="dialog"], div[class*="dialog"], div[class*="modal"], div[class*="popup"]')
|
|
131
|
+
.forEach((d) => {
|
|
132
|
+
const el = d;
|
|
133
|
+
const r = el.getBoundingClientRect();
|
|
134
|
+
if (r.width < 100 || r.height < 50)
|
|
135
|
+
return;
|
|
136
|
+
const clickables = Array.from(el.querySelectorAll('button, [role="button"], a, span[class*="btn"], div[class*="btn"]'))
|
|
137
|
+
.map((b) => (b.textContent ?? '').trim())
|
|
138
|
+
.filter((t) => t && t.length < 20);
|
|
139
|
+
out.push({
|
|
140
|
+
cls: (el.className?.toString?.() || '').slice(0, 100),
|
|
141
|
+
buttons: clickables.slice(0, 10),
|
|
142
|
+
text: (el.textContent ?? '').replace(/\s+/g, ' ').trim().slice(0, 200),
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
return out;
|
|
146
|
+
});
|
|
147
|
+
if (process.env.BB1688_DEBUG === '1') {
|
|
148
|
+
process.stderr.write(`[debug] dialogs after add-cart click: ${JSON.stringify(dialogState)}\n`);
|
|
149
|
+
}
|
|
150
|
+
// If there's a confirmation modal with a 加入 / 确认 button, click it.
|
|
151
|
+
const confirmSelector = 'div[role="dialog"] button:has-text("加入采购车"):visible, ' +
|
|
152
|
+
'div[role="dialog"] button:has-text("确认加入"):visible, ' +
|
|
153
|
+
'div[class*="dialog"] button:has-text("加入采购车"):visible, ' +
|
|
154
|
+
'div[class*="dialog"] button:has-text("确认"):visible';
|
|
155
|
+
const confirmBtn = page.locator(confirmSelector).first();
|
|
156
|
+
if (await confirmBtn.count()) {
|
|
157
|
+
await confirmBtn.click({ force: true });
|
|
158
|
+
}
|
|
159
|
+
await new Promise((r) => setTimeout(r, 4000));
|
|
160
|
+
if (process.env.BB1688_DEBUG === '1') {
|
|
161
|
+
process.stderr.write(`[debug] mtop POSTs after full flow: ${JSON.stringify(cartWrites)}\n`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
await page.close().catch(() => { });
|
|
166
|
+
}
|
|
167
|
+
// 3. Verify by checking cart for the offerId + skuId combination.
|
|
168
|
+
info('Verifying...');
|
|
169
|
+
const after = await cartListExecute(ctx, {});
|
|
170
|
+
const added = after.items.find((i) => i.offerId === args.offerId && i.skuId === args.skuId);
|
|
171
|
+
if (!added) {
|
|
172
|
+
throw new CliError(17, 'ADD_NOT_REFLECTED', 'Add-to-cart click did not result in a cart entry. The page may have changed.');
|
|
173
|
+
}
|
|
174
|
+
return { ok: true, added };
|
|
175
|
+
}
|
|
176
|
+
export async function run(opts) {
|
|
177
|
+
if (!opts.offerId) {
|
|
178
|
+
throw new CliError(2, 'BAD_INPUT', 'offerId required.');
|
|
179
|
+
}
|
|
180
|
+
if (!opts.sku) {
|
|
181
|
+
throw new CliError(2, 'BAD_INPUT', '--sku <skuId> required.');
|
|
182
|
+
}
|
|
183
|
+
const qty = parseInt(opts.qty ?? '1', 10);
|
|
184
|
+
if (!Number.isFinite(qty) || qty < 1) {
|
|
185
|
+
throw new CliError(2, 'BAD_INPUT', '--qty must be a positive integer.');
|
|
186
|
+
}
|
|
187
|
+
const data = await dispatch('cart-add', { offerId: opts.offerId, skuId: opts.sku, quantity: qty }, { headed: opts.headed, profile: opts.profile });
|
|
188
|
+
emit({
|
|
189
|
+
human: () => {
|
|
190
|
+
const a = data.added;
|
|
191
|
+
process.stdout.write(`Added: ${a.productTitle.slice(0, 60)}\n` +
|
|
192
|
+
` cartId: ${a.cartId}\n` +
|
|
193
|
+
` spec: ${a.skuTitle ?? '(none)'}\n` +
|
|
194
|
+
` qty: ${a.quantity}×¥${a.unitPrice.toFixed(2)} = ¥${a.amount.toFixed(2)}\n`);
|
|
195
|
+
},
|
|
196
|
+
data,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=cart-add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart-add.js","sourceRoot":"","sources":["../../src/commands/cart-add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { dispatch } from '../session/dispatch.js';
|
|
2
|
+
import { emit, info } from '../io/output.js';
|
|
3
|
+
import { CliError } from '../io/errors.js';
|
|
4
|
+
const CART_URL = 'https://cart.1688.com/';
|
|
5
|
+
const RENDER_API_RE = /mtop\.1688\.buycenter\.mtoppurchaseastoreservice\.render/i;
|
|
6
|
+
export async function execute(ctx, _args) {
|
|
7
|
+
const page = await ctx.newPage();
|
|
8
|
+
let resolveCapture;
|
|
9
|
+
const captured = new Promise((r) => {
|
|
10
|
+
resolveCapture = r;
|
|
11
|
+
});
|
|
12
|
+
const onResp = async (resp) => {
|
|
13
|
+
if (!RENDER_API_RE.test(resp.url()))
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
const text = await resp.text();
|
|
17
|
+
const parsed = parseMtop(text);
|
|
18
|
+
if (typeof parsed?.data?.model === 'string') {
|
|
19
|
+
resolveCapture(JSON.parse(parsed.data.model));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
/* ignore parse errors */
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
page.on('response', onResp);
|
|
27
|
+
info('Loading cart...');
|
|
28
|
+
try {
|
|
29
|
+
await page.goto(CART_URL, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
throw new CliError(9, 'NETWORK_ERROR', `Failed to load cart page: ${e.message}`);
|
|
33
|
+
}
|
|
34
|
+
if (/login\.1688\.com|login\.taobao\.com/.test(page.url())) {
|
|
35
|
+
throw new CliError(3, 'NOT_LOGGED_IN', 'Session expired. Run `1688 login`.');
|
|
36
|
+
}
|
|
37
|
+
const model = await Promise.race([
|
|
38
|
+
captured,
|
|
39
|
+
new Promise((res) => setTimeout(() => res(null), 25000)),
|
|
40
|
+
]);
|
|
41
|
+
page.off('response', onResp);
|
|
42
|
+
await page.close().catch(() => { });
|
|
43
|
+
if (!model) {
|
|
44
|
+
throw new CliError(11, 'NO_CART_DATA', 'Cart response was not captured. The page may have changed or been risk-controlled.');
|
|
45
|
+
}
|
|
46
|
+
return parseCart(model);
|
|
47
|
+
}
|
|
48
|
+
function parseMtop(text) {
|
|
49
|
+
const t = text.trim();
|
|
50
|
+
const m = t.match(/^\s*mtopjsonp\d+\(([\s\S]*)\)\s*$/);
|
|
51
|
+
return JSON.parse(m ? m[1] : t);
|
|
52
|
+
}
|
|
53
|
+
function parseCart(model) {
|
|
54
|
+
const data = model.data ?? {};
|
|
55
|
+
const items = [];
|
|
56
|
+
// Build offerId → group (has title) and sellerId → shop maps
|
|
57
|
+
const groupsByOffer = new Map();
|
|
58
|
+
const shopsBySeller = new Map();
|
|
59
|
+
for (const [k, comp] of Object.entries(data)) {
|
|
60
|
+
if (/^item_group_\d+$/.test(k)) {
|
|
61
|
+
const f = comp.fields;
|
|
62
|
+
if (f?.offerId !== undefined)
|
|
63
|
+
groupsByOffer.set(String(f.offerId), f);
|
|
64
|
+
}
|
|
65
|
+
else if (/^shop_top_\d+$/.test(k)) {
|
|
66
|
+
const f = comp.fields;
|
|
67
|
+
if (f?.sellerId !== undefined)
|
|
68
|
+
shopsBySeller.set(String(f.sellerId), f);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const [k, comp] of Object.entries(data)) {
|
|
72
|
+
if (!/^item_\d+$/.test(k))
|
|
73
|
+
continue;
|
|
74
|
+
const f = comp.fields;
|
|
75
|
+
if (!f)
|
|
76
|
+
continue;
|
|
77
|
+
const offerId = f.offerId !== undefined ? String(f.offerId) : '';
|
|
78
|
+
const sellerId = f.sellerId !== undefined ? String(f.sellerId) : '';
|
|
79
|
+
const group = groupsByOffer.get(offerId);
|
|
80
|
+
const shop = shopsBySeller.get(sellerId);
|
|
81
|
+
items.push({
|
|
82
|
+
cartId: f.cartId !== undefined ? String(f.cartId) : '',
|
|
83
|
+
offerId,
|
|
84
|
+
skuId: f.skuId !== undefined ? String(f.skuId) : null,
|
|
85
|
+
productTitle: group?.title ?? '',
|
|
86
|
+
skuTitle: f.skuTitle ?? null,
|
|
87
|
+
unit: f.unit ?? null,
|
|
88
|
+
quantity: f.quantity ?? 0,
|
|
89
|
+
unitPrice: parseFloatOrZero(f.unitPrice),
|
|
90
|
+
amount: parseFloatOrZero(f.amount),
|
|
91
|
+
minQuantity: f.minQuantity ?? null,
|
|
92
|
+
maxQuantity: f.maxQuantity ?? null,
|
|
93
|
+
image: normalizeImage(f.pic),
|
|
94
|
+
checked: f.checked ?? false,
|
|
95
|
+
effective: f.effective ?? true,
|
|
96
|
+
addedAt: f.addTime ?? null,
|
|
97
|
+
seller: {
|
|
98
|
+
sellerId,
|
|
99
|
+
name: shop?.companyName ?? null,
|
|
100
|
+
loginId: shop?.loginId ?? null,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// Sort by addedAt desc (newest first) when present
|
|
105
|
+
items.sort((a, b) => (a.addedAt && b.addedAt ? b.addedAt.localeCompare(a.addedAt) : 0));
|
|
106
|
+
return {
|
|
107
|
+
total: items.length,
|
|
108
|
+
selectedCount: items.filter((i) => i.checked).length,
|
|
109
|
+
items,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function parseFloatOrZero(s) {
|
|
113
|
+
if (s === undefined)
|
|
114
|
+
return 0;
|
|
115
|
+
const n = typeof s === 'string' ? parseFloat(s) : s;
|
|
116
|
+
return Number.isFinite(n) ? n : 0;
|
|
117
|
+
}
|
|
118
|
+
function normalizeImage(pic) {
|
|
119
|
+
if (!pic)
|
|
120
|
+
return null;
|
|
121
|
+
if (pic.startsWith('//'))
|
|
122
|
+
return 'https:' + pic;
|
|
123
|
+
return pic;
|
|
124
|
+
}
|
|
125
|
+
export async function run(opts) {
|
|
126
|
+
const data = await dispatch('cart-list', {}, { headed: opts.headed, profile: opts.profile });
|
|
127
|
+
emit({
|
|
128
|
+
human: () => printCart(data),
|
|
129
|
+
data,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function printCart(r) {
|
|
133
|
+
if (r.items.length === 0) {
|
|
134
|
+
process.stdout.write('Cart is empty.\n');
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
process.stdout.write(`Cart: ${r.total} items (${r.selectedCount} selected)\n\n`);
|
|
138
|
+
const w = String(r.items.length).length;
|
|
139
|
+
r.items.forEach((it, i) => {
|
|
140
|
+
const idx = String(i + 1).padStart(w, ' ');
|
|
141
|
+
const check = it.checked ? '☑' : '☐';
|
|
142
|
+
const eff = it.effective ? '' : ' [失效]';
|
|
143
|
+
process.stdout.write(`${idx}. ${check} ${truncate(it.productTitle, 50)}${eff}\n`);
|
|
144
|
+
const pad = ' '.repeat(w + 2);
|
|
145
|
+
process.stdout.write(`${pad}${it.quantity}×¥${it.unitPrice.toFixed(2)} = ¥${it.amount.toFixed(2)}${it.unit ? ` /${it.unit}` : ''}\n`);
|
|
146
|
+
if (it.skuTitle)
|
|
147
|
+
process.stdout.write(`${pad}sku: ${it.skuTitle}\n`);
|
|
148
|
+
if (it.seller.name)
|
|
149
|
+
process.stdout.write(`${pad}seller: ${it.seller.name}\n`);
|
|
150
|
+
process.stdout.write(`${pad}cartId: ${it.cartId} · offerId: ${it.offerId}\n`);
|
|
151
|
+
if (it.addedAt)
|
|
152
|
+
process.stdout.write(`${pad}added: ${it.addedAt}\n`);
|
|
153
|
+
if (i < r.items.length - 1)
|
|
154
|
+
process.stdout.write('\n');
|
|
155
|
+
});
|
|
156
|
+
const totalAmount = r.items
|
|
157
|
+
.filter((i) => i.checked && i.effective)
|
|
158
|
+
.reduce((s, i) => s + i.amount, 0);
|
|
159
|
+
if (totalAmount > 0) {
|
|
160
|
+
process.stdout.write(`\nSelected total: ¥${totalAmount.toFixed(2)}\n`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function truncate(s, n) {
|
|
164
|
+
if (!s)
|
|
165
|
+
return '(no title)';
|
|
166
|
+
return s.length <= n ? s : s.slice(0, n - 1) + '…';
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=cart-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart-list.js","sourceRoot":"","sources":["../../src/commands/cart-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { dispatch } from '../session/dispatch.js';
|
|
2
|
+
import { emit, info } from '../io/output.js';
|
|
3
|
+
import { CliError } from '../io/errors.js';
|
|
4
|
+
import { execute as cartListExecute, } from './cart-list.js';
|
|
5
|
+
export async function execute(ctx, args) {
|
|
6
|
+
if (!/^\d+$/.test(args.cartId)) {
|
|
7
|
+
throw new CliError(2, 'BAD_INPUT', `Invalid cartId: ${args.cartId}`);
|
|
8
|
+
}
|
|
9
|
+
// 1. Locate the target item in the current cart.
|
|
10
|
+
info('Looking up cart item...');
|
|
11
|
+
const before = await cartListExecute(ctx, {});
|
|
12
|
+
const target = before.items.find((i) => i.cartId === args.cartId);
|
|
13
|
+
if (!target) {
|
|
14
|
+
throw new CliError(12, 'CART_ITEM_NOT_FOUND', `Cart item ${args.cartId} not found. Run \`1688 cart list\` to see current items.`);
|
|
15
|
+
}
|
|
16
|
+
// 2. Open cart page; check the matching row; click bulk-delete; confirm.
|
|
17
|
+
info(`Removing "${target.productTitle.slice(0, 30)}"...`);
|
|
18
|
+
const page = await ctx.newPage();
|
|
19
|
+
try {
|
|
20
|
+
await page.goto('https://cart.1688.com/', {
|
|
21
|
+
waitUntil: 'domcontentloaded',
|
|
22
|
+
timeout: 30000,
|
|
23
|
+
});
|
|
24
|
+
if (/login\.1688\.com|login\.taobao\.com/.test(page.url())) {
|
|
25
|
+
throw new CliError(3, 'NOT_LOGGED_IN', 'Session expired. Run `1688 login`.');
|
|
26
|
+
}
|
|
27
|
+
// Wait for cart items to render.
|
|
28
|
+
try {
|
|
29
|
+
await page.waitForSelector('input[type="checkbox"].next-checkbox-input', {
|
|
30
|
+
timeout: 15000,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
throw new CliError(11, 'CART_NOT_LOADED', 'Cart page did not finish loading.');
|
|
35
|
+
}
|
|
36
|
+
// Slight pause for async hydration of item rows.
|
|
37
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
38
|
+
// Click the checkbox of the SKU-specific row (use skuTitle to disambiguate
|
|
39
|
+
// multiple variants of the same product, which share productTitle).
|
|
40
|
+
const titleHint = target.productTitle.slice(0, 12);
|
|
41
|
+
const skuHint = target.skuTitle?.trim() ?? null;
|
|
42
|
+
const clicked = await page.evaluate(({ titleHint, skuHint }) => {
|
|
43
|
+
const probe = skuHint && skuHint.length >= 3 ? skuHint : titleHint;
|
|
44
|
+
const all = Array.from(document.querySelectorAll('*'));
|
|
45
|
+
const candidates = all.filter((el) => el.children.length === 0 &&
|
|
46
|
+
el.textContent !== null &&
|
|
47
|
+
el.textContent.includes(probe));
|
|
48
|
+
for (const c of candidates) {
|
|
49
|
+
let row = c;
|
|
50
|
+
for (let d = 0; d < 10 && row; d++) {
|
|
51
|
+
row = row.parentElement;
|
|
52
|
+
if (!row)
|
|
53
|
+
break;
|
|
54
|
+
const txt = row.textContent ?? '';
|
|
55
|
+
if (!txt.includes(titleHint))
|
|
56
|
+
continue;
|
|
57
|
+
const cb = row.querySelector('.next-checkbox-wrapper');
|
|
58
|
+
if (cb) {
|
|
59
|
+
const aria = cb.querySelector('[aria-checked]');
|
|
60
|
+
const wasChecked = aria?.getAttribute('aria-checked') === 'true';
|
|
61
|
+
if (!wasChecked)
|
|
62
|
+
cb.click();
|
|
63
|
+
return { ok: true, alreadyChecked: wasChecked };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { ok: false, reason: 'row-not-found' };
|
|
68
|
+
}, { titleHint, skuHint });
|
|
69
|
+
if (!clicked.ok) {
|
|
70
|
+
throw new CliError(14, 'UI_ELEMENT_NOT_FOUND', `Could not locate cart row for "${target.productTitle}": ${clicked.reason}`);
|
|
71
|
+
}
|
|
72
|
+
// Give server time to ack the selection.
|
|
73
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
74
|
+
// Click the bulk "删除" button at the cart footer.
|
|
75
|
+
await page
|
|
76
|
+
.locator('button:has-text("删除")')
|
|
77
|
+
.first()
|
|
78
|
+
.click({ force: true, timeout: 5000 });
|
|
79
|
+
// Confirm dialog.
|
|
80
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
81
|
+
const confirmed = await page
|
|
82
|
+
.locator('div[class*="next-dialog"] button.next-btn-primary:visible, ' +
|
|
83
|
+
'[role="dialog"] button:has-text("确认"):visible, ' +
|
|
84
|
+
'[role="dialog"] button:has-text("确定"):visible')
|
|
85
|
+
.first()
|
|
86
|
+
.click({ force: true, timeout: 5000 })
|
|
87
|
+
.then(() => true)
|
|
88
|
+
.catch(() => false);
|
|
89
|
+
if (!confirmed) {
|
|
90
|
+
throw new CliError(15, 'CONFIRM_FAILED', 'Delete confirmation dialog not found or not clickable.');
|
|
91
|
+
}
|
|
92
|
+
// Allow the server to process.
|
|
93
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await page.close().catch(() => { });
|
|
97
|
+
}
|
|
98
|
+
// 3. Verify removal by re-fetching cart.
|
|
99
|
+
const after = await cartListExecute(ctx, {});
|
|
100
|
+
if (after.items.some((i) => i.cartId === args.cartId)) {
|
|
101
|
+
throw new CliError(16, 'REMOVE_NOT_REFLECTED', 'Item still present after delete. The UI flow may have failed silently.');
|
|
102
|
+
}
|
|
103
|
+
return { ok: true, removed: target };
|
|
104
|
+
}
|
|
105
|
+
export async function run(opts) {
|
|
106
|
+
if (!opts.cartId) {
|
|
107
|
+
throw new CliError(2, 'BAD_INPUT', 'cartId required.');
|
|
108
|
+
}
|
|
109
|
+
const data = await dispatch('cart-remove', { cartId: opts.cartId }, { headed: opts.headed, profile: opts.profile });
|
|
110
|
+
emit({
|
|
111
|
+
human: () => {
|
|
112
|
+
process.stdout.write(`Removed: ${data.removed.productTitle.slice(0, 60)}\n` +
|
|
113
|
+
` cartId: ${data.removed.cartId}\n` +
|
|
114
|
+
` was: ${data.removed.quantity}×¥${data.removed.unitPrice.toFixed(2)} = ¥${data.removed.amount.toFixed(2)}\n`);
|
|
115
|
+
},
|
|
116
|
+
data,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=cart-remove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart-remove.js","sourceRoot":"","sources":["../../src/commands/cart-remove.ts"],"names":[],"mappings":"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"}
|