@tui-sandbox/library 11.11.2 → 12.0.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/dist/browser/assets/index-CYUPHpRk.css +1 -0
- package/dist/browser/assets/index-DPQpUaDL.js +9 -0
- package/dist/browser/index.html +2 -2
- package/dist/src/browser/neovim-client.d.ts +2 -0
- package/dist/src/browser/neovim-client.js +2 -0
- package/dist/src/browser/neovim-client.js.map +1 -1
- package/dist/src/client/index.d.ts +1 -0
- package/dist/src/client/neovim-terminal-client.d.ts +0 -2
- package/dist/src/client/neovim-terminal-client.js +0 -2
- package/dist/src/client/neovim-terminal-client.js.map +1 -1
- package/dist/src/client/startTerminal.d.ts +0 -2
- package/dist/src/client/startTerminal.js +0 -2
- package/dist/src/client/startTerminal.js.map +1 -1
- package/dist/src/client/terminal-terminal-client.d.ts +0 -1
- package/dist/src/client/terminal-terminal-client.js +0 -1
- package/dist/src/client/terminal-terminal-client.js.map +1 -1
- package/dist/src/server/cypress-support/contents.js +9 -11
- package/dist/src/server/cypress-support/contents.js.map +1 -1
- package/dist/src/server/index.d.ts +4 -0
- package/dist/src/server/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +34 -8
- package/CHANGELOG.md +0 -941
- package/dist/browser/assets/index-BQzArJW3.js +0 -9
- package/dist/browser/assets/index-hkmOP7rU.css +0 -1
- package/index.html +0 -11
- package/src/browser/neovim-client.ts +0 -126
- package/src/client/MyNeovimConfigModification.test.ts +0 -25
- package/src/client/MyNeovimConfigModification.ts +0 -8
- package/src/client/color-utilities.test.ts +0 -10
- package/src/client/color-utilities.ts +0 -9
- package/src/client/cypress-assertions.ts +0 -35
- package/src/client/index.ts +0 -4
- package/src/client/neovim-terminal-client.ts +0 -130
- package/src/client/public/DejaVuSansMNerdFontMono-Regular.ttf +0 -0
- package/src/client/startTerminal.ts +0 -97
- package/src/client/style.css +0 -32
- package/src/client/terminal-config.ts +0 -25
- package/src/client/terminal-terminal-client.ts +0 -106
- package/src/client/validateMouseEvent.ts +0 -22
- package/src/scripts/commands/commandRun.ts +0 -68
- package/src/scripts/commands/commandTuiNeovimExec.ts +0 -36
- package/src/scripts/commands/commandTuiNeovimPrepare.ts +0 -12
- package/src/scripts/commands/commandTuiStart.ts +0 -36
- package/src/scripts/parseArguments.test.ts +0 -28
- package/src/scripts/parseArguments.ts +0 -66
- package/src/scripts/resolveConfig.test.ts +0 -78
- package/src/scripts/resolveTuiConfig.ts +0 -65
- package/src/scripts/tui.ts +0 -77
- package/src/server/TestServer.ts +0 -73
- package/src/server/applications/neovim/NeovimApplication.ts +0 -236
- package/src/server/applications/neovim/NeovimJavascriptApiClient.test.ts +0 -48
- package/src/server/applications/neovim/NeovimJavascriptApiClient.ts +0 -68
- package/src/server/applications/neovim/api.ts +0 -257
- package/src/server/applications/neovim/environment/TempDirectory.ts +0 -18
- package/src/server/applications/neovim/environment/createTempDir.test.ts +0 -29
- package/src/server/applications/neovim/environment/createTempDir.ts +0 -91
- package/src/server/applications/neovim/neovimRouter.ts +0 -100
- package/src/server/applications/neovim/prepareNewTestDirectory.test.ts +0 -32
- package/src/server/applications/neovim/prepareNewTestDirectory.ts +0 -21
- package/src/server/applications/terminal/TerminalTestApplication.ts +0 -101
- package/src/server/applications/terminal/api.ts +0 -89
- package/src/server/applications/terminal/runBlockingShellCommand.test.ts +0 -41
- package/src/server/applications/terminal/runBlockingShellCommand.ts +0 -64
- package/src/server/applications/terminal/terminalRouter.ts +0 -47
- package/src/server/blockingCommandInputSchema.test.ts +0 -24
- package/src/server/blockingCommandInputSchema.ts +0 -27
- package/src/server/config.test.ts +0 -7
- package/src/server/config.ts +0 -18
- package/src/server/connection/trpc.ts +0 -3
- package/src/server/cypress-support/contents.ts +0 -245
- package/src/server/cypress-support/createCypressSupportFile.test.ts +0 -69
- package/src/server/cypress-support/createCypressSupportFile.ts +0 -56
- package/src/server/dirtree/index.test.ts +0 -352
- package/src/server/dirtree/index.ts +0 -144
- package/src/server/dirtree/json-to-zod.ts +0 -60
- package/src/server/index.ts +0 -6
- package/src/server/server.ts +0 -34
- package/src/server/types.ts +0 -98
- package/src/server/updateTestdirectorySchemaFile.test.ts +0 -49
- package/src/server/updateTestdirectorySchemaFile.ts +0 -71
- package/src/server/utilities/DisposableSingleApplication.test.ts +0 -92
- package/src/server/utilities/DisposableSingleApplication.ts +0 -49
- package/src/server/utilities/Lazy.ts +0 -16
- package/src/server/utilities/TerminalApplication.ts +0 -100
- package/src/server/utilities/generator.test.ts +0 -50
- package/src/server/utilities/generator.ts +0 -12
- package/src/server/utilities/tabId.ts +0 -4
- package/src/server/utilities/timeout.ts +0 -3
- package/src/server/utilities/timeoutable.ts +0 -19
- package/tsconfig.json +0 -31
- package/vite.config.js +0 -27
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
import assert from "assert"
|
|
2
|
-
import path from "path"
|
|
3
|
-
import { describe, expect, it } from "vitest"
|
|
4
|
-
import { createDefaultConfig } from "../config.js"
|
|
5
|
-
import type { NeovimIntegrationDefaultAppName, TestServerConfig } from "../updateTestdirectorySchemaFile.js"
|
|
6
|
-
import { Lazy } from "../utilities/Lazy.js"
|
|
7
|
-
import { buildSchemaForDirectoryTree, getDirectoryTree } from "./index.js"
|
|
8
|
-
|
|
9
|
-
describe("dirtree", () => {
|
|
10
|
-
const output = new Lazy(() =>
|
|
11
|
-
getDirectoryTree(path.join(__dirname, "..", "..", "..", "..", "integration-tests", "test-environment"))
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
it("can get a list of all the files", () => {
|
|
15
|
-
const result = output.get().allFiles
|
|
16
|
-
|
|
17
|
-
assert(result)
|
|
18
|
-
expect(result.length).toBeGreaterThan(1)
|
|
19
|
-
assert(result[0])
|
|
20
|
-
expect(result[0].relativePath).toBeTruthy()
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it("should be able to build a typescript type for the tree", async () => {
|
|
24
|
-
const config: TestServerConfig = {
|
|
25
|
-
...createDefaultConfig("/my/root/path", {}),
|
|
26
|
-
integrations: {
|
|
27
|
-
neovim: {
|
|
28
|
-
NVIM_APPNAMEs: ["nvim" satisfies NeovimIntegrationDefaultAppName, "nvim_alt"],
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
const result = await buildSchemaForDirectoryTree(output.get(), "MyDirectoryTree", config)
|
|
33
|
-
|
|
34
|
-
expect(result).toMatchInlineSnapshot(`
|
|
35
|
-
"
|
|
36
|
-
// Note: This file is autogenerated. Do not edit it directly.
|
|
37
|
-
//
|
|
38
|
-
// Describes the contents of the test directory, which is a blueprint for
|
|
39
|
-
// files and directories. Tests can create a unique, safe environment for
|
|
40
|
-
// interacting with the contents of such a directory.
|
|
41
|
-
//
|
|
42
|
-
// Having strong typing for the test directory contents ensures that tests can
|
|
43
|
-
// be written with confidence that the files and directories they expect are
|
|
44
|
-
// actually found. Otherwise the tests are brittle and can break easily.
|
|
45
|
-
|
|
46
|
-
import * as z from "zod"
|
|
47
|
-
|
|
48
|
-
export const MyDirectoryTreeSchema = z.object({
|
|
49
|
-
name: z.literal("test-environment/"),
|
|
50
|
-
type: z.literal("directory"),
|
|
51
|
-
contents: z.object({
|
|
52
|
-
".bashrc": z.object({ name: z.literal(".bashrc"), type: z.literal("file") }),
|
|
53
|
-
".config": z.object({
|
|
54
|
-
name: z.literal(".config/"),
|
|
55
|
-
type: z.literal("directory"),
|
|
56
|
-
contents: z.object({
|
|
57
|
-
".gitkeep": z.object({ name: z.literal(".gitkeep"), type: z.literal("file") }),
|
|
58
|
-
nvim: z.object({
|
|
59
|
-
name: z.literal("nvim/"),
|
|
60
|
-
type: z.literal("directory"),
|
|
61
|
-
contents: z.object({
|
|
62
|
-
"init.lua": z.object({ name: z.literal("init.lua"), type: z.literal("file") }),
|
|
63
|
-
"prepare.lua": z.object({ name: z.literal("prepare.lua"), type: z.literal("file") }),
|
|
64
|
-
}),
|
|
65
|
-
}),
|
|
66
|
-
nvim_alt: z.object({
|
|
67
|
-
name: z.literal("nvim_alt/"),
|
|
68
|
-
type: z.literal("directory"),
|
|
69
|
-
contents: z.object({
|
|
70
|
-
"init.lua": z.object({ name: z.literal("init.lua"), type: z.literal("file") }),
|
|
71
|
-
"prepare.lua": z.object({ name: z.literal("prepare.lua"), type: z.literal("file") }),
|
|
72
|
-
}),
|
|
73
|
-
}),
|
|
74
|
-
}),
|
|
75
|
-
}),
|
|
76
|
-
"config-modifications": z.object({
|
|
77
|
-
name: z.literal("config-modifications/"),
|
|
78
|
-
type: z.literal("directory"),
|
|
79
|
-
contents: z.object({
|
|
80
|
-
"add_command_to_count_open_buffers.lua": z.object({
|
|
81
|
-
name: z.literal("add_command_to_count_open_buffers.lua"),
|
|
82
|
-
type: z.literal("file"),
|
|
83
|
-
}),
|
|
84
|
-
"add_command_to_update_buffer_after_timeout.lua": z.object({
|
|
85
|
-
name: z.literal("add_command_to_update_buffer_after_timeout.lua"),
|
|
86
|
-
type: z.literal("file"),
|
|
87
|
-
}),
|
|
88
|
-
"don't_crash_when_modification_contains_unescaped_characters\\".lua": z.object({
|
|
89
|
-
name: z.literal("don't_crash_when_modification_contains_unescaped_characters\\".lua"),
|
|
90
|
-
type: z.literal("file"),
|
|
91
|
-
}),
|
|
92
|
-
subdir: z.object({
|
|
93
|
-
name: z.literal("subdir/"),
|
|
94
|
-
type: z.literal("directory"),
|
|
95
|
-
contents: z.object({
|
|
96
|
-
"subdir-modification.lua": z.object({
|
|
97
|
-
name: z.literal("subdir-modification.lua"),
|
|
98
|
-
type: z.literal("file"),
|
|
99
|
-
}),
|
|
100
|
-
}),
|
|
101
|
-
}),
|
|
102
|
-
}),
|
|
103
|
-
}),
|
|
104
|
-
"dir with spaces": z.object({
|
|
105
|
-
name: z.literal("dir with spaces/"),
|
|
106
|
-
type: z.literal("directory"),
|
|
107
|
-
contents: z.object({
|
|
108
|
-
"file1.txt": z.object({ name: z.literal("file1.txt"), type: z.literal("file") }),
|
|
109
|
-
"file2.txt": z.object({ name: z.literal("file2.txt"), type: z.literal("file") }),
|
|
110
|
-
}),
|
|
111
|
-
}),
|
|
112
|
-
"file.txt": z.object({ name: z.literal("file.txt"), type: z.literal("file") }),
|
|
113
|
-
"initial-file.txt": z.object({ name: z.literal("initial-file.txt"), type: z.literal("file") }),
|
|
114
|
-
"lua-project": z.object({
|
|
115
|
-
name: z.literal("lua-project/"),
|
|
116
|
-
type: z.literal("directory"),
|
|
117
|
-
contents: z.object({
|
|
118
|
-
".luarc.json": z.object({ name: z.literal(".luarc.json"), type: z.literal("file") }),
|
|
119
|
-
"config.lua": z.object({ name: z.literal("config.lua"), type: z.literal("file") }),
|
|
120
|
-
"init.lua": z.object({ name: z.literal("init.lua"), type: z.literal("file") }),
|
|
121
|
-
}),
|
|
122
|
-
}),
|
|
123
|
-
"other-subdirectory": z.object({
|
|
124
|
-
name: z.literal("other-subdirectory/"),
|
|
125
|
-
type: z.literal("directory"),
|
|
126
|
-
contents: z.object({
|
|
127
|
-
"other-sub-file.txt": z.object({ name: z.literal("other-sub-file.txt"), type: z.literal("file") }),
|
|
128
|
-
}),
|
|
129
|
-
}),
|
|
130
|
-
routes: z.object({
|
|
131
|
-
name: z.literal("routes/"),
|
|
132
|
-
type: z.literal("directory"),
|
|
133
|
-
contents: z.object({
|
|
134
|
-
"posts.$postId": z.object({
|
|
135
|
-
name: z.literal("posts.$postId/"),
|
|
136
|
-
type: z.literal("directory"),
|
|
137
|
-
contents: z.object({
|
|
138
|
-
"adjacent-file.txt": z.object({ name: z.literal("adjacent-file.txt"), type: z.literal("file") }),
|
|
139
|
-
"route.tsx": z.object({ name: z.literal("route.tsx"), type: z.literal("file") }),
|
|
140
|
-
"should-be-excluded-file.txt": z.object({
|
|
141
|
-
name: z.literal("should-be-excluded-file.txt"),
|
|
142
|
-
type: z.literal("file"),
|
|
143
|
-
}),
|
|
144
|
-
}),
|
|
145
|
-
}),
|
|
146
|
-
}),
|
|
147
|
-
}),
|
|
148
|
-
subdirectory: z.object({
|
|
149
|
-
name: z.literal("subdirectory/"),
|
|
150
|
-
type: z.literal("directory"),
|
|
151
|
-
contents: z.object({
|
|
152
|
-
"subdirectory-file.txt": z.object({ name: z.literal("subdirectory-file.txt"), type: z.literal("file") }),
|
|
153
|
-
}),
|
|
154
|
-
}),
|
|
155
|
-
"symlink-target.txt": z.object({
|
|
156
|
-
name: z.literal("symlink-target.txt"),
|
|
157
|
-
type: z.literal("file-symlink"),
|
|
158
|
-
target: z.literal("symlink-test/symlink-target.txt"),
|
|
159
|
-
}),
|
|
160
|
-
"symlink-test": z.object({
|
|
161
|
-
name: z.literal("symlink-test/"),
|
|
162
|
-
type: z.literal("directory"),
|
|
163
|
-
contents: z.object({
|
|
164
|
-
"symlink-target.txt": z.object({ name: z.literal("symlink-target.txt"), type: z.literal("file") }),
|
|
165
|
-
}),
|
|
166
|
-
}),
|
|
167
|
-
}),
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
export const MyDirectoryTreeContentsSchema = MyDirectoryTreeSchema.shape.contents
|
|
171
|
-
export type MyDirectoryTreeContentsSchemaType = z.infer<typeof MyDirectoryTreeSchema>
|
|
172
|
-
|
|
173
|
-
export type MyDirectoryTree = MyDirectoryTreeContentsSchemaType["contents"]
|
|
174
|
-
|
|
175
|
-
export const testDirectoryFiles = z.enum([
|
|
176
|
-
".bashrc",
|
|
177
|
-
".config/.gitkeep",
|
|
178
|
-
".config/nvim/init.lua",
|
|
179
|
-
".config/nvim/prepare.lua",
|
|
180
|
-
".config/nvim",
|
|
181
|
-
".config/nvim_alt/init.lua",
|
|
182
|
-
".config/nvim_alt/prepare.lua",
|
|
183
|
-
".config/nvim_alt",
|
|
184
|
-
".config",
|
|
185
|
-
"config-modifications/add_command_to_count_open_buffers.lua",
|
|
186
|
-
"config-modifications/add_command_to_update_buffer_after_timeout.lua",
|
|
187
|
-
"config-modifications/don't_crash_when_modification_contains_unescaped_characters\\".lua",
|
|
188
|
-
"config-modifications/subdir/subdir-modification.lua",
|
|
189
|
-
"config-modifications/subdir",
|
|
190
|
-
"config-modifications",
|
|
191
|
-
"dir with spaces/file1.txt",
|
|
192
|
-
"dir with spaces/file2.txt",
|
|
193
|
-
"dir with spaces",
|
|
194
|
-
"file.txt",
|
|
195
|
-
"initial-file.txt",
|
|
196
|
-
"lua-project/.luarc.json",
|
|
197
|
-
"lua-project/config.lua",
|
|
198
|
-
"lua-project/init.lua",
|
|
199
|
-
"lua-project",
|
|
200
|
-
"other-subdirectory/other-sub-file.txt",
|
|
201
|
-
"other-subdirectory",
|
|
202
|
-
"routes/posts.$postId/adjacent-file.txt",
|
|
203
|
-
"routes/posts.$postId/route.tsx",
|
|
204
|
-
"routes/posts.$postId/should-be-excluded-file.txt",
|
|
205
|
-
"routes/posts.$postId",
|
|
206
|
-
"routes",
|
|
207
|
-
"subdirectory/subdirectory-file.txt",
|
|
208
|
-
"subdirectory",
|
|
209
|
-
"symlink-target.txt",
|
|
210
|
-
"symlink-test/symlink-target.txt",
|
|
211
|
-
"symlink-test",
|
|
212
|
-
"."
|
|
213
|
-
])
|
|
214
|
-
export type MyTestDirectoryFile = z.infer<typeof testDirectoryFiles>
|
|
215
|
-
export type MyNeovimAppName = "nvim" | "nvim_alt""
|
|
216
|
-
`)
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
it("creates an empty schema when the directory cannot be read", async () => {
|
|
220
|
-
const config: TestServerConfig = createDefaultConfig("/my/root/path", {})
|
|
221
|
-
const tree = getDirectoryTree("nonexistent")
|
|
222
|
-
const result = await buildSchemaForDirectoryTree(tree, "MyDirectoryTree", config)
|
|
223
|
-
expect(result).toMatchInlineSnapshot(`
|
|
224
|
-
"
|
|
225
|
-
// Note: This file is autogenerated. Do not edit it directly.
|
|
226
|
-
//
|
|
227
|
-
// Describes the contents of the test directory, which is a blueprint for
|
|
228
|
-
// files and directories. Tests can create a unique, safe environment for
|
|
229
|
-
// interacting with the contents of such a directory.
|
|
230
|
-
//
|
|
231
|
-
// Having strong typing for the test directory contents ensures that tests can
|
|
232
|
-
// be written with confidence that the files and directories they expect are
|
|
233
|
-
// actually found. Otherwise the tests are brittle and can break easily.
|
|
234
|
-
|
|
235
|
-
import * as z from "zod"
|
|
236
|
-
|
|
237
|
-
export const MyDirectoryTreeSchema = z.object({
|
|
238
|
-
type: z.literal("directory"),
|
|
239
|
-
name: z.literal("root"),
|
|
240
|
-
contents: z.object({}),
|
|
241
|
-
})
|
|
242
|
-
|
|
243
|
-
export const MyDirectoryTreeContentsSchema = MyDirectoryTreeSchema.shape.contents
|
|
244
|
-
export type MyDirectoryTreeContentsSchemaType = z.infer<typeof MyDirectoryTreeSchema>
|
|
245
|
-
|
|
246
|
-
export type MyDirectoryTree = MyDirectoryTreeContentsSchemaType["contents"]
|
|
247
|
-
|
|
248
|
-
export const testDirectoryFiles = z.enum([])
|
|
249
|
-
export type MyTestDirectoryFile = z.infer<typeof testDirectoryFiles>
|
|
250
|
-
export type MyNeovimAppName = "nvim""
|
|
251
|
-
`)
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
describe("provides type-safe access to NVIM_APPNAMEs", () => {
|
|
255
|
-
// the user can configure the NVIM_APPNAMEs they are using in their
|
|
256
|
-
// configuration. These should be available for them in a type-safe manner so
|
|
257
|
-
// that they have the least possible friction when coding.
|
|
258
|
-
//
|
|
259
|
-
const smallDirectory = path.resolve(__dirname, "../../../../integration-tests/test-environment/other-subdirectory/")
|
|
260
|
-
|
|
261
|
-
it("when there is a single name", async () => {
|
|
262
|
-
const config: TestServerConfig = createDefaultConfig("/my/root/path", {})
|
|
263
|
-
assert(config.integrations.neovim.NVIM_APPNAMEs.length === 1)
|
|
264
|
-
const tinytree = getDirectoryTree(smallDirectory)
|
|
265
|
-
const result = await buildSchemaForDirectoryTree(tinytree, "MyDirectoryTree", config)
|
|
266
|
-
|
|
267
|
-
expect(result).toMatchInlineSnapshot(`
|
|
268
|
-
"
|
|
269
|
-
// Note: This file is autogenerated. Do not edit it directly.
|
|
270
|
-
//
|
|
271
|
-
// Describes the contents of the test directory, which is a blueprint for
|
|
272
|
-
// files and directories. Tests can create a unique, safe environment for
|
|
273
|
-
// interacting with the contents of such a directory.
|
|
274
|
-
//
|
|
275
|
-
// Having strong typing for the test directory contents ensures that tests can
|
|
276
|
-
// be written with confidence that the files and directories they expect are
|
|
277
|
-
// actually found. Otherwise the tests are brittle and can break easily.
|
|
278
|
-
|
|
279
|
-
import * as z from "zod"
|
|
280
|
-
|
|
281
|
-
export const MyDirectoryTreeSchema = z.object({
|
|
282
|
-
name: z.literal("other-subdirectory/"),
|
|
283
|
-
type: z.literal("directory"),
|
|
284
|
-
contents: z.object({
|
|
285
|
-
"other-sub-file.txt": z.object({ name: z.literal("other-sub-file.txt"), type: z.literal("file") }),
|
|
286
|
-
}),
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
export const MyDirectoryTreeContentsSchema = MyDirectoryTreeSchema.shape.contents
|
|
290
|
-
export type MyDirectoryTreeContentsSchemaType = z.infer<typeof MyDirectoryTreeSchema>
|
|
291
|
-
|
|
292
|
-
export type MyDirectoryTree = MyDirectoryTreeContentsSchemaType["contents"]
|
|
293
|
-
|
|
294
|
-
export const testDirectoryFiles = z.enum([
|
|
295
|
-
"other-sub-file.txt",
|
|
296
|
-
"."
|
|
297
|
-
])
|
|
298
|
-
export type MyTestDirectoryFile = z.infer<typeof testDirectoryFiles>
|
|
299
|
-
export type MyNeovimAppName = "nvim""
|
|
300
|
-
`)
|
|
301
|
-
// 👆🏻 from the default config
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
it("when there are multiple names", async () => {
|
|
305
|
-
const config: TestServerConfig = {
|
|
306
|
-
...createDefaultConfig("/my/root/path", {}),
|
|
307
|
-
integrations: {
|
|
308
|
-
neovim: {
|
|
309
|
-
NVIM_APPNAMEs: ["nvim" satisfies NeovimIntegrationDefaultAppName, "nvim_alt"],
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
}
|
|
313
|
-
const tinytree = getDirectoryTree(smallDirectory)
|
|
314
|
-
const result = await buildSchemaForDirectoryTree(tinytree, "MyDirectoryTree", config)
|
|
315
|
-
|
|
316
|
-
expect(result).toMatchInlineSnapshot(`
|
|
317
|
-
"
|
|
318
|
-
// Note: This file is autogenerated. Do not edit it directly.
|
|
319
|
-
//
|
|
320
|
-
// Describes the contents of the test directory, which is a blueprint for
|
|
321
|
-
// files and directories. Tests can create a unique, safe environment for
|
|
322
|
-
// interacting with the contents of such a directory.
|
|
323
|
-
//
|
|
324
|
-
// Having strong typing for the test directory contents ensures that tests can
|
|
325
|
-
// be written with confidence that the files and directories they expect are
|
|
326
|
-
// actually found. Otherwise the tests are brittle and can break easily.
|
|
327
|
-
|
|
328
|
-
import * as z from "zod"
|
|
329
|
-
|
|
330
|
-
export const MyDirectoryTreeSchema = z.object({
|
|
331
|
-
name: z.literal("other-subdirectory/"),
|
|
332
|
-
type: z.literal("directory"),
|
|
333
|
-
contents: z.object({
|
|
334
|
-
"other-sub-file.txt": z.object({ name: z.literal("other-sub-file.txt"), type: z.literal("file") }),
|
|
335
|
-
}),
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
export const MyDirectoryTreeContentsSchema = MyDirectoryTreeSchema.shape.contents
|
|
339
|
-
export type MyDirectoryTreeContentsSchemaType = z.infer<typeof MyDirectoryTreeSchema>
|
|
340
|
-
|
|
341
|
-
export type MyDirectoryTree = MyDirectoryTreeContentsSchemaType["contents"]
|
|
342
|
-
|
|
343
|
-
export const testDirectoryFiles = z.enum([
|
|
344
|
-
"other-sub-file.txt",
|
|
345
|
-
"."
|
|
346
|
-
])
|
|
347
|
-
export type MyTestDirectoryFile = z.infer<typeof testDirectoryFiles>
|
|
348
|
-
export type MyNeovimAppName = "nvim" | "nvim_alt""
|
|
349
|
-
`)
|
|
350
|
-
})
|
|
351
|
-
})
|
|
352
|
-
})
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import assert from "assert"
|
|
2
|
-
import type { Dree } from "dree"
|
|
3
|
-
import { scan, Type } from "dree"
|
|
4
|
-
import { readlinkSync } from "fs"
|
|
5
|
-
import { format, resolveConfig } from "prettier"
|
|
6
|
-
import { fileURLToPath } from "url"
|
|
7
|
-
import { debuglog } from "util"
|
|
8
|
-
import type { TestServerConfig } from "../updateTestdirectorySchemaFile.js"
|
|
9
|
-
import { jsonToZod } from "./json-to-zod.js"
|
|
10
|
-
|
|
11
|
-
const log = debuglog("tui-sandbox.dirtree")
|
|
12
|
-
type TreeResult = { dree: Dree | undefined; allFiles: Dree[] }
|
|
13
|
-
|
|
14
|
-
/** Convert a directory tree to a TypeScript type. This is useful for testing
|
|
15
|
-
* as the initial state of the test directory is fully known in tests. */
|
|
16
|
-
export function getDirectoryTree(path: string): TreeResult {
|
|
17
|
-
const allFiles: Dree[] = []
|
|
18
|
-
const result = scan(
|
|
19
|
-
path,
|
|
20
|
-
{
|
|
21
|
-
exclude: [/.repro/, /testdirs/],
|
|
22
|
-
hash: false,
|
|
23
|
-
size: false,
|
|
24
|
-
sizeInBytes: false,
|
|
25
|
-
},
|
|
26
|
-
file => {
|
|
27
|
-
allFiles.push(file)
|
|
28
|
-
},
|
|
29
|
-
dir => {
|
|
30
|
-
allFiles.push(dir)
|
|
31
|
-
}
|
|
32
|
-
) as Dree | null // https://github.com/euberdeveloper/dree/pull/51
|
|
33
|
-
|
|
34
|
-
return { dree: result ?? undefined, allFiles }
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
type TreeNode = FileNode | FileSymlinkNode | DirectoryNode
|
|
38
|
-
|
|
39
|
-
type FileNode = {
|
|
40
|
-
type: "file"
|
|
41
|
-
name: string
|
|
42
|
-
}
|
|
43
|
-
type FileSymlinkNode = {
|
|
44
|
-
type: "file-symlink"
|
|
45
|
-
name: string
|
|
46
|
-
/** The target of the symlink, a filepath. */
|
|
47
|
-
target: string
|
|
48
|
-
}
|
|
49
|
-
type DirectoryNode = {
|
|
50
|
-
type: "directory"
|
|
51
|
-
name: string
|
|
52
|
-
contents: Record<string, TreeNode>
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function convertDree(root: Dree | undefined): TreeNode {
|
|
56
|
-
if (!root) {
|
|
57
|
-
return { type: Type.DIRECTORY, name: "root", contents: {} }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (root.type === Type.FILE) {
|
|
61
|
-
if (root.isSymbolicLink) {
|
|
62
|
-
const target = readlinkSync(root.path)
|
|
63
|
-
return {
|
|
64
|
-
name: root.name,
|
|
65
|
-
type: "file-symlink",
|
|
66
|
-
target,
|
|
67
|
-
} satisfies FileSymlinkNode
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
name: root.name,
|
|
72
|
-
type: root.type,
|
|
73
|
-
} satisfies FileNode
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const node: DirectoryNode = {
|
|
77
|
-
name: `${root.name}/`,
|
|
78
|
-
type: root.type,
|
|
79
|
-
contents: {},
|
|
80
|
-
}
|
|
81
|
-
for (const child of root.children || []) {
|
|
82
|
-
node.contents[child.name] = convertDree(child)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return node
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export async function buildSchemaForDirectoryTree(
|
|
89
|
-
result: TreeResult,
|
|
90
|
-
name: string,
|
|
91
|
-
config: TestServerConfig
|
|
92
|
-
): Promise<string> {
|
|
93
|
-
const root = convertDree(result.dree)
|
|
94
|
-
|
|
95
|
-
const schema = (await jsonToZod(root, `${name}Schema`)).split("\n")
|
|
96
|
-
|
|
97
|
-
const lines = `
|
|
98
|
-
// Note: This file is autogenerated. Do not edit it directly.
|
|
99
|
-
//
|
|
100
|
-
// Describes the contents of the test directory, which is a blueprint for
|
|
101
|
-
// files and directories. Tests can create a unique, safe environment for
|
|
102
|
-
// interacting with the contents of such a directory.
|
|
103
|
-
//
|
|
104
|
-
// Having strong typing for the test directory contents ensures that tests can
|
|
105
|
-
// be written with confidence that the files and directories they expect are
|
|
106
|
-
// actually found. Otherwise the tests are brittle and can break easily.
|
|
107
|
-
`.split("\n")
|
|
108
|
-
|
|
109
|
-
const allFilePaths = result.allFiles.map(f => f.relativePath)
|
|
110
|
-
const ContentsSchema = `${name}ContentsSchema`
|
|
111
|
-
const ContentsSchemaType = `${name}ContentsSchemaType`
|
|
112
|
-
|
|
113
|
-
assert(config.integrations.neovim.NVIM_APPNAMEs.length > 0, "At least one NVIM_APPNAME must be configured")
|
|
114
|
-
const NVIM_APPNAMEsUnion =
|
|
115
|
-
config.integrations.neovim.NVIM_APPNAMEs.length > 1
|
|
116
|
-
? config.integrations.neovim.NVIM_APPNAMEs.map(a => `"${a}"`).join(" | ")
|
|
117
|
-
: `"${config.integrations.neovim.NVIM_APPNAMEs[0]}"`
|
|
118
|
-
|
|
119
|
-
return [
|
|
120
|
-
...lines,
|
|
121
|
-
...schema,
|
|
122
|
-
`export const ${ContentsSchema} = ${name}Schema.shape.contents`,
|
|
123
|
-
`export type ${ContentsSchemaType} = z.infer<typeof ${name}Schema>`,
|
|
124
|
-
"",
|
|
125
|
-
`export type ${name} = ${ContentsSchemaType}["contents"]`,
|
|
126
|
-
"",
|
|
127
|
-
`export const testDirectoryFiles = z.enum(${JSON.stringify(allFilePaths, null, 2)})`,
|
|
128
|
-
`export type MyTestDirectoryFile = z.infer<typeof testDirectoryFiles>`,
|
|
129
|
-
`export type MyNeovimAppName = ${NVIM_APPNAMEsUnion}`,
|
|
130
|
-
].join("\n")
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
134
|
-
|
|
135
|
-
export async function buildTestDirectorySchema(config: TestServerConfig): Promise<string> {
|
|
136
|
-
log("Building schema for test directory", config.directories.testEnvironmentPath)
|
|
137
|
-
const dree = getDirectoryTree(config.directories.testEnvironmentPath)
|
|
138
|
-
let text = await buildSchemaForDirectoryTree(dree, "MyTestDirectory", config)
|
|
139
|
-
|
|
140
|
-
const options = await resolveConfig(__filename)
|
|
141
|
-
text = await format(text, { ...options, parser: "typescript" })
|
|
142
|
-
|
|
143
|
-
return text
|
|
144
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { format, resolveConfig } from "prettier"
|
|
2
|
-
import babelParser from "prettier/parser-babel"
|
|
3
|
-
import { fileURLToPath } from "url"
|
|
4
|
-
|
|
5
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
6
|
-
|
|
7
|
-
export async function jsonToZod(object: unknown, name: string = "schema"): Promise<string> {
|
|
8
|
-
const parse = (o: unknown, seen: object[]): string => {
|
|
9
|
-
switch (typeof o) {
|
|
10
|
-
case "string":
|
|
11
|
-
return `z.literal("${o.replaceAll('"', `\\"`)}")`
|
|
12
|
-
case "number":
|
|
13
|
-
return "z.number()"
|
|
14
|
-
case "bigint":
|
|
15
|
-
return "z.number().int()"
|
|
16
|
-
case "boolean":
|
|
17
|
-
return "z.boolean()"
|
|
18
|
-
case "object":
|
|
19
|
-
if (o === null) {
|
|
20
|
-
return "z.null()"
|
|
21
|
-
}
|
|
22
|
-
if (seen.find(_obj => Object.is(_obj, o))) {
|
|
23
|
-
throw new Error("Circular objects are not supported")
|
|
24
|
-
}
|
|
25
|
-
seen.push(o)
|
|
26
|
-
if (Array.isArray(o)) {
|
|
27
|
-
const options = o
|
|
28
|
-
.map(obj => parse(obj, seen))
|
|
29
|
-
.reduce((acc: string[], curr: string) => (acc.includes(curr) ? acc : [...acc, curr]), [])
|
|
30
|
-
if (options.length === 1) {
|
|
31
|
-
return `z.array(${options[0]})`
|
|
32
|
-
} else if (options.length > 1) {
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
34
|
-
return `z.array(z.union([${options}]))`
|
|
35
|
-
} else {
|
|
36
|
-
return `z.array(z.unknown())`
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
40
|
-
return `z.object({${Object.entries(o).map(([k, v]) => {
|
|
41
|
-
const key = k.replaceAll("'", "\\'")
|
|
42
|
-
return `'${key}':${parse(v, seen)}`
|
|
43
|
-
})}})`
|
|
44
|
-
case "undefined":
|
|
45
|
-
return "z.undefined()"
|
|
46
|
-
case "function":
|
|
47
|
-
return "z.function()"
|
|
48
|
-
case "symbol":
|
|
49
|
-
default:
|
|
50
|
-
return "z.unknown()"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
const prettierConfig = await resolveConfig(__filename)
|
|
54
|
-
|
|
55
|
-
return format(`import * as z from "zod"\n\nexport const ${name}=${parse(object, [])}`, {
|
|
56
|
-
...prettierConfig,
|
|
57
|
-
parser: "babel",
|
|
58
|
-
plugins: [babelParser],
|
|
59
|
-
})
|
|
60
|
-
}
|
package/src/server/index.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// This is the public server api. Semantic versioning will be applied to this.
|
|
2
|
-
|
|
3
|
-
export { startTestServer } from "./server.js"
|
|
4
|
-
export { updateTestdirectorySchemaFile } from "./updateTestdirectorySchemaFile.js"
|
|
5
|
-
export type { TestServerConfig } from "./updateTestdirectorySchemaFile.js"
|
|
6
|
-
export { Lazy } from "./utilities/Lazy.js"
|
package/src/server/server.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { inferRouterInputs } from "@trpc/server"
|
|
2
|
-
import { createNeovimRouter } from "./applications/neovim/neovimRouter.js"
|
|
3
|
-
import { createTerminalRouter } from "./applications/terminal/terminalRouter.js"
|
|
4
|
-
import { trpc } from "./connection/trpc.js"
|
|
5
|
-
import { TestServer } from "./TestServer.js"
|
|
6
|
-
import type { TestServerConfig } from "./updateTestdirectorySchemaFile.js"
|
|
7
|
-
|
|
8
|
-
/** @private */
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
10
|
-
export async function createAppRouter(config: TestServerConfig) {
|
|
11
|
-
const appRouter = trpc.router({
|
|
12
|
-
terminal: createTerminalRouter(config),
|
|
13
|
-
neovim: createNeovimRouter(config),
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
return appRouter
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type AppRouter = Awaited<ReturnType<typeof createAppRouter>>
|
|
20
|
-
export type RouterInput = inferRouterInputs<AppRouter>
|
|
21
|
-
|
|
22
|
-
export async function startTestServer(config: TestServerConfig): Promise<void> {
|
|
23
|
-
try {
|
|
24
|
-
const testServer = new TestServer({
|
|
25
|
-
port: config.port,
|
|
26
|
-
})
|
|
27
|
-
const appRouter = await createAppRouter(config)
|
|
28
|
-
|
|
29
|
-
await testServer.startAndRun(appRouter)
|
|
30
|
-
} catch (err: unknown) {
|
|
31
|
-
console.error("Error starting test server", err)
|
|
32
|
-
throw err
|
|
33
|
-
}
|
|
34
|
-
}
|