doordash-cli 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/CHANGELOG.md +47 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +3 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +180 -0
- package/dist/cli.test.d.ts +1 -0
- package/dist/cli.test.js +154 -0
- package/dist/direct-api.d.ts +530 -0
- package/dist/direct-api.js +2297 -0
- package/dist/direct-api.test.d.ts +1 -0
- package/dist/direct-api.test.js +701 -0
- package/dist/lib.d.ts +21 -0
- package/dist/lib.js +202 -0
- package/docs/examples.md +158 -0
- package/docs/install.md +63 -0
- package/man/dd-cli.1 +241 -0
- package/man/doordash-cli.1 +1 -0
- package/package.json +70 -0
- package/scripts/install-manpage.sh +14 -0
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type AddToCartResult, type AuthBootstrapResult, type AuthResult, type CartResult, type ItemResult, type MenuResult, type OrderResult, type OrdersResult, type SearchResult, type SetAddressResult, type UpdateCartResult } from "./direct-api.js";
|
|
2
|
+
export declare const SAFE_COMMANDS: readonly ["install-browser", "auth-check", "auth-bootstrap", "auth-clear", "set-address", "search", "menu", "item", "orders", "order", "add-to-cart", "update-cart", "cart"];
|
|
3
|
+
export declare const BLOCKED_COMMANDS: readonly ["checkout", "place-order", "track-order", "payment", "pay", "tip", "submit-order"];
|
|
4
|
+
export type SafeCommand = (typeof SAFE_COMMANDS)[number];
|
|
5
|
+
export type CommandFlags = Record<string, string>;
|
|
6
|
+
export type CommandResult = {
|
|
7
|
+
success: true;
|
|
8
|
+
message: string;
|
|
9
|
+
browser: "chromium";
|
|
10
|
+
} | AuthResult | AuthBootstrapResult | {
|
|
11
|
+
success: true;
|
|
12
|
+
message: string;
|
|
13
|
+
cookiesPath: string;
|
|
14
|
+
storageStatePath: string;
|
|
15
|
+
} | SetAddressResult | SearchResult | MenuResult | ItemResult | OrdersResult | OrderResult | AddToCartResult | UpdateCartResult | CartResult;
|
|
16
|
+
export declare function isSafeCommand(value: string): value is SafeCommand;
|
|
17
|
+
export declare function isBlockedCommand(value: string): value is (typeof BLOCKED_COMMANDS)[number];
|
|
18
|
+
export declare function assertSafeCommand(value: string): asserts value is SafeCommand;
|
|
19
|
+
export declare function assertAllowedFlags(command: SafeCommand, args: CommandFlags): void;
|
|
20
|
+
export declare function runCommand(command: SafeCommand, args: CommandFlags): Promise<CommandResult>;
|
|
21
|
+
export declare function shutdown(): Promise<void>;
|
package/dist/lib.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { cleanup as browserCleanup } from "@striderlabs/mcp-doordash/dist/browser.js";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { addToCartDirect, bootstrapAuthSession, checkAuthDirect, cleanupDirect, clearStoredSession, getCartDirect, getItemDirect, getMenuDirect, getOrderDirect, getOrdersDirect, parseOptionSelectionsJson, searchRestaurantsDirect, setAddressDirect, updateCartDirect, } from "./direct-api.js";
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const PLAYWRIGHT_CLI_PATH = join(dirname(require.resolve("playwright/package.json")), "cli.js");
|
|
8
|
+
export const SAFE_COMMANDS = [
|
|
9
|
+
"install-browser",
|
|
10
|
+
"auth-check",
|
|
11
|
+
"auth-bootstrap",
|
|
12
|
+
"auth-clear",
|
|
13
|
+
"set-address",
|
|
14
|
+
"search",
|
|
15
|
+
"menu",
|
|
16
|
+
"item",
|
|
17
|
+
"orders",
|
|
18
|
+
"order",
|
|
19
|
+
"add-to-cart",
|
|
20
|
+
"update-cart",
|
|
21
|
+
"cart",
|
|
22
|
+
];
|
|
23
|
+
export const BLOCKED_COMMANDS = [
|
|
24
|
+
"checkout",
|
|
25
|
+
"place-order",
|
|
26
|
+
"track-order",
|
|
27
|
+
"payment",
|
|
28
|
+
"pay",
|
|
29
|
+
"tip",
|
|
30
|
+
"submit-order",
|
|
31
|
+
];
|
|
32
|
+
const COMMAND_FLAGS = {
|
|
33
|
+
"install-browser": [],
|
|
34
|
+
"auth-check": [],
|
|
35
|
+
"auth-bootstrap": [],
|
|
36
|
+
"auth-clear": [],
|
|
37
|
+
"set-address": ["address"],
|
|
38
|
+
search: ["query", "cuisine"],
|
|
39
|
+
menu: ["restaurant-id"],
|
|
40
|
+
item: ["restaurant-id", "item-id"],
|
|
41
|
+
orders: ["limit", "active-only"],
|
|
42
|
+
order: ["order-id"],
|
|
43
|
+
"add-to-cart": ["restaurant-id", "item-id", "item-name", "quantity", "special-instructions", "options-json"],
|
|
44
|
+
"update-cart": ["cart-item-id", "quantity"],
|
|
45
|
+
cart: [],
|
|
46
|
+
};
|
|
47
|
+
export function isSafeCommand(value) {
|
|
48
|
+
return SAFE_COMMANDS.includes(value);
|
|
49
|
+
}
|
|
50
|
+
export function isBlockedCommand(value) {
|
|
51
|
+
return BLOCKED_COMMANDS.includes(value);
|
|
52
|
+
}
|
|
53
|
+
export function assertSafeCommand(value) {
|
|
54
|
+
if (isSafeCommand(value)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (isBlockedCommand(value)) {
|
|
58
|
+
const guidance = value === "track-order" ? " Use `orders` or `order --order-id ...` for read-only existing-order status instead." : "";
|
|
59
|
+
throw new Error(`Blocked command: ${value}. This CLI is read-only for browse, cart, and existing-order inspection only; checkout, order placement, and payment actions stay out of scope.${guidance}`);
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Unsupported command: ${value}. Allowed commands: ${SAFE_COMMANDS.join(", ")}`);
|
|
62
|
+
}
|
|
63
|
+
export function assertAllowedFlags(command, args) {
|
|
64
|
+
const allowedFlags = new Set(COMMAND_FLAGS[command]);
|
|
65
|
+
const unknownFlags = Object.keys(args).filter((key) => key !== "help" && !allowedFlags.has(key));
|
|
66
|
+
if (unknownFlags.length === 0) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const allowedText = COMMAND_FLAGS[command].length > 0 ? COMMAND_FLAGS[command].join(", ") : "(none)";
|
|
70
|
+
throw new Error(`Unsupported flag(s) for ${command}: ${unknownFlags.join(", ")}. Allowed flags: ${allowedText}`);
|
|
71
|
+
}
|
|
72
|
+
export async function runCommand(command, args) {
|
|
73
|
+
assertAllowedFlags(command, args);
|
|
74
|
+
switch (command) {
|
|
75
|
+
case "install-browser":
|
|
76
|
+
return installBrowser();
|
|
77
|
+
case "auth-check":
|
|
78
|
+
return checkAuthDirect();
|
|
79
|
+
case "auth-bootstrap":
|
|
80
|
+
return bootstrapAuthSession();
|
|
81
|
+
case "auth-clear":
|
|
82
|
+
return clearStoredSession();
|
|
83
|
+
case "set-address": {
|
|
84
|
+
const address = requiredArg(args, "address");
|
|
85
|
+
return setAddressDirect(address);
|
|
86
|
+
}
|
|
87
|
+
case "search": {
|
|
88
|
+
const query = requiredArg(args, "query");
|
|
89
|
+
const cuisine = optionalArg(args, "cuisine");
|
|
90
|
+
return searchRestaurantsDirect(query, cuisine);
|
|
91
|
+
}
|
|
92
|
+
case "menu": {
|
|
93
|
+
const restaurantId = requiredArg(args, "restaurant-id");
|
|
94
|
+
return getMenuDirect(restaurantId);
|
|
95
|
+
}
|
|
96
|
+
case "item": {
|
|
97
|
+
const restaurantId = requiredArg(args, "restaurant-id");
|
|
98
|
+
const itemId = requiredArg(args, "item-id");
|
|
99
|
+
return getItemDirect(restaurantId, itemId);
|
|
100
|
+
}
|
|
101
|
+
case "orders": {
|
|
102
|
+
const limitRaw = optionalArg(args, "limit");
|
|
103
|
+
const limit = limitRaw === undefined ? undefined : Number.parseInt(limitRaw, 10);
|
|
104
|
+
if (limitRaw !== undefined && (!Number.isInteger(limit) || (limit ?? 0) < 1)) {
|
|
105
|
+
throw new Error(`Invalid --limit: ${limitRaw}`);
|
|
106
|
+
}
|
|
107
|
+
return getOrdersDirect({
|
|
108
|
+
limit,
|
|
109
|
+
activeOnly: parseBooleanFlag(optionalArg(args, "active-only"), "active-only") ?? false,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
case "order": {
|
|
113
|
+
const orderId = requiredArg(args, "order-id");
|
|
114
|
+
return getOrderDirect(orderId);
|
|
115
|
+
}
|
|
116
|
+
case "add-to-cart": {
|
|
117
|
+
const restaurantId = requiredArg(args, "restaurant-id");
|
|
118
|
+
const itemId = optionalArg(args, "item-id");
|
|
119
|
+
const itemName = optionalArg(args, "item-name");
|
|
120
|
+
const quantityRaw = optionalArg(args, "quantity");
|
|
121
|
+
const specialInstructions = optionalArg(args, "special-instructions");
|
|
122
|
+
const optionsJson = optionalArg(args, "options-json");
|
|
123
|
+
const quantity = quantityRaw === undefined ? 1 : Number.parseInt(quantityRaw, 10);
|
|
124
|
+
if (!itemId && !itemName) {
|
|
125
|
+
throw new Error("Missing required flag --item-id or --item-name");
|
|
126
|
+
}
|
|
127
|
+
if (!Number.isInteger(quantity) || quantity < 1) {
|
|
128
|
+
throw new Error(`Invalid --quantity: ${quantityRaw}`);
|
|
129
|
+
}
|
|
130
|
+
return addToCartDirect({
|
|
131
|
+
restaurantId,
|
|
132
|
+
itemId,
|
|
133
|
+
itemName,
|
|
134
|
+
quantity,
|
|
135
|
+
specialInstructions,
|
|
136
|
+
optionSelections: optionsJson ? parseOptionSelectionsJson(optionsJson) : [],
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
case "update-cart": {
|
|
140
|
+
const cartItemId = requiredArg(args, "cart-item-id");
|
|
141
|
+
const quantityRaw = requiredArg(args, "quantity");
|
|
142
|
+
const quantity = Number.parseInt(quantityRaw, 10);
|
|
143
|
+
if (!Number.isInteger(quantity) || quantity < 0) {
|
|
144
|
+
throw new Error(`Invalid --quantity: ${quantityRaw}`);
|
|
145
|
+
}
|
|
146
|
+
return updateCartDirect({
|
|
147
|
+
cartItemId,
|
|
148
|
+
quantity,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
case "cart":
|
|
152
|
+
return getCartDirect();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export async function shutdown() {
|
|
156
|
+
await cleanupDirect().catch(() => { });
|
|
157
|
+
await browserCleanup().catch(() => { });
|
|
158
|
+
}
|
|
159
|
+
async function installBrowser() {
|
|
160
|
+
await new Promise((resolve, reject) => {
|
|
161
|
+
const child = spawn(process.execPath, [PLAYWRIGHT_CLI_PATH, "install", "chromium"], {
|
|
162
|
+
stdio: "inherit",
|
|
163
|
+
});
|
|
164
|
+
child.once("error", reject);
|
|
165
|
+
child.once("exit", (code, signal) => {
|
|
166
|
+
if (code === 0) {
|
|
167
|
+
resolve();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
reject(new Error(`Playwright browser install failed (code=${code ?? "null"}, signal=${signal ?? "none"})`));
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
success: true,
|
|
175
|
+
browser: "chromium",
|
|
176
|
+
message: "Chromium is installed for doordash-cli.",
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function requiredArg(args, key) {
|
|
180
|
+
const value = args[key];
|
|
181
|
+
if (!value) {
|
|
182
|
+
throw new Error(`Missing required flag --${key}`);
|
|
183
|
+
}
|
|
184
|
+
return value;
|
|
185
|
+
}
|
|
186
|
+
function optionalArg(args, key) {
|
|
187
|
+
const value = args[key];
|
|
188
|
+
return value && value.length > 0 ? value : undefined;
|
|
189
|
+
}
|
|
190
|
+
function parseBooleanFlag(value, key) {
|
|
191
|
+
if (value === undefined) {
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
const normalized = value.toLowerCase();
|
|
195
|
+
if (["true", "1", "yes", "on"].includes(normalized)) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
if (["false", "0", "no", "off"].includes(normalized)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
throw new Error(`Invalid --${key}: ${value}. Expected true or false.`);
|
|
202
|
+
}
|
package/docs/examples.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# doordash-cli examples
|
|
2
|
+
|
|
3
|
+
Use the preferred lowercase command name `dd-cli`. `doordash-cli` is an equivalent alias.
|
|
4
|
+
|
|
5
|
+
If you are running from a local checkout without linking, prefix commands with:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run cli --
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For installation and first-run setup, see [install.md](install.md).
|
|
12
|
+
|
|
13
|
+
All commands print JSON.
|
|
14
|
+
|
|
15
|
+
## Session setup
|
|
16
|
+
|
|
17
|
+
Install the matching Chromium build once if you do not already have it:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
dd-cli install-browser
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Check whether you already have reusable session state:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
dd-cli auth-check
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
If needed, launch Chromium for a one-time sign-in and save reusable state:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dd-cli auth-bootstrap
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Reset saved session state when you want a clean start:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
dd-cli auth-clear
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Search, menus, and items
|
|
42
|
+
|
|
43
|
+
Set the active delivery address before discovery commands:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
dd-cli set-address --address "350 5th Ave, New York, NY 10118"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Search by query, with or without a cuisine filter:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
dd-cli search --query tacos
|
|
53
|
+
dd-cli search --query tacos --cuisine mexican
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Inspect a restaurant menu and a specific item:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
dd-cli menu --restaurant-id 1721744
|
|
60
|
+
dd-cli item --restaurant-id 1721744 --item-id 546936015
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Existing orders
|
|
64
|
+
|
|
65
|
+
List recent existing orders:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
dd-cli orders
|
|
69
|
+
dd-cli orders --limit 5
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Focus on still-active orders only:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
dd-cli orders --active-only
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Inspect one order in detail. `--order-id` accepts the CLI's returned internal ID, `orderUuid`, or `deliveryUuid`:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
dd-cli order --order-id 3f4c6d0e-1234-5678-90ab-cdef12345678
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Cart basics
|
|
85
|
+
|
|
86
|
+
Add by item ID:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
dd-cli add-to-cart --restaurant-id 1721744 --item-id 876658890 --quantity 2
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Add by visible item name:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
dd-cli add-to-cart --restaurant-id 1721744 --item-name "Spicy Tuna Roll"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Add with special instructions:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
dd-cli add-to-cart \
|
|
102
|
+
--restaurant-id 1721744 \
|
|
103
|
+
--item-name "Fries" \
|
|
104
|
+
--special-instructions "extra crispy"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Update quantity or remove an item:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
dd-cli update-cart --cart-item-id 3b231d03-5a72-4636-8d12-c8769d706d45 --quantity 1
|
|
111
|
+
dd-cli update-cart --cart-item-id 3b231d03-5a72-4636-8d12-c8769d706d45 --quantity 0
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Inspect the active cart:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
dd-cli cart
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Configurable items
|
|
121
|
+
|
|
122
|
+
For items with required option groups, pass `--options-json` with explicit selections:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
dd-cli add-to-cart \
|
|
126
|
+
--restaurant-id 1721744 \
|
|
127
|
+
--item-id 546936015 \
|
|
128
|
+
--options-json '[
|
|
129
|
+
{"groupId":"703393388","optionId":"4716032529"},
|
|
130
|
+
{"groupId":"703393389","optionId":"4716042466"}
|
|
131
|
+
]'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Supported standalone recommended add-ons can include recursive `children` selections:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
dd-cli add-to-cart \
|
|
138
|
+
--restaurant-id 1721744 \
|
|
139
|
+
--item-id 546936015 \
|
|
140
|
+
--options-json '[
|
|
141
|
+
{"groupId":"703393388","optionId":"4716032529"},
|
|
142
|
+
{"groupId":"703393389","optionId":"4716042466"},
|
|
143
|
+
{
|
|
144
|
+
"groupId":"recommended_option_546935995",
|
|
145
|
+
"optionId":"546936011",
|
|
146
|
+
"children":[
|
|
147
|
+
{"groupId":"780057412","optionId":"4702669757"}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
]'
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Guardrails:
|
|
154
|
+
|
|
155
|
+
- unknown group IDs or option IDs are rejected
|
|
156
|
+
- required min/max selection counts are enforced
|
|
157
|
+
- duplicate nested selections are rejected
|
|
158
|
+
- unsupported nested transport shapes fail closed
|
package/docs/install.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Install and first run
|
|
2
|
+
|
|
3
|
+
## Install from npm
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install -g doordash-cli
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
That installs both lowercase command names: `doordash-cli` and `dd-cli`.
|
|
10
|
+
|
|
11
|
+
Package page: <https://www.npmjs.com/package/doordash-cli>
|
|
12
|
+
|
|
13
|
+
## Install from source instead
|
|
14
|
+
|
|
15
|
+
If you want the latest unreleased work or a local checkout you can edit, install from a checkout:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git clone https://github.com/LatencyTDH/doordash-cli.git
|
|
19
|
+
cd doordash-cli
|
|
20
|
+
npm install
|
|
21
|
+
npm link
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
After `npm link`, both `doordash-cli` and `dd-cli` resolve globally from your checkout.
|
|
25
|
+
|
|
26
|
+
## Run from a checkout without linking
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm run cli -- --help
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If you stay in checkout mode, replace `doordash-cli` with `npm run cli --` in the examples below.
|
|
33
|
+
|
|
34
|
+
## Install the browser once
|
|
35
|
+
|
|
36
|
+
If you plan to use `auth-bootstrap`, install the matching Playwright Chromium build:
|
|
37
|
+
|
|
38
|
+
### Global or linked install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
doordash-cli install-browser
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Checkout without linking
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm run install:browser
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## First run
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
doordash-cli auth-bootstrap
|
|
54
|
+
doordash-cli auth-check
|
|
55
|
+
doordash-cli set-address --address "350 5th Ave, New York, NY 10118"
|
|
56
|
+
doordash-cli search --query sushi
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Session reuse
|
|
60
|
+
|
|
61
|
+
If you already have a compatible signed-in DoorDash browser session available, direct commands may reuse it instead of opening a fresh browser context.
|
|
62
|
+
|
|
63
|
+
If not, run `doordash-cli auth-bootstrap` once to save reusable state for later commands.
|
package/man/dd-cli.1
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
.TH DD-CLI 1 "2026-03-10" "doordash-cli 0.1.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
dd-cli, doordash-cli \- unofficial cart-safe DoorDash CLI for browsing, read-only order inspection, and cart management
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B dd-cli
|
|
6
|
+
[\fICOMMAND\fR] [\fIOPTIONS\fR]
|
|
7
|
+
.br
|
|
8
|
+
.B doordash-cli
|
|
9
|
+
[\fICOMMAND\fR] [\fIOPTIONS\fR]
|
|
10
|
+
.SH DESCRIPTION
|
|
11
|
+
.B dd-cli
|
|
12
|
+
is a focused DoorDash command line interface for the parts of the workflow that
|
|
13
|
+
fit well in a terminal: signing in, setting delivery context, searching stores,
|
|
14
|
+
inspecting menus and items, inspecting existing orders, and managing the cart.
|
|
15
|
+
.PP
|
|
16
|
+
The command surface is intentionally small. The CLI does not expose checkout,
|
|
17
|
+
order placement, payment actions, or order mutation/cancellation. Read-only
|
|
18
|
+
existing-order inspection is allowed. If a payload cannot be validated safely
|
|
19
|
+
from known DoorDash consumer-web request shapes, the tool fails closed instead
|
|
20
|
+
of guessing.
|
|
21
|
+
.PP
|
|
22
|
+
If invoked with no command, or with
|
|
23
|
+
.BR -h / --help ,
|
|
24
|
+
it prints usage text and exits successfully.
|
|
25
|
+
.PP
|
|
26
|
+
The preferred command name is
|
|
27
|
+
.BR dd-cli .
|
|
28
|
+
.B doordash-cli
|
|
29
|
+
is installed as a lowercase alias.
|
|
30
|
+
.SH COMMANDS
|
|
31
|
+
.TP
|
|
32
|
+
.B install-browser
|
|
33
|
+
Install the matching Playwright Chromium build used by this package.
|
|
34
|
+
.TP
|
|
35
|
+
.B auth-check
|
|
36
|
+
Verify whether the saved session appears authenticated. This command can also
|
|
37
|
+
import an already-signed-in compatible managed-browser DoorDash session when a
|
|
38
|
+
usable CDP endpoint is available.
|
|
39
|
+
.TP
|
|
40
|
+
.B auth-bootstrap
|
|
41
|
+
Launch Chromium for a one-time manual sign-in flow, then save reusable browser
|
|
42
|
+
state for later direct API calls.
|
|
43
|
+
.TP
|
|
44
|
+
.B auth-clear
|
|
45
|
+
Delete stored session material used by this CLI.
|
|
46
|
+
.TP
|
|
47
|
+
.BI "set-address --address " ADDRESS
|
|
48
|
+
Resolve and persist the active delivery address. Saved addresses are reused when
|
|
49
|
+
possible; new addresses are enrolled through DoorDash's consumer-web address
|
|
50
|
+
APIs.
|
|
51
|
+
.TP
|
|
52
|
+
.BI "search --query " TEXT " [--cuisine " CUISINE "]"
|
|
53
|
+
Search for restaurants matching a query, optionally narrowed by cuisine.
|
|
54
|
+
.TP
|
|
55
|
+
.BI "menu --restaurant-id " ID
|
|
56
|
+
Fetch a restaurant menu.
|
|
57
|
+
.TP
|
|
58
|
+
.BI "item --restaurant-id " ID " --item-id " ITEM_ID
|
|
59
|
+
Fetch detailed information for a single item.
|
|
60
|
+
.TP
|
|
61
|
+
.BI "orders [--limit " N "] [--active-only]"
|
|
62
|
+
List existing orders with current status, totals, timestamps, and item
|
|
63
|
+
summaries.
|
|
64
|
+
.TP
|
|
65
|
+
.BI "order --order-id " ID
|
|
66
|
+
Inspect one existing order in more detail. The identifier may be the CLI's
|
|
67
|
+
returned internal order ID,
|
|
68
|
+
.BR orderUuid ,
|
|
69
|
+
or
|
|
70
|
+
.BR deliveryUuid .
|
|
71
|
+
.TP
|
|
72
|
+
.BI "add-to-cart --restaurant-id " ID " (--item-id " ITEM_ID " | --item-name " NAME ") [--quantity " N "] [--special-instructions " TEXT "] [--options-json " JSON "]"
|
|
73
|
+
Add an item to the active cart. Configurable items require explicit option
|
|
74
|
+
selections via
|
|
75
|
+
.BR --options-json .
|
|
76
|
+
.TP
|
|
77
|
+
.BI "update-cart --cart-item-id " ID " --quantity " N
|
|
78
|
+
Update a cart item's quantity. Use quantity
|
|
79
|
+
.B 0
|
|
80
|
+
to remove it.
|
|
81
|
+
.TP
|
|
82
|
+
.B cart
|
|
83
|
+
Show the current cart.
|
|
84
|
+
.SH OPTIONS
|
|
85
|
+
.TP
|
|
86
|
+
.BR -h , " --help"
|
|
87
|
+
Show usage information.
|
|
88
|
+
.TP
|
|
89
|
+
.BR -v , " --version"
|
|
90
|
+
Show the packaged CLI version.
|
|
91
|
+
.TP
|
|
92
|
+
.BI --address " ADDRESS"
|
|
93
|
+
Freeform delivery address for
|
|
94
|
+
.BR set-address .
|
|
95
|
+
.TP
|
|
96
|
+
.BI --query " TEXT"
|
|
97
|
+
Restaurant search query.
|
|
98
|
+
.TP
|
|
99
|
+
.BI --cuisine " CUISINE"
|
|
100
|
+
Optional cuisine filter for
|
|
101
|
+
.BR search .
|
|
102
|
+
.TP
|
|
103
|
+
.BI --restaurant-id " ID"
|
|
104
|
+
DoorDash restaurant identifier used by
|
|
105
|
+
.BR menu ,
|
|
106
|
+
.BR item ,
|
|
107
|
+
and
|
|
108
|
+
.BR add-to-cart .
|
|
109
|
+
.TP
|
|
110
|
+
.BI --item-id " ID"
|
|
111
|
+
DoorDash item identifier.
|
|
112
|
+
.TP
|
|
113
|
+
.BI --item-name " NAME"
|
|
114
|
+
Fallback item lookup by visible item name when an item ID is not convenient.
|
|
115
|
+
.TP
|
|
116
|
+
.BI --order-id " ID"
|
|
117
|
+
Existing-order identifier accepted by
|
|
118
|
+
.BR order .
|
|
119
|
+
.TP
|
|
120
|
+
.BI --limit " N"
|
|
121
|
+
Maximum number of existing orders to return for
|
|
122
|
+
.BR orders .
|
|
123
|
+
.TP
|
|
124
|
+
.B --active-only
|
|
125
|
+
Filter
|
|
126
|
+
.B orders
|
|
127
|
+
output to active / still-tracking orders only.
|
|
128
|
+
.TP
|
|
129
|
+
.BI --quantity " N"
|
|
130
|
+
Positive integer quantity for add/update operations.
|
|
131
|
+
.TP
|
|
132
|
+
.BI --cart-item-id " ID"
|
|
133
|
+
DoorDash cart item identifier for
|
|
134
|
+
.BR update-cart .
|
|
135
|
+
.TP
|
|
136
|
+
.BI --special-instructions " TEXT"
|
|
137
|
+
Freeform item instructions for
|
|
138
|
+
.BR add-to-cart .
|
|
139
|
+
.TP
|
|
140
|
+
.BI --options-json " JSON"
|
|
141
|
+
Structured option selections for configurable items. Some supported standalone
|
|
142
|
+
recommended add-ons can be represented with recursive
|
|
143
|
+
.B children
|
|
144
|
+
arrays.
|
|
145
|
+
.SH EXAMPLES
|
|
146
|
+
.PP
|
|
147
|
+
Show help, version, and read the manual:
|
|
148
|
+
.PP
|
|
149
|
+
.EX
|
|
150
|
+
dd-cli --help
|
|
151
|
+
dd-cli --version
|
|
152
|
+
man dd-cli
|
|
153
|
+
.EE
|
|
154
|
+
.PP
|
|
155
|
+
Install the matching browser build once:
|
|
156
|
+
.PP
|
|
157
|
+
.EX
|
|
158
|
+
dd-cli install-browser
|
|
159
|
+
.EE
|
|
160
|
+
.PP
|
|
161
|
+
Bootstrap a reusable session:
|
|
162
|
+
.PP
|
|
163
|
+
.EX
|
|
164
|
+
dd-cli auth-bootstrap
|
|
165
|
+
.EE
|
|
166
|
+
.PP
|
|
167
|
+
Set an address and search for sushi:
|
|
168
|
+
.PP
|
|
169
|
+
.EX
|
|
170
|
+
dd-cli set-address --address "350 5th Ave, New York, NY 10118"
|
|
171
|
+
dd-cli search --query sushi
|
|
172
|
+
.EE
|
|
173
|
+
.PP
|
|
174
|
+
Inspect existing orders:
|
|
175
|
+
.PP
|
|
176
|
+
.EX
|
|
177
|
+
dd-cli orders
|
|
178
|
+
dd-cli orders --active-only
|
|
179
|
+
dd-cli order --order-id 3f4c6d0e-1234-5678-90ab-cdef12345678
|
|
180
|
+
.EE
|
|
181
|
+
.PP
|
|
182
|
+
Add a configurable item to the cart:
|
|
183
|
+
.PP
|
|
184
|
+
.EX
|
|
185
|
+
dd-cli add-to-cart \
|
|
186
|
+
--restaurant-id 1721744 \
|
|
187
|
+
--item-id 546936015 \
|
|
188
|
+
--options-json '[{"groupId":"703393388","optionId":"4716032529"},{"groupId":"703393389","optionId":"4716042466"}]'
|
|
189
|
+
.EE
|
|
190
|
+
.SH OUTPUT
|
|
191
|
+
Commands print JSON on standard output so they can be piped into shell tools,
|
|
192
|
+
parsers, or scripts.
|
|
193
|
+
.SH SESSION STORAGE
|
|
194
|
+
The CLI persists reusable session state under the user's configuration
|
|
195
|
+
directory. The exact file layout is an implementation detail and may evolve over
|
|
196
|
+
time, but the saved state is reused across runs unless cleared with
|
|
197
|
+
.BR auth-clear .
|
|
198
|
+
.SH ENVIRONMENT
|
|
199
|
+
.TP
|
|
200
|
+
.B DOORDASH_MANAGED_BROWSER_CDP_URL
|
|
201
|
+
Preferred Chrome DevTools Protocol endpoint for importing an already-signed-in
|
|
202
|
+
compatible managed-browser session.
|
|
203
|
+
.PP
|
|
204
|
+
The CLI may also honor additional compatible CDP endpoint environment variables
|
|
205
|
+
for integration convenience.
|
|
206
|
+
.SH EXIT STATUS
|
|
207
|
+
.TP
|
|
208
|
+
.B 0
|
|
209
|
+
Success, including help and no-argument usage output.
|
|
210
|
+
.TP
|
|
211
|
+
.B 1
|
|
212
|
+
Validation error, blocked command, unsupported flag, or runtime failure.
|
|
213
|
+
.SH SAFETY
|
|
214
|
+
The CLI is intentionally limited to browsing, read-only existing-order
|
|
215
|
+
inspection, and cart management. Dangerous commands such as checkout,
|
|
216
|
+
place-order, payment actions, and order mutation/cancellation are blocked
|
|
217
|
+
immediately. The legacy
|
|
218
|
+
.B track-order
|
|
219
|
+
verb remains blocked; use
|
|
220
|
+
.B orders
|
|
221
|
+
or
|
|
222
|
+
.B order
|
|
223
|
+
instead.
|
|
224
|
+
.SH MAN PAGE INSTALLATION
|
|
225
|
+
For cloned or linked development checkouts, install the local manual pages with:
|
|
226
|
+
.PP
|
|
227
|
+
.EX
|
|
228
|
+
npm run install:man
|
|
229
|
+
.EE
|
|
230
|
+
.PP
|
|
231
|
+
This links
|
|
232
|
+
.BR dd-cli (1)
|
|
233
|
+
and
|
|
234
|
+
.BR doordash-cli (1)
|
|
235
|
+
into the user's local manpath, typically
|
|
236
|
+
.I ~/.local/share/man/man1
|
|
237
|
+
on Linux.
|
|
238
|
+
.SH SEE ALSO
|
|
239
|
+
.BR doordash-cli (1),
|
|
240
|
+
.BR npm (1),
|
|
241
|
+
.BR man (1)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.so man1/dd-cli.1
|