@ait-co/devtools 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/panel/styles.ts","../../src/panel/index.ts"],"sourcesContent":["/**\n * Floating Panel CSS (inline, 외부 의존성 없음)\n */\n\nexport const PANEL_STYLES = /* css */ `\n .ait-panel-toggle {\n position: fixed;\n bottom: 16px;\n right: 16px;\n z-index: 99999;\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: #3182F6;\n border: none;\n cursor: pointer;\n box-shadow: 0 2px 12px rgba(0,0,0,0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 20px;\n color: white;\n transition: transform 0.15s;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n }\n .ait-panel-toggle:hover {\n transform: scale(1.1);\n }\n\n .ait-panel {\n position: fixed;\n bottom: 72px;\n right: 16px;\n z-index: 99998;\n width: 360px;\n max-height: 520px;\n background: #1a1a2e;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\n font-family: -apple-system, BlinkMacSystemFont, 'Pretendard', sans-serif;\n font-size: 13px;\n color: #e0e0e0;\n overflow: hidden;\n display: none;\n }\n .ait-panel.open {\n display: flex;\n flex-direction: column;\n }\n\n .ait-panel-header {\n padding: 12px 16px;\n background: #16213e;\n font-weight: 600;\n font-size: 14px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-bottom: 1px solid #2a2a4a;\n }\n .ait-panel-header span {\n color: #3182F6;\n }\n\n .ait-panel-tabs {\n display: flex;\n background: #16213e;\n border-bottom: 1px solid #2a2a4a;\n overflow-x: auto;\n scrollbar-width: none;\n }\n .ait-panel-tabs::-webkit-scrollbar { display: none; }\n\n .ait-panel-tab {\n padding: 8px 12px;\n font-size: 12px;\n color: #888;\n cursor: pointer;\n white-space: nowrap;\n border-bottom: 2px solid transparent;\n background: none;\n border-top: none;\n border-left: none;\n border-right: none;\n font-family: inherit;\n }\n .ait-panel-tab:hover {\n color: #bbb;\n }\n .ait-panel-tab.active {\n color: #3182F6;\n border-bottom-color: #3182F6;\n }\n\n .ait-panel-body {\n padding: 12px 16px;\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n }\n\n .ait-section {\n margin-bottom: 16px;\n }\n .ait-section-title {\n font-size: 11px;\n text-transform: uppercase;\n color: #666;\n margin-bottom: 8px;\n letter-spacing: 0.5px;\n }\n\n .ait-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 6px;\n }\n .ait-row label {\n color: #aaa;\n font-size: 12px;\n }\n\n .ait-select {\n background: #2a2a4a;\n color: #e0e0e0;\n border: 1px solid #3a3a5a;\n border-radius: 4px;\n padding: 4px 8px;\n font-size: 12px;\n font-family: inherit;\n cursor: pointer;\n }\n\n .ait-input {\n background: #2a2a4a;\n color: #e0e0e0;\n border: 1px solid #3a3a5a;\n border-radius: 4px;\n padding: 4px 8px;\n font-size: 12px;\n width: 100px;\n font-family: inherit;\n }\n\n .ait-btn {\n background: #3182F6;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n cursor: pointer;\n font-family: inherit;\n }\n .ait-btn:hover {\n background: #1b6ef3;\n }\n .ait-btn-sm {\n padding: 4px 8px;\n font-size: 11px;\n }\n .ait-btn-danger {\n background: #e74c3c;\n }\n .ait-btn-danger:hover {\n background: #c0392b;\n }\n\n .ait-log-entry {\n font-family: 'SF Mono', 'Menlo', monospace;\n font-size: 11px;\n padding: 3px 0;\n border-bottom: 1px solid #2a2a4a;\n color: #aaa;\n }\n .ait-log-entry .ait-log-type {\n color: #3182F6;\n font-weight: 600;\n margin-right: 6px;\n }\n .ait-log-entry .ait-log-time {\n color: #555;\n margin-right: 6px;\n }\n\n .ait-storage-row {\n font-family: 'SF Mono', 'Menlo', monospace;\n font-size: 11px;\n display: flex;\n gap: 8px;\n padding: 4px 0;\n border-bottom: 1px solid #2a2a4a;\n }\n .ait-storage-key {\n color: #e8a87c;\n min-width: 80px;\n word-break: break-all;\n }\n .ait-storage-value {\n color: #95e6cb;\n flex: 1;\n word-break: break-all;\n }\n`;\n","/**\n * ait-devtools Floating Panel\n *\n * import 하면 자동으로 페이지에 DevTools 패널을 마운트한다.\n * 외부 의존성 없이 vanilla DOM으로 구현.\n */\n\nimport { aitState } from '../mock/state.js';\nimport type { PermissionName, PermissionStatus, NetworkStatus, PlatformOS, OperationalEnvironment, IapNextResult } from '../mock/state.js';\nimport { PANEL_STYLES } from './styles.js';\n\ntype TabId = 'env' | 'permissions' | 'location' | 'iap' | 'events' | 'analytics' | 'storage';\n\nconst TABS: Array<{ id: TabId; label: string }> = [\n { id: 'env', label: 'Environment' },\n { id: 'permissions', label: 'Permissions' },\n { id: 'location', label: 'Location' },\n { id: 'iap', label: 'IAP' },\n { id: 'events', label: 'Events' },\n { id: 'analytics', label: 'Analytics' },\n { id: 'storage', label: 'Storage' },\n];\n\nfunction h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string>,\n ...children: (string | Node)[]\n): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag);\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n if (k === 'className') el.className = v;\n else el.setAttribute(k, v);\n }\n }\n for (const child of children) {\n el.append(typeof child === 'string' ? document.createTextNode(child) : child);\n }\n return el;\n}\n\nfunction selectRow(\n label: string,\n options: string[],\n value: string,\n onChange: (v: string) => void,\n): HTMLElement {\n const select = h('select', { className: 'ait-select' });\n for (const opt of options) {\n const option = h('option', { value: opt }, opt);\n if (opt === value) option.selected = true;\n select.appendChild(option);\n }\n select.addEventListener('change', () => onChange(select.value));\n return h('div', { className: 'ait-row' }, h('label', {}, label), select);\n}\n\nfunction inputRow(label: string, value: string, onChange: (v: string) => void): HTMLElement {\n const input = h('input', { className: 'ait-input', value });\n input.addEventListener('change', () => onChange(input.value));\n return h('div', { className: 'ait-row' }, h('label', {}, label), input);\n}\n\nfunction renderEnvTab(): HTMLElement {\n const s = aitState.state;\n const container = h('div');\n\n container.append(\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'Platform'),\n selectRow('OS', ['ios', 'android'], s.platform, v => aitState.update({ platform: v as PlatformOS })),\n inputRow('App Version', s.appVersion, v => aitState.update({ appVersion: v })),\n selectRow('Environment', ['toss', 'sandbox'], s.environment, v => aitState.update({ environment: v as OperationalEnvironment })),\n inputRow('Locale', s.locale, v => aitState.update({ locale: v })),\n ),\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'Network'),\n selectRow('Status', ['WIFI', '4G', '5G', '3G', '2G', 'OFFLINE', 'WWAN', 'UNKNOWN'], s.networkStatus, v => aitState.update({ networkStatus: v as NetworkStatus })),\n ),\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'Safe Area Insets'),\n inputRow('Top', String(s.safeAreaInsets.top), v => aitState.patch('safeAreaInsets', { top: Number(v) })),\n inputRow('Bottom', String(s.safeAreaInsets.bottom), v => aitState.patch('safeAreaInsets', { bottom: Number(v) })),\n ),\n );\n return container;\n}\n\nfunction renderPermissionsTab(): HTMLElement {\n const s = aitState.state;\n const container = h('div');\n const names: PermissionName[] = ['camera', 'photos', 'geolocation', 'clipboard', 'contacts', 'microphone'];\n const statuses: PermissionStatus[] = ['allowed', 'denied', 'notDetermined'];\n\n container.append(\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'Device Permissions'),\n ...names.map(name =>\n selectRow(name, statuses, s.permissions[name], v => {\n aitState.patch('permissions', { [name]: v as PermissionStatus });\n }),\n ),\n ),\n );\n return container;\n}\n\nfunction renderLocationTab(): HTMLElement {\n const s = aitState.state;\n const container = h('div');\n\n container.append(\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'Current Location'),\n inputRow('Latitude', String(s.location.coords.latitude), v => {\n const coords = { ...s.location.coords, latitude: Number(v) };\n aitState.patch('location', { coords } as Partial<typeof s.location>);\n }),\n inputRow('Longitude', String(s.location.coords.longitude), v => {\n const coords = { ...s.location.coords, longitude: Number(v) };\n aitState.patch('location', { coords } as Partial<typeof s.location>);\n }),\n inputRow('Accuracy', String(s.location.coords.accuracy), v => {\n const coords = { ...s.location.coords, accuracy: Number(v) };\n aitState.patch('location', { coords } as Partial<typeof s.location>);\n }),\n ),\n );\n return container;\n}\n\nfunction renderIapTab(): HTMLElement {\n const s = aitState.state;\n const container = h('div');\n const results: IapNextResult[] = ['success', 'USER_CANCELED', 'INVALID_PRODUCT_ID', 'PAYMENT_PENDING', 'NETWORK_ERROR', 'ITEM_ALREADY_OWNED', 'INTERNAL_ERROR'];\n\n container.append(\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'IAP Simulator'),\n selectRow('Next Purchase Result', results, s.iap.nextResult, v => {\n aitState.patch('iap', { nextResult: v as IapNextResult });\n }),\n ),\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'TossPay'),\n selectRow('Next Payment Result', ['success', 'fail'], s.payment.nextResult, v => {\n aitState.patch('payment', { nextResult: v as 'success' | 'fail' });\n }),\n ),\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, `Completed Orders (${s.iap.completedOrders.length})`),\n ...s.iap.completedOrders.slice(-5).map(o =>\n h('div', { className: 'ait-log-entry' },\n h('span', { className: 'ait-log-type' }, o.status),\n `${o.sku} (${o.orderId.slice(-8)})`,\n ),\n ),\n ),\n );\n return container;\n}\n\nfunction renderEventsTab(): HTMLElement {\n const container = h('div');\n\n const backBtn = h('button', { className: 'ait-btn' }, 'Trigger Back Event');\n backBtn.addEventListener('click', () => aitState.trigger('backEvent'));\n\n const homeBtn = h('button', { className: 'ait-btn' }, 'Trigger Home Event');\n homeBtn.addEventListener('click', () => aitState.trigger('homeEvent'));\n\n container.append(\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'Navigation Events'),\n h('div', { className: 'ait-row' }, backBtn, homeBtn),\n ),\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-section-title' }, 'Login'),\n selectRow('Logged In', ['true', 'false'], String(aitState.state.auth.isLoggedIn), v => {\n aitState.patch('auth', { isLoggedIn: v === 'true' });\n }),\n selectRow('Toss Login Integrated', ['true', 'false'], String(aitState.state.auth.isTossLoginIntegrated), v => {\n aitState.patch('auth', { isTossLoginIntegrated: v === 'true' });\n }),\n ),\n );\n return container;\n}\n\nfunction renderAnalyticsTab(): HTMLElement {\n const container = h('div');\n const logs = aitState.state.analyticsLog;\n\n const clearBtn = h('button', { className: 'ait-btn ait-btn-sm ait-btn-danger' }, 'Clear');\n clearBtn.addEventListener('click', () => {\n aitState.state.analyticsLog.length = 0;\n refreshPanel();\n });\n\n container.append(\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-row' },\n h('div', { className: 'ait-section-title' }, `Analytics Log (${logs.length})`),\n clearBtn,\n ),\n ...logs.slice(-30).reverse().map(entry => {\n const time = new Date(entry.timestamp).toLocaleTimeString('ko-KR', { hour12: false });\n return h('div', { className: 'ait-log-entry' },\n h('span', { className: 'ait-log-time' }, time),\n h('span', { className: 'ait-log-type' }, entry.type),\n JSON.stringify(entry.params),\n );\n }),\n ),\n );\n return container;\n}\n\nfunction renderStorageTab(): HTMLElement {\n const container = h('div');\n const prefix = '__ait_storage:';\n const entries: Array<[string, string]> = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith(prefix)) {\n entries.push([key.slice(prefix.length), localStorage.getItem(key) ?? '']);\n }\n }\n\n const clearBtn = h('button', { className: 'ait-btn ait-btn-sm ait-btn-danger' }, 'Clear All');\n clearBtn.addEventListener('click', () => {\n entries.forEach(([key]) => localStorage.removeItem(prefix + key));\n refreshPanel();\n });\n\n container.append(\n h('div', { className: 'ait-section' },\n h('div', { className: 'ait-row' },\n h('div', { className: 'ait-section-title' }, `Storage (${entries.length} items)`),\n clearBtn,\n ),\n entries.length === 0\n ? h('div', { style: 'color:#555;font-size:12px' }, 'No items in storage')\n : h('div', {},\n ...entries.map(([key, value]) =>\n h('div', { className: 'ait-storage-row' },\n h('span', { className: 'ait-storage-key' }, key),\n h('span', { className: 'ait-storage-value' }, value.length > 100 ? value.slice(0, 100) + '...' : value),\n ),\n ),\n ),\n ),\n );\n return container;\n}\n\nconst TAB_RENDERERS: Record<TabId, () => HTMLElement> = {\n env: renderEnvTab,\n permissions: renderPermissionsTab,\n location: renderLocationTab,\n iap: renderIapTab,\n events: renderEventsTab,\n analytics: renderAnalyticsTab,\n storage: renderStorageTab,\n};\n\n// --- Mount ---\n\nlet currentTab: TabId = 'env';\nlet panelEl: HTMLElement | null = null;\nlet bodyEl: HTMLElement | null = null;\nlet tabsEl: HTMLElement | null = null;\n\nfunction refreshPanel() {\n if (!bodyEl || !tabsEl) return;\n bodyEl.innerHTML = '';\n bodyEl.appendChild(TAB_RENDERERS[currentTab]());\n\n tabsEl.querySelectorAll('.ait-panel-tab').forEach(el => {\n el.classList.toggle('active', el.getAttribute('data-tab') === currentTab);\n });\n}\n\nfunction mount() {\n if (typeof document === 'undefined') return;\n if (document.querySelector('.ait-panel-toggle')) return;\n\n // Styles\n const style = document.createElement('style');\n style.textContent = PANEL_STYLES;\n document.head.appendChild(style);\n\n // Toggle button\n const toggle = h('button', { className: 'ait-panel-toggle', title: 'AIT DevTools' }, 'AIT');\n let isOpen = false;\n\n // Panel\n panelEl = h('div', { className: 'ait-panel' });\n\n const header = h('div', { className: 'ait-panel-header' },\n h('span', {}, 'AIT DevTools'),\n h('span', { style: 'font-size:11px;color:#666;font-weight:400' }, `v${aitState.state.appVersion}`),\n );\n\n tabsEl = h('div', { className: 'ait-panel-tabs' });\n for (const tab of TABS) {\n const tabEl = h('button', { className: 'ait-panel-tab', 'data-tab': tab.id }, tab.label);\n tabEl.addEventListener('click', () => {\n currentTab = tab.id;\n refreshPanel();\n });\n tabsEl.appendChild(tabEl);\n }\n\n bodyEl = h('div', { className: 'ait-panel-body' });\n\n panelEl.append(header, tabsEl, bodyEl);\n document.body.append(panelEl, toggle);\n\n toggle.addEventListener('click', () => {\n isOpen = !isOpen;\n panelEl!.classList.toggle('open', isOpen);\n if (isOpen) refreshPanel();\n });\n\n // 상태 변경 시 자동 갱신 (analytics, storage 탭)\n aitState.subscribe(() => {\n if (isOpen && (currentTab === 'analytics' || currentTab === 'storage')) {\n refreshPanel();\n }\n });\n\n refreshPanel();\n}\n\n// DOM ready 시 마운트\nif (typeof document !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', mount);\n } else {\n mount();\n }\n}\n\nexport { mount };\n"],"mappings":"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","names":[]}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/unplugin/index.ts
21
+ var unplugin_exports = {};
22
+ __export(unplugin_exports, {
23
+ default: () => unplugin_default,
24
+ esbuild: () => esbuild,
25
+ rollup: () => rollup,
26
+ rspack: () => rspack,
27
+ vite: () => vite,
28
+ webpack: () => webpack
29
+ });
30
+ module.exports = __toCommonJS(unplugin_exports);
31
+ var import_unplugin = require("unplugin");
32
+ var FRAMEWORK_ID = "@apps-in-toss/web-framework";
33
+ var BRIDGE_ID = "@apps-in-toss/web-bridge";
34
+ var ANALYTICS_ID = "@apps-in-toss/web-analytics";
35
+ var aitDevtoolsPlugin = (0, import_unplugin.createUnplugin)((options) => {
36
+ const _panel = options?.panel ?? true;
37
+ return {
38
+ name: "ait-devtools",
39
+ enforce: "pre",
40
+ resolveId(id) {
41
+ if (id === FRAMEWORK_ID || id === BRIDGE_ID || id === ANALYTICS_ID) {
42
+ return "ait-devtools/mock";
43
+ }
44
+ return null;
45
+ },
46
+ transformInclude(id) {
47
+ if (!_panel) return false;
48
+ return /\.(tsx?|jsx?)$/.test(id) && /main|index|entry|app/i.test(id);
49
+ },
50
+ transform(code, id) {
51
+ if (!_panel) return null;
52
+ if (code.includes("ait-devtools/panel")) return null;
53
+ if (/main|index|entry/i.test(id) && !id.includes("node_modules")) {
54
+ return `import 'ait-devtools/panel';
55
+ ${code}`;
56
+ }
57
+ return null;
58
+ }
59
+ };
60
+ });
61
+ var vite = aitDevtoolsPlugin.vite;
62
+ var webpack = aitDevtoolsPlugin.webpack;
63
+ var rollup = aitDevtoolsPlugin.rollup;
64
+ var esbuild = aitDevtoolsPlugin.esbuild;
65
+ var rspack = aitDevtoolsPlugin.rspack;
66
+ var unplugin_default = aitDevtoolsPlugin;
67
+ // Annotate the CommonJS export names for ESM import in node:
68
+ 0 && (module.exports = {
69
+ esbuild,
70
+ rollup,
71
+ rspack,
72
+ vite,
73
+ webpack
74
+ });
75
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/unplugin/index.ts"],"sourcesContent":["/**\n * ait-devtools unplugin\n *\n * 모든 주요 번들러를 지원하는 단일 플러그인.\n * @apps-in-toss/web-framework → ait-devtools/mock 으로 alias 설정.\n *\n * Usage:\n * import aitDevtools from 'ait-devtools/unplugin';\n *\n * // Vite\n * export default { plugins: [aitDevtools.vite()] };\n *\n * // Webpack / Next.js\n * config.plugins.push(aitDevtools.webpack());\n *\n * // Rspack\n * config.plugins.push(aitDevtools.rspack());\n *\n * // esbuild\n * { plugins: [aitDevtools.esbuild()] }\n *\n * // Rollup\n * { plugins: [aitDevtools.rollup()] }\n */\n\nimport { createUnplugin } from 'unplugin';\n\nexport interface AitDevtoolsOptions {\n /**\n * 패널 자동 주입 여부 (default: true)\n * true이면 진입점에 floating panel import를 자동 추가한다.\n */\n panel?: boolean;\n}\n\nconst FRAMEWORK_ID = '@apps-in-toss/web-framework';\nconst BRIDGE_ID = '@apps-in-toss/web-bridge';\nconst ANALYTICS_ID = '@apps-in-toss/web-analytics';\n\nconst aitDevtoolsPlugin = createUnplugin((options?: AitDevtoolsOptions) => {\n const _panel = options?.panel ?? true;\n\n return {\n name: 'ait-devtools',\n enforce: 'pre' as const,\n\n resolveId(id: string) {\n // @apps-in-toss/web-framework → ait-devtools/mock\n if (id === FRAMEWORK_ID || id === BRIDGE_ID || id === ANALYTICS_ID) {\n return 'ait-devtools/mock';\n }\n return null;\n },\n\n transformInclude(id: string) {\n if (!_panel) return false;\n // 진입점 파일에만 패널 import를 주입\n return /\\.(tsx?|jsx?)$/.test(id) && /main|index|entry|app/i.test(id);\n },\n\n transform(code: string, id: string) {\n if (!_panel) return null;\n // 이미 패널이 import 되어있으면 스킵\n if (code.includes('ait-devtools/panel')) return null;\n // 진입점에서 가장 처음으로 실행되도록 prepend\n if (/main|index|entry/i.test(id) && !id.includes('node_modules')) {\n return `import 'ait-devtools/panel';\\n${code}`;\n }\n return null;\n },\n };\n});\n\nexport const vite = aitDevtoolsPlugin.vite;\nexport const webpack = aitDevtoolsPlugin.webpack;\nexport const rollup = aitDevtoolsPlugin.rollup;\nexport const esbuild = aitDevtoolsPlugin.esbuild;\nexport const rspack = aitDevtoolsPlugin.rspack;\n\nexport default aitDevtoolsPlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBA,sBAA+B;AAU/B,IAAM,eAAe;AACrB,IAAM,YAAY;AAClB,IAAM,eAAe;AAErB,IAAM,wBAAoB,gCAAe,CAAC,YAAiC;AACzE,QAAM,SAAS,SAAS,SAAS;AAEjC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,UAAU,IAAY;AAEpB,UAAI,OAAO,gBAAgB,OAAO,aAAa,OAAO,cAAc;AAClE,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IAEA,iBAAiB,IAAY;AAC3B,UAAI,CAAC,OAAQ,QAAO;AAEpB,aAAO,iBAAiB,KAAK,EAAE,KAAK,wBAAwB,KAAK,EAAE;AAAA,IACrE;AAAA,IAEA,UAAU,MAAc,IAAY;AAClC,UAAI,CAAC,OAAQ,QAAO;AAEpB,UAAI,KAAK,SAAS,oBAAoB,EAAG,QAAO;AAEhD,UAAI,oBAAoB,KAAK,EAAE,KAAK,CAAC,GAAG,SAAS,cAAc,GAAG;AAChE,eAAO;AAAA,EAAiC,IAAI;AAAA,MAC9C;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF,CAAC;AAEM,IAAM,OAAO,kBAAkB;AAC/B,IAAM,UAAU,kBAAkB;AAClC,IAAM,SAAS,kBAAkB;AACjC,IAAM,UAAU,kBAAkB;AAClC,IAAM,SAAS,kBAAkB;AAExC,IAAO,mBAAQ;","names":[]}
@@ -0,0 +1,46 @@
1
+ // src/unplugin/index.ts
2
+ import { createUnplugin } from "unplugin";
3
+ var FRAMEWORK_ID = "@apps-in-toss/web-framework";
4
+ var BRIDGE_ID = "@apps-in-toss/web-bridge";
5
+ var ANALYTICS_ID = "@apps-in-toss/web-analytics";
6
+ var aitDevtoolsPlugin = createUnplugin((options) => {
7
+ const _panel = options?.panel ?? true;
8
+ return {
9
+ name: "ait-devtools",
10
+ enforce: "pre",
11
+ resolveId(id) {
12
+ if (id === FRAMEWORK_ID || id === BRIDGE_ID || id === ANALYTICS_ID) {
13
+ return "ait-devtools/mock";
14
+ }
15
+ return null;
16
+ },
17
+ transformInclude(id) {
18
+ if (!_panel) return false;
19
+ return /\.(tsx?|jsx?)$/.test(id) && /main|index|entry|app/i.test(id);
20
+ },
21
+ transform(code, id) {
22
+ if (!_panel) return null;
23
+ if (code.includes("ait-devtools/panel")) return null;
24
+ if (/main|index|entry/i.test(id) && !id.includes("node_modules")) {
25
+ return `import 'ait-devtools/panel';
26
+ ${code}`;
27
+ }
28
+ return null;
29
+ }
30
+ };
31
+ });
32
+ var vite = aitDevtoolsPlugin.vite;
33
+ var webpack = aitDevtoolsPlugin.webpack;
34
+ var rollup = aitDevtoolsPlugin.rollup;
35
+ var esbuild = aitDevtoolsPlugin.esbuild;
36
+ var rspack = aitDevtoolsPlugin.rspack;
37
+ var unplugin_default = aitDevtoolsPlugin;
38
+ export {
39
+ unplugin_default as default,
40
+ esbuild,
41
+ rollup,
42
+ rspack,
43
+ vite,
44
+ webpack
45
+ };
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/unplugin/index.ts"],"sourcesContent":["/**\n * ait-devtools unplugin\n *\n * 모든 주요 번들러를 지원하는 단일 플러그인.\n * @apps-in-toss/web-framework → ait-devtools/mock 으로 alias 설정.\n *\n * Usage:\n * import aitDevtools from 'ait-devtools/unplugin';\n *\n * // Vite\n * export default { plugins: [aitDevtools.vite()] };\n *\n * // Webpack / Next.js\n * config.plugins.push(aitDevtools.webpack());\n *\n * // Rspack\n * config.plugins.push(aitDevtools.rspack());\n *\n * // esbuild\n * { plugins: [aitDevtools.esbuild()] }\n *\n * // Rollup\n * { plugins: [aitDevtools.rollup()] }\n */\n\nimport { createUnplugin } from 'unplugin';\n\nexport interface AitDevtoolsOptions {\n /**\n * 패널 자동 주입 여부 (default: true)\n * true이면 진입점에 floating panel import를 자동 추가한다.\n */\n panel?: boolean;\n}\n\nconst FRAMEWORK_ID = '@apps-in-toss/web-framework';\nconst BRIDGE_ID = '@apps-in-toss/web-bridge';\nconst ANALYTICS_ID = '@apps-in-toss/web-analytics';\n\nconst aitDevtoolsPlugin = createUnplugin((options?: AitDevtoolsOptions) => {\n const _panel = options?.panel ?? true;\n\n return {\n name: 'ait-devtools',\n enforce: 'pre' as const,\n\n resolveId(id: string) {\n // @apps-in-toss/web-framework → ait-devtools/mock\n if (id === FRAMEWORK_ID || id === BRIDGE_ID || id === ANALYTICS_ID) {\n return 'ait-devtools/mock';\n }\n return null;\n },\n\n transformInclude(id: string) {\n if (!_panel) return false;\n // 진입점 파일에만 패널 import를 주입\n return /\\.(tsx?|jsx?)$/.test(id) && /main|index|entry|app/i.test(id);\n },\n\n transform(code: string, id: string) {\n if (!_panel) return null;\n // 이미 패널이 import 되어있으면 스킵\n if (code.includes('ait-devtools/panel')) return null;\n // 진입점에서 가장 처음으로 실행되도록 prepend\n if (/main|index|entry/i.test(id) && !id.includes('node_modules')) {\n return `import 'ait-devtools/panel';\\n${code}`;\n }\n return null;\n },\n };\n});\n\nexport const vite = aitDevtoolsPlugin.vite;\nexport const webpack = aitDevtoolsPlugin.webpack;\nexport const rollup = aitDevtoolsPlugin.rollup;\nexport const esbuild = aitDevtoolsPlugin.esbuild;\nexport const rspack = aitDevtoolsPlugin.rspack;\n\nexport default aitDevtoolsPlugin;\n"],"mappings":";AAyBA,SAAS,sBAAsB;AAU/B,IAAM,eAAe;AACrB,IAAM,YAAY;AAClB,IAAM,eAAe;AAErB,IAAM,oBAAoB,eAAe,CAAC,YAAiC;AACzE,QAAM,SAAS,SAAS,SAAS;AAEjC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,UAAU,IAAY;AAEpB,UAAI,OAAO,gBAAgB,OAAO,aAAa,OAAO,cAAc;AAClE,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IAEA,iBAAiB,IAAY;AAC3B,UAAI,CAAC,OAAQ,QAAO;AAEpB,aAAO,iBAAiB,KAAK,EAAE,KAAK,wBAAwB,KAAK,EAAE;AAAA,IACrE;AAAA,IAEA,UAAU,MAAc,IAAY;AAClC,UAAI,CAAC,OAAQ,QAAO;AAEpB,UAAI,KAAK,SAAS,oBAAoB,EAAG,QAAO;AAEhD,UAAI,oBAAoB,KAAK,EAAE,KAAK,CAAC,GAAG,SAAS,cAAc,GAAG;AAChE,eAAO;AAAA,EAAiC,IAAI;AAAA,MAC9C;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF,CAAC;AAEM,IAAM,OAAO,kBAAkB;AAC/B,IAAM,UAAU,kBAAkB;AAClC,IAAM,SAAS,kBAAkB;AACjC,IAAM,UAAU,kBAAkB;AAClC,IAAM,SAAS,kBAAkB;AAExC,IAAO,mBAAQ;","names":[]}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@ait-co/devtools",
3
+ "version": "0.0.1",
4
+ "description": "Development tools for Apps in Toss mini-apps — mock SDK, floating devtools panel, and universal bundler plugin",
5
+ "type": "module",
6
+ "main": "./dist/mock/index.js",
7
+ "types": "./dist/mock/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/mock/index.d.ts",
11
+ "import": "./dist/mock/index.js"
12
+ },
13
+ "./mock": {
14
+ "types": "./dist/mock/index.d.ts",
15
+ "import": "./dist/mock/index.js"
16
+ },
17
+ "./panel": {
18
+ "types": "./dist/panel/index.d.ts",
19
+ "import": "./dist/panel/index.js"
20
+ },
21
+ "./unplugin": {
22
+ "types": "./dist/unplugin/index.d.ts",
23
+ "import": "./dist/unplugin/index.js",
24
+ "require": "./dist/unplugin/index.cjs"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "peerDependencies": {
31
+ "@apps-in-toss/web-framework": "^2.0.0"
32
+ },
33
+ "peerDependenciesMeta": {
34
+ "@apps-in-toss/web-framework": {
35
+ "optional": true
36
+ }
37
+ },
38
+ "dependencies": {
39
+ "unplugin": "^2.3.2"
40
+ },
41
+ "devDependencies": {
42
+ "@apps-in-toss/web-framework": "^2.4.1",
43
+ "tsup": "^8.4.0",
44
+ "typescript": "^5.8.3",
45
+ "vitest": "^3.1.1",
46
+ "tsx": "^4.19.4"
47
+ },
48
+ "keywords": [
49
+ "apps-in-toss",
50
+ "toss",
51
+ "mini-app",
52
+ "devtools",
53
+ "mock",
54
+ "sdk"
55
+ ],
56
+ "license": "BSD-3-Clause",
57
+ "publishConfig": {
58
+ "access": "public"
59
+ },
60
+ "repository": {
61
+ "type": "git",
62
+ "url": "https://github.com/apps-in-toss-community/devtools"
63
+ },
64
+ "scripts": {
65
+ "build": "tsup",
66
+ "dev": "tsup --watch",
67
+ "typecheck": "tsc --noEmit",
68
+ "test": "vitest run",
69
+ "check-sdk-update": "tsx scripts/check-sdk-update.ts"
70
+ }
71
+ }