@ps-generator-bridge/sdk 0.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.
- package/LICENSE +21 -0
- package/dist/PsPhotoshopProxy-BjnvziWn.d.cts +879 -0
- package/dist/PsPhotoshopProxy-BjnvziWn.d.ts +879 -0
- package/dist/index.cjs +1131 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +210 -0
- package/dist/index.d.ts +210 -0
- package/dist/index.js +1117 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.cjs +915 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +457 -0
- package/dist/plugin.d.ts +457 -0
- package/dist/plugin.js +902 -0
- package/dist/plugin.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/photoshop/jsx-runner.ts","../src/photoshop/JsxBuilder.ts","../src/photoshop/PhotoshopLayer.ts","../src/photoshop/PhotoshopLayers.ts","../src/photoshop/PhotoshopSelection.ts","../src/photoshop/PhotoshopDocument.ts","../src/photoshop/PhotoshopApp.ts","../src/photoshop/PsPhotoshopProxy.ts","../src/photoshop/enums.ts","../src/plugin/base.ts","../src/plugin/decorators.ts"],"names":[],"mappings":"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","file":"plugin.cjs","sourcesContent":["/**\n * The minimal slice of a JSX runner the Photoshop DOM proxy depends on: run a\n * raw ExtendScript string and resolve its evaluation result. Defined locally\n * (not imported from the generator contract) so the proxy stays transport- and\n * host-agnostic and can be wired to any backend that can evaluate a script.\n *\n * The server's `JsxRunnerApi` satisfies this structurally (`plugin.jsx`), so a\n * plugin passes `this.jsx` straight in. A future client-side backend would\n * supply its own adapter.\n */\nexport interface PsJsxRunner {\n run<T = unknown>(script: string): Promise<T>;\n}\n\n/**\n * Evaluate an ExtendScript expression and JSON-parse its result.\n *\n * `run` returns the evaluation verbatim (a string), so wrapping the expression\n * in `JSON.stringify` on the ExtendScript side is what lets numbers, booleans,\n * strings, arrays and objects all cross the bridge with their real type instead\n * of arriving as untyped strings. `JSON` is available because the default\n * engine is primed with polyfills before any plugin runs.\n */\nexport function evalJson<T>(jsx: PsJsxRunner, expr: string): Promise<T> {\n return jsx.run<string>(`JSON.stringify(${expr})`).then((s) => JSON.parse(s) as T);\n}\n\n/**\n * Read a numeric property, coercing on the ExtendScript side first. Document\n * dimensions are `UnitValue` objects, not plain numbers; `Number(...)` collapses\n * them to their scalar before serialization.\n */\nexport function evalNumber(jsx: PsJsxRunner, expr: string): Promise<number> {\n return evalJson<number>(jsx, `Number(${expr})`);\n}\n\n/** Read a string property (coerced with `String(...)` for safety). */\nexport function evalString(jsx: PsJsxRunner, expr: string): Promise<string> {\n return evalJson<string>(jsx, `String(${expr})`);\n}\n\n/** Read a boolean property (coerced with `Boolean(...)`). */\nexport function evalBool(jsx: PsJsxRunner, expr: string): Promise<boolean> {\n return evalJson<boolean>(jsx, `Boolean(${expr})`);\n}\n","/**\n * Builds ExtendScript fragments from typed values.\n * @internal Used only inside `photoshop/`; not exported from the SDK.\n *\n * Responsibilities: escape string arguments against injection, serialize file\n * paths to `new File(path)`, pass enum strings through verbatim, and serialize\n * numbers, booleans and arrays.\n */\nexport class JsxBuilder {\n /**\n * Escape a string into a JSX string literal. `JSON.stringify` handles quotes,\n * newlines and Unicode.\n *\n * @example JsxBuilder.string(\"O'Brien\") // -> \"\\\"O'Brien\\\"\"\n */\n static string(value: string): string {\n return JSON.stringify(value);\n }\n\n /**\n * Serialize a path to an ExtendScript `File` constructor.\n *\n * @example JsxBuilder.file(\"/path/to/file.psd\") // -> 'new File(\"/path/to/file.psd\")'\n */\n static file(path: string): string {\n return `new File(${JSON.stringify(path)})`;\n }\n\n /** Serialize a number, rejecting NaN/Infinity. */\n static number(value: number): string {\n if (!isFinite(value)) {\n throw new Error(`JsxBuilder.number: invalid value ${value}`);\n }\n return String(value);\n }\n\n /** Serialize a boolean. */\n static boolean(value: boolean): string {\n return value ? \"true\" : \"false\";\n }\n\n /** Pass an enum string through (already in `EnumName.MEMBER` form). */\n static enum_(value: string): string {\n return value;\n }\n\n /**\n * Serialize a numeric array to a JSX array literal (bounds, crop, etc.).\n *\n * @example JsxBuilder.numberArray([0, 0, 100, 100]) // -> '[0,0,100,100]'\n */\n static numberArray(arr: number[]): string {\n return JSON.stringify(arr);\n }\n\n /** Serialize a 2-D numeric array (selection boundary points). */\n static regionArray(region: number[][]): string {\n return JSON.stringify(region);\n }\n\n /**\n * Build a method-call expression from pre-serialized args.\n *\n * @example JsxBuilder.call(\"app.open\", [JsxBuilder.file(path)])\n * // -> 'app.open(new File(\"/path/to/file.psd\"))'\n */\n static call(path: string, args: string[]): string {\n return `${path}(${args.join(\", \")})`;\n }\n\n /**\n * Build a property assignment statement.\n *\n * @example JsxBuilder.assign(\"app.activeDocument.activeLayer.name\", JsxBuilder.string(\"New Name\"))\n * // -> 'app.activeDocument.activeLayer.name = \"New Name\"'\n */\n static assign(path: string, value: string): string {\n return `${path} = ${value}`;\n }\n}\n","import type { PsJsxRunner } from \"./jsx-runner\";\nimport { evalNumber, evalString, evalBool, evalJson } from \"./jsx-runner\";\nimport { JsxBuilder } from \"./JsxBuilder\";\nimport type { BlendModeValue, AnchorPositionValue, ElementPlacementValue } from \"./enums\";\nimport type { PsBounds } from \"./types\";\n\n/**\n * Wraps an ExtendScript Layer / ArtLayer / LayerSet: the shared Layer\n * properties and methods plus ArtLayer-only members such as `kind`.\n *\n * @remarks\n * `activeLayer` may be an ArtLayer or a LayerSet. Read `typename` before\n * touching ArtLayer-only members:\n * - \"ArtLayer\" -> a normal layer, `kind` is valid\n * - \"LayerSet\" -> a group, `kind` is unavailable\n *\n * @example\n * const layer = this.photoshop.activeDocument.activeLayer;\n * const name = await layer.name;\n * await layer.setName(\"Background\");\n * await layer.setVisible(false);\n */\nexport class PhotoshopLayer {\n constructor(\n private readonly _jsx: PsJsxRunner,\n private readonly _path: string // e.g. \"app.activeDocument.activeLayer\"\n ) {}\n\n // --- Layer read-only properties -----------------------------------------\n\n /** Unique layer id. */\n get id(): Promise<number> {\n return evalNumber(this._jsx, `${this._path}.id`);\n }\n\n /** Layer name. */\n get name(): Promise<string> {\n return evalString(this._jsx, `${this._path}.name`);\n }\n\n /** Layer visibility. */\n get visible(): Promise<boolean> {\n return evalBool(this._jsx, `${this._path}.visible`);\n }\n\n /** Layer opacity (0-100). */\n get opacity(): Promise<number> {\n return evalNumber(this._jsx, `${this._path}.opacity`);\n }\n\n /** BlendMode code -> enum-name map (all 27 members, plus newer ones). */\n private static readonly _BLEND_MODE_MAP: Record<number, string> = {\n 1: \"PASSTHROUGH\",\n 2: \"NORMAL\",\n 3: \"DISSOLVE\",\n 4: \"DARKEN\",\n 5: \"MULTIPLY\",\n 6: \"COLORBURN\",\n 7: \"LINEARBURN\",\n 8: \"LIGHTEN\",\n 9: \"SCREEN\",\n 10: \"COLORDODGE\",\n 11: \"LINEARDODGE\",\n 12: \"OVERLAY\",\n 13: \"SOFTLIGHT\",\n 14: \"HARDLIGHT\",\n 15: \"VIVIDLIGHT\",\n 16: \"LINEARLIGHT\",\n 17: \"PINLIGHT\",\n 18: \"DIFFERENCE\",\n 19: \"EXCLUSION\",\n 20: \"HUE\",\n 21: \"SATURATION\",\n 22: \"COLORBLEND\",\n 23: \"LUMINOSITY\",\n 26: \"HARDMIX\",\n 27: \"SUBTRACT\",\n 28: \"DARKERCOLOR\",\n 29: \"LIGHTERCOLOR\",\n 30: \"DIVIDE\",\n };\n\n /**\n * Blend mode as an enum-name string (e.g. \"BlendMode.NORMAL\"). ExtendScript\n * yields the numeric code; the static map turns it into a readable name.\n */\n get blendMode(): Promise<string> {\n return evalNumber(this._jsx, `${this._path}.blendMode`).then(\n (code) => PhotoshopLayer._BLEND_MODE_MAP[code] ?? `BlendMode.UNKNOWN_${code}`\n );\n }\n\n /** Whether the layer is fully locked. */\n get allLocked(): Promise<boolean> {\n return evalBool(this._jsx, `${this._path}.allLocked`);\n }\n\n /**\n * Layer bounds `[left, top, right, bottom]`.\n *\n * @remarks Units follow `rulerUnits`; values are not pixels unless it is\n * `Units.PIXELS`.\n */\n get bounds(): Promise<PsBounds> {\n const expr = `(function(){ var b = ${this._path}.bounds; return [b[0], b[1], b[2], b[3]]; })()`;\n return evalJson<PsBounds>(this._jsx, expr);\n }\n\n // --- ArtLayer-only properties -------------------------------------------\n\n /** LayerKind code -> enum-name map. */\n private static readonly _LAYER_KIND_MAP: Record<number, string> = {\n 1: \"NORMAL\",\n 2: \"TEXT\",\n 3: \"SOLIDFILL\",\n 4: \"GRADIENTFILL\",\n 5: \"LEVELS\",\n 6: \"CURVES\",\n 7: \"COLORBALANCE\",\n 8: \"HUESATURATION\",\n 9: \"BRIGHTNESSCONTRAST\",\n 10: \"THRESHOLD\",\n 11: \"POSTERIZE\",\n 12: \"CHANNELMIXER\",\n 13: \"GRADIENTMAP\",\n 14: \"INVERSION\",\n 15: \"EXPOSURE\",\n 16: \"PHOTOFILTER\",\n 17: \"SELECTIVECOLOR\",\n 18: \"SMARTOBJECT\",\n 20: \"VIBRANCE\",\n 21: \"VIDEO\",\n 22: \"BLACKANDWHITE\",\n 23: \"LAYER3D\",\n 26: \"COLORLOOKUP\",\n };\n\n /**\n * Layer kind as an enum-name string (e.g. \"LayerKind.NORMAL\"). ArtLayer only;\n * reading it on a LayerSet throws. Check `typename` first.\n *\n * @remarks GRADIENTFILL=4 and PATTERNFILL=4 collide in Adobe's enums, so a\n * kind of 4 always maps to GRADIENTFILL.\n */\n get kind(): Promise<string> {\n return evalNumber(this._jsx, `${this._path}.kind`).then(\n (code) => PhotoshopLayer._LAYER_KIND_MAP[code] ?? `LayerKind.UNKNOWN_${code}`\n );\n }\n\n /** Object type name (\"ArtLayer\" or \"LayerSet\"). */\n get typename(): Promise<string> {\n return evalString(this._jsx, `${this._path}.typename`);\n }\n\n // --- Property writes -----------------------------------------------------\n\n /** Set the layer name. */\n async setName(value: string): Promise<void> {\n await this._jsx.run(JsxBuilder.assign(`${this._path}.name`, JsxBuilder.string(value)));\n }\n\n /** Set layer visibility. */\n async setVisible(value: boolean): Promise<void> {\n await this._jsx.run(JsxBuilder.assign(`${this._path}.visible`, JsxBuilder.boolean(value)));\n }\n\n /** Set layer opacity (0-100). */\n async setOpacity(value: number): Promise<void> {\n await this._jsx.run(JsxBuilder.assign(`${this._path}.opacity`, JsxBuilder.number(value)));\n }\n\n /**\n * Set the blend mode.\n *\n * @example\n * import { BlendMode } from \"@ps-generator-bridge/sdk/plugin\";\n * await layer.setBlendMode(BlendMode.MULTIPLY);\n */\n async setBlendMode(value: BlendModeValue): Promise<void> {\n await this._jsx.run(JsxBuilder.assign(`${this._path}.blendMode`, JsxBuilder.enum_(value)));\n }\n\n /** Set whether the layer is fully locked. */\n async setAllLocked(value: boolean): Promise<void> {\n await this._jsx.run(JsxBuilder.assign(`${this._path}.allLocked`, JsxBuilder.boolean(value)));\n }\n\n // --- Methods -------------------------------------------------------------\n\n /** Delete this layer. */\n async remove(): Promise<void> {\n await this._jsx.run(`${this._path}.remove()`);\n }\n\n /** Duplicate this layer (the copy becomes `activeLayer`). */\n async duplicate(): Promise<PhotoshopLayer> {\n await this._jsx.run(`${this._path}.duplicate()`);\n return new PhotoshopLayer(this._jsx, \"app.activeDocument.activeLayer\");\n }\n\n /**\n * Move this layer relative to another.\n *\n * @param relativeObjectJsxPath JSX path of the reference layer (e.g.\n * \"app.activeDocument.layers[0]\").\n * @param insertionLocation placement enum.\n *\n * @remarks Pass a bare JSX path expression. A `PhotoshopLayers.getByName()`\n * path contains quotes and cannot be used as a reference expression here.\n *\n * @example\n * import { ElementPlacement } from \"@ps-generator-bridge/sdk/plugin\";\n * await layer.move(\"app.activeDocument.layers[0]\", ElementPlacement.PLACEBEFORE);\n */\n async move(\n relativeObjectJsxPath: string,\n insertionLocation: ElementPlacementValue\n ): Promise<void> {\n await this._jsx.run(\n `${this._path}.move(${relativeObjectJsxPath}, ${JsxBuilder.enum_(insertionLocation)})`\n );\n }\n\n /** Translate the layer by a pixel delta. */\n async translate(deltaX: number, deltaY: number): Promise<void> {\n await this._jsx.run(\n JsxBuilder.call(`${this._path}.translate`, [\n JsxBuilder.number(deltaX),\n JsxBuilder.number(deltaY),\n ])\n );\n }\n\n /**\n * Scale the layer.\n *\n * @param horizontal horizontal scale percent (150 = 150%).\n * @param vertical vertical scale percent.\n * @param anchor scaling anchor (optional).\n */\n async resize(horizontal: number, vertical: number, anchor?: AnchorPositionValue): Promise<void> {\n const args: string[] = [JsxBuilder.number(horizontal), JsxBuilder.number(vertical)];\n if (anchor !== undefined) args.push(JsxBuilder.enum_(anchor));\n await this._jsx.run(JsxBuilder.call(`${this._path}.resize`, args));\n }\n\n /**\n * Rotate the layer.\n *\n * @param angle degrees, clockwise positive.\n * @param anchor rotation anchor (optional).\n */\n async rotate(angle: number, anchor?: AnchorPositionValue): Promise<void> {\n const args: string[] = [JsxBuilder.number(angle)];\n if (anchor !== undefined) args.push(JsxBuilder.enum_(anchor));\n await this._jsx.run(JsxBuilder.call(`${this._path}.rotate`, args));\n }\n\n /** Move the layer to the end of its stack. */\n async moveToEnd(): Promise<void> {\n await this._jsx.run(`${this._path}.moveToEnd()`);\n }\n}\n","import type { PsJsxRunner } from \"./jsx-runner\";\nimport { evalNumber } from \"./jsx-runner\";\nimport { JsxBuilder } from \"./JsxBuilder\";\nimport { PhotoshopLayer } from \"./PhotoshopLayer\";\n\n/**\n * Wraps an ExtendScript Layers collection (`Document.layers` or\n * `LayerSet.layers`).\n *\n * @example\n * const layers = this.photoshop.activeDocument.layers;\n * const count = await layers.length;\n * const first = layers.at(0);\n * const named = layers.getByName(\"Background\");\n */\nexport class PhotoshopLayers {\n constructor(\n private readonly _jsx: PsJsxRunner,\n private readonly _path: string // e.g. \"app.activeDocument.layers\"\n ) {}\n\n /** Number of layers in the collection. */\n get length(): Promise<number> {\n return evalNumber(this._jsx, `${this._path}.length`);\n }\n\n /**\n * Access a layer by index. The collection is 0-based, matching JavaScript;\n * `layers[0]` is the top-most layer.\n */\n at(index: number): PhotoshopLayer {\n return new PhotoshopLayer(this._jsx, `${this._path}[${index}]`);\n }\n\n /**\n * Look up a layer by name (case-sensitive). The returned wrapper works for\n * property reads/writes but its path contains a `getByName(...)` call, so it\n * must not be passed as `PhotoshopLayer.move()`'s reference path.\n */\n getByName(name: string): PhotoshopLayer {\n const escapedName = JsxBuilder.string(name);\n return new PhotoshopLayer(this._jsx, `${this._path}.getByName(${escapedName})`);\n }\n}\n","import type { PsJsxRunner } from \"./jsx-runner\";\nimport { evalBool, evalJson } from \"./jsx-runner\";\nimport { JsxBuilder } from \"./JsxBuilder\";\nimport type { SelectionTypeValue } from \"./enums\";\nimport type { PsBounds } from \"./types\";\n\n/**\n * Wraps `Document.selection`.\n *\n * @example\n * const sel = this.photoshop.activeDocument.selection;\n * await sel.selectAll();\n * const bounds = await sel.bounds;\n * await sel.deselect();\n */\nexport class PhotoshopSelection {\n constructor(\n private readonly _jsx: PsJsxRunner,\n private readonly _path: string // e.g. \"app.activeDocument.selection\"\n ) {}\n\n /**\n * Selection bounds `[left, top, right, bottom]`. Throws when there is no\n * selection.\n *\n * @remarks Units follow `rulerUnits`.\n */\n get bounds(): Promise<PsBounds> {\n const expr = `(function(){ var b = ${this._path}.bounds; return [b[0], b[1], b[2], b[3]]; })()`;\n return evalJson<PsBounds>(this._jsx, expr);\n }\n\n /** Whether the selection is a solid (un-feathered) rectangle. */\n get solid(): Promise<boolean> {\n return evalBool(this._jsx, `${this._path}.solid`);\n }\n\n // --- Methods -------------------------------------------------------------\n\n /** Select the whole canvas. */\n async selectAll(): Promise<void> {\n await this._jsx.run(`${this._path}.selectAll()`);\n }\n\n /** Deselect. */\n async deselect(): Promise<void> {\n await this._jsx.run(`${this._path}.deselect()`);\n }\n\n /** Invert the selection. */\n async invert(): Promise<void> {\n await this._jsx.run(`${this._path}.invert()`);\n }\n\n /**\n * Create a selection from a region of points.\n *\n * @param region polygon points, e.g. `[[0,0],[100,0],[100,100],[0,100]]`.\n * @param type selection operation (optional, defaults to replace).\n * @param feather feather radius in pixels (optional).\n * @param antiAlias anti-alias the edges (optional).\n *\n * @example\n * import { SelectionType } from \"@ps-generator-bridge/sdk/plugin\";\n * await sel.select([[0,0],[100,0],[100,100],[0,100]], SelectionType.REPLACE, 0, true);\n */\n async select(\n region: number[][],\n type?: SelectionTypeValue,\n feather?: number,\n antiAlias?: boolean\n ): Promise<void> {\n const args: string[] = [JsxBuilder.regionArray(region)];\n if (type !== undefined) args.push(JsxBuilder.enum_(type));\n if (feather !== undefined) args.push(JsxBuilder.number(feather));\n if (antiAlias !== undefined) args.push(JsxBuilder.boolean(antiAlias));\n await this._jsx.run(JsxBuilder.call(`${this._path}.select`, args));\n }\n\n /** Grow the selection by `by` pixels. */\n async expand(by: number): Promise<void> {\n await this._jsx.run(JsxBuilder.call(`${this._path}.expand`, [JsxBuilder.number(by)]));\n }\n\n /** Shrink the selection by `by` pixels. */\n async contract(by: number): Promise<void> {\n await this._jsx.run(JsxBuilder.call(`${this._path}.contract`, [JsxBuilder.number(by)]));\n }\n\n /** Feather the selection edge by `by` pixels. */\n async feather(by: number): Promise<void> {\n await this._jsx.run(JsxBuilder.call(`${this._path}.feather`, [JsxBuilder.number(by)]));\n }\n\n /** Translate the selection boundary (content stays put). */\n async translateBoundary(deltaX: number, deltaY: number): Promise<void> {\n await this._jsx.run(\n JsxBuilder.call(`${this._path}.translateBoundary`, [\n JsxBuilder.number(deltaX),\n JsxBuilder.number(deltaY),\n ])\n );\n }\n}\n","import type { PsJsxRunner } from \"./jsx-runner\";\nimport { evalNumber, evalString, evalBool, evalJson } from \"./jsx-runner\";\nimport { JsxBuilder } from \"./JsxBuilder\";\nimport { PhotoshopLayer } from \"./PhotoshopLayer\";\nimport { PhotoshopLayers } from \"./PhotoshopLayers\";\nimport { PhotoshopSelection } from \"./PhotoshopSelection\";\nimport type { SaveOptionsValue } from \"./enums\";\nimport type { PsBounds } from \"./types\";\n\n/**\n * Wraps an ExtendScript Document.\n *\n * @example\n * const doc = this.photoshop.activeDocument;\n * const name = await doc.name;\n * const [width, height] = await Promise.all([doc.width, doc.height]);\n * await doc.save();\n */\nexport class PhotoshopDocument {\n constructor(\n private readonly _jsx: PsJsxRunner,\n private readonly _path: string // e.g. \"app.activeDocument\"\n ) {}\n\n // --- Read-only properties -----------------------------------------------\n\n /** Document name (file name, without directory). */\n get name(): Promise<string> {\n return evalString(this._jsx, `${this._path}.name`);\n }\n\n /** Unique document id. */\n get id(): Promise<number> {\n return evalNumber(this._jsx, `${this._path}.id`);\n }\n\n /**\n * Document width.\n *\n * @remarks The unit follows Photoshop's current `app.preferences.rulerUnits`.\n * For guaranteed pixels, set `rulerUnits` to `Units.PIXELS` first (e.g. via\n * `this.jsx.run(...)`).\n */\n get width(): Promise<number> {\n return evalNumber(this._jsx, `${this._path}.width`);\n }\n\n /**\n * Document height.\n *\n * @remarks The unit follows `rulerUnits` (see {@link width}).\n */\n get height(): Promise<number> {\n return evalNumber(this._jsx, `${this._path}.height`);\n }\n\n /** Document resolution (PPI). */\n get resolution(): Promise<number> {\n return evalNumber(this._jsx, `${this._path}.resolution`);\n }\n\n /** Document color mode as an enum-name string (e.g. \"DocumentMode.RGB\"). */\n get mode(): Promise<string> {\n const expr = `(function(){\n var m = ${this._path}.mode;\n if (m === DocumentMode.RGB) return \"DocumentMode.RGB\";\n if (m === DocumentMode.CMYK) return \"DocumentMode.CMYK\";\n if (m === DocumentMode.GRAYSCALE) return \"DocumentMode.GRAYSCALE\";\n if (m === DocumentMode.LAB) return \"DocumentMode.LAB\";\n if (m === DocumentMode.BITMAP) return \"DocumentMode.BITMAP\";\n if (m === DocumentMode.INDEXEDCOLOR) return \"DocumentMode.INDEXEDCOLOR\";\n if (m === DocumentMode.MULTICHANNEL) return \"DocumentMode.MULTICHANNEL\";\n if (m === DocumentMode.DUOTONE) return \"DocumentMode.DUOTONE\";\n return String(m);\n })()`;\n return evalJson<string>(this._jsx, expr);\n }\n\n /** Whether the document is saved since its last change. */\n get saved(): Promise<boolean> {\n return evalBool(this._jsx, `${this._path}.saved`);\n }\n\n /**\n * Full document path (native `fsName`). For an unsaved document this may\n * return a temporary path or throw.\n */\n get fullName(): Promise<string> {\n return evalString(this._jsx, `${this._path}.fullName.fsName`);\n }\n\n /** Directory containing the document (native `fsName`). */\n get path(): Promise<string> {\n return evalString(this._jsx, `${this._path}.path.fsName`);\n }\n\n // --- Child navigation (synchronous; no request) -------------------------\n\n /** The active layer. */\n get activeLayer(): PhotoshopLayer {\n return new PhotoshopLayer(this._jsx, `${this._path}.activeLayer`);\n }\n\n /** The Layers collection (ArtLayers + LayerSets). */\n get layers(): PhotoshopLayers {\n return new PhotoshopLayers(this._jsx, `${this._path}.layers`);\n }\n\n /** The selection. */\n get selection(): PhotoshopSelection {\n return new PhotoshopSelection(this._jsx, `${this._path}.selection`);\n }\n\n // --- Methods -------------------------------------------------------------\n\n /** Save the document in its current format. */\n async save(): Promise<void> {\n await this._jsx.run(`${this._path}.save()`);\n }\n\n /**\n * Close the document.\n *\n * @param saving save behavior before closing (defaults to not saving).\n *\n * @example\n * import { SaveOptions } from \"@ps-generator-bridge/sdk/plugin\";\n * await doc.close(SaveOptions.DONOTSAVECHANGES);\n */\n async close(saving: SaveOptionsValue = \"SaveOptions.DONOTSAVECHANGES\"): Promise<void> {\n await this._jsx.run(JsxBuilder.call(`${this._path}.close`, [JsxBuilder.enum_(saving)]));\n }\n\n /**\n * Save to a path. Mirrors ExtendScript\n * `saveAs(saveIn, options?, asCopy?, extensionType?)`; only `saveIn` and\n * `asCopy` are exposed, `options` is undefined and `extensionType` is left to\n * the Photoshop default.\n *\n * @param saveIn destination path.\n * @param asCopy save as a copy (does not change the document's saved state).\n */\n async saveAs(saveIn: string, asCopy?: boolean): Promise<void> {\n const script = `${this._path}.saveAs(${JsxBuilder.file(saveIn)}${\n asCopy !== undefined ? `, undefined, ${JsxBuilder.boolean(asCopy)}` : \"\"\n })`;\n await this._jsx.run(script);\n }\n\n /** Flatten all layers into a single background layer. */\n async flatten(): Promise<void> {\n await this._jsx.run(`${this._path}.flatten()`);\n }\n\n /** Merge all visible layers. */\n async mergeVisibleLayers(): Promise<void> {\n await this._jsx.run(`${this._path}.mergeVisibleLayers()`);\n }\n\n /** Rasterize all layers. */\n async rasterizeAllLayers(): Promise<void> {\n await this._jsx.run(`${this._path}.rasterizeAllLayers()`);\n }\n\n /**\n * Duplicate the document.\n *\n * @param name optional name for the copy.\n * @returns the duplicated document.\n *\n * @remarks Assumes `duplicate()` makes the copy the active document, so the\n * result points at `app.activeDocument`.\n */\n async duplicate(name?: string): Promise<PhotoshopDocument> {\n const args = name !== undefined ? [JsxBuilder.string(name)] : [];\n await this._jsx.run(JsxBuilder.call(`${this._path}.duplicate`, args));\n return new PhotoshopDocument(this._jsx, \"app.activeDocument\");\n }\n\n /**\n * Resize the canvas.\n *\n * @param width new width in pixels.\n * @param height new height in pixels.\n * @param anchor anchor position (optional, defaults to center).\n *\n * @example\n * import { AnchorPosition } from \"@ps-generator-bridge/sdk/plugin\";\n * await doc.resizeCanvas(1920, 1080, AnchorPosition.MIDDLECENTER);\n */\n async resizeCanvas(width: number, height: number, anchor?: string): Promise<void> {\n const args: string[] = [JsxBuilder.number(width), JsxBuilder.number(height)];\n if (anchor !== undefined) args.push(JsxBuilder.enum_(anchor));\n await this._jsx.run(JsxBuilder.call(`${this._path}.resizeCanvas`, args));\n }\n\n /**\n * Resize the image.\n *\n * @param width new width in pixels (optional).\n * @param height new height in pixels (optional).\n * @param resolution new resolution in PPI (optional).\n */\n async resizeImage(width?: number, height?: number, resolution?: number): Promise<void> {\n const args: string[] = [\n width !== undefined ? JsxBuilder.number(width) : \"undefined\",\n height !== undefined ? JsxBuilder.number(height) : \"undefined\",\n resolution !== undefined ? JsxBuilder.number(resolution) : \"undefined\",\n ];\n await this._jsx.run(JsxBuilder.call(`${this._path}.resizeImage`, args));\n }\n\n /** Rotate the canvas by `angle` degrees. */\n async rotateCanvas(angle: number): Promise<void> {\n await this._jsx.run(JsxBuilder.call(`${this._path}.rotateCanvas`, [JsxBuilder.number(angle)]));\n }\n\n /**\n * Crop the document to `bounds` `[left, top, right, bottom]` (pixels).\n *\n * @remarks Only `bounds` is exposed; ExtendScript `crop()` also takes angle,\n * width and height — reach those via `this.jsx.run(...)` if needed.\n */\n async crop(bounds: PsBounds): Promise<void> {\n const script = `${this._path}.crop(${JsxBuilder.numberArray(Array.from(bounds))})`;\n await this._jsx.run(script);\n }\n}\n","import type { PsJsxRunner } from \"./jsx-runner\";\nimport { evalString, evalJson } from \"./jsx-runner\";\nimport { JsxBuilder } from \"./JsxBuilder\";\nimport { PhotoshopDocument } from \"./PhotoshopDocument\";\nimport type { PsColor } from \"./types\";\n\n/**\n * Wraps the ExtendScript global `app` object.\n *\n * @example\n * const version = await this.photoshop.app.version; // \"25.0\"\n * await this.photoshop.app.open(\"/path/to/design.psd\");\n */\nexport class PhotoshopApp {\n private readonly _path = \"app\";\n\n constructor(private readonly _jsx: PsJsxRunner) {}\n\n // --- Read-only properties -----------------------------------------------\n\n /** Photoshop version (e.g. \"25.0\"). */\n get version(): Promise<string> {\n return evalString(this._jsx, `${this._path}.version`);\n }\n\n /** Application locale (e.g. \"zh_CN\"). */\n get locale(): Promise<string> {\n return evalString(this._jsx, `${this._path}.locale`);\n }\n\n /** Application name (e.g. \"Adobe Photoshop\"). */\n get name(): Promise<string> {\n return evalString(this._jsx, `${this._path}.name`);\n }\n\n /** Internal build number. */\n get build(): Promise<string> {\n return evalString(this._jsx, `${this._path}.build`);\n }\n\n /**\n * Install path (native `fsName`). `app.path` is a File in ExtendScript, so the\n * string comes from `.fsName`.\n */\n get path(): Promise<string> {\n return evalString(this._jsx, `${this._path}.path.fsName`);\n }\n\n /**\n * Current foreground color (RGB).\n *\n * @remarks The first version returns only the RGB approximation; in CMYK/Lab\n * documents this is Photoshop's converted RGB and may lose precision. The\n * `cmyk` field is reserved and currently always undefined.\n */\n get foregroundColor(): Promise<PsColor> {\n const expr = `(function(){\n var c = ${this._path}.foregroundColor;\n return {\n model: \"rgb\",\n rgb: { red: c.rgb.red, green: c.rgb.green, blue: c.rgb.blue, hexValue: c.rgb.hexValue }\n };\n })()`;\n return evalJson<PsColor>(this._jsx, expr);\n }\n\n /** Shortcut for `activeDocument` reached through the `app` path. */\n get activeDocument(): PhotoshopDocument {\n return new PhotoshopDocument(this._jsx, `${this._path}.activeDocument`);\n }\n\n // --- Methods -------------------------------------------------------------\n\n /**\n * Open a file and return its Document wrapper. The opened document becomes the\n * active document.\n *\n * @param filePath native or POSIX path.\n *\n * @example\n * const doc = await this.photoshop.app.open(\"/Users/me/design.psd\");\n */\n async open(filePath: string): Promise<PhotoshopDocument> {\n const script = JsxBuilder.call(`${this._path}.open`, [JsxBuilder.file(filePath)]);\n await this._jsx.run(script);\n return new PhotoshopDocument(this._jsx, `${this._path}.activeDocument`);\n }\n\n /** Emit a beep. */\n async beep(): Promise<void> {\n await this._jsx.run(`${this._path}.beep()`);\n }\n}\n","import type { PsJsxRunner } from \"./jsx-runner\";\nimport { PhotoshopApp } from \"./PhotoshopApp\";\nimport { PhotoshopDocument } from \"./PhotoshopDocument\";\n\n/**\n * Entry point of the Photoshop DOM proxy. A plugin reaches it through\n * `this.photoshop`:\n *\n * ```ts\n * const version = await this.photoshop.app.version;\n * const name = await this.photoshop.activeDocument.name;\n * ```\n *\n * Transport-agnostic: every property read and method call lowers to an\n * ExtendScript string run through the injected {@link PsJsxRunner}. The proxy\n * holds no PS state of its own.\n *\n * @remarks\n * - `app` maps to the ExtendScript global `app` (Application).\n * - `activeDocument` is a shortcut for `app.activeDocument`.\n * - With no active document, reading any property of `activeDocument` throws.\n */\nexport class PsPhotoshopProxy {\n /** Application wrapper; its path is fixed to \"app\". */\n readonly app: PhotoshopApp;\n\n private readonly _jsx: PsJsxRunner;\n\n constructor(jsx: PsJsxRunner) {\n this._jsx = jsx;\n this.app = new PhotoshopApp(this._jsx);\n }\n\n /**\n * The active document (shortcut for `app.activeDocument`). A fresh wrapper is\n * created on each access; wrappers are lightweight and stateless.\n */\n get activeDocument(): PhotoshopDocument {\n return new PhotoshopDocument(this._jsx, \"app.activeDocument\");\n }\n}\n","/**\n * Photoshop DOM enum constants. Each value is the ExtendScript global enum name\n * string, embeddable directly into a JSX fragment.\n *\n * @example\n * await this.photoshop.activeDocument.close(SaveOptions.DONOTSAVECHANGES);\n * // emits JSX: app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)\n */\n\nexport const SaveOptions = {\n /** Do not save changes. */\n DONOTSAVECHANGES: \"SaveOptions.DONOTSAVECHANGES\",\n /** Prompt the user. */\n PROMPTTOSAVECHANGES: \"SaveOptions.PROMPTTOSAVECHANGES\",\n /** Save changes. */\n SAVECHANGES: \"SaveOptions.SAVECHANGES\",\n} as const;\nexport type SaveOptionsValue = (typeof SaveOptions)[keyof typeof SaveOptions];\n\nexport const LayerKind = {\n NORMAL: \"LayerKind.NORMAL\",\n TEXT: \"LayerKind.TEXT\",\n SMARTOBJECT: \"LayerKind.SMARTOBJECT\",\n SOLIDFILL: \"LayerKind.SOLIDFILL\",\n /**\n * @remarks In `enums.d.ts`, GRADIENTFILL=4 and PATTERNFILL=4 share a value\n * (an Adobe enum conflict); a kind of 4 always maps back to GRADIENTFILL and\n * the two cannot be told apart at runtime (disambiguate by layer name etc.).\n */\n GRADIENTFILL: \"LayerKind.GRADIENTFILL\",\n PATTERNFILL: \"LayerKind.PATTERNFILL\",\n LEVELS: \"LayerKind.LEVELS\",\n CURVES: \"LayerKind.CURVES\",\n BRIGHTNESSCONTRAST: \"LayerKind.BRIGHTNESSCONTRAST\",\n HUESATURATION: \"LayerKind.HUESATURATION\",\n COLORBALANCE: \"LayerKind.COLORBALANCE\",\n INVERSION: \"LayerKind.INVERSION\",\n POSTERIZE: \"LayerKind.POSTERIZE\",\n THRESHOLD: \"LayerKind.THRESHOLD\",\n EXPOSURE: \"LayerKind.EXPOSURE\",\n VIBRANCE: \"LayerKind.VIBRANCE\",\n VIDEO: \"LayerKind.VIDEO\",\n LAYER3D: \"LayerKind.LAYER3D\",\n BLACKANDWHITE: \"LayerKind.BLACKANDWHITE\",\n CHANNELMIXER: \"LayerKind.CHANNELMIXER\",\n GRADIENTMAP: \"LayerKind.GRADIENTMAP\",\n SELECTIVECOLOR: \"LayerKind.SELECTIVECOLOR\",\n PHOTOFILTER: \"LayerKind.PHOTOFILTER\",\n COLORLOOKUP: \"LayerKind.COLORLOOKUP\",\n} as const;\nexport type LayerKindValue = (typeof LayerKind)[keyof typeof LayerKind];\n\nexport const BlendMode = {\n NORMAL: \"BlendMode.NORMAL\",\n DISSOLVE: \"BlendMode.DISSOLVE\",\n DARKEN: \"BlendMode.DARKEN\",\n MULTIPLY: \"BlendMode.MULTIPLY\",\n COLORBURN: \"BlendMode.COLORBURN\",\n LINEARBURN: \"BlendMode.LINEARBURN\",\n DARKERCOLOR: \"BlendMode.DARKERCOLOR\",\n LIGHTEN: \"BlendMode.LIGHTEN\",\n SCREEN: \"BlendMode.SCREEN\",\n COLORDODGE: \"BlendMode.COLORDODGE\",\n LINEARDODGE: \"BlendMode.LINEARDODGE\",\n LIGHTERCOLOR: \"BlendMode.LIGHTERCOLOR\",\n OVERLAY: \"BlendMode.OVERLAY\",\n SOFTLIGHT: \"BlendMode.SOFTLIGHT\",\n HARDLIGHT: \"BlendMode.HARDLIGHT\",\n VIVIDLIGHT: \"BlendMode.VIVIDLIGHT\",\n LINEARLIGHT: \"BlendMode.LINEARLIGHT\",\n PINLIGHT: \"BlendMode.PINLIGHT\",\n HARDMIX: \"BlendMode.HARDMIX\",\n DIFFERENCE: \"BlendMode.DIFFERENCE\",\n EXCLUSION: \"BlendMode.EXCLUSION\",\n SUBTRACT: \"BlendMode.SUBTRACT\",\n DIVIDE: \"BlendMode.DIVIDE\",\n HUE: \"BlendMode.HUE\",\n SATURATION: \"BlendMode.SATURATION\",\n COLORBLEND: \"BlendMode.COLORBLEND\",\n LUMINOSITY: \"BlendMode.LUMINOSITY\",\n PASSTHROUGH: \"BlendMode.PASSTHROUGH\",\n} as const;\nexport type BlendModeValue = (typeof BlendMode)[keyof typeof BlendMode];\n\nexport const ElementPlacement = {\n PLACEATBEGINNING: \"ElementPlacement.PLACEATBEGINNING\",\n PLACEINSIDE: \"ElementPlacement.PLACEINSIDE\",\n PLACEBEFORE: \"ElementPlacement.PLACEBEFORE\",\n PLACEAFTER: \"ElementPlacement.PLACEAFTER\",\n PLACEATEND: \"ElementPlacement.PLACEATEND\",\n} as const;\nexport type ElementPlacementValue = (typeof ElementPlacement)[keyof typeof ElementPlacement];\n\nexport const AnchorPosition = {\n TOPLEFT: \"AnchorPosition.TOPLEFT\",\n TOPCENTER: \"AnchorPosition.TOPCENTER\",\n TOPRIGHT: \"AnchorPosition.TOPRIGHT\",\n MIDDLELEFT: \"AnchorPosition.MIDDLELEFT\",\n MIDDLECENTER: \"AnchorPosition.MIDDLECENTER\",\n MIDDLERIGHT: \"AnchorPosition.MIDDLERIGHT\",\n BOTTOMLEFT: \"AnchorPosition.BOTTOMLEFT\",\n BOTTOMCENTER: \"AnchorPosition.BOTTOMCENTER\",\n BOTTOMRIGHT: \"AnchorPosition.BOTTOMRIGHT\",\n} as const;\nexport type AnchorPositionValue = (typeof AnchorPosition)[keyof typeof AnchorPosition];\n\nexport const DocumentMode = {\n BITMAP: \"DocumentMode.BITMAP\",\n GRAYSCALE: \"DocumentMode.GRAYSCALE\",\n RGB: \"DocumentMode.RGB\",\n CMYK: \"DocumentMode.CMYK\",\n LAB: \"DocumentMode.LAB\",\n INDEXEDCOLOR: \"DocumentMode.INDEXEDCOLOR\",\n MULTICHANNEL: \"DocumentMode.MULTICHANNEL\",\n DUOTONE: \"DocumentMode.DUOTONE\",\n} as const;\nexport type DocumentModeValue = (typeof DocumentMode)[keyof typeof DocumentMode];\n\nexport const SelectionType = {\n REPLACE: \"SelectionType.REPLACE\",\n EXTEND: \"SelectionType.EXTEND\",\n DIMINISH: \"SelectionType.DIMINISH\",\n INTERSECT: \"SelectionType.INTERSECT\",\n} as const;\nexport type SelectionTypeValue = (typeof SelectionType)[keyof typeof SelectionType];\n","import type { PluginHost } from \"./host\";\nimport type { PluginClientBus } from \"./bus\";\nimport type { JsxRunnerApi, PhotoshopEvents } from \"@ps-generator-bridge/generator/contract\";\nimport { PsPhotoshopProxy } from \"../photoshop\";\n\n// A *global* brand so \"extends BasePlugin\" can be detected across\n// separately-bundled SDK copies (an external plugin bundles its own\n// @ps-generator-bridge/sdk/plugin, so `instanceof BasePlugin` against the\n// server's copy would fail). Stamped on BasePlugin.prototype; any subclass\n// inherits it via the prototype chain. See `isBasePluginClass`.\nconst BASE_PLUGIN_BRAND = Symbol.for(\"ps-generator-bridge.BasePlugin\");\n\n/**\n * Base class for plugins (ADR 0009 / RFC 0003). A plugin is the orchestration\n * layer above feature modules: it composes one or more module calls (reached\n * through `this.modules`, e.g. `this.modules.layer`) and exposes\n * its own `@ws`/`@api` handlers, bootstrapped the same way as modules.\n *\n * Dependency direction is strictly downward: a plugin may depend on modules,\n * never on sibling plugins and never in reverse (modules must not reach\n * plugins). `plugin` is the abstract PluginHost interface — never the\n * concrete server plugin — so a plugin depends only on this SDK subpath.\n *\n * `@ws`/`@api` names are written in full by the developer (e.g.\n * `@ws(\"LayerOps:merge\")`) — `bootstrap` does not inject or derive a namespace.\n * Use a `Domain:action` prefix to keep names from colliding across modules and\n * plugins (ADR 0006 convention); the assembler's `registerMethod` is a silent\n * `Map.set`, so prefix uniqueness is the developer's responsibility.\n *\n * Client push: `broadcast`/`send` reach only this plugin's own online clients,\n * via the PluginClientBus the server attaches after construction. A subclass\n * may override `onConnect`/`onDisconnect` to react to its clients coming and\n * going; the defaults are no-ops.\n */\nexport abstract class BasePlugin {\n /** Stable URL identity of this plugin (read from the class's `static id`). */\n readonly id: string;\n /** The abstract plugin contract (never the concrete server plugin). */\n protected readonly plugin: PluginHost;\n\n private bus: PluginClientBus | undefined;\n private _photoshop: PsPhotoshopProxy | undefined;\n\n constructor(id: string, plugin: PluginHost) {\n this.id = id;\n this.plugin = plugin;\n }\n\n /** Feature modules, reached by short key (shortcut for `this.plugin.modules`). */\n protected get modules(): PluginHost[\"modules\"] {\n return this.plugin.modules;\n }\n\n /**\n * The jsx runner scoped to this plugin's own `jsx/` dir (shortcut for\n * `this.plugin.jsx`, RFC 0005). `jsx.execute(\"x\")` runs `<pluginRoot>/jsx/x.jsx`;\n * `jsx.executeBuiltin(\"Document/getDocumentInfo\")` reaches the host's built-in\n * tree.\n */\n protected get jsx(): JsxRunnerApi {\n return this.plugin.jsx;\n }\n\n /**\n * Typed, listen-only Photoshop event stream (shortcut for `this.plugin.events`).\n * Subscriptions are lazy on the server side: the first `on`/`once` for an event\n * subscribes upstream, and the last `off` unsubscribes.\n */\n protected get events(): PhotoshopEvents {\n return this.plugin.events;\n }\n\n /**\n * Photoshop DOM proxy, a typed object wrapper over `this.jsx`. Read and write\n * the live document through `this.photoshop.app` / `this.photoshop.activeDocument`\n * (e.g. `await this.photoshop.activeDocument.name`) instead of hand-writing\n * ExtendScript. Lazily built once and backed by this plugin's own jsx runner;\n * drop to `this.jsx.run(...)` for anything the proxy does not cover.\n */\n protected get photoshop(): PsPhotoshopProxy {\n return (this._photoshop ??= new PsPhotoshopProxy(this.jsx));\n }\n\n /**\n * Attach the per-plugin client bus. Called by the server's assembler after\n * construction and before `listen`, so `broadcast`/`send` are live by the time\n * any handler can fire. Not part of the public Plugin authoring API.\n */\n _attachBus(bus: PluginClientBus): void {\n this.bus = bus;\n }\n\n /** Push an Event to every online client of this plugin. */\n broadcast(type: string, data: unknown): void {\n this.bus?.broadcast(type, data);\n }\n\n /** Push an Event to one client of this plugin (no-op if not connected). */\n send(clientId: string, type: string, data: unknown): void {\n this.bus?.send(clientId, type, data);\n }\n\n /** Called after a client handshake registers with this plugin. Default no-op. */\n onConnect(_clientId: string): void {}\n\n /** Called after a client socket is removed from this plugin. Default no-op. */\n onDisconnect(_clientId: string): void {}\n}\n\n// Stamp the brand on the prototype (inherited by every subclass) so the loader's\n// isBasePluginClass check works across separately-bundled SDK copies.\nObject.defineProperty(BasePlugin.prototype, BASE_PLUGIN_BRAND, {\n value: true,\n enumerable: false,\n configurable: false,\n writable: false,\n});\n\n/**\n * Whether `S` is a class that extends BasePlugin. Uses the global brand rather\n * than `instanceof` so it works when `S` came from a separately-bundled copy of\n * this SDK (external plugins). The brand is inherited via the prototype chain,\n * so direct and indirect subclasses both qualify.\n */\nexport function isBasePluginClass(S: unknown): boolean {\n if (typeof S !== \"function\") return false;\n const proto = (S as { prototype?: unknown }).prototype;\n return proto != null && Boolean((proto as Record<symbol, unknown>)[BASE_PLUGIN_BRAND]);\n}\n","import type { HttpMethod, ApiRouteSpec, AssemblyTarget } from \"./types\";\n\n// Standard TC39 decorators stash metadata on the class under Symbol.metadata.\n// Node (and PS's Node 18) lacks the well-known symbol at runtime, so we polyfill\n// it once, before any decorated class is defined (this module is imported by\n// every module/plugin file that uses @ws/@api). Verified to work under\n// tsup/esbuild targeting node18. The symbol is captured into a typed const so\n// the rest of the file does not depend on `Symbol.metadata` being present in the\n// TS lib (target is ES2021).\n(Symbol as { metadata?: symbol }).metadata ??= Symbol.for(\"Symbol.metadata\");\nconst METADATA = (Symbol as unknown as { metadata: symbol }).metadata;\n\n// A *global* symbol so the devkit works across separately-bundled SDK copies:\n// an external plugin bundles its own @ps-generator-bridge/sdk/plugin, so its\n// @ws/@api decorator and the server's bootstrap must agree on the handler-stash\n// key even though they are different module identities. A unique Symbol() would\n// not match; Symbol.for is shared across bundles. The stash itself is still\n// per-class (own-property on each class's metadata), so this introduces no\n// cross-class leakage.\nconst HANDLERS = Symbol.for(\"ps-generator-bridge.handlers\");\n\ninterface WsHandlerMeta {\n kind: \"ws\";\n name: string;\n methodKey: string;\n}\n\ninterface ApiHandlerMeta {\n kind: \"api\";\n method: HttpMethod | HttpMethod[];\n url: string;\n methodKey: string;\n}\n\ntype HandlerMeta = WsHandlerMeta | ApiHandlerMeta;\n\ntype MetadataLike = Record<string | symbol, unknown>;\n\n// Push onto the *own* handler array of this class's metadata. `context.metadata`\n// is prototype-chained to the base class, so without the own-property guard a\n// subclass method would append into the base class's array.\nfunction pushHandler(metadata: MetadataLike, meta: HandlerMeta): void {\n if (!Object.prototype.hasOwnProperty.call(metadata, HANDLERS)) {\n metadata[HANDLERS] = [];\n }\n (metadata[HANDLERS] as HandlerMeta[]).push(meta);\n}\n\n/** Mark a method as a WS Request handler registered under `name` (ADR 0006). */\nexport function ws(name: string) {\n return function (_value: unknown, context: ClassMethodDecoratorContext): void {\n pushHandler(context.metadata as MetadataLike, {\n kind: \"ws\",\n name,\n methodKey: String(context.name),\n });\n };\n}\n\n/**\n * Mark a method as an HTTP route handler. `@api(\"/path\")` defaults to GET;\n * `@api({ method, url })` selects the verb(s) (ADR 0006). The route URL is\n * registered verbatim for modules (under `/{path}`) and prefixed with the\n * plugin id for plugins (under `/{pluginId}/{path}`, RFC 0004) — the\n * decorator only collects metadata; the assembly target decides the final URL.\n */\nexport function api(pathOrRoute: string | { method?: HttpMethod | HttpMethod[]; url: string }) {\n const route =\n typeof pathOrRoute === \"string\"\n ? { method: \"GET\" as HttpMethod, url: pathOrRoute }\n : { method: pathOrRoute.method ?? (\"GET\" as HttpMethod), url: pathOrRoute.url };\n return function (_value: unknown, context: ClassMethodDecoratorContext): void {\n pushHandler(context.metadata as MetadataLike, {\n kind: \"api\",\n method: route.method,\n url: route.url,\n methodKey: String(context.name),\n });\n };\n}\n\n/**\n * Second stage of decorator registration (ADR 0006 / 0009): scan a module or\n * plugin instance's collected metadata and register each decorated method\n * against the assembly target, bound to the instance so handlers can reach\n * `this`. Walks the metadata prototype chain so inherited handlers are included.\n * The `@ws`/`@api` name is registered verbatim — developers write the full\n * `Domain:action` name; no namespace is injected. For a plugin, the target is\n * the per-plugin scoped assembler (RFC 0004); for a module, the global Registry.\n */\nexport function bootstrap(instance: object, target: AssemblyTarget): void {\n const ctor = instance.constructor as unknown as Record<symbol, unknown>;\n const collected: HandlerMeta[] = [];\n let metadata = ctor[METADATA] as MetadataLike | undefined;\n while (metadata) {\n if (Object.prototype.hasOwnProperty.call(metadata, HANDLERS)) {\n collected.push(...(metadata[HANDLERS] as HandlerMeta[]));\n }\n metadata = Object.getPrototypeOf(metadata) as MetadataLike | undefined;\n }\n\n for (const meta of collected) {\n const fn = (instance as Record<string, unknown>)[meta.methodKey];\n if (typeof fn !== \"function\") continue;\n const bound = (fn as (...args: unknown[]) => unknown).bind(instance);\n if (meta.kind === \"ws\") {\n target.registerMethod(meta.name, bound);\n } else {\n target.registerApi({ method: meta.method, url: meta.url, handler: bound });\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { L as LayerSpec, e as PsPhotoshopProxy } from './PsPhotoshopProxy-BjnvziWn.cjs';
|
|
2
|
+
export { A as AnchorPosition, w as AnchorPositionValue, x as BlendMode, y as BlendModeValue, D as DocumentMode, z as DocumentModeValue, C as ElementPlacement, F as ElementPlacementValue, G as LayerKind, H as LayerKindValue, J as PhotoshopApp, K as PhotoshopDocument, N as PhotoshopLayer, O as PhotoshopLayers, Q as PhotoshopSelection, T as PsBoundsTuple, U as PsColor, V as SaveOptions, X as SaveOptionsValue, Y as SelectionType, Z as SelectionTypeValue } from './PsPhotoshopProxy-BjnvziWn.cjs';
|
|
3
|
+
|
|
4
|
+
type PsBounds = {
|
|
5
|
+
left: number;
|
|
6
|
+
right: number;
|
|
7
|
+
top: number;
|
|
8
|
+
bottom: number;
|
|
9
|
+
};
|
|
10
|
+
type PsRect = {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The slice of JsxRunner a Plugin reaches through `plugin.jsx` (RFC 0003 /
|
|
19
|
+
* RFC 0005). The concrete JsxRunner `implements` this (and `forPlugin` returns a
|
|
20
|
+
* scoped view that also implements it), so the plugin contract can never drift
|
|
21
|
+
* from the implementation; the SDK re-exports it (via src/contract.ts) as the
|
|
22
|
+
* type of `PluginHost.jsx`. Excludes lifecycle (`init`) and the low-level pixmap
|
|
23
|
+
* channel (`openJSXFile`) — plugins only run jsx by name (or raw string).
|
|
24
|
+
*
|
|
25
|
+
* `execute` resolves against *this handle's own* jsx scope: the built-in `jsx/`
|
|
26
|
+
* tree for the host's root runner, or the plugin's own `jsx/` dir for the scoped
|
|
27
|
+
* view `plugin.jsx` returns. `executeBuiltin` always targets the built-in tree,
|
|
28
|
+
* so a plugin can reach a host domain (e.g. `Document/getDocumentInfo`) without
|
|
29
|
+
* knowing its own id or dir. `run` takes a raw script and is scope-independent.
|
|
30
|
+
*/
|
|
31
|
+
interface JsxRunnerApi {
|
|
32
|
+
execute<T = unknown>(name: string, params?: Record<string, unknown>, sharedEngineSafe?: boolean): Promise<T>;
|
|
33
|
+
executeBuiltin<T = unknown>(name: string, params?: Record<string, unknown>, sharedEngineSafe?: boolean): Promise<T>;
|
|
34
|
+
run<T = unknown>(script: string): Promise<T>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Layer/document bounds in pixels. The console logged this as `[Object]` (not
|
|
39
|
+
* expanded); this is the standard generator bounds shape.
|
|
40
|
+
*/
|
|
41
|
+
interface Bounds {
|
|
42
|
+
top: number;
|
|
43
|
+
left: number;
|
|
44
|
+
bottom: number;
|
|
45
|
+
right: number;
|
|
46
|
+
}
|
|
47
|
+
/** One entry in `imageChanged.layers` — a layer touched by the change. */
|
|
48
|
+
interface ImageChangedLayer {
|
|
49
|
+
/** Layer id (stable across the session). */
|
|
50
|
+
id: number;
|
|
51
|
+
/** Present (true) when the layer's pixels changed. */
|
|
52
|
+
pixels?: boolean;
|
|
53
|
+
/** Present (true) when the layer was removed in this change. */
|
|
54
|
+
removed?: boolean;
|
|
55
|
+
/** Layer bounds; present on geometry/pixel changes. */
|
|
56
|
+
bounds?: Bounds;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Payload of the `imageChanged` event. Fields are a union of everything PS may
|
|
60
|
+
* send; only `version` / `timeStamp` / `count` / `id` are always present. A
|
|
61
|
+
* single event carries *either* metadata flags (`metaDataOnly`, `selection`),
|
|
62
|
+
* *or* `layers`, *or* document-level flags (`active` / `file` / `closed`).
|
|
63
|
+
*/
|
|
64
|
+
interface ImageChangedEvent {
|
|
65
|
+
/** Generator protocol version, e.g. "1.6.1". */
|
|
66
|
+
version: string;
|
|
67
|
+
/** Seconds since epoch (float), e.g. 1782455135.936. */
|
|
68
|
+
timeStamp: number;
|
|
69
|
+
/** Per-document monotonically increasing change counter (resets per doc id). */
|
|
70
|
+
count: number;
|
|
71
|
+
/** Document id this change belongs to. */
|
|
72
|
+
id: number;
|
|
73
|
+
/** True on the first event for a doc / on activation. */
|
|
74
|
+
active?: boolean;
|
|
75
|
+
/** Document title or full path, e.g. "Test-恢复的.psd" or "C:\\...\\Test.psd". */
|
|
76
|
+
file?: string;
|
|
77
|
+
/** True when the document was closed. */
|
|
78
|
+
closed?: boolean;
|
|
79
|
+
/** True when only metadata changed (no pixel/layer body). */
|
|
80
|
+
metaDataOnly?: boolean;
|
|
81
|
+
/** Selected layer indices; empty array when the selection is cleared. */
|
|
82
|
+
selection?: number[];
|
|
83
|
+
/** Layers touched by this change (pixel edits, bounds, removals). */
|
|
84
|
+
layers?: ImageChangedLayer[];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Map of Photoshop event name -> payload type passed to the listener. Shapes
|
|
88
|
+
* marked "observed" were confirmed from live PS output; the rest are inferred
|
|
89
|
+
* from the generator protocol docs.
|
|
90
|
+
*/
|
|
91
|
+
interface PhotoshopEventMap {
|
|
92
|
+
/** [workspace display name] (inferred). */
|
|
93
|
+
workspaceChanged: string;
|
|
94
|
+
/** Tool name, e.g. "paintbrushTool" / "moveTool" (observed). */
|
|
95
|
+
toolChanged: string;
|
|
96
|
+
/** "enter" | "exit" (inferred). */
|
|
97
|
+
quickMaskStateChanged: string;
|
|
98
|
+
/** Document id (observed). */
|
|
99
|
+
documentChanged: number;
|
|
100
|
+
/** Document id of the closed document (observed). */
|
|
101
|
+
closedDocument: number;
|
|
102
|
+
/** Document id (inferred). */
|
|
103
|
+
newDocumentViewCreated: number;
|
|
104
|
+
/** Document id (inferred). */
|
|
105
|
+
activeViewChanged: number;
|
|
106
|
+
/** Document id of the now-current document (observed). */
|
|
107
|
+
currentDocumentChanged: number;
|
|
108
|
+
/** Color as 6-character hex value (inferred). */
|
|
109
|
+
backgroundColorChanged: string;
|
|
110
|
+
/** Color as 6-character hex value (inferred). */
|
|
111
|
+
foregroundColorChanged: string;
|
|
112
|
+
/** Image/document change descriptor (observed). */
|
|
113
|
+
imageChanged: ImageChangedEvent;
|
|
114
|
+
}
|
|
115
|
+
/** Listener for a given Photoshop event key. */
|
|
116
|
+
type PhotoshopEventListener<K extends keyof PhotoshopEventMap> = (payload: PhotoshopEventMap[K]) => void;
|
|
117
|
+
/**
|
|
118
|
+
* Listen-only typed surface a Plugin reaches through `plugin.events` /
|
|
119
|
+
* `this.events`. `EventManager` (an `EventEmitter`) `implements` this; `emit` is
|
|
120
|
+
* deliberately excluded — a Plugin subscribes, it never dispatches Photoshop
|
|
121
|
+
* events.
|
|
122
|
+
*/
|
|
123
|
+
interface PhotoshopEvents {
|
|
124
|
+
on<K extends keyof PhotoshopEventMap>(event: K, listener: PhotoshopEventListener<K>): this;
|
|
125
|
+
once<K extends keyof PhotoshopEventMap>(event: K, listener: PhotoshopEventListener<K>): this;
|
|
126
|
+
off<K extends keyof PhotoshopEventMap>(event: K, listener: PhotoshopEventListener<K>): this;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Action-domain feature module (ADR 0006). Exposes the `Action:*` WS Request
|
|
131
|
+
* methods, each backed by a packaged `jsx/Action/<name>.jsx` script run through
|
|
132
|
+
* the plugin's `JsxRunner` (ADR 0008). A jsx failure follows the `"Error:"`
|
|
133
|
+
* prefix convention: `JsxRunner` throws, and `Registry.dispatch` turns it into an
|
|
134
|
+
* INTERNAL response — the methods themselves do not catch.
|
|
135
|
+
*
|
|
136
|
+
* Migrated from LightAi's `ActionManager`. The `@McpTool` metadata did not carry
|
|
137
|
+
* over (no MCP runtime here — only the `@ws` WS path), but the human-facing
|
|
138
|
+
* descriptions are preserved as method JSDoc.
|
|
139
|
+
*/
|
|
140
|
+
/**
|
|
141
|
+
* The Action module surface a Plugin reaches through `plugin.modules.action`
|
|
142
|
+
* (RFC 0003). `ActionModule implements` this; the SDK re-exports it via
|
|
143
|
+
* src/contract.ts.
|
|
144
|
+
*/
|
|
145
|
+
interface ActionModuleApi {
|
|
146
|
+
autoCutout(): Promise<boolean>;
|
|
147
|
+
removeBackground(): Promise<{
|
|
148
|
+
success: boolean;
|
|
149
|
+
}>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
type PsDocument = {
|
|
153
|
+
id: number;
|
|
154
|
+
name: string;
|
|
155
|
+
width: number;
|
|
156
|
+
height: number;
|
|
157
|
+
resolution: number;
|
|
158
|
+
isDirty: boolean;
|
|
159
|
+
filePath?: string;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* The Document module surface a Plugin reaches through `plugin.modules.document`
|
|
163
|
+
* (RFC 0003). `DocumentModule implements` this; the SDK re-exports it via
|
|
164
|
+
* src/contract.ts.
|
|
165
|
+
*/
|
|
166
|
+
interface DocumentModuleApi {
|
|
167
|
+
getCurrentDocument(): Promise<PsDocument>;
|
|
168
|
+
exportDocument(params: Record<string, unknown>): Promise<unknown>;
|
|
169
|
+
saveDocument(params: {
|
|
170
|
+
savePath?: string;
|
|
171
|
+
}): Promise<unknown>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Single-layer pixmap export + preview, isolated from the buggy
|
|
176
|
+
* `generator.getPixmap` (generator-core's version omits the
|
|
177
|
+
* `includeAdjustors/Children/ClipBase/Clipped` flags and passes a stray
|
|
178
|
+
* `settings.thread` field). `getPixmap` here is a faithful port of
|
|
179
|
+
* LightAi's `LayerManager.getPixmap` (index.ts:364-482): it calls the plugin's
|
|
180
|
+
* own `Layer/getLayerPixmap.jsx` over the progress channel and collects the
|
|
181
|
+
* bounds + pixmap + ICC profile messages Photoshop streams back.
|
|
182
|
+
*
|
|
183
|
+
* Whole-document export is handled separately by generator-core's
|
|
184
|
+
* `getDocumentPixmap` (to be wired up later); this module only deals with
|
|
185
|
+
* explicit layer specs, which is what `Layer/getLayerPixmap.jsx` requires.
|
|
186
|
+
*
|
|
187
|
+
* Encoding (raw RGBA -> PNG) goes through `sharp`, externalized from the bundle
|
|
188
|
+
* and resolved from node_modules at runtime inside Photoshop's Node.
|
|
189
|
+
*/
|
|
190
|
+
/**
|
|
191
|
+
* The Image module surface a Plugin reaches through `plugin.modules.image`
|
|
192
|
+
* (RFC 0003). `ImageModule implements` this; the SDK re-exports it via
|
|
193
|
+
* src/contract.ts. `settings` is widened to `Record<string, unknown>` so the
|
|
194
|
+
* plugin contract does not drag the generator-core `GetPixmapSettings` namespace
|
|
195
|
+
* into the SDK; `buffer` is `Uint8Array` (not `Buffer`) so the SDK stays
|
|
196
|
+
* Node-free.
|
|
197
|
+
*/
|
|
198
|
+
interface ImageModuleApi {
|
|
199
|
+
exportImage(options: {
|
|
200
|
+
documentId?: number;
|
|
201
|
+
layerSpec: LayerSpec;
|
|
202
|
+
settings?: Record<string, unknown>;
|
|
203
|
+
}): Promise<ImageResult>;
|
|
204
|
+
getPreview(options: {
|
|
205
|
+
documentId?: number;
|
|
206
|
+
layerSpec: number;
|
|
207
|
+
}): Promise<ImageResult>;
|
|
208
|
+
exportDocument(options: {
|
|
209
|
+
documentId?: number;
|
|
210
|
+
settings?: Record<string, unknown>;
|
|
211
|
+
}): Promise<ImageResult>;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Result of an image export / preview: PNG bytes plus geometry metadata. The
|
|
215
|
+
* bytes are typed as `Uint8Array` (the implementation returns a `Buffer`, which
|
|
216
|
+
* is a `Uint8Array` subtype) so this type can cross into the Node-free SDK
|
|
217
|
+
* contract unchanged.
|
|
218
|
+
*/
|
|
219
|
+
interface ImageResult {
|
|
220
|
+
buffer: Uint8Array;
|
|
221
|
+
bounds: PsBounds;
|
|
222
|
+
width: number;
|
|
223
|
+
height: number;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Plugin-facing COS contract (RFC 0008). The minimal slice modules and plugins
|
|
228
|
+
* reach through `plugin.cos`: upload in-memory bytes or a local file and get back
|
|
229
|
+
* a ready-to-use signed URL. Params use `Uint8Array`/path strings (never `Buffer`
|
|
230
|
+
* or the COS SDK's own types) so the SDK's re-export of this interface stays
|
|
231
|
+
* Node-free, mirroring how `ImageModuleApi` is exposed.
|
|
232
|
+
*/
|
|
233
|
+
interface CosServiceApi {
|
|
234
|
+
/** Upload raw bytes, returning a signed URL. `name` labels the object key. */
|
|
235
|
+
uploadObject(data: Uint8Array, name?: string): Promise<string>;
|
|
236
|
+
/** Upload a local file by path, returning a signed URL. */
|
|
237
|
+
uploadFile(dir: string, name?: string): Promise<string>;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
declare class PsLayer {
|
|
241
|
+
id: number;
|
|
242
|
+
index: number;
|
|
243
|
+
name: string;
|
|
244
|
+
type: number;
|
|
245
|
+
visible: boolean;
|
|
246
|
+
bounds: PsBounds;
|
|
247
|
+
rect: PsRect;
|
|
248
|
+
clip: boolean;
|
|
249
|
+
children?: PsLayer[];
|
|
250
|
+
constructor(init: Partial<PsLayer>);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* The Layer module surface a Plugin reaches through `plugin.modules.layer`
|
|
254
|
+
* (RFC 0003). `LayerModule implements` this, so the plugin contract tracks the
|
|
255
|
+
* implementation by compiler force; the SDK re-exports it via src/contract.ts.
|
|
256
|
+
*/
|
|
257
|
+
interface LayerModuleApi {
|
|
258
|
+
getLayerInfo(options?: {
|
|
259
|
+
id?: number;
|
|
260
|
+
index?: number;
|
|
261
|
+
getChildren?: boolean;
|
|
262
|
+
getGeneratorSettings?: boolean;
|
|
263
|
+
}): Promise<PsLayer>;
|
|
264
|
+
getLayerInfoByID(layerID: number, options?: {
|
|
265
|
+
getChildren: boolean;
|
|
266
|
+
}): Promise<PsLayer>;
|
|
267
|
+
getLayerInfoByIndex(layerIndex: number, options?: {
|
|
268
|
+
getChildren: boolean;
|
|
269
|
+
}): Promise<PsLayer>;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* The plugin contract a Plugin depends on (RFC 0003) — a deliberately narrowed
|
|
274
|
+
* view of the server's `PsBridgeHost`. Exposes only what a Plugin needs: the JSX
|
|
275
|
+
* seam and the feature-module accessors (all typed by the generator's own
|
|
276
|
+
* contract interfaces), plus the listen-only event stream. Excludes
|
|
277
|
+
* broadcast/emit/server/the raw generator handle — a Plugin manages its own
|
|
278
|
+
* clients through BasePlugin.broadcast/send.
|
|
279
|
+
*
|
|
280
|
+
* This is the one hand-written piece of the plugin surface that stays in the
|
|
281
|
+
* SDK: it is a *curation* of the host, not a mirror of it. Its member types are
|
|
282
|
+
* imported (type-only) from the generator contract so they can never drift from
|
|
283
|
+
* the implementation. The server's `PsBridgeHost implements PluginHost`;
|
|
284
|
+
* external Plugins only ever see this interface, so they depend on the SDK alone
|
|
285
|
+
* at runtime, never on the server package.
|
|
286
|
+
*/
|
|
287
|
+
interface PluginHost {
|
|
288
|
+
readonly jsx: JsxRunnerApi;
|
|
289
|
+
/** Feature modules, reached by short key (e.g. `plugin.modules.layer`). */
|
|
290
|
+
readonly modules: {
|
|
291
|
+
layer: LayerModuleApi;
|
|
292
|
+
document: DocumentModuleApi;
|
|
293
|
+
action: ActionModuleApi;
|
|
294
|
+
image: ImageModuleApi;
|
|
295
|
+
};
|
|
296
|
+
/** Typed, listen-only Photoshop event stream (lazy subscribe). */
|
|
297
|
+
readonly events: PhotoshopEvents;
|
|
298
|
+
/**
|
|
299
|
+
* Optional object-storage upload service (RFC 0008). Present only when the host
|
|
300
|
+
* has COS configured via the environment; undefined otherwise. A plugin guards
|
|
301
|
+
* on it: `if (this.plugin.cos) await this.plugin.cos.uploadObject(bytes)`.
|
|
302
|
+
*/
|
|
303
|
+
readonly cos?: CosServiceApi;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Per-plugin client push bus (RFC 0004). BasePlugin.broadcast/send delegate to
|
|
308
|
+
* this; the server's per-plugin assembler attaches a concrete adapter backed by
|
|
309
|
+
* the plugin's own ClientStore after construction. Defined in the SDK so
|
|
310
|
+
* BasePlugin can be implemented without depending on the server.
|
|
311
|
+
*/
|
|
312
|
+
interface PluginClientBus {
|
|
313
|
+
/** Push an Event to every online client of this plugin. */
|
|
314
|
+
broadcast(type: string, data: unknown): void;
|
|
315
|
+
/** Push an Event to one client of this plugin (no-op if not connected). */
|
|
316
|
+
send(clientId: string, type: string, data: unknown): void;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Base class for plugins (ADR 0009 / RFC 0003). A plugin is the orchestration
|
|
321
|
+
* layer above feature modules: it composes one or more module calls (reached
|
|
322
|
+
* through `this.modules`, e.g. `this.modules.layer`) and exposes
|
|
323
|
+
* its own `@ws`/`@api` handlers, bootstrapped the same way as modules.
|
|
324
|
+
*
|
|
325
|
+
* Dependency direction is strictly downward: a plugin may depend on modules,
|
|
326
|
+
* never on sibling plugins and never in reverse (modules must not reach
|
|
327
|
+
* plugins). `plugin` is the abstract PluginHost interface — never the
|
|
328
|
+
* concrete server plugin — so a plugin depends only on this SDK subpath.
|
|
329
|
+
*
|
|
330
|
+
* `@ws`/`@api` names are written in full by the developer (e.g.
|
|
331
|
+
* `@ws("LayerOps:merge")`) — `bootstrap` does not inject or derive a namespace.
|
|
332
|
+
* Use a `Domain:action` prefix to keep names from colliding across modules and
|
|
333
|
+
* plugins (ADR 0006 convention); the assembler's `registerMethod` is a silent
|
|
334
|
+
* `Map.set`, so prefix uniqueness is the developer's responsibility.
|
|
335
|
+
*
|
|
336
|
+
* Client push: `broadcast`/`send` reach only this plugin's own online clients,
|
|
337
|
+
* via the PluginClientBus the server attaches after construction. A subclass
|
|
338
|
+
* may override `onConnect`/`onDisconnect` to react to its clients coming and
|
|
339
|
+
* going; the defaults are no-ops.
|
|
340
|
+
*/
|
|
341
|
+
declare abstract class BasePlugin {
|
|
342
|
+
/** Stable URL identity of this plugin (read from the class's `static id`). */
|
|
343
|
+
readonly id: string;
|
|
344
|
+
/** The abstract plugin contract (never the concrete server plugin). */
|
|
345
|
+
protected readonly plugin: PluginHost;
|
|
346
|
+
private bus;
|
|
347
|
+
private _photoshop;
|
|
348
|
+
constructor(id: string, plugin: PluginHost);
|
|
349
|
+
/** Feature modules, reached by short key (shortcut for `this.plugin.modules`). */
|
|
350
|
+
protected get modules(): PluginHost["modules"];
|
|
351
|
+
/**
|
|
352
|
+
* The jsx runner scoped to this plugin's own `jsx/` dir (shortcut for
|
|
353
|
+
* `this.plugin.jsx`, RFC 0005). `jsx.execute("x")` runs `<pluginRoot>/jsx/x.jsx`;
|
|
354
|
+
* `jsx.executeBuiltin("Document/getDocumentInfo")` reaches the host's built-in
|
|
355
|
+
* tree.
|
|
356
|
+
*/
|
|
357
|
+
protected get jsx(): JsxRunnerApi;
|
|
358
|
+
/**
|
|
359
|
+
* Typed, listen-only Photoshop event stream (shortcut for `this.plugin.events`).
|
|
360
|
+
* Subscriptions are lazy on the server side: the first `on`/`once` for an event
|
|
361
|
+
* subscribes upstream, and the last `off` unsubscribes.
|
|
362
|
+
*/
|
|
363
|
+
protected get events(): PhotoshopEvents;
|
|
364
|
+
/**
|
|
365
|
+
* Photoshop DOM proxy, a typed object wrapper over `this.jsx`. Read and write
|
|
366
|
+
* the live document through `this.photoshop.app` / `this.photoshop.activeDocument`
|
|
367
|
+
* (e.g. `await this.photoshop.activeDocument.name`) instead of hand-writing
|
|
368
|
+
* ExtendScript. Lazily built once and backed by this plugin's own jsx runner;
|
|
369
|
+
* drop to `this.jsx.run(...)` for anything the proxy does not cover.
|
|
370
|
+
*/
|
|
371
|
+
protected get photoshop(): PsPhotoshopProxy;
|
|
372
|
+
/**
|
|
373
|
+
* Attach the per-plugin client bus. Called by the server's assembler after
|
|
374
|
+
* construction and before `listen`, so `broadcast`/`send` are live by the time
|
|
375
|
+
* any handler can fire. Not part of the public Plugin authoring API.
|
|
376
|
+
*/
|
|
377
|
+
_attachBus(bus: PluginClientBus): void;
|
|
378
|
+
/** Push an Event to every online client of this plugin. */
|
|
379
|
+
broadcast(type: string, data: unknown): void;
|
|
380
|
+
/** Push an Event to one client of this plugin (no-op if not connected). */
|
|
381
|
+
send(clientId: string, type: string, data: unknown): void;
|
|
382
|
+
/** Called after a client handshake registers with this plugin. Default no-op. */
|
|
383
|
+
onConnect(_clientId: string): void;
|
|
384
|
+
/** Called after a client socket is removed from this plugin. Default no-op. */
|
|
385
|
+
onDisconnect(_clientId: string): void;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Whether `S` is a class that extends BasePlugin. Uses the global brand rather
|
|
389
|
+
* than `instanceof` so it works when `S` came from a separately-bundled copy of
|
|
390
|
+
* this SDK (external plugins). The brand is inherited via the prototype chain,
|
|
391
|
+
* so direct and indirect subclasses both qualify.
|
|
392
|
+
*/
|
|
393
|
+
declare function isBasePluginClass(S: unknown): boolean;
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Minimal HTTP vocabulary for the @api decorator (ADR 0006 / RFC 0003). The SDK
|
|
397
|
+
* plugin subpath is platform-neutral and must not depend on fastify, so it
|
|
398
|
+
* declares its own string union; the server adapts it to fastify's HTTPMethods
|
|
399
|
+
* at the assembly boundary.
|
|
400
|
+
*/
|
|
401
|
+
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
|
|
402
|
+
/**
|
|
403
|
+
* A WS Request handler as seen by the plugin devkit (ADR 0006 open-ended
|
|
404
|
+
* contract). params/result are `unknown` at this layer; the SDK re-applies
|
|
405
|
+
* strong types for declared methods. `ctx` is opaque here — the server supplies
|
|
406
|
+
* a typed HandlerContext, and a handler accepting `unknown` accepts it.
|
|
407
|
+
*/
|
|
408
|
+
type MethodHandler = (params: unknown, ctx: unknown) => Promise<unknown> | unknown;
|
|
409
|
+
/**
|
|
410
|
+
* An HTTP route handler as seen by the plugin devkit. request/reply are opaque
|
|
411
|
+
* (platform-neutral SDK); the server casts to fastify's request/reply at the
|
|
412
|
+
* assembly boundary.
|
|
413
|
+
*/
|
|
414
|
+
type ApiHandler = (request: unknown, reply: unknown) => Promise<unknown> | unknown;
|
|
415
|
+
/** An HTTP route a module or plugin exposes via @api (ADR 0006). */
|
|
416
|
+
interface ApiRouteSpec {
|
|
417
|
+
method: HttpMethod | HttpMethod[];
|
|
418
|
+
url: string;
|
|
419
|
+
handler: ApiHandler;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Abstract assembly target (ADR 0006 / RFC 0003): the second-stage bootstrap
|
|
423
|
+
* registers scanned @ws/@api metadata against this. The server provides two
|
|
424
|
+
* concrete implementations — the global Registry (modules + builtins) and a
|
|
425
|
+
* per-plugin scoped assembler (RFC 0004). The SDK only depends on this shape,
|
|
426
|
+
* keeping the dependency arrow server -> sdk / plugin -> sdk acyclic.
|
|
427
|
+
*/
|
|
428
|
+
interface AssemblyTarget {
|
|
429
|
+
registerMethod(name: string, handler: MethodHandler): void;
|
|
430
|
+
registerApi(route: ApiRouteSpec): void;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/** Mark a method as a WS Request handler registered under `name` (ADR 0006). */
|
|
434
|
+
declare function ws(name: string): (_value: unknown, context: ClassMethodDecoratorContext) => void;
|
|
435
|
+
/**
|
|
436
|
+
* Mark a method as an HTTP route handler. `@api("/path")` defaults to GET;
|
|
437
|
+
* `@api({ method, url })` selects the verb(s) (ADR 0006). The route URL is
|
|
438
|
+
* registered verbatim for modules (under `/{path}`) and prefixed with the
|
|
439
|
+
* plugin id for plugins (under `/{pluginId}/{path}`, RFC 0004) — the
|
|
440
|
+
* decorator only collects metadata; the assembly target decides the final URL.
|
|
441
|
+
*/
|
|
442
|
+
declare function api(pathOrRoute: string | {
|
|
443
|
+
method?: HttpMethod | HttpMethod[];
|
|
444
|
+
url: string;
|
|
445
|
+
}): (_value: unknown, context: ClassMethodDecoratorContext) => void;
|
|
446
|
+
/**
|
|
447
|
+
* Second stage of decorator registration (ADR 0006 / 0009): scan a module or
|
|
448
|
+
* plugin instance's collected metadata and register each decorated method
|
|
449
|
+
* against the assembly target, bound to the instance so handlers can reach
|
|
450
|
+
* `this`. Walks the metadata prototype chain so inherited handlers are included.
|
|
451
|
+
* The `@ws`/`@api` name is registered verbatim — developers write the full
|
|
452
|
+
* `Domain:action` name; no namespace is injected. For a plugin, the target is
|
|
453
|
+
* the per-plugin scoped assembler (RFC 0004); for a module, the global Registry.
|
|
454
|
+
*/
|
|
455
|
+
declare function bootstrap(instance: object, target: AssemblyTarget): void;
|
|
456
|
+
|
|
457
|
+
export { type ActionModuleApi, type ApiHandler, type ApiRouteSpec, type AssemblyTarget, BasePlugin, type Bounds, type CosServiceApi, type DocumentModuleApi, type HttpMethod, type ImageChangedEvent, type ImageChangedLayer, type ImageModuleApi, type ImageResult, type JsxRunnerApi, type LayerModuleApi, LayerSpec, type MethodHandler, type PhotoshopEventListener, type PhotoshopEventMap, type PhotoshopEvents, type PluginClientBus, type PluginHost, type PsBounds, type PsDocument, PsLayer, PsPhotoshopProxy, type PsRect, api, bootstrap, isBasePluginClass, ws };
|