@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.
Files changed (92) hide show
  1. package/dist/browser/assets/index-CYUPHpRk.css +1 -0
  2. package/dist/browser/assets/index-DPQpUaDL.js +9 -0
  3. package/dist/browser/index.html +2 -2
  4. package/dist/src/browser/neovim-client.d.ts +2 -0
  5. package/dist/src/browser/neovim-client.js +2 -0
  6. package/dist/src/browser/neovim-client.js.map +1 -1
  7. package/dist/src/client/index.d.ts +1 -0
  8. package/dist/src/client/neovim-terminal-client.d.ts +0 -2
  9. package/dist/src/client/neovim-terminal-client.js +0 -2
  10. package/dist/src/client/neovim-terminal-client.js.map +1 -1
  11. package/dist/src/client/startTerminal.d.ts +0 -2
  12. package/dist/src/client/startTerminal.js +0 -2
  13. package/dist/src/client/startTerminal.js.map +1 -1
  14. package/dist/src/client/terminal-terminal-client.d.ts +0 -1
  15. package/dist/src/client/terminal-terminal-client.js +0 -1
  16. package/dist/src/client/terminal-terminal-client.js.map +1 -1
  17. package/dist/src/server/cypress-support/contents.js +9 -11
  18. package/dist/src/server/cypress-support/contents.js.map +1 -1
  19. package/dist/src/server/index.d.ts +4 -0
  20. package/dist/src/server/index.js.map +1 -1
  21. package/dist/tsconfig.tsbuildinfo +1 -1
  22. package/package.json +34 -8
  23. package/CHANGELOG.md +0 -941
  24. package/dist/browser/assets/index-BQzArJW3.js +0 -9
  25. package/dist/browser/assets/index-hkmOP7rU.css +0 -1
  26. package/index.html +0 -11
  27. package/src/browser/neovim-client.ts +0 -126
  28. package/src/client/MyNeovimConfigModification.test.ts +0 -25
  29. package/src/client/MyNeovimConfigModification.ts +0 -8
  30. package/src/client/color-utilities.test.ts +0 -10
  31. package/src/client/color-utilities.ts +0 -9
  32. package/src/client/cypress-assertions.ts +0 -35
  33. package/src/client/index.ts +0 -4
  34. package/src/client/neovim-terminal-client.ts +0 -130
  35. package/src/client/public/DejaVuSansMNerdFontMono-Regular.ttf +0 -0
  36. package/src/client/startTerminal.ts +0 -97
  37. package/src/client/style.css +0 -32
  38. package/src/client/terminal-config.ts +0 -25
  39. package/src/client/terminal-terminal-client.ts +0 -106
  40. package/src/client/validateMouseEvent.ts +0 -22
  41. package/src/scripts/commands/commandRun.ts +0 -68
  42. package/src/scripts/commands/commandTuiNeovimExec.ts +0 -36
  43. package/src/scripts/commands/commandTuiNeovimPrepare.ts +0 -12
  44. package/src/scripts/commands/commandTuiStart.ts +0 -36
  45. package/src/scripts/parseArguments.test.ts +0 -28
  46. package/src/scripts/parseArguments.ts +0 -66
  47. package/src/scripts/resolveConfig.test.ts +0 -78
  48. package/src/scripts/resolveTuiConfig.ts +0 -65
  49. package/src/scripts/tui.ts +0 -77
  50. package/src/server/TestServer.ts +0 -73
  51. package/src/server/applications/neovim/NeovimApplication.ts +0 -236
  52. package/src/server/applications/neovim/NeovimJavascriptApiClient.test.ts +0 -48
  53. package/src/server/applications/neovim/NeovimJavascriptApiClient.ts +0 -68
  54. package/src/server/applications/neovim/api.ts +0 -257
  55. package/src/server/applications/neovim/environment/TempDirectory.ts +0 -18
  56. package/src/server/applications/neovim/environment/createTempDir.test.ts +0 -29
  57. package/src/server/applications/neovim/environment/createTempDir.ts +0 -91
  58. package/src/server/applications/neovim/neovimRouter.ts +0 -100
  59. package/src/server/applications/neovim/prepareNewTestDirectory.test.ts +0 -32
  60. package/src/server/applications/neovim/prepareNewTestDirectory.ts +0 -21
  61. package/src/server/applications/terminal/TerminalTestApplication.ts +0 -101
  62. package/src/server/applications/terminal/api.ts +0 -89
  63. package/src/server/applications/terminal/runBlockingShellCommand.test.ts +0 -41
  64. package/src/server/applications/terminal/runBlockingShellCommand.ts +0 -64
  65. package/src/server/applications/terminal/terminalRouter.ts +0 -47
  66. package/src/server/blockingCommandInputSchema.test.ts +0 -24
  67. package/src/server/blockingCommandInputSchema.ts +0 -27
  68. package/src/server/config.test.ts +0 -7
  69. package/src/server/config.ts +0 -18
  70. package/src/server/connection/trpc.ts +0 -3
  71. package/src/server/cypress-support/contents.ts +0 -245
  72. package/src/server/cypress-support/createCypressSupportFile.test.ts +0 -69
  73. package/src/server/cypress-support/createCypressSupportFile.ts +0 -56
  74. package/src/server/dirtree/index.test.ts +0 -352
  75. package/src/server/dirtree/index.ts +0 -144
  76. package/src/server/dirtree/json-to-zod.ts +0 -60
  77. package/src/server/index.ts +0 -6
  78. package/src/server/server.ts +0 -34
  79. package/src/server/types.ts +0 -98
  80. package/src/server/updateTestdirectorySchemaFile.test.ts +0 -49
  81. package/src/server/updateTestdirectorySchemaFile.ts +0 -71
  82. package/src/server/utilities/DisposableSingleApplication.test.ts +0 -92
  83. package/src/server/utilities/DisposableSingleApplication.ts +0 -49
  84. package/src/server/utilities/Lazy.ts +0 -16
  85. package/src/server/utilities/TerminalApplication.ts +0 -100
  86. package/src/server/utilities/generator.test.ts +0 -50
  87. package/src/server/utilities/generator.ts +0 -12
  88. package/src/server/utilities/tabId.ts +0 -4
  89. package/src/server/utilities/timeout.ts +0 -3
  90. package/src/server/utilities/timeoutable.ts +0 -19
  91. package/tsconfig.json +0 -31
  92. 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
- }
@@ -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"
@@ -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
- }