xgen-dex-ide 1.60.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/README.md +42 -0
- package/dist/components/ActivityBar.d.ts +21 -0
- package/dist/components/ActivityBar.d.ts.map +1 -0
- package/dist/components/ActivityBar.js +14 -0
- package/dist/components/ActivityBar.js.map +1 -0
- package/dist/components/EditorArea.d.ts +5 -0
- package/dist/components/EditorArea.d.ts.map +1 -0
- package/dist/components/EditorArea.js +468 -0
- package/dist/components/EditorArea.js.map +1 -0
- package/dist/components/Explorer.d.ts +2 -0
- package/dist/components/Explorer.d.ts.map +1 -0
- package/dist/components/Explorer.js +349 -0
- package/dist/components/Explorer.js.map +1 -0
- package/dist/components/IdeView.d.ts +24 -0
- package/dist/components/IdeView.d.ts.map +1 -0
- package/dist/components/IdeView.js +359 -0
- package/dist/components/IdeView.js.map +1 -0
- package/dist/components/QuickOpen.d.ts +2 -0
- package/dist/components/QuickOpen.d.ts.map +1 -0
- package/dist/components/QuickOpen.js +204 -0
- package/dist/components/QuickOpen.js.map +1 -0
- package/dist/components/ScmView.d.ts +6 -0
- package/dist/components/ScmView.d.ts.map +1 -0
- package/dist/components/ScmView.js +283 -0
- package/dist/components/ScmView.js.map +1 -0
- package/dist/components/SearchView.d.ts +2 -0
- package/dist/components/SearchView.d.ts.map +1 -0
- package/dist/components/SearchView.js +97 -0
- package/dist/components/SearchView.js.map +1 -0
- package/dist/components/StatusBar.d.ts +2 -0
- package/dist/components/StatusBar.d.ts.map +1 -0
- package/dist/components/StatusBar.js +71 -0
- package/dist/components/StatusBar.js.map +1 -0
- package/dist/components/TerminalPanel.d.ts +6 -0
- package/dist/components/TerminalPanel.d.ts.map +1 -0
- package/dist/components/TerminalPanel.js +101 -0
- package/dist/components/TerminalPanel.js.map +1 -0
- package/dist/components/hooks.d.ts +25 -0
- package/dist/components/hooks.d.ts.map +1 -0
- package/dist/components/hooks.js +99 -0
- package/dist/components/hooks.js.map +1 -0
- package/dist/components/icons.d.ts +23 -0
- package/dist/components/icons.d.ts.map +1 -0
- package/dist/components/icons.js +123 -0
- package/dist/components/icons.js.map +1 -0
- package/dist/components/primitives.d.ts +57 -0
- package/dist/components/primitives.d.ts.map +1 -0
- package/dist/components/primitives.js +263 -0
- package/dist/components/primitives.js.map +1 -0
- package/dist/fuzzy.d.ts +17 -0
- package/dist/fuzzy.d.ts.map +1 -0
- package/dist/fuzzy.js +62 -0
- package/dist/fuzzy.js.map +1 -0
- package/dist/git-model.d.ts +104 -0
- package/dist/git-model.d.ts.map +1 -0
- package/dist/git-model.js +126 -0
- package/dist/git-model.js.map +1 -0
- package/dist/ide.css +2203 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/keys.d.ts +33 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +98 -0
- package/dist/keys.js.map +1 -0
- package/dist/paths.d.ts +14 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +66 -0
- package/dist/paths.js.map +1 -0
- package/dist/store.d.ts +406 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +1464 -0
- package/dist/store.js.map +1 -0
- package/dist/terminal.d.ts +60 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +293 -0
- package/dist/terminal.js.map +1 -0
- package/dist/text.d.ts +26 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +76 -0
- package/dist/text.js.map +1 -0
- package/dist/tree.d.ts +31 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +105 -0
- package/dist/tree.js.map +1 -0
- package/dist/types.d.ts +216 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* xgen-dex-ide — 채팅 안의 IDE 보기.
|
|
3
|
+
*
|
|
4
|
+
* 쓰는 법(호스트):
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* import { IdeStore, IdeView } from 'xgen-dex-ide';
|
|
8
|
+
* import 'xgen-dex-ide/ide.css';
|
|
9
|
+
*
|
|
10
|
+
* const store = new IdeStore(host); // 에이전트마다 하나 — 탭이 닫힐 때 store.dispose()
|
|
11
|
+
* <IdeView store={store} chat={<Chat />} theme="dark" />
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* `host` 는 {@link IdeHost} 를 구현한다: 스토리지 목록·샌드박스 파일·터미널 소켓·git·Monaco.
|
|
15
|
+
*/
|
|
16
|
+
export { IdeView, type IdeViewProps } from './components/IdeView.js';
|
|
17
|
+
export type { SideView } from './components/ActivityBar.js';
|
|
18
|
+
export { IdeStore, DEFAULT_LAYOUT, type IdeState, type Layout, type IdeCommand, type EditorTab, type EditorGroup, type DocState } from './store.js';
|
|
19
|
+
export { IdeError } from './types.js';
|
|
20
|
+
export type { IdeHost, IdeFileEntry, IdeSessionInfo, IdeReadResult, IdeSaveResult, IdeStat, IdeFsOp, IdeSearchQuery, IdeSearchMatch, IdeSearchResult, IdeReplaceResult, IdeTerminalInfo, TerminalServerFrame, TerminalClientFrame, TerminalConnection, TerminalHandlers, MonacoApi, ThemeKind, } from './types.js';
|
|
21
|
+
export type { GitStatus, GitChange, GitRemote, GitAccount, GitBranches } from './git-model.js';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjJ,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,YAAY,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,aAAa,EACb,aAAa,EACb,OAAO,EACP,OAAO,EACP,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,SAAS,GACV,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* xgen-dex-ide — 채팅 안의 IDE 보기.
|
|
3
|
+
*
|
|
4
|
+
* 쓰는 법(호스트):
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* import { IdeStore, IdeView } from 'xgen-dex-ide';
|
|
8
|
+
* import 'xgen-dex-ide/ide.css';
|
|
9
|
+
*
|
|
10
|
+
* const store = new IdeStore(host); // 에이전트마다 하나 — 탭이 닫힐 때 store.dispose()
|
|
11
|
+
* <IdeView store={store} chat={<Chat />} theme="dark" />
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* `host` 는 {@link IdeHost} 를 구현한다: 스토리지 목록·샌드박스 파일·터미널 소켓·git·Monaco.
|
|
15
|
+
*/
|
|
16
|
+
export { IdeView } from './components/IdeView.js';
|
|
17
|
+
export { IdeStore, DEFAULT_LAYOUT } from './store.js';
|
|
18
|
+
export { IdeError } from './types.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,OAAO,EAAqB,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAgG,MAAM,SAAS,CAAC;AACjJ,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/keys.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 단축키 — `Mod` 는 맥에서 Cmd, 그 밖에서 Ctrl. 두 번 누르는 조합(`Mod+K S`)도 받는다.
|
|
3
|
+
*
|
|
4
|
+
* 편집기 안(Monaco)의 단축키는 Monaco 가 처리한다. 여기는 IDE 전체의 것(저장·빠른 열기·
|
|
5
|
+
* 패널 토글)이고, 편집기가 먼저 먹지 않도록 Monaco 에도 같은 명령을 건다(IdeView).
|
|
6
|
+
*/
|
|
7
|
+
export declare const isMac: boolean;
|
|
8
|
+
export interface KeyStroke {
|
|
9
|
+
mod: boolean;
|
|
10
|
+
shift: boolean;
|
|
11
|
+
alt: boolean;
|
|
12
|
+
key: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function parseStroke(spec: string): KeyStroke;
|
|
15
|
+
export declare function parseBinding(spec: string): KeyStroke[];
|
|
16
|
+
/** 이벤트의 키 이름 — 배열이 바뀌어도(한글 입력 상태) 물리 키로 맞춘다. */
|
|
17
|
+
export declare function eventKey(e: Pick<KeyboardEvent, 'key' | 'code'>): string;
|
|
18
|
+
export declare function matchesStroke(e: Pick<KeyboardEvent, 'key' | 'code' | 'ctrlKey' | 'metaKey' | 'shiftKey' | 'altKey'>, s: KeyStroke, mac?: boolean): boolean;
|
|
19
|
+
/** 화면에 보일 표기 — `Mod+Shift+P` → `Ctrl+Shift+P` / `⇧⌘P`. */
|
|
20
|
+
export declare function formatBinding(spec: string, mac?: boolean): string;
|
|
21
|
+
/**
|
|
22
|
+
* 조합 판정기 — 첫 타가 맞으면 다음 타를 기다린다(1.5초).
|
|
23
|
+
* `feed` 는 끝까지 맞으면 그 바인딩을, 기다리는 중이면 `'pending'` 을, 아니면 null 을 준다.
|
|
24
|
+
*/
|
|
25
|
+
export declare class ChordMatcher<T extends string> {
|
|
26
|
+
private readonly mac;
|
|
27
|
+
private pending;
|
|
28
|
+
private pendingAt;
|
|
29
|
+
private readonly table;
|
|
30
|
+
constructor(bindings: Record<T, string>, mac?: boolean);
|
|
31
|
+
feed(e: Pick<KeyboardEvent, 'key' | 'code' | 'ctrlKey' | 'metaKey' | 'shiftKey' | 'altKey'>): T | 'pending' | null;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,KAAK,SAC2F,CAAC;AAE9G,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAKnD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAEtD;AAED,gDAAgD;AAChD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,MAAM,CAAC,GAAG,MAAM,CAcvE;AAED,wBAAgB,aAAa,CAC3B,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC,EACtF,CAAC,EAAE,SAAS,EACZ,GAAG,UAAQ,GACV,OAAO,CAMT;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAQ,GAAG,MAAM,CAQ/D;AAED;;;GAGG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM;IAKC,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJ7D,OAAO,CAAC,OAAO,CAAuD;IACtE,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyC;gBAEnD,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,EAAmB,GAAG,UAAQ;IAIrE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,SAAS,GAAG,IAAI;CAqBnH"}
|
package/dist/keys.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 단축키 — `Mod` 는 맥에서 Cmd, 그 밖에서 Ctrl. 두 번 누르는 조합(`Mod+K S`)도 받는다.
|
|
3
|
+
*
|
|
4
|
+
* 편집기 안(Monaco)의 단축키는 Monaco 가 처리한다. 여기는 IDE 전체의 것(저장·빠른 열기·
|
|
5
|
+
* 패널 토글)이고, 편집기가 먼저 먹지 않도록 Monaco 에도 같은 명령을 건다(IdeView).
|
|
6
|
+
*/
|
|
7
|
+
export const isMac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || '');
|
|
8
|
+
export function parseStroke(spec) {
|
|
9
|
+
const parts = spec.split('+').map((p) => p.trim());
|
|
10
|
+
const key = parts.pop() ?? '';
|
|
11
|
+
const set = new Set(parts.map((p) => p.toLowerCase()));
|
|
12
|
+
return { mod: set.has('mod'), shift: set.has('shift'), alt: set.has('alt'), key: key.toLowerCase() };
|
|
13
|
+
}
|
|
14
|
+
export function parseBinding(spec) {
|
|
15
|
+
return spec.split(' ').filter(Boolean).map(parseStroke);
|
|
16
|
+
}
|
|
17
|
+
/** 이벤트의 키 이름 — 배열이 바뀌어도(한글 입력 상태) 물리 키로 맞춘다. */
|
|
18
|
+
export function eventKey(e) {
|
|
19
|
+
const code = e.code || '';
|
|
20
|
+
if (code.startsWith('Key'))
|
|
21
|
+
return code.slice(3).toLowerCase();
|
|
22
|
+
if (code.startsWith('Digit'))
|
|
23
|
+
return code.slice(5);
|
|
24
|
+
if (code === 'Backquote')
|
|
25
|
+
return '`';
|
|
26
|
+
if (code === 'Backslash')
|
|
27
|
+
return '\\';
|
|
28
|
+
if (code === 'Comma')
|
|
29
|
+
return ',';
|
|
30
|
+
if (code === 'Period')
|
|
31
|
+
return '.';
|
|
32
|
+
if (code === 'Slash')
|
|
33
|
+
return '/';
|
|
34
|
+
if (code === 'BracketLeft')
|
|
35
|
+
return '[';
|
|
36
|
+
if (code === 'BracketRight')
|
|
37
|
+
return ']';
|
|
38
|
+
if (code === 'Equal')
|
|
39
|
+
return '=';
|
|
40
|
+
if (code === 'Minus')
|
|
41
|
+
return '-';
|
|
42
|
+
return (e.key || '').toLowerCase();
|
|
43
|
+
}
|
|
44
|
+
export function matchesStroke(e, s, mac = isMac) {
|
|
45
|
+
const mod = mac ? e.metaKey : e.ctrlKey;
|
|
46
|
+
const otherMod = mac ? e.ctrlKey : e.metaKey;
|
|
47
|
+
return (mod === s.mod && !otherMod && e.shiftKey === s.shift && e.altKey === s.alt && eventKey(e) === s.key);
|
|
48
|
+
}
|
|
49
|
+
/** 화면에 보일 표기 — `Mod+Shift+P` → `Ctrl+Shift+P` / `⇧⌘P`. */
|
|
50
|
+
export function formatBinding(spec, mac = isMac) {
|
|
51
|
+
return parseBinding(spec)
|
|
52
|
+
.map((s) => {
|
|
53
|
+
const key = s.key.length === 1 ? s.key.toUpperCase() : s.key[0].toUpperCase() + s.key.slice(1);
|
|
54
|
+
if (mac)
|
|
55
|
+
return `${s.alt ? '⌥' : ''}${s.shift ? '⇧' : ''}${s.mod ? '⌘' : ''}${key}`;
|
|
56
|
+
return [s.mod ? 'Ctrl' : '', s.shift ? 'Shift' : '', s.alt ? 'Alt' : '', key].filter(Boolean).join('+');
|
|
57
|
+
})
|
|
58
|
+
.join(' ');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 조합 판정기 — 첫 타가 맞으면 다음 타를 기다린다(1.5초).
|
|
62
|
+
* `feed` 는 끝까지 맞으면 그 바인딩을, 기다리는 중이면 `'pending'` 을, 아니면 null 을 준다.
|
|
63
|
+
*/
|
|
64
|
+
export class ChordMatcher {
|
|
65
|
+
mac;
|
|
66
|
+
pending = null;
|
|
67
|
+
pendingAt = 0;
|
|
68
|
+
table;
|
|
69
|
+
constructor(bindings, mac = isMac) {
|
|
70
|
+
this.mac = mac;
|
|
71
|
+
this.table = Object.keys(bindings).map((b) => ({ binding: b, strokes: parseBinding(bindings[b]) }));
|
|
72
|
+
}
|
|
73
|
+
feed(e) {
|
|
74
|
+
if (['Control', 'Meta', 'Shift', 'Alt'].includes(e.key))
|
|
75
|
+
return this.pending ? 'pending' : null;
|
|
76
|
+
const now = Date.now();
|
|
77
|
+
if (this.pending && now - this.pendingAt < 1500) {
|
|
78
|
+
const hit = this.pending.find((p) => matchesStroke(e, p.strokes[1], this.mac));
|
|
79
|
+
this.pending = null;
|
|
80
|
+
if (hit)
|
|
81
|
+
return hit.binding;
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
this.pending = null;
|
|
85
|
+
for (const row of this.table) {
|
|
86
|
+
if (row.strokes.length === 1 && matchesStroke(e, row.strokes[0], this.mac))
|
|
87
|
+
return row.binding;
|
|
88
|
+
}
|
|
89
|
+
const starts = this.table.filter((r) => r.strokes.length === 2 && matchesStroke(e, r.strokes[0], this.mac));
|
|
90
|
+
if (starts.length) {
|
|
91
|
+
this.pending = starts;
|
|
92
|
+
this.pendingAt = now;
|
|
93
|
+
return 'pending';
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=keys.js.map
|
package/dist/keys.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** workspace 기준 경로 — 앞뒤 `/` 없이, 구분자는 `/`. 빈 문자열이 루트다. */
|
|
2
|
+
export declare function normalize(path: string): string;
|
|
3
|
+
export declare function join(...segments: string[]): string;
|
|
4
|
+
export declare function dirname(path: string): string;
|
|
5
|
+
export declare function basename(path: string): string;
|
|
6
|
+
/** 확장자(점 없이, 소문자). `.bashrc` 처럼 점으로 시작하는 이름은 확장자가 없다. */
|
|
7
|
+
export declare function extname(path: string): string;
|
|
8
|
+
/** `child` 가 `parent` 와 같거나 그 아래인가. */
|
|
9
|
+
export declare function isWithin(child: string, parent: string): boolean;
|
|
10
|
+
/** `parent` 아래에서 `name` 이 겹치지 않는 이름 — `a.txt` → `a copy.txt` → `a copy 2.txt`. */
|
|
11
|
+
export declare function uniqueCopyName(name: string, taken: Set<string>): string;
|
|
12
|
+
/** 새 이름으로 쓸 수 있는가 — 쓸 수 없으면 사유(화면 문구). */
|
|
13
|
+
export declare function invalidName(name: string): string | null;
|
|
14
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAEzD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW9C;AAED,wBAAgB,IAAI,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAElD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,yDAAyD;AACzD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED,uCAAuC;AACvC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAI/D;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAQvE;AAED,0CAA0C;AAC1C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQvD"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** workspace 기준 경로 — 앞뒤 `/` 없이, 구분자는 `/`. 빈 문자열이 루트다. */
|
|
2
|
+
export function normalize(path) {
|
|
3
|
+
const parts = [];
|
|
4
|
+
for (const seg of String(path ?? '').replace(/\\/g, '/').split('/')) {
|
|
5
|
+
if (!seg || seg === '.')
|
|
6
|
+
continue;
|
|
7
|
+
if (seg === '..') {
|
|
8
|
+
parts.pop();
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
parts.push(seg);
|
|
12
|
+
}
|
|
13
|
+
return parts.join('/');
|
|
14
|
+
}
|
|
15
|
+
export function join(...segments) {
|
|
16
|
+
return normalize(segments.filter((s) => s !== '').join('/'));
|
|
17
|
+
}
|
|
18
|
+
export function dirname(path) {
|
|
19
|
+
const p = normalize(path);
|
|
20
|
+
const i = p.lastIndexOf('/');
|
|
21
|
+
return i < 0 ? '' : p.slice(0, i);
|
|
22
|
+
}
|
|
23
|
+
export function basename(path) {
|
|
24
|
+
const p = normalize(path);
|
|
25
|
+
return p.slice(p.lastIndexOf('/') + 1);
|
|
26
|
+
}
|
|
27
|
+
/** 확장자(점 없이, 소문자). `.bashrc` 처럼 점으로 시작하는 이름은 확장자가 없다. */
|
|
28
|
+
export function extname(path) {
|
|
29
|
+
const name = basename(path);
|
|
30
|
+
const i = name.lastIndexOf('.');
|
|
31
|
+
return i <= 0 ? '' : name.slice(i + 1).toLowerCase();
|
|
32
|
+
}
|
|
33
|
+
/** `child` 가 `parent` 와 같거나 그 아래인가. */
|
|
34
|
+
export function isWithin(child, parent) {
|
|
35
|
+
const c = normalize(child);
|
|
36
|
+
const p = normalize(parent);
|
|
37
|
+
return p === '' || c === p || c.startsWith(p + '/');
|
|
38
|
+
}
|
|
39
|
+
/** `parent` 아래에서 `name` 이 겹치지 않는 이름 — `a.txt` → `a copy.txt` → `a copy 2.txt`. */
|
|
40
|
+
export function uniqueCopyName(name, taken) {
|
|
41
|
+
if (!taken.has(name))
|
|
42
|
+
return name;
|
|
43
|
+
const dot = name.lastIndexOf('.');
|
|
44
|
+
const stem = dot > 0 ? name.slice(0, dot) : name;
|
|
45
|
+
const ext = dot > 0 ? name.slice(dot) : '';
|
|
46
|
+
let candidate = `${stem} copy${ext}`;
|
|
47
|
+
for (let n = 2; taken.has(candidate); n += 1)
|
|
48
|
+
candidate = `${stem} copy ${n}${ext}`;
|
|
49
|
+
return candidate;
|
|
50
|
+
}
|
|
51
|
+
/** 새 이름으로 쓸 수 있는가 — 쓸 수 없으면 사유(화면 문구). */
|
|
52
|
+
export function invalidName(name) {
|
|
53
|
+
const n = name.trim();
|
|
54
|
+
if (!n)
|
|
55
|
+
return '이름을 입력하세요';
|
|
56
|
+
if (n === '.' || n === '..')
|
|
57
|
+
return '이 이름은 쓸 수 없습니다';
|
|
58
|
+
if (/[\\\0]/.test(n))
|
|
59
|
+
return '이름에 쓸 수 없는 문자가 있습니다';
|
|
60
|
+
if (n.startsWith('/') || n.endsWith('/'))
|
|
61
|
+
return '이름 앞뒤에 / 를 쓸 수 없습니다';
|
|
62
|
+
if (n.split('/').some((s) => !s || s === '.' || s === '..'))
|
|
63
|
+
return '경로가 올바르지 않습니다';
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
|