daiso 1.0.6 → 1.0.7
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 +60 -4
- package/dist/api/actionsProxy.js +111 -21
- package/dist/api/configStatus.js +5 -1
- package/dist/api/gs25Handlers.js +45 -10
- package/dist/api/healthChecks.js +50 -9
- package/dist/api/placesHandlers.js +44 -0
- package/dist/api/routes/healthRoutes.js +1 -1
- package/dist/api/routes/placesRoutes.js +9 -0
- package/dist/cli/commandOptions.js +64 -6
- package/dist/cli/commands/convenience.js +20 -0
- package/dist/cli.js +3 -1
- package/dist/cliHelp.js +14 -6
- package/dist/cliRenderer.js +9 -2
- package/dist/core/registry.js +21 -2
- package/dist/index.js +17 -3
- package/dist/pages/openapiFullSpec.js +3 -0
- package/dist/pages/openapiSpecActions.js +308 -42
- package/dist/pages/openapiSpecPathsPlaces.js +85 -0
- package/dist/pages/promptReferenceText.js +3 -0
- package/dist/pages/promptRetailCinemaText.js +22 -1
- package/dist/services/gs25/api.js +3 -0
- package/dist/services/gs25/client.js +211 -35
- package/dist/services/gs25/index.js +11 -3
- package/dist/services/gs25/tools/checkInventory.js +39 -12
- package/dist/services/gs25/tools/findNearbyStores.js +19 -5
- package/dist/services/gs25/tools/searchProducts.js +11 -4
- package/dist/services/oliveyoung/client.js +90 -41
- package/dist/services/places/client.js +116 -0
- package/dist/services/places/index.js +23 -0
- package/dist/services/places/tools/searchNearby.js +56 -0
- package/dist/services/places/types.js +1 -0
- package/dist/utils/zyte.js +45 -18
- package/openapi.json +19 -0
- package/openapi.yaml +13 -0
- package/package.json +3 -2
|
@@ -12,16 +12,74 @@ export const COMMAND_OPTION_ALLOWLISTS = {
|
|
|
12
12
|
stores: ['help', 'json', 'keyword', 'sido', 'gugun', 'dong', 'limit'],
|
|
13
13
|
inventory: ['help', 'json', 'keyword', 'lat', 'lng', 'page', 'pageSize'],
|
|
14
14
|
'display-location': ['help', 'json'],
|
|
15
|
+
places: ['help', 'json', 'location', 'category', 'keyword', 'limit', 'start', 'sort'],
|
|
15
16
|
'cu-stores': ['help', 'json', 'keyword', 'lat', 'lng', 'limit'],
|
|
16
|
-
'cu-inventory': [
|
|
17
|
+
'cu-inventory': [
|
|
18
|
+
'help',
|
|
19
|
+
'json',
|
|
20
|
+
'storeKeyword',
|
|
21
|
+
'lat',
|
|
22
|
+
'lng',
|
|
23
|
+
'size',
|
|
24
|
+
'offset',
|
|
25
|
+
'searchSort',
|
|
26
|
+
'storeLimit',
|
|
27
|
+
],
|
|
17
28
|
'lottecinema-theaters': ['help', 'json', 'keyword', 'lat', 'lng', 'playDate', 'limit'],
|
|
18
|
-
'lottecinema-movies': [
|
|
19
|
-
|
|
20
|
-
|
|
29
|
+
'lottecinema-movies': [
|
|
30
|
+
'help',
|
|
31
|
+
'json',
|
|
32
|
+
'keyword',
|
|
33
|
+
'playDate',
|
|
34
|
+
'theaterId',
|
|
35
|
+
'movieId',
|
|
36
|
+
'lat',
|
|
37
|
+
'lng',
|
|
38
|
+
],
|
|
39
|
+
'lottecinema-seats': [
|
|
40
|
+
'help',
|
|
41
|
+
'json',
|
|
42
|
+
'keyword',
|
|
43
|
+
'playDate',
|
|
44
|
+
'theaterId',
|
|
45
|
+
'movieId',
|
|
46
|
+
'lat',
|
|
47
|
+
'lng',
|
|
48
|
+
'limit',
|
|
49
|
+
],
|
|
50
|
+
'emart24-stores': [
|
|
51
|
+
'help',
|
|
52
|
+
'json',
|
|
53
|
+
'keyword',
|
|
54
|
+
'area1',
|
|
55
|
+
'area2',
|
|
56
|
+
'lat',
|
|
57
|
+
'lng',
|
|
58
|
+
'service24h',
|
|
59
|
+
'limit',
|
|
60
|
+
],
|
|
21
61
|
'emart24-products': ['help', 'json', 'page', 'pageSize'],
|
|
22
|
-
'emart24-inventory': [
|
|
62
|
+
'emart24-inventory': [
|
|
63
|
+
'help',
|
|
64
|
+
'json',
|
|
65
|
+
'bizNoArr',
|
|
66
|
+
'storeKeyword',
|
|
67
|
+
'area1',
|
|
68
|
+
'area2',
|
|
69
|
+
'lat',
|
|
70
|
+
'lng',
|
|
71
|
+
'storeLimit',
|
|
72
|
+
],
|
|
23
73
|
'lottemart-stores': ['help', 'json', 'keyword', 'area', 'brandVariant', 'lat', 'lng', 'limit'],
|
|
24
|
-
'lottemart-products': [
|
|
74
|
+
'lottemart-products': [
|
|
75
|
+
'help',
|
|
76
|
+
'json',
|
|
77
|
+
'storeCode',
|
|
78
|
+
'storeName',
|
|
79
|
+
'area',
|
|
80
|
+
'brandVariant',
|
|
81
|
+
'pageLimit',
|
|
82
|
+
],
|
|
25
83
|
'gs25-stores': ['help', 'json', 'keyword', 'lat', 'lng', 'serviceCode', 'limit'],
|
|
26
84
|
'gs25-products': ['help', 'json', 'serviceCode', 'limit'],
|
|
27
85
|
'gs25-inventory': ['help', 'json', 'storeKeyword', 'lat', 'lng', 'serviceCode', 'storeLimit'],
|
|
@@ -6,6 +6,26 @@ import { printCommandHelp } from '../../cliHelp.js';
|
|
|
6
6
|
import { parseCliArgs, toUrl, applyOptionsToQuery, toQueryOptions } from '../args.js';
|
|
7
7
|
import { validateCommandOptions } from '../commandOptions.js';
|
|
8
8
|
import { requestAndPrintResponse } from '../http.js';
|
|
9
|
+
export async function handlePlaces(options, deps) {
|
|
10
|
+
const parsed = parseCliArgs(options);
|
|
11
|
+
if (parsed.options.help === 'true') {
|
|
12
|
+
return printCommandHelp('places', deps.writeOut, deps.writeErr);
|
|
13
|
+
}
|
|
14
|
+
const location = parsed.positionals[0];
|
|
15
|
+
if (location) {
|
|
16
|
+
parsed.options = { location, ...parsed.options };
|
|
17
|
+
}
|
|
18
|
+
if (validateCommandOptions('places', parsed.options, deps.writeErr)) {
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
if (!parsed.options.location && !parsed.options.keyword) {
|
|
22
|
+
deps.writeErr('places 명령은 위치나 검색어가 필요합니다. 예: daiso places 강남역 --category cafe');
|
|
23
|
+
return 1;
|
|
24
|
+
}
|
|
25
|
+
const targetUrl = toUrl('/api/places/search');
|
|
26
|
+
applyOptionsToQuery(targetUrl, toQueryOptions(parsed.options));
|
|
27
|
+
return await requestAndPrintResponse(deps.fetchImpl, deps.writeOut, deps.writeErr, targetUrl, 'places', parsed.options.json === 'true');
|
|
28
|
+
}
|
|
9
29
|
export async function handleCuStores(options, deps) {
|
|
10
30
|
const parsed = parseCliArgs(options);
|
|
11
31
|
if (parsed.options.help === 'true') {
|
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import { DEFAULT_BASE_URL, DEFAULT_MCP_URL } from './cli/constants.js';
|
|
|
12
12
|
import { parseCliArgs } from './cli/args.js';
|
|
13
13
|
import { validateCommandOptions } from './cli/commandOptions.js';
|
|
14
14
|
import { handleGet, handleProducts, handleProduct, handleStores, handleInventory, handleDisplayLocation, } from './cli/commands/daiso.js';
|
|
15
|
-
import { handleCuStores, handleCuInventory, handleEmart24Stores, handleEmart24Products, handleEmart24Inventory, handleLotteMartStores, handleLotteMartProducts, handleGs25Stores, handleGs25Products, handleGs25Inventory, handleSevenElevenProducts, handleSevenElevenStores, handleSevenElevenPopwords, handleSevenElevenCatalog, handleLottecinemaTheaters, handleLottecinemaMovies, handleLottecinemaSeats, } from './cli/commands/convenience.js';
|
|
15
|
+
import { handleCuStores, handleCuInventory, handleEmart24Stores, handleEmart24Products, handleEmart24Inventory, handleLotteMartStores, handleLotteMartProducts, handlePlaces, handleGs25Stores, handleGs25Products, handleGs25Inventory, handleSevenElevenProducts, handleSevenElevenStores, handleSevenElevenPopwords, handleSevenElevenCatalog, handleLottecinemaTheaters, handleLottecinemaMovies, handleLottecinemaSeats, } from './cli/commands/convenience.js';
|
|
16
16
|
function rejectTopLevelUnknownOptions(options, command, deps) {
|
|
17
17
|
const parsed = parseCliArgs(options);
|
|
18
18
|
return validateCommandOptions(command, parsed.options, deps.writeErr);
|
|
@@ -112,6 +112,8 @@ export async function runCli(argv, deps) {
|
|
|
112
112
|
return await handleInventory(options, resolvedDeps);
|
|
113
113
|
if (command === 'display-location')
|
|
114
114
|
return await handleDisplayLocation(options, resolvedDeps);
|
|
115
|
+
if (command === 'places')
|
|
116
|
+
return await handlePlaces(options, resolvedDeps);
|
|
115
117
|
if (command === 'cu-stores')
|
|
116
118
|
return await handleCuStores(options, resolvedDeps);
|
|
117
119
|
if (command === 'cu-inventory')
|
package/dist/cliHelp.js
CHANGED
|
@@ -13,6 +13,7 @@ export const COMMAND_LIST = [
|
|
|
13
13
|
'stores',
|
|
14
14
|
'inventory',
|
|
15
15
|
'display-location',
|
|
16
|
+
'places',
|
|
16
17
|
'cu-stores',
|
|
17
18
|
'cu-inventory',
|
|
18
19
|
'lottecinema-theaters',
|
|
@@ -43,6 +44,7 @@ const COMMAND_SUMMARY = {
|
|
|
43
44
|
stores: '다이소 매장 검색',
|
|
44
45
|
inventory: '다이소 재고 조회',
|
|
45
46
|
'display-location': '다이소 진열 위치 조회',
|
|
47
|
+
places: '음식점/카페 등 주변 장소 검색',
|
|
46
48
|
'cu-stores': 'CU 매장 검색',
|
|
47
49
|
'cu-inventory': 'CU 재고 조회',
|
|
48
50
|
'lottecinema-theaters': '롯데시네마 주변 지점 조회',
|
|
@@ -68,11 +70,7 @@ const COMMAND_DETAIL = {
|
|
|
68
70
|
'사용법: daiso help [command]',
|
|
69
71
|
'예시: daiso help products',
|
|
70
72
|
],
|
|
71
|
-
version: [
|
|
72
|
-
'명령: version',
|
|
73
|
-
'설명: 설치된 daiso CLI 버전을 출력합니다.',
|
|
74
|
-
'사용법: daiso version',
|
|
75
|
-
],
|
|
73
|
+
version: ['명령: version', '설명: 설치된 daiso CLI 버전을 출력합니다.', '사용법: daiso version'],
|
|
76
74
|
url: [
|
|
77
75
|
'명령: url',
|
|
78
76
|
'설명: MCP 엔드포인트 URL을 출력합니다.',
|
|
@@ -141,6 +139,15 @@ const COMMAND_DETAIL = {
|
|
|
141
139
|
'옵션: --json',
|
|
142
140
|
'예시: daiso display-location 1034604 04515',
|
|
143
141
|
],
|
|
142
|
+
places: [
|
|
143
|
+
'명령: places',
|
|
144
|
+
'설명: 네이버 지역 검색으로 음식점, 카페, 디저트 가게 등 주변 장소를 검색합니다.',
|
|
145
|
+
'사용법: daiso places <location> [--category cafe|restaurant|food|dessert|all] [--keyword 검색어] [--limit N] [--json]',
|
|
146
|
+
'필수: <location> 또는 --keyword',
|
|
147
|
+
'옵션: --category, --keyword, --limit, --start, --sort, --json',
|
|
148
|
+
'예시: daiso places 강남역 --category cafe --limit 5',
|
|
149
|
+
'예시: daiso places 성수동 --keyword 브런치 --limit 5',
|
|
150
|
+
],
|
|
144
151
|
'cu-stores': [
|
|
145
152
|
'명령: cu-stores',
|
|
146
153
|
'설명: CU 매장 검색 API를 호출합니다.',
|
|
@@ -304,6 +311,7 @@ export function printHelp(writeOut) {
|
|
|
304
311
|
writeOut(' npx daiso stores 강남역');
|
|
305
312
|
writeOut(' npx daiso inventory 1034604 --keyword 강남역');
|
|
306
313
|
writeOut(' npx daiso display-location 1034604 04515');
|
|
314
|
+
writeOut(' npx daiso places 강남역 --category cafe --limit 5');
|
|
307
315
|
writeOut(' npx daiso cu-stores 강남');
|
|
308
316
|
writeOut(' npx daiso cu-inventory 과자 --storeKeyword 강남');
|
|
309
317
|
writeOut(' npx daiso lottecinema-theaters --keyword "안산 중앙역" --limit 5');
|
|
@@ -335,7 +343,7 @@ export function printHelp(writeOut) {
|
|
|
335
343
|
export function printCommandHelp(command, writeOut, writeErr) {
|
|
336
344
|
if (!Object.hasOwn(COMMAND_DETAIL, command)) {
|
|
337
345
|
writeErr(`도움말을 찾을 수 없는 명령어: ${command}`);
|
|
338
|
-
writeErr('사용 가능한 명령어: help, version, url, health, claude, get, products, product, stores, inventory, display-location, cu-stores, cu-inventory, lottecinema-theaters, lottecinema-movies, lottecinema-seats, lottemart-stores, lottemart-products, emart24-stores, emart24-products, emart24-inventory, gs25-stores, gs25-products, gs25-inventory, seveneleven-products, seveneleven-stores, seveneleven-popwords, seveneleven-catalog');
|
|
346
|
+
writeErr('사용 가능한 명령어: help, version, url, health, claude, get, products, product, stores, inventory, display-location, places, cu-stores, cu-inventory, lottecinema-theaters, lottecinema-movies, lottecinema-seats, lottemart-stores, lottemart-products, emart24-stores, emart24-products, emart24-inventory, gs25-stores, gs25-products, gs25-inventory, seveneleven-products, seveneleven-stores, seveneleven-popwords, seveneleven-catalog');
|
|
339
347
|
return 1;
|
|
340
348
|
}
|
|
341
349
|
const detail = COMMAND_DETAIL[command];
|
package/dist/cliRenderer.js
CHANGED
|
@@ -69,8 +69,14 @@ function formatCollection(title, items) {
|
|
|
69
69
|
entry.storeCode ??
|
|
70
70
|
entry.bizNo ??
|
|
71
71
|
entry.theaterId ??
|
|
72
|
-
entry.movieId
|
|
73
|
-
|
|
72
|
+
entry.movieId ??
|
|
73
|
+
entry.link;
|
|
74
|
+
const price = entry.price ??
|
|
75
|
+
entry.prc ??
|
|
76
|
+
entry.PD_PRC ??
|
|
77
|
+
entry.viewPrice ??
|
|
78
|
+
entry.priceToPay ??
|
|
79
|
+
entry.searchItemSellPrice;
|
|
74
80
|
let detail = `- ${name}`;
|
|
75
81
|
if (id !== undefined) {
|
|
76
82
|
detail += ` [${toText(id)}]`;
|
|
@@ -204,6 +210,7 @@ export function renderApiEnvelope(command, url, payload) {
|
|
|
204
210
|
lines.push(...formatCollection('제품 목록', data.products));
|
|
205
211
|
lines.push(...formatCollection('매장 목록', data.stores));
|
|
206
212
|
lines.push(...formatCollection('극장 목록', data.theaters));
|
|
213
|
+
lines.push(...formatCollection('장소 목록', data.places));
|
|
207
214
|
lines.push(...formatCollection('영화 목록', data.movies));
|
|
208
215
|
lines.push(...formatCollection('시간표', data.timetable));
|
|
209
216
|
lines.push(...formatCollection('좌석 목록', data.seats));
|
package/dist/core/registry.js
CHANGED
|
@@ -7,7 +7,9 @@ import * as z from 'zod';
|
|
|
7
7
|
import { getErrorMessage, toStandardErrorDiagnostics } from './errors.js';
|
|
8
8
|
const DEFAULT_OUTPUT_SCHEMA = z.object({}).loose().describe('도구 실행 결과(JSON 객체)');
|
|
9
9
|
function createFallbackOutputSchema(toolName) {
|
|
10
|
-
if (toolName.includes('search_products') ||
|
|
10
|
+
if (toolName.includes('search_products') ||
|
|
11
|
+
toolName.includes('searchProducts') ||
|
|
12
|
+
toolName.endsWith('_products')) {
|
|
11
13
|
return {
|
|
12
14
|
keyword: z.string().optional(),
|
|
13
15
|
query: z.string().optional(),
|
|
@@ -19,7 +21,9 @@ function createFallbackOutputSchema(toolName) {
|
|
|
19
21
|
note: z.string().optional(),
|
|
20
22
|
};
|
|
21
23
|
}
|
|
22
|
-
if (toolName.includes('find_stores') ||
|
|
24
|
+
if (toolName.includes('find_stores') ||
|
|
25
|
+
toolName.includes('nearby_stores') ||
|
|
26
|
+
toolName.includes('search_stores')) {
|
|
23
27
|
return {
|
|
24
28
|
keyword: z.string().optional(),
|
|
25
29
|
searchParams: z.unknown().optional(),
|
|
@@ -30,6 +34,18 @@ function createFallbackOutputSchema(toolName) {
|
|
|
30
34
|
stores: z.array(z.unknown()).optional(),
|
|
31
35
|
};
|
|
32
36
|
}
|
|
37
|
+
if (toolName.includes('places')) {
|
|
38
|
+
return {
|
|
39
|
+
provider: z.string().optional(),
|
|
40
|
+
searchMode: z.string().optional(),
|
|
41
|
+
query: z.string().optional(),
|
|
42
|
+
category: z.string().optional(),
|
|
43
|
+
location: z.string().optional(),
|
|
44
|
+
totalCount: z.number().optional(),
|
|
45
|
+
count: z.number().optional(),
|
|
46
|
+
places: z.array(z.unknown()).optional(),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
33
49
|
if (toolName.includes('inventory')) {
|
|
34
50
|
return {
|
|
35
51
|
productId: z.string().optional(),
|
|
@@ -178,6 +194,9 @@ function withStandardCollections(payload) {
|
|
|
178
194
|
if (Array.isArray(payload.stores)) {
|
|
179
195
|
standard.stores = normalizeStores(payload.stores);
|
|
180
196
|
}
|
|
197
|
+
if (Array.isArray(payload.places)) {
|
|
198
|
+
standard.places = normalizeStores(payload.places);
|
|
199
|
+
}
|
|
181
200
|
if (Array.isArray(payload.theaters)) {
|
|
182
201
|
standard.theaters = normalizeStores(payload.theaters);
|
|
183
202
|
}
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import { createCuService } from './services/cu/index.js';
|
|
|
19
19
|
import { createEmart24Service } from './services/emart24/index.js';
|
|
20
20
|
import { createGs25Service } from './services/gs25/index.js';
|
|
21
21
|
import { createSevenElevenService } from './services/seveneleven/index.js';
|
|
22
|
+
import { createPlacesService } from './services/places/index.js';
|
|
22
23
|
import { createPromptResponse } from './pages/prompt.js';
|
|
23
24
|
import { createFullOpenApiJsonResponse, createFullOpenApiYamlResponse, createOpenApiJsonResponse, createOpenApiYamlResponse, } from './pages/openapi.js';
|
|
24
25
|
import { createPrivacyResponse } from './pages/privacy.js';
|
|
@@ -33,6 +34,7 @@ import { registerCuRoutes } from './api/routes/cuRoutes.js';
|
|
|
33
34
|
import { registerEmart24Routes } from './api/routes/emart24Routes.js';
|
|
34
35
|
import { registerGs25Routes } from './api/routes/gs25Routes.js';
|
|
35
36
|
import { registerSevenElevenRoutes } from './api/routes/sevenelevenRoutes.js';
|
|
37
|
+
import { registerPlacesRoutes } from './api/routes/placesRoutes.js';
|
|
36
38
|
import { registerHealthRoutes } from './api/routes/healthRoutes.js';
|
|
37
39
|
import { buildConfigStatus } from './api/configStatus.js';
|
|
38
40
|
// 서버 메타데이터
|
|
@@ -48,8 +50,15 @@ const createRegistry = (bindings) => {
|
|
|
48
50
|
const registry = new ServiceRegistry();
|
|
49
51
|
registry.registerAll([
|
|
50
52
|
createDaisoService,
|
|
51
|
-
createGs25Service
|
|
53
|
+
() => createGs25Service({
|
|
54
|
+
googleMapsApiKey: bindings?.GOOGLE_MAPS_API_KEY,
|
|
55
|
+
zyteApiKey: bindings?.ZYTE_API_KEY,
|
|
56
|
+
}),
|
|
52
57
|
createSevenElevenService,
|
|
58
|
+
() => createPlacesService({
|
|
59
|
+
naverClientId: bindings?.NAVER_CLIENT_ID,
|
|
60
|
+
naverClientSecret: bindings?.NAVER_CLIENT_SECRET,
|
|
61
|
+
}),
|
|
53
62
|
createCuService,
|
|
54
63
|
createEmart24Service,
|
|
55
64
|
() => createLotteMartService({
|
|
@@ -87,9 +96,13 @@ const createMcpServer = (bindings) => {
|
|
|
87
96
|
*/
|
|
88
97
|
const isInitializeRequest = (body) => {
|
|
89
98
|
if (Array.isArray(body)) {
|
|
90
|
-
return body.some((item) => typeof item === 'object' &&
|
|
99
|
+
return body.some((item) => typeof item === 'object' &&
|
|
100
|
+
item !== null &&
|
|
101
|
+
item.method === 'initialize');
|
|
91
102
|
}
|
|
92
|
-
return typeof body === 'object' &&
|
|
103
|
+
return (typeof body === 'object' &&
|
|
104
|
+
body !== null &&
|
|
105
|
+
body.method === 'initialize');
|
|
93
106
|
};
|
|
94
107
|
/**
|
|
95
108
|
* 새 세션 transport/server를 생성합니다.
|
|
@@ -230,6 +243,7 @@ app.get('/privacy', (c) => {
|
|
|
230
243
|
registerDaisoRoutes(app);
|
|
231
244
|
registerGs25Routes(app);
|
|
232
245
|
registerSevenElevenRoutes(app);
|
|
246
|
+
registerPlacesRoutes(app);
|
|
233
247
|
registerCuRoutes(app);
|
|
234
248
|
registerEmart24Routes(app);
|
|
235
249
|
registerLotteMartRoutes(app);
|
|
@@ -10,6 +10,7 @@ import { OPENAPI_PATHS_CGV } from './openapiSpecPathsCgv.js';
|
|
|
10
10
|
import { OPENAPI_PATHS_LOTTECINEMA } from './openapiSpecPathsLottecinema.js';
|
|
11
11
|
import { OPENAPI_PATHS_GS25 } from './openapiSpecPathsGs25.js';
|
|
12
12
|
import { OPENAPI_PATHS_SEVENELEVEN } from './openapiSpecPathsSeveneleven.js';
|
|
13
|
+
import { OPENAPI_PATHS_PLACES } from './openapiSpecPathsPlaces.js';
|
|
13
14
|
import { OPENAPI_COMPONENTS } from './openapiSpecComponents.js';
|
|
14
15
|
export function generateFullOpenApiSpec(baseUrl) {
|
|
15
16
|
return {
|
|
@@ -29,6 +30,7 @@ export function generateFullOpenApiSpec(baseUrl) {
|
|
|
29
30
|
- 🎬 **메가박스 지점/영화 조회**: 주변 지점, 상영 목록, 잔여 좌석 조회
|
|
30
31
|
- 🎞️ **롯데시네마 지점/영화 조회**: 주변 지점, 상영 목록, 잔여 좌석 조회
|
|
31
32
|
- 🎥 **CGV 지점/영화 조회**: 극장 목록, 영화 목록, 시간표 조회
|
|
33
|
+
- 🍽️ **주변 음식점/카페 검색**: 네이버 지역 검색 기반 장소 조회
|
|
32
34
|
|
|
33
35
|
## 사용 팁
|
|
34
36
|
1. 한글 검색어는 URL 인코딩이 자동 처리됩니다
|
|
@@ -49,6 +51,7 @@ export function generateFullOpenApiSpec(baseUrl) {
|
|
|
49
51
|
...OPENAPI_PATHS_LOTTEMART,
|
|
50
52
|
...OPENAPI_PATHS_GS25,
|
|
51
53
|
...OPENAPI_PATHS_SEVENELEVEN,
|
|
54
|
+
...OPENAPI_PATHS_PLACES,
|
|
52
55
|
...OPENAPI_PATHS_MEGABOX,
|
|
53
56
|
...OPENAPI_PATHS_LOTTECINEMA,
|
|
54
57
|
...OPENAPI_PATHS_CGV,
|