@bubblydoo/uxp-devtools-common 0.0.3 → 0.0.5

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/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import CDP from 'chrome-remote-interface';
2
2
  export { DevtoolsConnection, setupDevtoolsConnection } from './setup-devtools-url.js';
3
- export { setGlobalUxpLogger } from './uxp-logger.js';
3
+ export { setGlobalUxpLogger, setGlobalUxpLoggerLevel } from './uxp-logger.js';
4
+ import 'node:http';
5
+ import 'node:events';
4
6
  import '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';
5
7
 
6
8
  declare function setupCdpSession(cdtUrl: string): Promise<CDP.Client>;
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import CDP from 'chrome-remote-interface';
2
+ import EventEmitter from 'events';
2
3
  import fs from 'fs/promises';
3
4
  import path from 'path';
4
5
  import AppClient from '@adobe-fixed-uxp/uxp-devtools-core/core/service/clients/AppClient';
5
6
  import Server from '@adobe-fixed-uxp/uxp-devtools-core/core/service/Server';
6
- import DevToolsHelper from '@adobe-fixed-uxp/uxp-devtools-helper';
7
7
  import z from 'zod';
8
8
  import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';
9
9
 
@@ -37,7 +37,25 @@ async function waitForExecutionContextCreated(cdp, runAfterListenerAttached) {
37
37
  return executionContextCreatedPromise;
38
38
  }
39
39
  function setGlobalUxpLogger() {
40
- globalThis.UxpLogger = new Logger();
40
+ const logger = new Logger();
41
+ logger.level = 2;
42
+ globalThis.UxpLogger = logger;
43
+ }
44
+ function setGlobalUxpLoggerLevel(level) {
45
+ const logger = globalThis.UxpLogger;
46
+ if (!logger) {
47
+ throw new Error("UxpLogger is not set");
48
+ }
49
+ const levelNumber = {
50
+ error: 1,
51
+ warn: 2,
52
+ info: 3,
53
+ debug: 4
54
+ }[level];
55
+ if (!levelNumber) {
56
+ throw new Error(`Invalid level: ${level}`);
57
+ }
58
+ logger.level = levelNumber;
41
59
  }
42
60
 
43
61
  // src/setup-devtools-url.ts
@@ -69,6 +87,7 @@ async function fileExists(path2) {
69
87
  }
70
88
  }
71
89
  async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
90
+ const { default: DevToolsHelper } = await import('@adobe-fixed-uxp/uxp-devtools-helper');
72
91
  if (!path.isAbsolute(pluginPath)) {
73
92
  throw new Error("pluginPath must be an absolute path");
74
93
  }
@@ -86,7 +105,6 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
86
105
  const server = new Server(PORT);
87
106
  server.run();
88
107
  devtoolsManager.setServerDetails(PORT);
89
- console.log("port", PORT);
90
108
  await new Promise((resolve) => setTimeout(resolve, 1500));
91
109
  const psClient = server.clients.values().next().value;
92
110
  if (!psClient) {
@@ -106,7 +124,6 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
106
124
  reject(error);
107
125
  return;
108
126
  }
109
- console.log("response for", message.action, response);
110
127
  resolve(schema.parse(response));
111
128
  });
112
129
  });
@@ -161,7 +178,6 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
161
178
  const connection = {
162
179
  url: cdtUrl,
163
180
  teardown: async () => {
164
- console.log("Tearing down devtools URL");
165
181
  try {
166
182
  await callPluginHandler(
167
183
  psClient,
@@ -175,7 +191,6 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
175
191
  requestId: z.number()
176
192
  })
177
193
  );
178
- console.log("Plugin unloaded");
179
194
  } catch (error) {
180
195
  console.error("Error unloading plugin:", error);
181
196
  }
@@ -186,27 +201,26 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
186
201
  }
187
202
  try {
188
203
  devtoolsManager.terminate();
189
- console.log("DevToolsHelper terminated");
190
204
  } catch (error) {
191
205
  console.error("Error terminating DevToolsHelper:", error);
192
206
  }
193
- }
207
+ },
208
+ events: new EventEmitter()
194
209
  };
210
+ server.on("socketConnection", (socket, req) => {
211
+ connection.events.emit("connection", socket, req);
212
+ });
195
213
  return connection;
196
214
  }
197
215
 
198
216
  // src/uxp-cdp-defaults.ts
199
217
  async function setupCdpSessionWithUxpDefaults(cdp) {
200
- console.log("Setting up CDP defaults");
201
218
  await cdp.Network.enable();
202
219
  await cdp.Page.enable();
203
220
  await cdp.Page.getResourceTree();
204
221
  await cdp.Runtime.enable();
205
222
  await cdp.DOM.enable();
206
223
  await cdp.CSS.enable();
207
- await cdp.Debugger.enable({ maxScriptsCacheSize: 1e7 });
208
- await cdp.Debugger.setPauseOnExceptions({ state: "none" });
209
- await cdp.Debugger.setAsyncCallStackDepth({ maxDepth: 32 });
210
224
  await cdp.Overlay.enable();
211
225
  await cdp.Overlay.setShowViewportSizeOnResize({ show: true });
212
226
  await cdp.Profiler.enable();
@@ -220,6 +234,6 @@ async function setupCdpSessionWithUxpDefaults(cdp) {
220
234
  await cdp.Runtime.runIfWaitingForDebugger();
221
235
  }
222
236
 
223
- export { setGlobalUxpLogger, setupCdpSession, setupCdpSessionWithUxpDefaults, setupDevtoolsConnection, waitForExecutionContextCreated };
237
+ export { setGlobalUxpLogger, setGlobalUxpLoggerLevel, setupCdpSession, setupCdpSessionWithUxpDefaults, setupDevtoolsConnection, waitForExecutionContextCreated };
224
238
  //# sourceMappingURL=index.js.map
225
239
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cdp-session.ts","../src/uxp-logger.ts","../src/setup-devtools-url.ts","../src/uxp-cdp-defaults.ts"],"names":["path","psClient"],"mappings":"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","file":"index.js","sourcesContent":["import CDP from 'chrome-remote-interface';\n\nexport async function setupCdpSession(cdtUrl: string) {\n const uuid = crypto.randomUUID();\n\n const cdp = await CDP({\n useHostName: false,\n local: true,\n target: {\n description: 'CDT',\n devtoolsFrontendUrl: null!,\n id: `cdt-${uuid}`,\n title: 'CDT',\n type: 'page',\n url: 'about:blank',\n webSocketDebuggerUrl: cdtUrl,\n },\n });\n\n return cdp;\n}\n\ninterface ExecutionContextDescription {\n id: number;\n origin: string;\n name: string;\n uniqueId: string;\n}\n\nexport async function waitForExecutionContextCreated(cdp: CDP.Client, runAfterListenerAttached?: () => Promise<void>) {\n const executionContextCreatedPromise = new Promise<ExecutionContextDescription>((resolve) => {\n cdp.Runtime.on('executionContextCreated', (event) => {\n resolve(event.context);\n });\n });\n if (runAfterListenerAttached) {\n await runAfterListenerAttached();\n }\n return executionContextCreatedPromise;\n}\n","import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';\n\n/* eslint-disable vars-on-top */\ndeclare global {\n var UxpLogger: Logger;\n}\n\nexport function setGlobalUxpLogger() {\n globalThis.UxpLogger = new Logger();\n}\n","/* eslint-disable no-console */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport AppClient from '@adobe-fixed-uxp/uxp-devtools-core/core/service/clients/AppClient';\nimport Server from '@adobe-fixed-uxp/uxp-devtools-core/core/service/Server';\nimport DevToolsHelper from '@adobe-fixed-uxp/uxp-devtools-helper';\nimport z from 'zod';\nimport { setGlobalUxpLogger } from './uxp-logger';\n\nError.stackTraceLimit = Infinity;\n\nsetGlobalUxpLogger();\n\nconst DEFAULT_PORTS = [14001, 14002, 14003, 14004, 14005, 14006, 14007, 14008, 14009, 14010];\n\nconst loadReplySchema = z.object({\n command: z.literal('reply'),\n pluginSessionId: z.string(),\n breakOnStart: z.boolean(),\n requestId: z.number(),\n});\n\nconst validateReplySchema = z.object({\n command: z.literal('reply'),\n requestId: z.number(),\n success: z.boolean(),\n});\n\nconst debugReplySchema = z.object({\n command: z.literal('reply'),\n wsdebugUrl: z.string(),\n chromeDevToolsUrl: z.string(),\n});\n\nasync function fileExists(path: string) {\n try {\n await fs.access(path);\n return true;\n }\n catch {\n return false;\n }\n}\n\nexport interface DevtoolsConnection {\n /** Debugger websocket URL */\n url: string;\n /** Unload the plugin and tear down the Vulcan connection */\n teardown: () => Promise<void>;\n}\n\nexport async function setupDevtoolsConnection(pluginPath: string, ports: number[] = DEFAULT_PORTS): Promise<DevtoolsConnection> {\n if (!path.isAbsolute(pluginPath)) {\n throw new Error('pluginPath must be an absolute path');\n }\n const manifestPath = path.join(pluginPath, 'manifest.json');\n if (!await fileExists(manifestPath)) {\n throw new Error('manifest.json not found');\n }\n\n const devtoolsManager = new DevToolsHelper(true);\n const appsList = devtoolsManager.getAppsList();\n\n const isPsOpen = appsList.some(app => app.appId === 'PS');\n if (!isPsOpen) {\n throw new Error('Photoshop is not open');\n }\n\n const PORT = ports[Math.floor(Math.random() * ports.length)]!;\n\n const server = new Server(PORT);\n server.run();\n\n // this goes through Adobe's Vulcan system, which is a binary black box\n devtoolsManager.setServerDetails(PORT);\n\n console.log('port', PORT);\n\n await new Promise(resolve => setTimeout(resolve, 1500));\n\n const psClient = server.clients.values().next().value;\n\n if (!psClient) {\n throw new Error('No PS client found');\n }\n\n if (!(psClient instanceof AppClient)) {\n throw new TypeError('PS client is not an AppClient');\n }\n\n // const discoverReplySchema = z.object({\n // command: z.literal('reply'),\n // pluginSessionId: z.string(),\n // breakOnStart: z.boolean(),\n // requestId: z.number(),\n // });\n\n /**\n * Helper to promisify handler_Plugin calls with error handling and schema validation\n */\n function callPluginHandler<T extends z.ZodTypeAny>(\n psClient: AppClient,\n message: Parameters<AppClient['handler_Plugin']>[0],\n schema: T,\n ): Promise<z.infer<T>> {\n return new Promise((resolve, reject) => {\n psClient.handler_Plugin(message, (error: Error | null, response: any) => {\n if (response?.error) {\n reject(new Error(response.error));\n return;\n }\n if (error) {\n reject(error);\n return;\n }\n console.log('response for', message.action, response);\n resolve(schema.parse(response));\n });\n });\n }\n\n const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));\n const pluginId = manifest.id;\n\n const validateResult = await callPluginHandler(\n psClient,\n {\n action: 'validate',\n command: 'Plugin',\n params: {\n provider: {\n type: 'disk',\n id: pluginId,\n path: pluginPath,\n },\n },\n manifest,\n },\n validateReplySchema,\n );\n\n if (!validateResult.success) {\n throw new Error('Validation failed');\n }\n\n const { pluginSessionId } = await callPluginHandler(\n psClient,\n {\n action: 'load',\n command: 'Plugin',\n params: {\n provider: {\n type: 'disk',\n id: pluginId,\n path: pluginPath,\n },\n },\n breakOnStart: false,\n },\n loadReplySchema,\n );\n\n const result = await callPluginHandler(\n psClient,\n {\n action: 'debug',\n command: 'Plugin',\n pluginSessionId,\n },\n debugReplySchema,\n );\n\n const cdtUrl = result.wsdebugUrl.replace('ws=', 'ws://');\n\n const connection: DevtoolsConnection = {\n url: cdtUrl,\n teardown: async () => {\n console.log('Tearing down devtools URL');\n // Unload the plugin from Photoshop\n try {\n await callPluginHandler(\n psClient,\n {\n action: 'unload',\n command: 'Plugin',\n pluginSessionId,\n },\n z.object({\n command: z.literal('reply'),\n requestId: z.number(),\n }),\n );\n console.log('Plugin unloaded');\n }\n catch (error) {\n console.error('Error unloading plugin:', error);\n }\n\n try {\n await server.close();\n }\n catch (error) {\n console.error('Error closing server:', error);\n }\n\n // Terminate the DevToolsHelper (Adobe Vulcan native library)\n // This is crucial to prevent hanging handles\n try {\n devtoolsManager.terminate();\n console.log('DevToolsHelper terminated');\n }\n catch (error) {\n console.error('Error terminating DevToolsHelper:', error);\n }\n },\n };\n\n return connection;\n}\n","import type CDP from 'chrome-remote-interface';\n\nexport async function setupCdpSessionWithUxpDefaults(cdp: CDP.Client) {\n // these were all copied from wireshark\n console.log('Setting up CDP defaults');\n await cdp.Network.enable();\n await cdp.Page.enable();\n await cdp.Page.getResourceTree();\n await cdp.Runtime.enable();\n await cdp.DOM.enable();\n await cdp.CSS.enable();\n await cdp.Debugger.enable({ maxScriptsCacheSize: 10000000 });\n await cdp.Debugger.setPauseOnExceptions({ state: 'none' });\n await cdp.Debugger.setAsyncCallStackDepth({ maxDepth: 32 });\n await cdp.Overlay.enable();\n await cdp.Overlay.setShowViewportSizeOnResize({ show: true });\n await cdp.Profiler.enable();\n await cdp.Log.enable();\n await cdp.Target.setAutoAttach({\n autoAttach: true,\n waitForDebuggerOnStart: true,\n flatten: true,\n });\n await cdp.Debugger.setBlackboxPatterns({ patterns: [] });\n await cdp.Runtime.runIfWaitingForDebugger();\n}\n"]}
1
+ {"version":3,"sources":["../src/cdp-session.ts","../src/uxp-logger.ts","../src/setup-devtools-url.ts","../src/uxp-cdp-defaults.ts"],"names":["path","psClient"],"mappings":"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","file":"index.js","sourcesContent":["import CDP from 'chrome-remote-interface';\n\nexport async function setupCdpSession(cdtUrl: string) {\n const uuid = crypto.randomUUID();\n\n const cdp = await CDP({\n useHostName: false,\n local: true,\n target: {\n description: 'CDT',\n devtoolsFrontendUrl: null!,\n id: `cdt-${uuid}`,\n title: 'CDT',\n type: 'page',\n url: 'about:blank',\n webSocketDebuggerUrl: cdtUrl,\n },\n });\n\n return cdp;\n}\n\ninterface ExecutionContextDescription {\n id: number;\n origin: string;\n name: string;\n uniqueId: string;\n}\n\nexport async function waitForExecutionContextCreated(cdp: CDP.Client, runAfterListenerAttached?: () => Promise<void>) {\n const executionContextCreatedPromise = new Promise<ExecutionContextDescription>((resolve) => {\n cdp.Runtime.on('executionContextCreated', (event) => {\n resolve(event.context);\n });\n });\n if (runAfterListenerAttached) {\n await runAfterListenerAttached();\n }\n return executionContextCreatedPromise;\n}\n","import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';\n\n/* eslint-disable vars-on-top */\ndeclare global {\n var UxpLogger: Logger;\n}\n\nexport function setGlobalUxpLogger() {\n const logger = new Logger();\n logger.level = 2; // warn\n globalThis.UxpLogger = logger;\n}\n\nexport function setGlobalUxpLoggerLevel(level: 'error' | 'warn' | 'info' | 'debug') {\n const logger = globalThis.UxpLogger;\n if (!logger) {\n throw new Error('UxpLogger is not set');\n }\n const levelNumber = {\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n }[level];\n if (!levelNumber) {\n throw new Error(`Invalid level: ${level}`);\n }\n logger.level = levelNumber;\n}\n","import type http from 'node:http';\nimport EventEmitter from 'node:events';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport AppClient from '@adobe-fixed-uxp/uxp-devtools-core/core/service/clients/AppClient';\nimport Server from '@adobe-fixed-uxp/uxp-devtools-core/core/service/Server';\nimport z from 'zod';\nimport { setGlobalUxpLogger } from './uxp-logger';\n\nError.stackTraceLimit = Infinity;\n\nsetGlobalUxpLogger();\n\nconst DEFAULT_PORTS = [14001, 14002, 14003, 14004, 14005, 14006, 14007, 14008, 14009, 14010];\n\nconst loadReplySchema = z.object({\n command: z.literal('reply'),\n pluginSessionId: z.string(),\n breakOnStart: z.boolean(),\n requestId: z.number(),\n});\n\nconst validateReplySchema = z.object({\n command: z.literal('reply'),\n requestId: z.number(),\n success: z.boolean(),\n});\n\nconst debugReplySchema = z.object({\n command: z.literal('reply'),\n wsdebugUrl: z.string(),\n chromeDevToolsUrl: z.string(),\n});\n\nasync function fileExists(path: string) {\n try {\n await fs.access(path);\n return true;\n }\n catch {\n return false;\n }\n}\n\ninterface DevtoolsConnectionEventMap {\n connection: [socket: unknown, req: http.IncomingMessage];\n}\n\nexport interface DevtoolsConnection {\n /** Debugger websocket URL */\n url: string;\n /** Unload the plugin and tear down the Vulcan connection */\n teardown: () => Promise<void>;\n\n events: EventEmitter<DevtoolsConnectionEventMap>;\n}\n\nexport async function setupDevtoolsConnection(pluginPath: string, ports: number[] = DEFAULT_PORTS): Promise<DevtoolsConnection> {\n const { default: DevToolsHelper } = await import('@adobe-fixed-uxp/uxp-devtools-helper');\n\n if (!path.isAbsolute(pluginPath)) {\n throw new Error('pluginPath must be an absolute path');\n }\n const manifestPath = path.join(pluginPath, 'manifest.json');\n if (!await fileExists(manifestPath)) {\n throw new Error('manifest.json not found');\n }\n\n const devtoolsManager = new DevToolsHelper(true);\n const appsList = devtoolsManager.getAppsList();\n\n const isPsOpen = appsList.some(app => app.appId === 'PS');\n if (!isPsOpen) {\n throw new Error('Photoshop is not open');\n }\n\n const PORT = ports[Math.floor(Math.random() * ports.length)]!;\n\n const server = new Server(PORT);\n server.run();\n\n // this goes through Adobe's Vulcan system, which is a binary black box\n devtoolsManager.setServerDetails(PORT);\n\n // console.log('port', PORT);\n\n await new Promise(resolve => setTimeout(resolve, 1500));\n\n const psClient = server.clients.values().next().value;\n\n if (!psClient) {\n throw new Error('No PS client found');\n }\n\n if (!(psClient instanceof AppClient)) {\n throw new TypeError('PS client is not an AppClient');\n }\n\n // const discoverReplySchema = z.object({\n // command: z.literal('reply'),\n // pluginSessionId: z.string(),\n // breakOnStart: z.boolean(),\n // requestId: z.number(),\n // });\n\n /**\n * Helper to promisify handler_Plugin calls with error handling and schema validation\n */\n function callPluginHandler<T extends z.ZodTypeAny>(\n psClient: AppClient,\n message: Parameters<AppClient['handler_Plugin']>[0],\n schema: T,\n ): Promise<z.infer<T>> {\n return new Promise((resolve, reject) => {\n psClient.handler_Plugin(message, (error: Error | null, response: any) => {\n if (response?.error) {\n reject(new Error(response.error));\n return;\n }\n if (error) {\n reject(error);\n return;\n }\n // console.log('response for', message.action, response);\n resolve(schema.parse(response));\n });\n });\n }\n\n const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));\n const pluginId = manifest.id;\n\n const validateResult = await callPluginHandler(\n psClient,\n {\n action: 'validate',\n command: 'Plugin',\n params: {\n provider: {\n type: 'disk',\n id: pluginId,\n path: pluginPath,\n },\n },\n manifest,\n },\n validateReplySchema,\n );\n\n if (!validateResult.success) {\n throw new Error('Validation failed');\n }\n\n const { pluginSessionId } = await callPluginHandler(\n psClient,\n {\n action: 'load',\n command: 'Plugin',\n params: {\n provider: {\n type: 'disk',\n id: pluginId,\n path: pluginPath,\n },\n },\n breakOnStart: false,\n },\n loadReplySchema,\n );\n\n const result = await callPluginHandler(\n psClient,\n {\n action: 'debug',\n command: 'Plugin',\n pluginSessionId,\n },\n debugReplySchema,\n );\n\n const cdtUrl = result.wsdebugUrl.replace('ws=', 'ws://');\n\n const connection: DevtoolsConnection = {\n url: cdtUrl,\n teardown: async () => {\n // Unload the plugin from Photoshop\n try {\n await callPluginHandler(\n psClient,\n {\n action: 'unload',\n command: 'Plugin',\n pluginSessionId,\n },\n z.object({\n command: z.literal('reply'),\n requestId: z.number(),\n }),\n );\n // console.log('Plugin unloaded');\n }\n catch (error) {\n console.error('Error unloading plugin:', error);\n }\n\n try {\n await server.close();\n }\n catch (error) {\n console.error('Error closing server:', error);\n }\n\n // Terminate the DevToolsHelper (Adobe Vulcan native library)\n // This is crucial to prevent hanging handles\n try {\n devtoolsManager.terminate();\n // console.log('DevToolsHelper terminated');\n }\n catch (error) {\n console.error('Error terminating DevToolsHelper:', error);\n }\n },\n events: new EventEmitter<DevtoolsConnectionEventMap>(),\n };\n\n server.on('socketConnection', (socket, req) => {\n connection.events.emit('connection', socket, req);\n });\n\n return connection;\n}\n","import type CDP from 'chrome-remote-interface';\n\nexport async function setupCdpSessionWithUxpDefaults(cdp: CDP.Client) {\n // these were all copied from wireshark\n // console.log('Setting up CDP defaults');\n await cdp.Network.enable();\n await cdp.Page.enable();\n await cdp.Page.getResourceTree();\n await cdp.Runtime.enable();\n await cdp.DOM.enable();\n await cdp.CSS.enable();\n // await cdp.Debugger.enable({ maxScriptsCacheSize: 10000000 });\n // await cdp.Debugger.setPauseOnExceptions({ state: 'none' });\n // await cdp.Debugger.setAsyncCallStackDepth({ maxDepth: 32 });\n await cdp.Overlay.enable();\n await cdp.Overlay.setShowViewportSizeOnResize({ show: true });\n await cdp.Profiler.enable();\n await cdp.Log.enable();\n await cdp.Target.setAutoAttach({\n autoAttach: true,\n waitForDebuggerOnStart: true,\n flatten: true,\n });\n await cdp.Debugger.setBlackboxPatterns({ patterns: [] });\n await cdp.Runtime.runIfWaitingForDebugger();\n}\n"]}
@@ -1,8 +1,15 @@
1
+ import http from 'node:http';
2
+ import EventEmitter from 'node:events';
3
+
4
+ interface DevtoolsConnectionEventMap {
5
+ connection: [socket: unknown, req: http.IncomingMessage];
6
+ }
1
7
  interface DevtoolsConnection {
2
8
  /** Debugger websocket URL */
3
9
  url: string;
4
10
  /** Unload the plugin and tear down the Vulcan connection */
5
11
  teardown: () => Promise<void>;
12
+ events: EventEmitter<DevtoolsConnectionEventMap>;
6
13
  }
7
14
  declare function setupDevtoolsConnection(pluginPath: string, ports?: number[]): Promise<DevtoolsConnection>;
8
15
 
@@ -1,14 +1,16 @@
1
+ import EventEmitter from 'events';
1
2
  import fs from 'fs/promises';
2
3
  import path from 'path';
3
4
  import AppClient from '@adobe-fixed-uxp/uxp-devtools-core/core/service/clients/AppClient';
4
5
  import Server from '@adobe-fixed-uxp/uxp-devtools-core/core/service/Server';
5
- import DevToolsHelper from '@adobe-fixed-uxp/uxp-devtools-helper';
6
6
  import z from 'zod';
7
7
  import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';
8
8
 
9
9
  // src/setup-devtools-url.ts
10
10
  function setGlobalUxpLogger() {
11
- globalThis.UxpLogger = new Logger();
11
+ const logger = new Logger();
12
+ logger.level = 2;
13
+ globalThis.UxpLogger = logger;
12
14
  }
13
15
 
14
16
  // src/setup-devtools-url.ts
@@ -40,6 +42,7 @@ async function fileExists(path2) {
40
42
  }
41
43
  }
42
44
  async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
45
+ const { default: DevToolsHelper } = await import('@adobe-fixed-uxp/uxp-devtools-helper');
43
46
  if (!path.isAbsolute(pluginPath)) {
44
47
  throw new Error("pluginPath must be an absolute path");
45
48
  }
@@ -57,7 +60,6 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
57
60
  const server = new Server(PORT);
58
61
  server.run();
59
62
  devtoolsManager.setServerDetails(PORT);
60
- console.log("port", PORT);
61
63
  await new Promise((resolve) => setTimeout(resolve, 1500));
62
64
  const psClient = server.clients.values().next().value;
63
65
  if (!psClient) {
@@ -77,7 +79,6 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
77
79
  reject(error);
78
80
  return;
79
81
  }
80
- console.log("response for", message.action, response);
81
82
  resolve(schema.parse(response));
82
83
  });
83
84
  });
@@ -132,7 +133,6 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
132
133
  const connection = {
133
134
  url: cdtUrl,
134
135
  teardown: async () => {
135
- console.log("Tearing down devtools URL");
136
136
  try {
137
137
  await callPluginHandler(
138
138
  psClient,
@@ -146,7 +146,6 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
146
146
  requestId: z.number()
147
147
  })
148
148
  );
149
- console.log("Plugin unloaded");
150
149
  } catch (error) {
151
150
  console.error("Error unloading plugin:", error);
152
151
  }
@@ -157,12 +156,15 @@ async function setupDevtoolsConnection(pluginPath, ports = DEFAULT_PORTS) {
157
156
  }
158
157
  try {
159
158
  devtoolsManager.terminate();
160
- console.log("DevToolsHelper terminated");
161
159
  } catch (error) {
162
160
  console.error("Error terminating DevToolsHelper:", error);
163
161
  }
164
- }
162
+ },
163
+ events: new EventEmitter()
165
164
  };
165
+ server.on("socketConnection", (socket, req) => {
166
+ connection.events.emit("connection", socket, req);
167
+ });
166
168
  return connection;
167
169
  }
168
170
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/uxp-logger.ts","../src/setup-devtools-url.ts"],"names":["path","psClient"],"mappings":"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","file":"setup-devtools-url.js","sourcesContent":["import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';\n\n/* eslint-disable vars-on-top */\ndeclare global {\n var UxpLogger: Logger;\n}\n\nexport function setGlobalUxpLogger() {\n globalThis.UxpLogger = new Logger();\n}\n","/* eslint-disable no-console */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport AppClient from '@adobe-fixed-uxp/uxp-devtools-core/core/service/clients/AppClient';\nimport Server from '@adobe-fixed-uxp/uxp-devtools-core/core/service/Server';\nimport DevToolsHelper from '@adobe-fixed-uxp/uxp-devtools-helper';\nimport z from 'zod';\nimport { setGlobalUxpLogger } from './uxp-logger';\n\nError.stackTraceLimit = Infinity;\n\nsetGlobalUxpLogger();\n\nconst DEFAULT_PORTS = [14001, 14002, 14003, 14004, 14005, 14006, 14007, 14008, 14009, 14010];\n\nconst loadReplySchema = z.object({\n command: z.literal('reply'),\n pluginSessionId: z.string(),\n breakOnStart: z.boolean(),\n requestId: z.number(),\n});\n\nconst validateReplySchema = z.object({\n command: z.literal('reply'),\n requestId: z.number(),\n success: z.boolean(),\n});\n\nconst debugReplySchema = z.object({\n command: z.literal('reply'),\n wsdebugUrl: z.string(),\n chromeDevToolsUrl: z.string(),\n});\n\nasync function fileExists(path: string) {\n try {\n await fs.access(path);\n return true;\n }\n catch {\n return false;\n }\n}\n\nexport interface DevtoolsConnection {\n /** Debugger websocket URL */\n url: string;\n /** Unload the plugin and tear down the Vulcan connection */\n teardown: () => Promise<void>;\n}\n\nexport async function setupDevtoolsConnection(pluginPath: string, ports: number[] = DEFAULT_PORTS): Promise<DevtoolsConnection> {\n if (!path.isAbsolute(pluginPath)) {\n throw new Error('pluginPath must be an absolute path');\n }\n const manifestPath = path.join(pluginPath, 'manifest.json');\n if (!await fileExists(manifestPath)) {\n throw new Error('manifest.json not found');\n }\n\n const devtoolsManager = new DevToolsHelper(true);\n const appsList = devtoolsManager.getAppsList();\n\n const isPsOpen = appsList.some(app => app.appId === 'PS');\n if (!isPsOpen) {\n throw new Error('Photoshop is not open');\n }\n\n const PORT = ports[Math.floor(Math.random() * ports.length)]!;\n\n const server = new Server(PORT);\n server.run();\n\n // this goes through Adobe's Vulcan system, which is a binary black box\n devtoolsManager.setServerDetails(PORT);\n\n console.log('port', PORT);\n\n await new Promise(resolve => setTimeout(resolve, 1500));\n\n const psClient = server.clients.values().next().value;\n\n if (!psClient) {\n throw new Error('No PS client found');\n }\n\n if (!(psClient instanceof AppClient)) {\n throw new TypeError('PS client is not an AppClient');\n }\n\n // const discoverReplySchema = z.object({\n // command: z.literal('reply'),\n // pluginSessionId: z.string(),\n // breakOnStart: z.boolean(),\n // requestId: z.number(),\n // });\n\n /**\n * Helper to promisify handler_Plugin calls with error handling and schema validation\n */\n function callPluginHandler<T extends z.ZodTypeAny>(\n psClient: AppClient,\n message: Parameters<AppClient['handler_Plugin']>[0],\n schema: T,\n ): Promise<z.infer<T>> {\n return new Promise((resolve, reject) => {\n psClient.handler_Plugin(message, (error: Error | null, response: any) => {\n if (response?.error) {\n reject(new Error(response.error));\n return;\n }\n if (error) {\n reject(error);\n return;\n }\n console.log('response for', message.action, response);\n resolve(schema.parse(response));\n });\n });\n }\n\n const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));\n const pluginId = manifest.id;\n\n const validateResult = await callPluginHandler(\n psClient,\n {\n action: 'validate',\n command: 'Plugin',\n params: {\n provider: {\n type: 'disk',\n id: pluginId,\n path: pluginPath,\n },\n },\n manifest,\n },\n validateReplySchema,\n );\n\n if (!validateResult.success) {\n throw new Error('Validation failed');\n }\n\n const { pluginSessionId } = await callPluginHandler(\n psClient,\n {\n action: 'load',\n command: 'Plugin',\n params: {\n provider: {\n type: 'disk',\n id: pluginId,\n path: pluginPath,\n },\n },\n breakOnStart: false,\n },\n loadReplySchema,\n );\n\n const result = await callPluginHandler(\n psClient,\n {\n action: 'debug',\n command: 'Plugin',\n pluginSessionId,\n },\n debugReplySchema,\n );\n\n const cdtUrl = result.wsdebugUrl.replace('ws=', 'ws://');\n\n const connection: DevtoolsConnection = {\n url: cdtUrl,\n teardown: async () => {\n console.log('Tearing down devtools URL');\n // Unload the plugin from Photoshop\n try {\n await callPluginHandler(\n psClient,\n {\n action: 'unload',\n command: 'Plugin',\n pluginSessionId,\n },\n z.object({\n command: z.literal('reply'),\n requestId: z.number(),\n }),\n );\n console.log('Plugin unloaded');\n }\n catch (error) {\n console.error('Error unloading plugin:', error);\n }\n\n try {\n await server.close();\n }\n catch (error) {\n console.error('Error closing server:', error);\n }\n\n // Terminate the DevToolsHelper (Adobe Vulcan native library)\n // This is crucial to prevent hanging handles\n try {\n devtoolsManager.terminate();\n console.log('DevToolsHelper terminated');\n }\n catch (error) {\n console.error('Error terminating DevToolsHelper:', error);\n }\n },\n };\n\n return connection;\n}\n"]}
1
+ {"version":3,"sources":["../src/uxp-logger.ts","../src/setup-devtools-url.ts"],"names":["path","psClient"],"mappings":"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","file":"setup-devtools-url.js","sourcesContent":["import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';\n\n/* eslint-disable vars-on-top */\ndeclare global {\n var UxpLogger: Logger;\n}\n\nexport function setGlobalUxpLogger() {\n const logger = new Logger();\n logger.level = 2; // warn\n globalThis.UxpLogger = logger;\n}\n\nexport function setGlobalUxpLoggerLevel(level: 'error' | 'warn' | 'info' | 'debug') {\n const logger = globalThis.UxpLogger;\n if (!logger) {\n throw new Error('UxpLogger is not set');\n }\n const levelNumber = {\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n }[level];\n if (!levelNumber) {\n throw new Error(`Invalid level: ${level}`);\n }\n logger.level = levelNumber;\n}\n","import type http from 'node:http';\nimport EventEmitter from 'node:events';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport AppClient from '@adobe-fixed-uxp/uxp-devtools-core/core/service/clients/AppClient';\nimport Server from '@adobe-fixed-uxp/uxp-devtools-core/core/service/Server';\nimport z from 'zod';\nimport { setGlobalUxpLogger } from './uxp-logger';\n\nError.stackTraceLimit = Infinity;\n\nsetGlobalUxpLogger();\n\nconst DEFAULT_PORTS = [14001, 14002, 14003, 14004, 14005, 14006, 14007, 14008, 14009, 14010];\n\nconst loadReplySchema = z.object({\n command: z.literal('reply'),\n pluginSessionId: z.string(),\n breakOnStart: z.boolean(),\n requestId: z.number(),\n});\n\nconst validateReplySchema = z.object({\n command: z.literal('reply'),\n requestId: z.number(),\n success: z.boolean(),\n});\n\nconst debugReplySchema = z.object({\n command: z.literal('reply'),\n wsdebugUrl: z.string(),\n chromeDevToolsUrl: z.string(),\n});\n\nasync function fileExists(path: string) {\n try {\n await fs.access(path);\n return true;\n }\n catch {\n return false;\n }\n}\n\ninterface DevtoolsConnectionEventMap {\n connection: [socket: unknown, req: http.IncomingMessage];\n}\n\nexport interface DevtoolsConnection {\n /** Debugger websocket URL */\n url: string;\n /** Unload the plugin and tear down the Vulcan connection */\n teardown: () => Promise<void>;\n\n events: EventEmitter<DevtoolsConnectionEventMap>;\n}\n\nexport async function setupDevtoolsConnection(pluginPath: string, ports: number[] = DEFAULT_PORTS): Promise<DevtoolsConnection> {\n const { default: DevToolsHelper } = await import('@adobe-fixed-uxp/uxp-devtools-helper');\n\n if (!path.isAbsolute(pluginPath)) {\n throw new Error('pluginPath must be an absolute path');\n }\n const manifestPath = path.join(pluginPath, 'manifest.json');\n if (!await fileExists(manifestPath)) {\n throw new Error('manifest.json not found');\n }\n\n const devtoolsManager = new DevToolsHelper(true);\n const appsList = devtoolsManager.getAppsList();\n\n const isPsOpen = appsList.some(app => app.appId === 'PS');\n if (!isPsOpen) {\n throw new Error('Photoshop is not open');\n }\n\n const PORT = ports[Math.floor(Math.random() * ports.length)]!;\n\n const server = new Server(PORT);\n server.run();\n\n // this goes through Adobe's Vulcan system, which is a binary black box\n devtoolsManager.setServerDetails(PORT);\n\n // console.log('port', PORT);\n\n await new Promise(resolve => setTimeout(resolve, 1500));\n\n const psClient = server.clients.values().next().value;\n\n if (!psClient) {\n throw new Error('No PS client found');\n }\n\n if (!(psClient instanceof AppClient)) {\n throw new TypeError('PS client is not an AppClient');\n }\n\n // const discoverReplySchema = z.object({\n // command: z.literal('reply'),\n // pluginSessionId: z.string(),\n // breakOnStart: z.boolean(),\n // requestId: z.number(),\n // });\n\n /**\n * Helper to promisify handler_Plugin calls with error handling and schema validation\n */\n function callPluginHandler<T extends z.ZodTypeAny>(\n psClient: AppClient,\n message: Parameters<AppClient['handler_Plugin']>[0],\n schema: T,\n ): Promise<z.infer<T>> {\n return new Promise((resolve, reject) => {\n psClient.handler_Plugin(message, (error: Error | null, response: any) => {\n if (response?.error) {\n reject(new Error(response.error));\n return;\n }\n if (error) {\n reject(error);\n return;\n }\n // console.log('response for', message.action, response);\n resolve(schema.parse(response));\n });\n });\n }\n\n const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));\n const pluginId = manifest.id;\n\n const validateResult = await callPluginHandler(\n psClient,\n {\n action: 'validate',\n command: 'Plugin',\n params: {\n provider: {\n type: 'disk',\n id: pluginId,\n path: pluginPath,\n },\n },\n manifest,\n },\n validateReplySchema,\n );\n\n if (!validateResult.success) {\n throw new Error('Validation failed');\n }\n\n const { pluginSessionId } = await callPluginHandler(\n psClient,\n {\n action: 'load',\n command: 'Plugin',\n params: {\n provider: {\n type: 'disk',\n id: pluginId,\n path: pluginPath,\n },\n },\n breakOnStart: false,\n },\n loadReplySchema,\n );\n\n const result = await callPluginHandler(\n psClient,\n {\n action: 'debug',\n command: 'Plugin',\n pluginSessionId,\n },\n debugReplySchema,\n );\n\n const cdtUrl = result.wsdebugUrl.replace('ws=', 'ws://');\n\n const connection: DevtoolsConnection = {\n url: cdtUrl,\n teardown: async () => {\n // Unload the plugin from Photoshop\n try {\n await callPluginHandler(\n psClient,\n {\n action: 'unload',\n command: 'Plugin',\n pluginSessionId,\n },\n z.object({\n command: z.literal('reply'),\n requestId: z.number(),\n }),\n );\n // console.log('Plugin unloaded');\n }\n catch (error) {\n console.error('Error unloading plugin:', error);\n }\n\n try {\n await server.close();\n }\n catch (error) {\n console.error('Error closing server:', error);\n }\n\n // Terminate the DevToolsHelper (Adobe Vulcan native library)\n // This is crucial to prevent hanging handles\n try {\n devtoolsManager.terminate();\n // console.log('DevToolsHelper terminated');\n }\n catch (error) {\n console.error('Error terminating DevToolsHelper:', error);\n }\n },\n events: new EventEmitter<DevtoolsConnectionEventMap>(),\n };\n\n server.on('socketConnection', (socket, req) => {\n connection.events.emit('connection', socket, req);\n });\n\n return connection;\n}\n"]}
@@ -4,5 +4,6 @@ declare global {
4
4
  var UxpLogger: Logger;
5
5
  }
6
6
  declare function setGlobalUxpLogger(): void;
7
+ declare function setGlobalUxpLoggerLevel(level: 'error' | 'warn' | 'info' | 'debug'): void;
7
8
 
8
- export { setGlobalUxpLogger };
9
+ export { setGlobalUxpLogger, setGlobalUxpLoggerLevel };
@@ -2,9 +2,27 @@ import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';
2
2
 
3
3
  // src/uxp-logger.ts
4
4
  function setGlobalUxpLogger() {
5
- globalThis.UxpLogger = new Logger();
5
+ const logger = new Logger();
6
+ logger.level = 2;
7
+ globalThis.UxpLogger = logger;
8
+ }
9
+ function setGlobalUxpLoggerLevel(level) {
10
+ const logger = globalThis.UxpLogger;
11
+ if (!logger) {
12
+ throw new Error("UxpLogger is not set");
13
+ }
14
+ const levelNumber = {
15
+ error: 1,
16
+ warn: 2,
17
+ info: 3,
18
+ debug: 4
19
+ }[level];
20
+ if (!levelNumber) {
21
+ throw new Error(`Invalid level: ${level}`);
22
+ }
23
+ logger.level = levelNumber;
6
24
  }
7
25
 
8
- export { setGlobalUxpLogger };
26
+ export { setGlobalUxpLogger, setGlobalUxpLoggerLevel };
9
27
  //# sourceMappingURL=uxp-logger.js.map
10
28
  //# sourceMappingURL=uxp-logger.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/uxp-logger.ts"],"names":[],"mappings":";;;AAOO,SAAS,kBAAA,GAAqB;AACnC,EAAA,UAAA,CAAW,SAAA,GAAY,IAAI,MAAA,EAAO;AACpC","file":"uxp-logger.js","sourcesContent":["import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';\n\n/* eslint-disable vars-on-top */\ndeclare global {\n var UxpLogger: Logger;\n}\n\nexport function setGlobalUxpLogger() {\n globalThis.UxpLogger = new Logger();\n}\n"]}
1
+ {"version":3,"sources":["../src/uxp-logger.ts"],"names":[],"mappings":";;;AAOO,SAAS,kBAAA,GAAqB;AACnC,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,EAAO;AAC1B,EAAA,MAAA,CAAO,KAAA,GAAQ,CAAA;AACf,EAAA,UAAA,CAAW,SAAA,GAAY,MAAA;AACzB;AAEO,SAAS,wBAAwB,KAAA,EAA4C;AAClF,EAAA,MAAM,SAAS,UAAA,CAAW,SAAA;AAC1B,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,MAAM,sBAAsB,CAAA;AAAA,EACxC;AACA,EAAA,MAAM,WAAA,GAAc;AAAA,IAClB,KAAA,EAAO,CAAA;AAAA,IACP,IAAA,EAAM,CAAA;AAAA,IACN,IAAA,EAAM,CAAA;AAAA,IACN,KAAA,EAAO;AAAA,IACP,KAAK,CAAA;AACP,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,KAAK,CAAA,CAAE,CAAA;AAAA,EAC3C;AACA,EAAA,MAAA,CAAO,KAAA,GAAQ,WAAA;AACjB","file":"uxp-logger.js","sourcesContent":["import { Logger } from '@adobe-fixed-uxp/uxp-devtools-core/core/common/Logger';\n\n/* eslint-disable vars-on-top */\ndeclare global {\n var UxpLogger: Logger;\n}\n\nexport function setGlobalUxpLogger() {\n const logger = new Logger();\n logger.level = 2; // warn\n globalThis.UxpLogger = logger;\n}\n\nexport function setGlobalUxpLoggerLevel(level: 'error' | 'warn' | 'info' | 'debug') {\n const logger = globalThis.UxpLogger;\n if (!logger) {\n throw new Error('UxpLogger is not set');\n }\n const levelNumber = {\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n }[level];\n if (!levelNumber) {\n throw new Error(`Invalid level: ${level}`);\n }\n logger.level = levelNumber;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bubblydoo/uxp-devtools-common",
3
3
  "type": "module",
4
- "version": "0.0.3",
4
+ "version": "0.0.5",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "fake-plugin"
26
26
  ],
27
27
  "dependencies": {
28
- "@adobe-fixed-uxp/uxp-devtools-core": "^1.6.3",
28
+ "@adobe-fixed-uxp/uxp-devtools-core": "^1.6.5",
29
29
  "@adobe-fixed-uxp/uxp-devtools-helper": "^1.6.2",
30
30
  "chrome-remote-interface": "^0.33.3",
31
31
  "zod": "^4.3.6"