daiso 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/cli.js +130 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,6 +44,13 @@ npx daiso help
|
|
|
44
44
|
npx daiso url
|
|
45
45
|
npx daiso health
|
|
46
46
|
npx daiso claude
|
|
47
|
+
|
|
48
|
+
# AI 없이 직접 조회
|
|
49
|
+
npx daiso products 수납박스
|
|
50
|
+
npx daiso product 1034604
|
|
51
|
+
npx daiso stores 강남역
|
|
52
|
+
npx daiso inventory 1034604 --keyword 강남역
|
|
53
|
+
npx daiso get /api/cgv/movies --playDate 20260307 --theaterCode 0056
|
|
47
54
|
```
|
|
48
55
|
|
|
49
56
|
<br>
|
package/dist/cli.js
CHANGED
|
@@ -33,11 +33,20 @@ function printHelp(writeOut) {
|
|
|
33
33
|
writeOut(' health 원격 서버 상태 확인');
|
|
34
34
|
writeOut(' claude Claude Code MCP 등록 명령 출력');
|
|
35
35
|
writeOut(' claude --exec Claude Code MCP 등록 명령 실행');
|
|
36
|
+
writeOut(' get 임의 API 경로 GET 호출');
|
|
37
|
+
writeOut(' products 다이소 제품 검색');
|
|
38
|
+
writeOut(' product 다이소 제품 상세 조회');
|
|
39
|
+
writeOut(' stores 다이소 매장 검색');
|
|
40
|
+
writeOut(' inventory 다이소 재고 조회');
|
|
36
41
|
writeOut('');
|
|
37
42
|
writeOut('예시:');
|
|
38
43
|
writeOut(' npx daiso url');
|
|
39
44
|
writeOut(' npx daiso health');
|
|
40
45
|
writeOut(' npx daiso claude');
|
|
46
|
+
writeOut(' npx daiso products 수납박스');
|
|
47
|
+
writeOut(' npx daiso stores 강남역');
|
|
48
|
+
writeOut(' npx daiso inventory 1034604 --keyword 강남역');
|
|
49
|
+
writeOut(' npx daiso get /api/cgv/movies --playDate 20260307 --theaterCode 0056');
|
|
41
50
|
}
|
|
42
51
|
async function execCommand(command, args) {
|
|
43
52
|
return await new Promise((resolve, reject) => {
|
|
@@ -67,6 +76,67 @@ function createDefaultDeps() {
|
|
|
67
76
|
runCommand: execCommand,
|
|
68
77
|
};
|
|
69
78
|
}
|
|
79
|
+
function parseCliArgs(args) {
|
|
80
|
+
const positionals = [];
|
|
81
|
+
const options = {};
|
|
82
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
83
|
+
const token = args[index];
|
|
84
|
+
if (!token.startsWith('--')) {
|
|
85
|
+
positionals.push(token);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const withoutPrefix = token.slice(2);
|
|
89
|
+
const equalIndex = withoutPrefix.indexOf('=');
|
|
90
|
+
if (equalIndex >= 0) {
|
|
91
|
+
const key = withoutPrefix.slice(0, equalIndex);
|
|
92
|
+
const value = withoutPrefix.slice(equalIndex + 1);
|
|
93
|
+
options[key] = value;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const key = withoutPrefix;
|
|
97
|
+
const nextValue = args[index + 1];
|
|
98
|
+
if (!nextValue || nextValue.startsWith('--')) {
|
|
99
|
+
options[key] = 'true';
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
options[key] = nextValue;
|
|
103
|
+
index += 1;
|
|
104
|
+
}
|
|
105
|
+
return { positionals, options };
|
|
106
|
+
}
|
|
107
|
+
function toUrl(pathOrUrl) {
|
|
108
|
+
if (pathOrUrl.startsWith('http://') || pathOrUrl.startsWith('https://')) {
|
|
109
|
+
return new URL(pathOrUrl);
|
|
110
|
+
}
|
|
111
|
+
const normalizedPath = pathOrUrl.startsWith('/') ? pathOrUrl : `/${pathOrUrl}`;
|
|
112
|
+
return new URL(normalizedPath, DEFAULT_BASE_URL);
|
|
113
|
+
}
|
|
114
|
+
function applyOptionsToQuery(url, options) {
|
|
115
|
+
for (const [key, value] of Object.entries(options)) {
|
|
116
|
+
url.searchParams.set(key, value);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async function requestAndPrintJson(fetchImpl, writeOut, writeErr, url) {
|
|
120
|
+
try {
|
|
121
|
+
const response = await fetchImpl(url.toString());
|
|
122
|
+
if (!response.ok) {
|
|
123
|
+
const bodyText = await response.text();
|
|
124
|
+
writeErr(`요청 실패: HTTP ${response.status}`);
|
|
125
|
+
if (bodyText) {
|
|
126
|
+
writeErr(bodyText);
|
|
127
|
+
}
|
|
128
|
+
return 1;
|
|
129
|
+
}
|
|
130
|
+
const payload = (await response.json());
|
|
131
|
+
writeOut(JSON.stringify(payload, null, 2));
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
136
|
+
writeErr(`요청 중 오류 발생: ${message}`);
|
|
137
|
+
return 1;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
70
140
|
export async function runCli(argv, deps) {
|
|
71
141
|
const resolvedDeps = {
|
|
72
142
|
...createDefaultDeps(),
|
|
@@ -121,6 +191,66 @@ export async function runCli(argv, deps) {
|
|
|
121
191
|
resolvedDeps.writeOut(`claude ${cliArgs.join(' ')}`);
|
|
122
192
|
return 0;
|
|
123
193
|
}
|
|
194
|
+
if (command === 'get') {
|
|
195
|
+
const parsed = parseCliArgs(options);
|
|
196
|
+
const targetPath = parsed.positionals[0];
|
|
197
|
+
if (!targetPath) {
|
|
198
|
+
resolvedDeps.writeErr('get 명령은 경로가 필요합니다. 예: daiso get /api/daiso/products --q 수납박스');
|
|
199
|
+
return 1;
|
|
200
|
+
}
|
|
201
|
+
const targetUrl = toUrl(targetPath);
|
|
202
|
+
applyOptionsToQuery(targetUrl, parsed.options);
|
|
203
|
+
return await requestAndPrintJson(resolvedDeps.fetchImpl, resolvedDeps.writeOut, resolvedDeps.writeErr, targetUrl);
|
|
204
|
+
}
|
|
205
|
+
if (command === 'products') {
|
|
206
|
+
const parsed = parseCliArgs(options);
|
|
207
|
+
const query = parsed.positionals[0];
|
|
208
|
+
if (!query) {
|
|
209
|
+
resolvedDeps.writeErr('products 명령은 검색어가 필요합니다. 예: daiso products 수납박스');
|
|
210
|
+
return 1;
|
|
211
|
+
}
|
|
212
|
+
const targetUrl = toUrl('/api/daiso/products');
|
|
213
|
+
targetUrl.searchParams.set('q', query);
|
|
214
|
+
applyOptionsToQuery(targetUrl, parsed.options);
|
|
215
|
+
return await requestAndPrintJson(resolvedDeps.fetchImpl, resolvedDeps.writeOut, resolvedDeps.writeErr, targetUrl);
|
|
216
|
+
}
|
|
217
|
+
if (command === 'product') {
|
|
218
|
+
const parsed = parseCliArgs(options);
|
|
219
|
+
const productId = parsed.positionals[0];
|
|
220
|
+
if (!productId) {
|
|
221
|
+
resolvedDeps.writeErr('product 명령은 제품 ID가 필요합니다. 예: daiso product 1034604');
|
|
222
|
+
return 1;
|
|
223
|
+
}
|
|
224
|
+
const targetUrl = toUrl(`/api/daiso/products/${productId}`);
|
|
225
|
+
applyOptionsToQuery(targetUrl, parsed.options);
|
|
226
|
+
return await requestAndPrintJson(resolvedDeps.fetchImpl, resolvedDeps.writeOut, resolvedDeps.writeErr, targetUrl);
|
|
227
|
+
}
|
|
228
|
+
if (command === 'stores') {
|
|
229
|
+
const parsed = parseCliArgs(options);
|
|
230
|
+
const keyword = parsed.positionals[0];
|
|
231
|
+
if (keyword) {
|
|
232
|
+
parsed.options.keyword = keyword;
|
|
233
|
+
}
|
|
234
|
+
if (!parsed.options.keyword && !parsed.options.sido) {
|
|
235
|
+
resolvedDeps.writeErr('stores 명령은 keyword 또는 --sido가 필요합니다. 예: daiso stores 강남역 / daiso stores --sido 서울');
|
|
236
|
+
return 1;
|
|
237
|
+
}
|
|
238
|
+
const targetUrl = toUrl('/api/daiso/stores');
|
|
239
|
+
applyOptionsToQuery(targetUrl, parsed.options);
|
|
240
|
+
return await requestAndPrintJson(resolvedDeps.fetchImpl, resolvedDeps.writeOut, resolvedDeps.writeErr, targetUrl);
|
|
241
|
+
}
|
|
242
|
+
if (command === 'inventory') {
|
|
243
|
+
const parsed = parseCliArgs(options);
|
|
244
|
+
const productId = parsed.positionals[0];
|
|
245
|
+
if (!productId) {
|
|
246
|
+
resolvedDeps.writeErr('inventory 명령은 제품 ID가 필요합니다. 예: daiso inventory 1034604 --keyword 강남역');
|
|
247
|
+
return 1;
|
|
248
|
+
}
|
|
249
|
+
const targetUrl = toUrl('/api/daiso/inventory');
|
|
250
|
+
targetUrl.searchParams.set('productId', productId);
|
|
251
|
+
applyOptionsToQuery(targetUrl, parsed.options);
|
|
252
|
+
return await requestAndPrintJson(resolvedDeps.fetchImpl, resolvedDeps.writeOut, resolvedDeps.writeErr, targetUrl);
|
|
253
|
+
}
|
|
124
254
|
resolvedDeps.writeErr(`알 수 없는 명령어: ${command}`);
|
|
125
255
|
resolvedDeps.writeErr('도움말: daiso help');
|
|
126
256
|
return 1;
|