1 | import { Maybe } from './common/types'
|
2 |
|
3 |
|
4 | export enum Branch {
|
5 | Public = 'public',
|
6 | Pretty = 'p',
|
7 | Private = 'private',
|
8 | PrivateLog = 'privateLog',
|
9 | Version = 'version'
|
10 | }
|
11 |
|
12 | export enum Kind {
|
13 | Directory = "directory",
|
14 | File = "file"
|
15 | }
|
16 |
|
17 | export type Path = string[]
|
18 |
|
19 | export type DirectoryPath = { directory: Path }
|
20 | export type FilePath = { file: Path }
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | export type DistinctivePath = DirectoryPath | FilePath
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | export function directory(...args: Path): DirectoryPath {
|
36 | if (args.some(p => p.includes("/"))) {
|
37 | throw new Error("Forward slashes `/` are not allowed")
|
38 | }
|
39 | return { directory: args }
|
40 | }
|
41 |
|
42 |
|
43 |
|
44 |
|
45 | export function file(...args: Path): FilePath {
|
46 | if (args.some(p => p.includes("/"))) {
|
47 | throw new Error("Forward slashes `/` are not allowed")
|
48 | }
|
49 | return { file: args }
|
50 | }
|
51 |
|
52 |
|
53 |
|
54 |
|
55 | export function root(): DirectoryPath {
|
56 | return { directory: [] }
|
57 | }
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 | export function fromPosix(path: string): DistinctivePath {
|
73 | const split = path.replace(/^\/+/, "").split("/")
|
74 | if (path.endsWith("/")) return { directory: split.slice(0, -1) }
|
75 | else if (path === "") return root()
|
76 | return { file: split }
|
77 | }
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | export function toPosix(
|
86 | path: DistinctivePath,
|
87 | { absolute }: { absolute: boolean } = { absolute: false }
|
88 | ): string {
|
89 | const prefix = absolute ? "/" : ""
|
90 | const joinedPath = unwrap(path).join("/")
|
91 | if (isDirectory(path)) return prefix + joinedPath + (joinedPath.length ? "/" : "")
|
92 | return prefix + joinedPath
|
93 | }
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 | export function combine(a: DirectoryPath, b: DistinctivePath): DistinctivePath {
|
104 | return map(p => unwrap(a).concat(p), b)
|
105 | }
|
106 |
|
107 |
|
108 |
|
109 |
|
110 | export function isBranch(branch: Branch, path: DistinctivePath): boolean {
|
111 | return unwrap(path)[0] === branch
|
112 | }
|
113 |
|
114 |
|
115 |
|
116 |
|
117 | export function isDirectory(path: DistinctivePath): path is DirectoryPath {
|
118 | return !!(path as DirectoryPath).directory
|
119 | }
|
120 |
|
121 |
|
122 |
|
123 |
|
124 | export function isFile(path: DistinctivePath): path is FilePath {
|
125 | return !!(path as FilePath).file
|
126 | }
|
127 |
|
128 |
|
129 |
|
130 |
|
131 | export function isRootDirectory(path: DirectoryPath): boolean {
|
132 | return path.directory.length === 0
|
133 | }
|
134 |
|
135 |
|
136 |
|
137 |
|
138 | export function isSameBranch(a: DistinctivePath, b: DistinctivePath): boolean {
|
139 | return unwrap(a)[0] === unwrap(b)[0]
|
140 | }
|
141 |
|
142 |
|
143 |
|
144 |
|
145 | export function isSameKind(a: DistinctivePath, b: DistinctivePath): boolean {
|
146 | if (isDirectory(a) && isDirectory(b)) return true
|
147 | else if (isFile(a) && isFile(b)) return true
|
148 | else return false
|
149 | }
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | export function kind(path: DistinctivePath): Kind {
|
155 | if (isDirectory(path)) return Kind.Directory
|
156 | return Kind.File
|
157 | }
|
158 |
|
159 |
|
160 |
|
161 |
|
162 | export function map(fn: (p: Path) => Path, path: DistinctivePath): DistinctivePath {
|
163 | if (isDirectory(path)) return { directory: fn(path.directory) }
|
164 | else if (isFile(path)) return { file: fn(path.file) }
|
165 | return path
|
166 | }
|
167 |
|
168 |
|
169 |
|
170 |
|
171 | export function parent(path: DistinctivePath): Maybe<DirectoryPath> {
|
172 | return isDirectory(path) && isRootDirectory(path as DirectoryPath)
|
173 | ? null
|
174 | : directory(...unwrap(path).slice(0, -1))
|
175 | }
|
176 |
|
177 |
|
178 |
|
179 |
|
180 | export function removeBranch(path: DistinctivePath): DistinctivePath {
|
181 | return map(
|
182 | p => isDirectory(path) || p.length > 1 ? p.slice(1) : p,
|
183 | path
|
184 | )
|
185 | }
|
186 |
|
187 |
|
188 |
|
189 |
|
190 | export function unwrap(path: DistinctivePath): Path {
|
191 | if (isDirectory(path)) {
|
192 | return path.directory
|
193 | } else if (isFile(path)) {
|
194 | return path.file
|
195 | }
|
196 |
|
197 | return []
|
198 | }
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 | export function log(path: Path): string {
|
209 | return `[ ${path.join(", ")} ]`
|
210 | }
|