@lvce-editor/test-with-playwright-worker 1.7.0 → 2.1.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 (39) hide show
  1. package/package.json +7 -8
  2. package/src/parts/Command/Command.js +1 -9
  3. package/src/parts/ErrorCodes/ErrorCodes.js +0 -17
  4. package/src/parts/GetServerPath/GetServerPath.js +3 -2
  5. package/src/parts/GetTests/GetTests.js +8 -2
  6. package/src/parts/HandleIpc/HandleIpc.js +2 -10
  7. package/src/parts/HandleMessage/HandleMessage.js +29 -0
  8. package/src/parts/IpcChild/IpcChild.js +6 -0
  9. package/src/parts/IpcChildModule/IpcChildModule.js +15 -2
  10. package/src/parts/IpcChildType/IpcChildType.js +7 -1
  11. package/src/parts/IsTestFile/IsTestFile.js +5 -3
  12. package/src/parts/JsonRpc/JsonRpc.js +1 -35
  13. package/src/parts/Main/Main.js +2 -2
  14. package/src/parts/Process/Process.js +0 -12
  15. package/src/parts/Callback/Callback.js +0 -39
  16. package/src/parts/Character/Character.js +0 -11
  17. package/src/parts/CleanStack/CleanStack.js +0 -93
  18. package/src/parts/Cli/Cli.js +0 -8
  19. package/src/parts/CommandNotFoundError/CommandNotFoundError.js +0 -9
  20. package/src/parts/CommandState/CommandState.js +0 -17
  21. package/src/parts/EncodingType/EncodingType.js +0 -1
  22. package/src/parts/GetErrorResponse/GetErrorResponse.js +0 -56
  23. package/src/parts/GetResponse/GetResponse.js +0 -12
  24. package/src/parts/GetSuccessResponse/GetSuccessResponse.js +0 -12
  25. package/src/parts/HandleCliArgs/HandleCliArgs.js +0 -20
  26. package/src/parts/Id/Id.js +0 -7
  27. package/src/parts/IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js +0 -41
  28. package/src/parts/IpcChildWithNodeWorker/IpcChildWithNodeWorker.js +0 -27
  29. package/src/parts/IpcError/IpcError.js +0 -6
  30. package/src/parts/JoinLines/JoinLines.js +0 -5
  31. package/src/parts/Json/Json.js +0 -17
  32. package/src/parts/JsonError/JsonError.js +0 -64
  33. package/src/parts/JsonParsingError/JsonParsingError.js +0 -17
  34. package/src/parts/JsonRpcErrorCode/JsonRpcErrorCode.js +0 -2
  35. package/src/parts/JsonRpcVersion/JsonRpcVersion.js +0 -1
  36. package/src/parts/Logger/Logger.js +0 -43
  37. package/src/parts/PrettyError/PrettyError.js +0 -138
  38. package/src/parts/PrintPrettyError/PrintPrettyError.js +0 -5
  39. package/src/parts/SplitLines/SplitLines.js +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/test-with-playwright-worker",
3
- "version": "1.7.0",
3
+ "version": "2.1.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -13,16 +13,15 @@
13
13
  "author": "",
14
14
  "license": "MIT",
15
15
  "dependencies": {
16
- "@lvce-editor/verror": "^1.5.0",
17
16
  "@lvce-editor/assert": "^1.3.0",
17
+ "@lvce-editor/command": "^1.2.0",
18
+ "@lvce-editor/ipc": "^11.1.0",
19
+ "@lvce-editor/json-rpc": "^5.0.0",
20
+ "@lvce-editor/verror": "^1.6.0",
18
21
  "@playwright/test": "^1.48.2",
19
- "get-port": "^7.1.0",
20
- "minimist": "^1.2.8",
21
- "read-pkg-up": "^11.0.0",
22
- "verror": "^1.10.1"
22
+ "get-port": "^7.1.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@types/jest": "^29.5.10",
26
- "@types/verror": "^1.10.10"
25
+ "@types/jest": "^29.5.10"
27
26
  }
28
27
  }
@@ -1,9 +1 @@
1
- import * as CommandState from '../CommandState/CommandState.js'
2
-
3
- export const execute = (command, ...args) => {
4
- const fn = CommandState.getCommand(command)
5
- if (!fn) {
6
- throw new Error(`Command not found ${command}`)
7
- }
8
- return fn(...args)
9
- }
1
+ export * from '@lvce-editor/command'
@@ -1,19 +1,2 @@
1
- export const E_COLOR_THEME_NOT_FOUND = 'E_COLOR_THEME_NOT_FOUND'
2
- export const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND'
3
- export const E_ICON_THEME_NOT_FOUND = 'E_ICON_THEME_NOT_FOUND'
4
- export const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE'
5
- export const E_MANIFEST_NOT_FOUND = 'E_MANIFEST_NOT_FOUND'
6
- export const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON'
7
- export const EACCES = 'EACCES'
8
- export const ECONNRESET = 'ECONNRESET'
9
- export const EEXIST = 'EEXIST'
10
- export const EISDIR = 'EISDIR'
11
- export const ELOOP = 'ELOOP'
12
1
  export const ENOENT = 'ENOENT'
13
- export const ENOTDIR = 'ENOTDIR'
14
- export const EPERM = 'EPERM'
15
- export const EPIPE = 'EPIPE'
16
- export const ERR_IPC_CHANNEL_CLOSED = 'ERR_IPC_CHANNEL_CLOSED'
17
- export const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND'
18
- export const EXDEV = 'EXDEV'
19
2
  export const E_NO_TEST_FILES = 'E_NO_TEST_FILES'
@@ -1,9 +1,10 @@
1
- import { join } from 'path'
1
+ import { join } from 'node:path'
2
+ import { pathToFileURL } from 'node:url'
2
3
 
3
4
  export const getServerPath = async () => {
4
5
  const toTry = [
5
6
  '@lvce-editor/server',
6
- join(process.cwd(), '..', 'server', 'node_modules', '@lvce-editor', 'server', 'index.js'),
7
+ pathToFileURL(join(process.cwd(), '..', 'server', 'node_modules', '@lvce-editor', 'server', 'index.js')).toString(),
7
8
  ]
8
9
 
9
10
  for (const path of toTry) {
@@ -4,13 +4,19 @@ import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js'
4
4
  import * as IsTestFile from '../IsTestFile/IsTestFile.js'
5
5
  import { NoTestFilesFoundError } from '../NoTestFilesFoundError/NoTestFilesFoundError.js'
6
6
 
7
+ const getName = (dirent) => {
8
+ return dirent.name
9
+ }
10
+
7
11
  /**
8
12
  * @param {string} testSrc
9
13
  */
10
14
  export const getTests = async (testSrc) => {
11
15
  try {
12
- const dirents = await readdir(testSrc)
13
- return dirents.filter(IsTestFile.isTestFile)
16
+ const dirents = await readdir(testSrc, {
17
+ withFileTypes: true,
18
+ })
19
+ return dirents.filter(IsTestFile.isTestFile).map(getName)
14
20
  } catch (error) {
15
21
  if (IsEnoentError.isEnoentError(error)) {
16
22
  throw new NoTestFilesFoundError(testSrc)
@@ -1,13 +1,5 @@
1
- import * as Assert from '../Assert/Assert.js'
2
- import * as GetResponse from '../GetResponse/GetResponse.js'
1
+ import * as HandleMessage from '../HandleMessage/HandleMessage.js'
3
2
 
4
3
  export const handleIpc = (ipc) => {
5
- Assert.object(ipc)
6
- const handleMessage = async (message) => {
7
- const response = await GetResponse.getResponse(message, ipc)
8
- if (response) {
9
- ipc.send(response)
10
- }
11
- }
12
- ipc.on('message', handleMessage)
4
+ ipc.addEventListener('message', HandleMessage.handleMessage)
13
5
  }
@@ -0,0 +1,29 @@
1
+ import * as Command from '../Command/Command.js'
2
+ import * as JsonRpc from '../JsonRpc/JsonRpc.js'
3
+
4
+ const prepare = (error) => {
5
+ return error
6
+ }
7
+
8
+ const requiresSocket = (method) => {
9
+ if (method === 'RunAllTests') {
10
+ return true
11
+ }
12
+ return false
13
+ }
14
+
15
+ const logError = (error) => {
16
+ console.error(error)
17
+ }
18
+
19
+ export const handleMessage = (event) => {
20
+ return JsonRpc.handleJsonRpcMessage(
21
+ event.target,
22
+ event.data,
23
+ Command.execute,
24
+ JsonRpc.resolve,
25
+ prepare,
26
+ logError,
27
+ requiresSocket,
28
+ )
29
+ }
@@ -4,6 +4,12 @@ export const listen = async ({ method, ...params }) => {
4
4
  const module = await IpcChildModule.getModule(method)
5
5
  // @ts-ignore
6
6
  const rawIpc = await module.listen(params)
7
+ // @ts-ignore
8
+ if (module.signal) {
9
+ // @ts-ignore
10
+ module.signal(rawIpc)
11
+ }
12
+ // @ts-ignore
7
13
  const ipc = module.wrap(rawIpc)
8
14
  return ipc
9
15
  }
@@ -1,11 +1,24 @@
1
+ import {
2
+ IpcChildWithElectronMessagePort,
3
+ IpcChildWithElectronUtilityProcess,
4
+ IpcChildWithNodeForkedProcess,
5
+ IpcChildWithNodeWorker,
6
+ IpcChildWithWebSocket,
7
+ } from '@lvce-editor/ipc'
1
8
  import * as IpcChildType from '../IpcChildType/IpcChildType.js'
2
9
 
3
10
  export const getModule = (method) => {
4
11
  switch (method) {
5
12
  case IpcChildType.NodeForkedProcess:
6
- return import('../IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js')
13
+ return IpcChildWithNodeForkedProcess
7
14
  case IpcChildType.NodeWorker:
8
- return import('../IpcChildWithNodeWorker/IpcChildWithNodeWorker.js')
15
+ return IpcChildWithNodeWorker
16
+ case IpcChildType.ElectronUtilityProcess:
17
+ return IpcChildWithElectronUtilityProcess
18
+ case IpcChildType.ElectronMessagePort:
19
+ return IpcChildWithElectronMessagePort
20
+ case IpcChildType.WebSocket:
21
+ return IpcChildWithWebSocket
9
22
  default:
10
23
  throw new Error('unexpected ipc type')
11
24
  }
@@ -1,5 +1,8 @@
1
1
  export const NodeWorker = 1
2
2
  export const NodeForkedProcess = 2
3
+ export const ElectronUtilityProcess = 3
4
+ export const ElectronMessagePort = 4
5
+ export const WebSocket = 6
3
6
 
4
7
  export const Auto = () => {
5
8
  const { argv } = process
@@ -9,5 +12,8 @@ export const Auto = () => {
9
12
  if (argv.includes('--ipc-type=node-forked-process')) {
10
13
  return NodeForkedProcess
11
14
  }
12
- throw new Error(`[test-worker] unknown ipc type`)
15
+ if (argv.includes('--ipc-type=electron-utility-process')) {
16
+ return ElectronUtilityProcess
17
+ }
18
+ throw new Error(`[shared-process] unknown ipc type`)
13
19
  }
@@ -1,6 +1,8 @@
1
+ import { Dirent } from 'node:fs'
2
+
1
3
  /**
2
- * @param {string} name
4
+ * @param {Dirent} dirent
3
5
  */
4
- export const isTestFile = (name) => {
5
- return !name.startsWith('_')
6
+ export const isTestFile = (dirent) => {
7
+ return dirent.isFile() && !dirent.name.startsWith('_')
6
8
  }
@@ -1,35 +1 @@
1
- import * as Callback from '../Callback/Callback.js'
2
- import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
3
-
4
- export const send = (transport, method, ...params) => {
5
- transport.send({
6
- jsonrpc: JsonRpcVersion.Two,
7
- method,
8
- params,
9
- })
10
- }
11
-
12
- export const invoke = (ipc, method, ...params) => {
13
- const { id, promise } = Callback.registerPromise()
14
- ipc.send({
15
- jsonrpc: JsonRpcVersion.Two,
16
- method,
17
- params,
18
- id,
19
- })
20
- return promise
21
- }
22
-
23
- export const invokeAndTransfer = (ipc, handle, method, ...params) => {
24
- const { id, promise } = Callback.registerPromise()
25
- ipc.sendAndTransfer(
26
- {
27
- jsonrpc: JsonRpcVersion.Two,
28
- method,
29
- params,
30
- id,
31
- },
32
- handle
33
- )
34
- return promise
35
- }
1
+ export * from '@lvce-editor/json-rpc'
@@ -1,5 +1,5 @@
1
+ import * as Command from '@lvce-editor/command'
1
2
  import * as CommandMap from '../CommandMap/CommandMap.js'
2
- import * as CommandState from '../CommandState/CommandState.js'
3
3
  import * as HandleIpc from '../HandleIpc/HandleIpc.js'
4
4
  import * as IpcChild from '../IpcChild/IpcChild.js'
5
5
  import * as IpcChildType from '../IpcChildType/IpcChildType.js'
@@ -28,7 +28,7 @@ export const main = async () => {
28
28
  Process.on('SIGINT', handleSigint)
29
29
  Process.on('SIGTERM', handleSigTerm)
30
30
  Process.on('uncaughtExceptionMonitor', ProcessListeners.handleUncaughtExceptionMonitor)
31
- CommandState.registerCommands(CommandMap.commandMap)
31
+ Command.register(CommandMap.commandMap)
32
32
  const ipc = await IpcChild.listen({
33
33
  method: IpcChildType.Auto(),
34
34
  })
@@ -1,15 +1,3 @@
1
- export const argv = process.argv
2
-
3
- export const env = process.env
4
-
5
- /**
6
- *
7
- * @param {number} code
8
- */
9
- export const exit = (code) => {
10
- process.exit(code)
11
- }
12
-
13
1
  /**
14
2
  *
15
3
  * @param {string} event
@@ -1,39 +0,0 @@
1
- import * as Id from '../Id/Id.js'
2
-
3
- export const state = {
4
- callbacks: Object.create(null),
5
- onceListeners: new Set(),
6
- }
7
-
8
- export const registerPromise = () => {
9
- const id = Id.create()
10
- const promise = new Promise((resolve, reject) => {
11
- state.callbacks[id] = { resolve, reject }
12
- })
13
- return { id, promise }
14
- }
15
-
16
- // TODO merge resolve and resolveEmpty
17
- export const resolve = (id, args) => {
18
- const { callbacks } = state
19
- if (!(id in callbacks)) {
20
- console.warn(`callback ${id} may already be disposed`)
21
- return
22
- }
23
- callbacks[id].resolve(args)
24
- delete callbacks[id]
25
- }
26
-
27
- export const reject = (id, error) => {
28
- const { callbacks } = state
29
- if (!(id in callbacks)) {
30
- console.warn(`callback (rejected) ${id} may already be disposed`)
31
- return
32
- }
33
- callbacks[id].reject(error)
34
- delete callbacks[id]
35
- }
36
-
37
- export const isAllEmpty = () => {
38
- return Object.keys(state.callbacks).length === 0 && state.onceListeners.size === 0
39
- }
@@ -1,11 +0,0 @@
1
- export const Backslash = '\\'
2
- export const Dash = '-'
3
- export const Dot = '.'
4
- export const EmptyString = ''
5
- export const NewLine = '\n'
6
- export const OpenAngleBracket = '<'
7
- export const Slash = '/'
8
- export const Space = ' '
9
- export const Tab = '\t'
10
- export const Underline = '_'
11
- export const T = 't'
@@ -1,93 +0,0 @@
1
- import * as SplitLines from '../SplitLines/SplitLines.js'
2
-
3
- const RE_AT = /^\s+at/
4
- const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/
5
- const RE_OBJECT_AS = /^\s*at (async )?Object\.\w+ \[as ([\w\.]+)\]/
6
- const RE_GET_RESPONSE = /^\s*at async getResponse/
7
- const RE_WEBSOCKET_HANDLE_MESSAGE = /^\s*at async WebSocket.handleMessage/
8
- const RE_EXECUTE_COMMAND_ASYNC = /^\s*at executeCommandAsync/
9
- const RE_HANDLE_OTHER_MESSAGES_FROM_MESSAGE_PORT = /^\s*at async MessagePort\.handleOtherMessagesFromMessagePort/
10
-
11
- const isInternalLine = (line) => {
12
- return line.includes('node:') || RE_AT_PROMISE_INDEX.test(line) || line.includes('node_modules/ws')
13
- }
14
-
15
- const isRelevantLine = (line) => {
16
- return !isInternalLine(line)
17
- }
18
-
19
- const isApplicationUsefulLine = (line, index) => {
20
- if (index === 0) {
21
- return true
22
- }
23
- if (RE_GET_RESPONSE.test(line)) {
24
- return false
25
- }
26
- if (RE_WEBSOCKET_HANDLE_MESSAGE.test(line)) {
27
- return false
28
- }
29
- if (RE_EXECUTE_COMMAND_ASYNC.test(line)) {
30
- return false
31
- }
32
- if (RE_HANDLE_OTHER_MESSAGES_FROM_MESSAGE_PORT.test(line)) {
33
- return false
34
- }
35
- return true
36
- }
37
-
38
- const isNormalStackLine = (line) => {
39
- return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line)
40
- }
41
-
42
- const cleanLine = (line) => {
43
- if (line.startsWith(' at exports.')) {
44
- return ' at ' + line.slice(' at exports.'.length)
45
- }
46
- if (line.startsWith(' at async exports.')) {
47
- return ' at async ' + line.slice(' at async exports.'.length)
48
- }
49
- if (line.startsWith(' at async Module.')) {
50
- return ' at async ' + line.slice(' at async Module.'.length)
51
- }
52
- if (line.startsWith(' at Module.')) {
53
- return ' at ' + line.slice(' at Module.'.length)
54
- }
55
- const objectMatch = line.match(RE_OBJECT_AS)
56
- if (objectMatch) {
57
- const rest = line.slice(objectMatch[0].length)
58
- if (objectMatch[1]) {
59
- return ' at ' + objectMatch[1] + objectMatch[2] + rest
60
- }
61
- return ' at ' + objectMatch[2] + rest
62
- }
63
- return line
64
- }
65
-
66
- const getDetails = (lines) => {
67
- const index = lines.findIndex(isNormalStackLine)
68
- return {
69
- custom: lines.slice(0, index),
70
- actualStack: lines.slice(index).map(cleanLine),
71
- }
72
- }
73
-
74
- const RE_PATH_1 = /^\/(.*)(\d+)$/
75
-
76
- const mergeCustom = (custom, relevantStack) => {
77
- if (custom.length === 0) {
78
- return relevantStack
79
- }
80
- const firstLine = custom[0]
81
- if (RE_PATH_1.test(firstLine)) {
82
- return [` at ${firstLine}`, ...relevantStack]
83
- }
84
- return relevantStack
85
- }
86
-
87
- export const cleanStack = (stack) => {
88
- const lines = SplitLines.splitLines(stack)
89
- const { custom, actualStack } = getDetails(lines)
90
- const relevantStack = actualStack.filter(isRelevantLine).filter(isApplicationUsefulLine)
91
- const merged = mergeCustom(custom, relevantStack)
92
- return merged
93
- }
@@ -1,8 +0,0 @@
1
- import * as HandleCliArgs from '../HandleCliArgs/HandleCliArgs.js'
2
- import * as Process from '../Process/Process.js'
3
-
4
- export const main = () => {
5
- HandleCliArgs.handleCliArgs({ argv: Process.argv, env: Process.env })
6
- }
7
-
8
- main()
@@ -1,9 +0,0 @@
1
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
2
-
3
- export class CommandNotFoundError extends Error {
4
- constructor(id) {
5
- super(`command ${id} not found`)
6
- this.name = 'CommandNotFoundError'
7
- this.code = ErrorCodes.E_COMMAND_NOT_FOUND
8
- }
9
- }
@@ -1,17 +0,0 @@
1
- export const state = {
2
- commands: Object.create(null),
3
- }
4
-
5
- export const registerCommand = (key, fn) => {
6
- state.commands[key] = fn
7
- }
8
-
9
- export const registerCommands = (commandMap) => {
10
- for (const [key, value] of Object.entries(commandMap)) {
11
- registerCommand(key, value)
12
- }
13
- }
14
-
15
- export const getCommand = (key) => {
16
- return state.commands[key]
17
- }
@@ -1 +0,0 @@
1
- export const Utf8 = 'utf8'
@@ -1,56 +0,0 @@
1
- import { CommandNotFoundError } from '../CommandNotFoundError/CommandNotFoundError.js'
2
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
3
- import * as JsonRpcErrorCode from '../JsonRpcErrorCode/JsonRpcErrorCode.js'
4
- import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
5
- import * as PrettyError from '../PrettyError/PrettyError.js'
6
- import * as PrintPrettyError from '../PrintPrettyError/PrintPrettyError.js'
7
-
8
- const shouldLogError = (error) => {
9
- if (error && error.code === ErrorCodes.ENOENT) {
10
- return false
11
- }
12
- return true
13
- }
14
-
15
- export const getErrorResponse = (message, error) => {
16
- if (error && error instanceof CommandNotFoundError) {
17
- return {
18
- jsonrpc: JsonRpcVersion.Two,
19
- id: message.id,
20
- error: {
21
- code: JsonRpcErrorCode.MethodNotFound,
22
- message: error.message,
23
- data: error.stack,
24
- },
25
- }
26
- }
27
- if (!shouldLogError(error)) {
28
- return {
29
- jsonrpc: JsonRpcVersion.Two,
30
- id: message.id,
31
- error: {
32
- code: JsonRpcErrorCode.Custom,
33
- message: `${error}`,
34
- data: {
35
- code: error.code,
36
- },
37
- },
38
- }
39
- }
40
- const prettyError = PrettyError.prepare(error)
41
- PrintPrettyError.printPrettyError(prettyError, `[terminal-process] `)
42
- return {
43
- jsonrpc: JsonRpcVersion.Two,
44
- id: message.id,
45
- error: {
46
- code: JsonRpcErrorCode.Custom,
47
- message: prettyError.message,
48
- data: {
49
- stack: prettyError.stack,
50
- codeFrame: prettyError.codeFrame,
51
- type: prettyError.type,
52
- code: prettyError.code,
53
- },
54
- },
55
- }
56
- }
@@ -1,12 +0,0 @@
1
- import * as Command from '../Command/Command.js'
2
- import * as GetErrorResponse from '../GetErrorResponse/GetErrorResponse.js'
3
- import * as GetSuccessResponse from '../GetSuccessResponse/GetSuccessResponse.js'
4
-
5
- export const getResponse = async (message, ipc) => {
6
- try {
7
- const result = await Command.execute(message.method, ipc, ...message.params)
8
- return GetSuccessResponse.getSuccessResponse(message, result)
9
- } catch (error) {
10
- return GetErrorResponse.getErrorResponse(message, error)
11
- }
12
- }
@@ -1,12 +0,0 @@
1
- import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
2
-
3
- export const getSuccessResponse = (message, result) => {
4
- if (!message.id) {
5
- return undefined
6
- }
7
- return {
8
- jsonrpc: JsonRpcVersion.Two,
9
- id: message.id,
10
- result: result ?? null,
11
- }
12
- }
@@ -1,20 +0,0 @@
1
- import * as RunAllTests from '../RunAllTests/RunAllTests.js'
2
-
3
- /**
4
- *
5
- * @param {{argv:string[], env:any}} param0
6
- */
7
- export const handleCliArgs = async ({ argv, env }) => {
8
- const cwd = process.cwd()
9
- const extensionPath = env.ONLY_EXTENSION
10
- const testPath = env.TEST_PATH || ''
11
- const headless = argv.includes('--headless')
12
- // TODO
13
- // @ts-ignore
14
- await RunAllTests.runAllTests({
15
- extensionPath,
16
- testPath,
17
- cwd,
18
- headless,
19
- })
20
- }
@@ -1,7 +0,0 @@
1
- export const state = {
2
- id: 0,
3
- }
4
-
5
- export const create = () => {
6
- return ++state.id
7
- }
@@ -1,41 +0,0 @@
1
- import { IpcError } from '../IpcError/IpcError.js'
2
-
3
- export const listen = async () => {
4
- if (!process.send) {
5
- throw new IpcError('process ipc is not available')
6
- }
7
- process.send('ready')
8
- return process
9
- }
10
-
11
- const getActualData = (message, handle) => {
12
- if (handle) {
13
- return {
14
- ...message,
15
- params: [...message.params, handle],
16
- }
17
- }
18
- return message
19
- }
20
-
21
- export const wrap = (process) => {
22
- return {
23
- process,
24
- on(event, listener) {
25
- if (event === 'message') {
26
- const wrappedListener = (message, handle) => {
27
- const actualData = getActualData(message, handle)
28
- listener(actualData)
29
- }
30
- this.process.on(event, wrappedListener)
31
- }
32
- },
33
- off(event, listener) {
34
- this.process.off(event, listener)
35
- },
36
- send(message) {
37
- this.process.send(message)
38
- },
39
- dispose() {},
40
- }
41
- }
@@ -1,27 +0,0 @@
1
- import { parentPort } from 'node:worker_threads'
2
-
3
- export const listen = async () => {
4
- if (!parentPort) {
5
- throw new Error('parentPort is required')
6
- }
7
- parentPort.postMessage('ready')
8
- return parentPort
9
- }
10
-
11
- export const wrap = (parentPort) => {
12
- return {
13
- parentPort,
14
- on(event, listener) {
15
- this.parentPort.on(event, listener)
16
- },
17
- off(event, listener) {
18
- this.parentPort.off(event, listener)
19
- },
20
- send(message) {
21
- this.parentPort.postMessage(message)
22
- },
23
- dispose() {
24
- this.parentPort.close()
25
- },
26
- }
27
- }
@@ -1,6 +0,0 @@
1
- export class IpcError extends Error {
2
- constructor(message) {
3
- super(message)
4
- this.name = 'IpcError'
5
- }
6
- }
@@ -1,5 +0,0 @@
1
- import * as Character from '../Character/Character.js'
2
-
3
- export const joinLines = (lines) => {
4
- return lines.join(Character.NewLine)
5
- }
@@ -1,17 +0,0 @@
1
- // parsing error handling based on https://github.com/sindresorhus/parse-json/blob/main/index.js
2
-
3
- import { JsonParsingError } from '../JsonParsingError/JsonParsingError.js'
4
-
5
- export const parse = async (string, filePath) => {
6
- try {
7
- return JSON.parse(string)
8
- } catch (error) {
9
- const JsonError = await import('../JsonError/JsonError.js')
10
- const errorProps = JsonError.getErrorPropsFromError(error, string, filePath)
11
- throw new JsonParsingError(errorProps.message, errorProps.codeFrame, errorProps.stack)
12
- }
13
- }
14
-
15
- export const stringify = (value) => {
16
- return JSON.stringify(value, null, 2) + '\n'
17
- }
@@ -1,64 +0,0 @@
1
- import { codeFrameColumns } from '@babel/code-frame'
2
- import { LinesAndColumns } from 'lines-and-columns'
3
-
4
- // parsing error handling based on https://github.com/sindresorhus/parse-json/blob/main/index.js
5
-
6
- const emptyError = {
7
- message: '',
8
- stack: '',
9
- codeFrame: '',
10
- }
11
-
12
- export const getErrorPropsFromError = (error, string, filePath) => {
13
- const indexMatch = error.message.match(/in JSON at position (\d+)/)
14
- if (indexMatch && indexMatch.length > 0) {
15
- const lines = new LinesAndColumns(string)
16
- const index = Number(indexMatch[1])
17
- const location = lines.locationForIndex(index)
18
- if (location) {
19
- const line = location.line + 1
20
- const column = location.column + 1
21
- const codeFrame = codeFrameColumns(string, { start: { line, column } }, { highlightCode: false })
22
- return {
23
- codeFrame,
24
- message: 'Json Parsing Error',
25
- stack: ` at ${filePath}:${line}:${column}`,
26
- }
27
- }
28
- }
29
- if (string.length === 0) {
30
- return {
31
- codeFrame: ``,
32
- message: 'Json Parsing Error: Cannot parse empty string',
33
- stack: ` at ${filePath}`,
34
- }
35
- }
36
-
37
- if (error.message === 'Unexpected end of JSON input') {
38
- const lines = new LinesAndColumns(string)
39
- const index = string.length - 1
40
- const location = lines.locationForIndex(index)
41
- if (location) {
42
- const codeFrame = codeFrameColumns(string, { start: { line: location.line + 1, column: location.column + 1 } }, { highlightCode: false })
43
- return {
44
- codeFrame,
45
- message: 'Json Parsing Error',
46
- stack: ` at ${filePath}`,
47
- }
48
- }
49
- }
50
- return {
51
- codeFrame: ``,
52
- message: 'Json Parsing Error',
53
- stack: ` at ${filePath}`,
54
- }
55
- }
56
-
57
- export const getErrorProps = (string, filePath) => {
58
- try {
59
- JSON.parse(string)
60
- return emptyError
61
- } catch (error) {
62
- return getErrorPropsFromError(error, string, filePath)
63
- }
64
- }
@@ -1,17 +0,0 @@
1
- import * as JoinLines from '../JoinLines/JoinLines.js'
2
- import * as SplitLines from '../SplitLines/SplitLines.js'
3
-
4
- export class JsonParsingError extends Error {
5
- constructor(message, codeFrame, stack) {
6
- super(message)
7
- this.name = 'JsonParsingError'
8
- if (codeFrame) {
9
- this.codeFrame = codeFrame
10
- }
11
-
12
- if (stack) {
13
- const parentStack = JoinLines.joinLines(SplitLines.splitLines(this.stack).slice(1))
14
- this.stack = this.name + ': ' + this.message + '\n' + stack + '\n' + parentStack
15
- }
16
- }
17
- }
@@ -1,2 +0,0 @@
1
- export const MethodNotFound = -32601
2
- export const Custom = -32001
@@ -1 +0,0 @@
1
- export const Two = '2.0'
@@ -1,43 +0,0 @@
1
- // TODO mock this module when used in unit tests
2
-
3
- const state = {
4
- /**
5
- * @type {Console|undefined}
6
- */
7
- console: undefined,
8
- }
9
-
10
- const createConsole = () => {
11
- return console
12
- }
13
-
14
- const getOrCreateLogger = () => {
15
- if (!state.console) {
16
- state.console = createConsole()
17
- }
18
- return state.console
19
- }
20
-
21
- export const log = (...args) => {
22
- const logger = getOrCreateLogger()
23
- logger.log(...args)
24
- console.log(...args)
25
- }
26
-
27
- export const info = (...args) => {
28
- const logger = getOrCreateLogger()
29
- logger.info(...args)
30
- console.info(...args)
31
- }
32
-
33
- export const warn = (...args) => {
34
- const logger = getOrCreateLogger()
35
- logger.warn(...args)
36
- console.warn(...args)
37
- }
38
-
39
- export const error = (...args) => {
40
- const logger = getOrCreateLogger()
41
- logger.error(...args)
42
- console.error(...args)
43
- }
@@ -1,138 +0,0 @@
1
- import { codeFrameColumns } from '@babel/code-frame'
2
- import { LinesAndColumns } from 'lines-and-columns'
3
- import { readFileSync } from 'node:fs'
4
- import { fileURLToPath } from 'node:url'
5
- import * as CleanStack from '../CleanStack/CleanStack.js'
6
- import * as EncodingType from '../EncodingType/EncodingType.js'
7
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
8
- import * as JoinLines from '../JoinLines/JoinLines.js'
9
- import * as Json from '../Json/Json.js'
10
- import * as SplitLines from '../SplitLines/SplitLines.js'
11
-
12
- const getActualPath = (fileUri) => {
13
- if (fileUri.startsWith('file://')) {
14
- return fileURLToPath(fileUri)
15
- }
16
- return fileUri
17
- }
18
-
19
- const RE_MODULE_NOT_FOUND_STACK = /Cannot find package '([^']+)' imported from (.+)$/
20
-
21
- const prepareModuleNotFoundError = (error) => {
22
- const { message } = error
23
- const match = message.match(RE_MODULE_NOT_FOUND_STACK)
24
- if (!match) {
25
- return {
26
- message,
27
- stack: error.stack,
28
- codeFrame: '',
29
- }
30
- }
31
- const notFoundModule = match[1]
32
- const importedFrom = match[2]
33
- const rawLines = readFileSync(importedFrom, EncodingType.Utf8)
34
- let line = 0
35
- let column = 0
36
- const splittedLines = SplitLines.splitLines(rawLines)
37
- for (let i = 0; i < splittedLines.length; i++) {
38
- const splittedLine = splittedLines[i]
39
- const index = splittedLine.indexOf(notFoundModule)
40
- if (index !== -1) {
41
- line = i + 1
42
- column = index
43
- break
44
- }
45
- }
46
- const location = {
47
- start: {
48
- line,
49
- column,
50
- },
51
- }
52
- const codeFrame = codeFrameColumns(rawLines, location)
53
- const stackLines = SplitLines.splitLines(error.stack)
54
- const newStackLines = [stackLines[0], ` at ${importedFrom}:${line}:${column}`, ...stackLines.slice(1)]
55
- const newStack = JoinLines.joinLines(newStackLines)
56
- return {
57
- message,
58
- stack: newStack,
59
- codeFrame,
60
- }
61
- }
62
-
63
- const getStackLinesToCut = (error) => {
64
- if (error && error.name === 'AssertionError') {
65
- return 1
66
- }
67
- return 0
68
- }
69
-
70
- export const prepare = (error) => {
71
- if (error && error.code === ErrorCodes.ERR_MODULE_NOT_FOUND) {
72
- return prepareModuleNotFoundError(error)
73
- }
74
- const { message } = error
75
- if (error && error.cause) {
76
- const cause = error.cause()
77
- if (cause) {
78
- error = cause
79
- }
80
- }
81
- const linesToCut = getStackLinesToCut(error)
82
- const lines = CleanStack.cleanStack(error.stack).slice(linesToCut)
83
- const file = lines[0]
84
- let codeFrame = ''
85
- if (error.codeFrame) {
86
- codeFrame = error.codeFrame
87
- } else if (file) {
88
- let match = file.match(/\((.*):(\d+):(\d+)\)$/)
89
- if (!match) {
90
- match = file.match(/at (.*):(\d+):(\d+)$/)
91
- }
92
- if (match) {
93
- const [_, path, line, column] = match
94
- const actualPath = getActualPath(path)
95
- const rawLines = readFileSync(actualPath, EncodingType.Utf8)
96
- const location = {
97
- start: {
98
- line: Number.parseInt(line),
99
- column: Number.parseInt(column),
100
- },
101
- }
102
- codeFrame = codeFrameColumns(rawLines, location)
103
- }
104
- }
105
- const relevantStack = JoinLines.joinLines(lines)
106
- return {
107
- message,
108
- stack: relevantStack,
109
- codeFrame,
110
- type: error.constructor.name,
111
- code: error.code,
112
- }
113
- }
114
-
115
- const fixBackslashes = (string) => {
116
- return string.replaceAll('\\\\', '\\')
117
- }
118
-
119
- export const prepareJsonError = (json, property, message) => {
120
- const string = fixBackslashes(Json.stringify(json))
121
- const stringifiedPropertyName = `"${property}"`
122
- const index = string.indexOf(stringifiedPropertyName) // TODO this could be wrong in some cases, find a better way
123
- console.log({ string, index })
124
- const jsonError = {
125
- stack: '',
126
- }
127
- if (index !== -1) {
128
- const lines = new LinesAndColumns(string)
129
- const location = lines.locationForIndex(index + stringifiedPropertyName.length + 1)
130
- const codeFrame = codeFrameColumns(string, {
131
- // @ts-ignore
132
- start: { line: location.line + 1, column: location.column + 1 },
133
- })
134
- jsonError.codeFrame = codeFrame
135
- }
136
- // jsonError.stack = `${bottomMessage}\n at ${filePath}`
137
- return jsonError
138
- }
@@ -1,5 +0,0 @@
1
- import * as Logger from '../Logger/Logger.js'
2
-
3
- export const printPrettyError = (prettyError, prefix = '') => {
4
- Logger.error(`${prefix}${prettyError.type}: ${prettyError.message}\n\n${prettyError.codeFrame}\n\n${prettyError.stack}\n`)
5
- }
@@ -1,5 +0,0 @@
1
- import * as Character from '../Character/Character.js'
2
-
3
- export const splitLines = (lines) => {
4
- return lines.split(Character.NewLine)
5
- }