@bubblydoo/uxp-toolkit 0.0.2
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/.turbo/turbo-build.log +15 -0
- package/CHANGELOG.md +7 -0
- package/dist/index.d.ts +271 -0
- package/dist/index.js +733 -0
- package/package.json +41 -0
- package/src/commands-library/getLayerProperties.ts +32 -0
- package/src/commands-library/renameLayer.ts +15 -0
- package/src/commands-library/renameLayer.uxp-test.ts +32 -0
- package/src/core/batchPlay.ts +16 -0
- package/src/core/command.ts +130 -0
- package/src/core/executeAsModal.ts +101 -0
- package/src/core/suspendHistory.ts +15 -0
- package/src/core/suspendHistory.uxp-test.ts +18 -0
- package/src/core-wrappers/executeAsModalAndSuspendHistory.ts +11 -0
- package/src/dom/getFlattenedDomLayersList.ts +43 -0
- package/src/dom/photoshopDomLayersToTree.ts +18 -0
- package/src/error-sourcemaps/sourcemaps.ts +100 -0
- package/src/error-sourcemaps/sourcemaps.uxp-test.ts +24 -0
- package/src/errors/ut-error.ts +6 -0
- package/src/filesystem/openFileByPath.ts +10 -0
- package/src/general-tree/flattenTree.ts +12 -0
- package/src/general-tree/layerRef.ts +4 -0
- package/src/general-tree/mapTree.ts +11 -0
- package/src/general-tree/mapTreeRef.ts +11 -0
- package/src/general-tree/treeTypes.ts +7 -0
- package/src/index.ts +73 -0
- package/src/metadata-storage/metadataStorage.ts +66 -0
- package/src/metadata-storage/metadataStorage.uxp-test.ts +35 -0
- package/src/node-compat/path/resolvePath.ts +19 -0
- package/src/other/applicationInfo.ts +169 -0
- package/src/other/applicationInfo.uxp-test.ts +11 -0
- package/src/other/clipboard.ts +10 -0
- package/src/other/clipboard.uxp-test.ts +17 -0
- package/src/other/uxpEntrypoints.ts +9 -0
- package/src/ut-tree/getFlattenedLayerDescriptorsList.ts +72 -0
- package/src/ut-tree/getLayerEffects.ts +41 -0
- package/src/ut-tree/getLayerProperties.ts +35 -0
- package/src/ut-tree/photoshopLayerDescriptorsToUTLayers.ts +182 -0
- package/src/ut-tree/photoshopLayerDescriptorsToUTLayers.uxp-test.ts +52 -0
- package/src/ut-tree/psLayerRef.ts +4 -0
- package/src/ut-tree/utLayersToTree.ts +21 -0
- package/src/util/utLayerToLayer.ts +41 -0
- package/test/fixtures/clipping-layers.psd +0 -0
- package/test/fixtures/one-layer.psd +0 -0
- package/test/index.ts +21 -0
- package/test/meta-tests/executeAsModal.uxp-test.ts +38 -0
- package/test/meta-tests/suspendHistory.uxp-test.ts +27 -0
- package/tsconfig.json +13 -0
- package/tsup.config.ts +9 -0
- package/uxp-tests.json +13 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Core – batchPlay & command building
|
|
2
|
+
export { batchPlay, type CorrectBatchPlayOptions } from "./core/batchPlay";
|
|
3
|
+
export {
|
|
4
|
+
createCommand,
|
|
5
|
+
batchPlayCommand,
|
|
6
|
+
batchPlayCommands,
|
|
7
|
+
createModifyingBatchPlayContext,
|
|
8
|
+
type UTCommandBase,
|
|
9
|
+
type UTCommandModifying,
|
|
10
|
+
type UTCommandNonModifying,
|
|
11
|
+
type UTCommandResult,
|
|
12
|
+
} from "./core/command";
|
|
13
|
+
|
|
14
|
+
// Core – execution context
|
|
15
|
+
export {
|
|
16
|
+
executeAsModal,
|
|
17
|
+
type CorrectExecutionContext,
|
|
18
|
+
type CorrectExecuteAsModalOptions,
|
|
19
|
+
type ExtendedExecutionContext,
|
|
20
|
+
} from "./core/executeAsModal";
|
|
21
|
+
export { suspendHistory, type SuspendHistoryContext } from "./core/suspendHistory";
|
|
22
|
+
|
|
23
|
+
// Core wrappers
|
|
24
|
+
export { executeAsModalAndSuspendHistory } from "./core-wrappers/executeAsModalAndSuspendHistory";
|
|
25
|
+
|
|
26
|
+
// Commands library
|
|
27
|
+
export { getLayerProperties } from "./commands-library/getLayerProperties";
|
|
28
|
+
export { createRenameLayerCommand } from "./commands-library/renameLayer";
|
|
29
|
+
|
|
30
|
+
// DOM – layers
|
|
31
|
+
export { getFlattenedDomLayersList } from "./dom/getFlattenedDomLayersList";
|
|
32
|
+
export { photoshopDomLayersToTree } from "./dom/photoshopDomLayersToTree";
|
|
33
|
+
|
|
34
|
+
// Filesystem
|
|
35
|
+
export { openFileByPath } from "./filesystem/openFileByPath";
|
|
36
|
+
|
|
37
|
+
// General tree
|
|
38
|
+
export { flattenTree } from "./general-tree/flattenTree";
|
|
39
|
+
export { mapTree } from "./general-tree/mapTree";
|
|
40
|
+
export { mapTreeRef } from "./general-tree/mapTreeRef";
|
|
41
|
+
export { type Tree } from "./general-tree/treeTypes";
|
|
42
|
+
export { type LayerRef } from "./general-tree/layerRef";
|
|
43
|
+
|
|
44
|
+
// Other
|
|
45
|
+
export { photoshopGetApplicationInfo } from "./other/applicationInfo";
|
|
46
|
+
export { copyToClipboard, readFromClipboard } from "./other/clipboard";
|
|
47
|
+
export { uxpEntrypointsSchema } from "./other/uxpEntrypoints";
|
|
48
|
+
|
|
49
|
+
// UT tree – layer descriptors & Photoshop tree
|
|
50
|
+
export {
|
|
51
|
+
getFlattenedLayerDescriptorsList,
|
|
52
|
+
type LayerDescriptor,
|
|
53
|
+
} from "./ut-tree/getFlattenedLayerDescriptorsList";
|
|
54
|
+
export {
|
|
55
|
+
createGetLayerPropertiesCommand,
|
|
56
|
+
getLayerProperties as getLayerPropertiesFromUtTree,
|
|
57
|
+
} from "./ut-tree/getLayerProperties";
|
|
58
|
+
export {
|
|
59
|
+
createGetLayerCommand as createGetLayerEffectsCommand,
|
|
60
|
+
getLayerEffects,
|
|
61
|
+
} from "./ut-tree/getLayerEffects";
|
|
62
|
+
export {
|
|
63
|
+
photoshopLayerDescriptorsToUTLayers,
|
|
64
|
+
type UTLayer,
|
|
65
|
+
} from "./ut-tree/photoshopLayerDescriptorsToUTLayers";
|
|
66
|
+
export { type PsLayerRef } from "./ut-tree/psLayerRef";
|
|
67
|
+
export { utLayersToTree, type UTLayerWithoutChildren } from "./ut-tree/utLayersToTree";
|
|
68
|
+
|
|
69
|
+
// Util
|
|
70
|
+
export { utLayerToDomLayer, utLayersToDomLayers } from "./util/utLayerToLayer";
|
|
71
|
+
|
|
72
|
+
// Error sourcemaps
|
|
73
|
+
export { parseUxpErrorSourcemaps, getBasicStackFrameAbsoluteFilePath, type BasicStackFrame } from "./error-sourcemaps/sourcemaps";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { convert } from "xmlbuilder2";
|
|
2
|
+
import type { Document } from "photoshop/dom/Document";
|
|
3
|
+
import { batchPlayCommand, createCommand, executeAsModal } from "@bubblydoo/uxp-toolkit";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
export const readDocumentMetadata = async (document: Document, { key, prefix }: { key: string, prefix: string }) => {
|
|
7
|
+
const converted = await readAllDocumentMetadata(document);
|
|
8
|
+
const property =
|
|
9
|
+
converted["x:xmpmeta"]["rdf:RDF"]["rdf:Description"][`${prefix}:${key}`];
|
|
10
|
+
|
|
11
|
+
return property;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const readAllDocumentMetadata = async (document: Document) => {
|
|
15
|
+
const metadata = await batchPlayCommand(
|
|
16
|
+
createCommand({
|
|
17
|
+
modifying: false,
|
|
18
|
+
descriptor: {
|
|
19
|
+
_obj: "get",
|
|
20
|
+
_target: {
|
|
21
|
+
_ref: [
|
|
22
|
+
{ _property: "XMPMetadataAsUTF8" },
|
|
23
|
+
{ _ref: "document", _id: document.id },
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
schema: z.object({
|
|
28
|
+
XMPMetadataAsUTF8: z.any(),
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return convert(metadata.XMPMetadataAsUTF8, {
|
|
34
|
+
format: "object",
|
|
35
|
+
}) as any;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const writeDocumentMetadata = async (document: Document, newProperty: { key: string, value: string, prefix: string, prefixNamespace: string }) => {
|
|
39
|
+
const initialMetadata = await readAllDocumentMetadata(document);
|
|
40
|
+
const obj = convert(initialMetadata, { format: "object" }) as any;
|
|
41
|
+
obj["x:xmpmeta"]["rdf:RDF"]["rdf:Description"][
|
|
42
|
+
`@xmlns:${newProperty.prefix}`
|
|
43
|
+
] = newProperty.prefixNamespace;
|
|
44
|
+
obj["x:xmpmeta"]["rdf:RDF"]["rdf:Description"][
|
|
45
|
+
`${newProperty.prefix}:${newProperty.key}`
|
|
46
|
+
] = newProperty.value;
|
|
47
|
+
const newXmpString = convert(obj, { format: "xml" });
|
|
48
|
+
await executeAsModal("Set Metadata", async (ctx) => {
|
|
49
|
+
const command = createCommand({
|
|
50
|
+
modifying: true,
|
|
51
|
+
descriptor: {
|
|
52
|
+
_obj: "set",
|
|
53
|
+
_target: [
|
|
54
|
+
{ _ref: "property", _property: "XMPMetadataAsUTF8" },
|
|
55
|
+
{ _ref: "document", _id: document.id },
|
|
56
|
+
],
|
|
57
|
+
to: {
|
|
58
|
+
_obj: "document",
|
|
59
|
+
XMPMetadataAsUTF8: newXmpString,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
schema: z.unknown(),
|
|
63
|
+
});
|
|
64
|
+
await ctx.batchPlayCommand(command, { synchronousExecution: true });
|
|
65
|
+
});
|
|
66
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { openFileByPath } from "../filesystem/openFileByPath";
|
|
2
|
+
import type { Test } from "@bubblydoo/uxp-test-framework";
|
|
3
|
+
import { expect } from "chai";
|
|
4
|
+
import { app } from "photoshop";
|
|
5
|
+
import {
|
|
6
|
+
readDocumentMetadata,
|
|
7
|
+
writeDocumentMetadata,
|
|
8
|
+
} from "./metadataStorage";
|
|
9
|
+
|
|
10
|
+
const TEST_PREFIX = "bubblytest";
|
|
11
|
+
const TEST_PREFIX_NAMESPACE = "https://example.com/bubbly-test";
|
|
12
|
+
const TEST_KEY = "testKey";
|
|
13
|
+
const TEST_VALUE = "test-value-written-by-uxp-test";
|
|
14
|
+
|
|
15
|
+
export const metadataStorageTest: Test = {
|
|
16
|
+
name: "Metadata Storage",
|
|
17
|
+
async run() {
|
|
18
|
+
await openFileByPath("plugin:/fixtures/one-layer.psd");
|
|
19
|
+
const document = app.activeDocument!;
|
|
20
|
+
|
|
21
|
+
await writeDocumentMetadata(document, {
|
|
22
|
+
key: TEST_KEY,
|
|
23
|
+
value: TEST_VALUE,
|
|
24
|
+
prefix: TEST_PREFIX,
|
|
25
|
+
prefixNamespace: TEST_PREFIX_NAMESPACE,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const readBack = await readDocumentMetadata(document, {
|
|
29
|
+
key: TEST_KEY,
|
|
30
|
+
prefix: TEST_PREFIX,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(readBack).to.equal(TEST_VALUE);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { resolve as nativeResolve } from "path";
|
|
2
|
+
|
|
3
|
+
/** for some reason native path.resolve in UXP returns a URL object
|
|
4
|
+
* this function converts it to a string
|
|
5
|
+
*/
|
|
6
|
+
export function pathResolve(...pathSegments: string[]): string {
|
|
7
|
+
const urlOrString = nativeResolve(...pathSegments) as URL | string;
|
|
8
|
+
if (typeof urlOrString === "string") {
|
|
9
|
+
return urlOrString;
|
|
10
|
+
}
|
|
11
|
+
if (isUrl(urlOrString)) {
|
|
12
|
+
return urlOrString.toString();
|
|
13
|
+
}
|
|
14
|
+
throw new Error("Unexpected URL object");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isUrl(urlOrString: any): urlOrString is URL {
|
|
18
|
+
return urlOrString instanceof URL;
|
|
19
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { batchPlayCommand, createCommand } from "../core/command";
|
|
3
|
+
|
|
4
|
+
export async function photoshopGetApplicationInfo() {
|
|
5
|
+
return await batchPlayCommand(photoshopApplicationInfoCommand);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const photoshopAppInfoSchema = z.object({
|
|
9
|
+
active: z.boolean(),
|
|
10
|
+
autoShowHomeScreen: z.boolean(),
|
|
11
|
+
available: z.number(),
|
|
12
|
+
buildNumber: z.string(),
|
|
13
|
+
documentArea: z.object({
|
|
14
|
+
left: z.number(),
|
|
15
|
+
top: z.number(),
|
|
16
|
+
right: z.number(),
|
|
17
|
+
bottom: z.number(),
|
|
18
|
+
}),
|
|
19
|
+
hostName: z.string(),
|
|
20
|
+
hostVersion: z.object({
|
|
21
|
+
versionMajor: z.number(),
|
|
22
|
+
versionMinor: z.number(),
|
|
23
|
+
versionFix: z.number(),
|
|
24
|
+
}),
|
|
25
|
+
localeInfo: z.object({
|
|
26
|
+
decimalPoint: z.string(),
|
|
27
|
+
}),
|
|
28
|
+
osVersion: z.string(),
|
|
29
|
+
panelList: z.array(
|
|
30
|
+
z.object({
|
|
31
|
+
ID: z.string(),
|
|
32
|
+
name: z.string(),
|
|
33
|
+
obscured: z.boolean(),
|
|
34
|
+
visible: z.boolean(),
|
|
35
|
+
})
|
|
36
|
+
),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const photoshopApplicationInfoCommand = createCommand({
|
|
40
|
+
modifying: false,
|
|
41
|
+
descriptor: {
|
|
42
|
+
_obj: "get",
|
|
43
|
+
_target: [
|
|
44
|
+
{
|
|
45
|
+
_ref: "application",
|
|
46
|
+
_enum: "ordinal",
|
|
47
|
+
_value: "targetEnum",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
schema: photoshopAppInfoSchema,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// $PnCK: {_enum: "cursorKind", _value: "brushSize"}
|
|
55
|
+
// MRUColorList: (2) [{…}, {…}]
|
|
56
|
+
// active: false
|
|
57
|
+
// autoShowHomeScreen: true
|
|
58
|
+
// available: 20622344192
|
|
59
|
+
// backgroundColor: {_obj: "RGBColor", red: 255, grain: 255, blue: 255}
|
|
60
|
+
// buildNumber: "26.8.0 (20250518.m.3079 c5cae55)"
|
|
61
|
+
// cachePrefs: {_obj: "cachePrefs", historyStates: 50, numberOfCacheLevels: 4, numberOfCacheLevels64: 4, tileSize: 131072, …}
|
|
62
|
+
// colorPickerPrefs: {_obj: "colorPickerPrefsClass", pickerKind: {…}, pickerID: ""}
|
|
63
|
+
// colorSettings: {_obj: "colorSettings", workingRGB: "Display P3", workingCMYK: "U.S. Web Coated (SWOP) v2", workingGray: "Dot Gain 20%", workingSpot: "Dot Gain 20%", …}
|
|
64
|
+
// contentCredentialsAvailable: true
|
|
65
|
+
// controlColor: {_enum: "controlColorChartreuse", _value: "controlColorDefault"}
|
|
66
|
+
// currentToolOptions: {_obj: "currentToolOptions", contiguous: true, selectionEnum: 0, $MrqI: {…}, $MrqF: {…}, …}
|
|
67
|
+
// defaultAppScript: 0
|
|
68
|
+
// displayPrefs: {_obj: "displayPrefs", paintingCursors: {…}, otherCursors: {…}, cursorShape: {…}, cursorBrushTipOutlineStrokeWidth: 2, …}
|
|
69
|
+
// documentArea: {left: 0, top: 56, right: 1512, bottom: 982}
|
|
70
|
+
// earlyAccessPrefs: {_obj: "earlyAccessPrefs"}
|
|
71
|
+
// exactPoints: false
|
|
72
|
+
// experimentalFeatures: {_obj: "experimentalFeatures", enhancedControlsTouchBarPropertyFeedback: true, expFeatureDeepUpscale: true, expFeatureContentAwareTracing: false, FocusMode: false, …}
|
|
73
|
+
// exportAssetsPrefs: {_obj: "exportAssetsPrefs", exportFileType: "PNG", exportFilePath: "", exportAssetJPGQualityEnum: 6, exportAssetsLocationSetting: 3, …}
|
|
74
|
+
// eyeDropperSample: {_enum: "eyeDropperSampleType", _value: "samplePoint"}
|
|
75
|
+
// featureAccessLevel: "PublicBeta"
|
|
76
|
+
// fileSavePrefs: {_obj: "fileSavePrefsClass", previewsQuery: {…}, previewWinThumbnail: true, extensionsQuery: {…}, lowerCase: true, …}
|
|
77
|
+
// fontLargeName: ".AppleSystemUIFont"
|
|
78
|
+
// fontLargeSize: 12
|
|
79
|
+
// fontList: {_obj: "fontList", fontName: Array(1294), fontPostScriptName: Array(1294), fontFamilyName: Array(1294), fontStyleName: Array(1294)}
|
|
80
|
+
// fontSmallName: ".AppleSystemUIFont"
|
|
81
|
+
// fontSmallSize: 10
|
|
82
|
+
// foregroundColor: {_obj: "RGBColor", red: 211.00000262260437, grain: 247.99610942602158, blue: 185.99611312150955}
|
|
83
|
+
// foregroundColorRGB: {_obj: "RGBColor", red: 201, grain: 249, blue: 179}
|
|
84
|
+
// generalPreferences: {_obj: "generalPreferences", colorPickerPrefs: {…}, colorPickerHUDMode: {…}, interpolationMethod: {…}, historyLog: false, …}
|
|
85
|
+
// globalAngle: {_obj: "globalAngle", globalLightingAngle: {…}, globalAltitude: {…}}
|
|
86
|
+
// gradientClassEvent: 4
|
|
87
|
+
// gridMajor: 65536
|
|
88
|
+
// guidesPrefs: {_obj: "guidesPrefs", guidesColor: {…}, guidesStyle: {…}, activeArtboardGuidesColor: {…}, activeArtboardGuidesStyle: {…}, …}
|
|
89
|
+
// highlightColorOption: {_enum: "highlightColorOptionEnumType", _value: "uiDefaultHighlightColor"}
|
|
90
|
+
// historyLogPreferences: {_obj: "historyLogPreferences", historyLog: false, saveHistoryTo: {…}, log: false, editLogItems: {…}, …}
|
|
91
|
+
// historyPreferences: {_obj: "historyPrefsClass", maximumStates: 50, snapshotInitial: true, nonLinear: false}
|
|
92
|
+
// homeScreenVisibility: true
|
|
93
|
+
// hostName: "Adobe Photoshop (Beta)"
|
|
94
|
+
// hostVersion: {_obj: "version", versionMajor: 26, versionMinor: 8, versionFix: 0}
|
|
95
|
+
// imageProcessingPrefs: {_obj: "imageProcessingPrefs", imageProcessingSelectSubjectPrefs: {…}, imageProcessingSelectionsProcessingPrefsStr: {…}, imageProcessingRemoveToolProcessingPrefsStr: {…}, imageProcessingEnhanceResolutionProcessingPrefsStr: {…}}
|
|
96
|
+
// interfaceBevelHighlight: {_obj: "interfaceColor", interfaceColorRed32: 112, interfaceColorGreen32: 112, interfaceColorBlue32: 112, interfaceColorRed2: 112, …}
|
|
97
|
+
// interfaceBevelShadow: {_obj: "interfaceColor", interfaceColorRed32: 74, interfaceColorGreen32: 74, interfaceColorBlue32: 74, interfaceColorRed2: 74, …}
|
|
98
|
+
// interfaceBlack: {_obj: "interfaceColor", interfaceColorRed32: 0, interfaceColorGreen32: 0, interfaceColorBlue32: 0, interfaceColorRed2: 0, …}
|
|
99
|
+
// interfaceBorder: {_obj: "interfaceColor", interfaceColorRed32: 255, interfaceColorGreen32: 255, interfaceColorBlue32: 255, interfaceColorRed2: 255, …}
|
|
100
|
+
// interfaceButtonDarkShadow: {_obj: "interfaceColor", interfaceColorRed32: 83, interfaceColorGreen32: 83, interfaceColorBlue32: 83, interfaceColorRed2: 83, …}
|
|
101
|
+
// interfaceButtonDownFill: {_obj: "interfaceColor", interfaceColorRed32: 56, interfaceColorGreen32: 56, interfaceColorBlue32: 56, interfaceColorRed2: 56, …}
|
|
102
|
+
// interfaceButtonShadow: {_obj: "interfaceColor", interfaceColorRed32: 255, interfaceColorGreen32: 255, interfaceColorBlue32: 255, interfaceColorRed2: 255, …}
|
|
103
|
+
// interfaceButtonText: {_obj: "interfaceColor", interfaceColorRed32: 240, interfaceColorGreen32: 240, interfaceColorBlue32: 240, interfaceColorRed2: 240, …}
|
|
104
|
+
// interfaceButtonUpFill: {_obj: "interfaceColor", interfaceColorRed32: 71, interfaceColorGreen32: 71, interfaceColorBlue32: 71, interfaceColorRed2: 71, …}
|
|
105
|
+
// interfaceCanvasColor: {_obj: "interfaceColor", interfaceColorRed32: 40, interfaceColorGreen32: 40, interfaceColorBlue32: 40, interfaceColorRed2: 40, …}
|
|
106
|
+
// interfaceIconFillActive: {_obj: "interfaceColor", interfaceColorRed32: 56, interfaceColorGreen32: 56, interfaceColorBlue32: 56, interfaceColorRed2: 56, …}
|
|
107
|
+
// interfaceIconFillDimmed: {_obj: "interfaceColor", interfaceColorRed32: 77, interfaceColorGreen32: 77, interfaceColorBlue32: 77, interfaceColorRed2: 77, …}
|
|
108
|
+
// interfaceIconFillSelected: {_obj: "interfaceColor", interfaceColorRed32: 56, interfaceColorGreen32: 56, interfaceColorBlue32: 56, interfaceColorRed2: 56, …}
|
|
109
|
+
// interfaceIconFrameActive: {_obj: "interfaceColor", interfaceColorRed32: 255, interfaceColorGreen32: 255, interfaceColorBlue32: 255, interfaceColorRed2: 255, …}
|
|
110
|
+
// interfaceIconFrameDimmed: {_obj: "interfaceColor", interfaceColorRed32: 94, interfaceColorGreen32: 94, interfaceColorBlue32: 94, interfaceColorRed2: 94, …}
|
|
111
|
+
// interfaceIconFrameSelected: {_obj: "interfaceColor", interfaceColorRed32: 255, interfaceColorGreen32: 255, interfaceColorBlue32: 255, interfaceColorRed2: 255, …}
|
|
112
|
+
// interfaceOWLPaletteFill: {_obj: "interfaceColor", interfaceColorRed32: 83, interfaceColorGreen32: 83, interfaceColorBlue32: 83, interfaceColorRed2: 83, …}
|
|
113
|
+
// interfacePaletteFill: {_obj: "interfaceColor", interfaceColorRed32: 83, interfaceColorGreen32: 83, interfaceColorBlue32: 83, interfaceColorRed2: 83, …}
|
|
114
|
+
// interfacePrefs: {_obj: "interfacePrefs", colorChannels: false, canvasBackgroundColors: Array(4), showMenuColors: true, paletteEnhancedFontTypeKey: {…}, …}
|
|
115
|
+
// interfaceRed: {_obj: "interfaceColor", interfaceColorRed32: 238, interfaceColorGreen32: 0, interfaceColorBlue32: 0, interfaceColorRed2: 238, …}
|
|
116
|
+
// interfaceStaticText: {_obj: "interfaceColor", interfaceColorRed32: 214, interfaceColorGreen32: 214, interfaceColorBlue32: 214, interfaceColorRed2: 214, …}
|
|
117
|
+
// interfaceToolTipBackground: {_obj: "interfaceColor", interfaceColorRed32: 255, interfaceColorGreen32: 255, interfaceColorBlue32: 205, interfaceColorRed2: 255, …}
|
|
118
|
+
// interfaceToolTipText: {_obj: "interfaceColor", interfaceColorRed32: 0, interfaceColorGreen32: 0, interfaceColorBlue32: 0, interfaceColorRed2: 0, …}
|
|
119
|
+
// interfaceTransparencyBackground: {_obj: "interfaceColor", interfaceColorRed32: 204, interfaceColorGreen32: 204, interfaceColorBlue32: 204, interfaceColorRed2: 204, …}
|
|
120
|
+
// interfaceTransparencyForeground: {_obj: "interfaceColor", interfaceColorRed32: 255, interfaceColorGreen32: 255, interfaceColorBlue32: 255, interfaceColorRed2: 255, …}
|
|
121
|
+
// interfaceWhite: {_obj: "interfaceColor", interfaceColorRed32: 255, interfaceColorGreen32: 255, interfaceColorBlue32: 255, interfaceColorRed2: 255, …}
|
|
122
|
+
// interpolationMethod: {_enum: "interpolationType", _value: "bicubicAutomatic"}
|
|
123
|
+
// kuiBrightnessLevel: {_enum: "uiBrightnessLevelEnumType", _value: "kPanelBrightnessMediumGray"}
|
|
124
|
+
// layerThumbnailSize: {_enum: "size", _value: "small"}
|
|
125
|
+
// layerVisibilityChangesAreUndoable: true
|
|
126
|
+
// limited: false
|
|
127
|
+
// localeInfo: {decimalPoint: ","}
|
|
128
|
+
// modalDialogLevel: 0
|
|
129
|
+
// modalToolLevel: 0
|
|
130
|
+
// mondoFilterLevel: 0
|
|
131
|
+
// numberOfActionSets: 2
|
|
132
|
+
// numberOfCacheLevels: 4
|
|
133
|
+
// numberOfCacheLevels64: 4
|
|
134
|
+
// numberOfDocuments: 0
|
|
135
|
+
// osVersion: "Mac OS 26.0.0"
|
|
136
|
+
// panelList: (48) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
|
|
137
|
+
// panelUILockIsEnabled: false
|
|
138
|
+
// playbackOptions: {performance: {…}, historyStates: {…}}
|
|
139
|
+
// pluginPicker: {_obj: "pluginPicker", showAllFilterGalleryEntries: false, enablePluginDeveloperMode: true, generatorEnabled: false}
|
|
140
|
+
// preferencesFolder: {_path: "/Users/otto/Library/Preferences/Adobe Photoshop (Beta) Settings/", _kind: "local"}
|
|
141
|
+
// presetManager: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
|
|
142
|
+
// printSettings: {_obj: "printSettings", $cMat: true, $gWrn: false, $pWht: true, $Runt: 1, …}
|
|
143
|
+
// privacyPrefs: {_obj: "privacyPrefs"}
|
|
144
|
+
// recentFiles: (100) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
|
|
145
|
+
// recentFilesAsStrings: (100) ["/Users/otto/BubblyDoo Dropbox/NAS/Products/Peppa P… Be Anything - Style v1/2025/characterPreview.psd", "/Users/otto/Downloads/download (11).png", "/Users/otto/Code/projects/bubbly/doo/packages/uxp-toolkit/src/test-fixtures/color-profile-test-2.psd", "/Users/otto/BubblyDoo Dropbox/NAS/Products/Bing/Bo…k/Art/Done/Cover/bingBusySearchBook_coverSoft.psd", "/Users/otto/Downloads/body-colors-new.psd", "/Users/otto/BubblyDoo Dropbox/NAS/Products/In-hous…se Father's Day Book/v1_2024/Color files/skin.psd", "/Users/otto/Downloads/download (9).png", "/Users/otto/Downloads/body-colors (2).psd", "/Users/otto/Downloads/body-colors (1).psd", "/Users/otto/Downloads/body-colors.psd", "/Users/otto/Downloads/93cf41f0-f56d-4314-b80c-aa210c604f2a.png", "/Users/otto/Downloads/download (2).png", "/Users/otto/Pictures/Screenshots/Screenshot 2025-06-01 at 15.36.48.png", "/Users/otto/Pictures/Screenshots/Screenshot 2025-06-01 at 15.36.42.png", "/Users/otto/Pictures/Screenshots/Screenshot 2025-05-28 at 21.22.05.png", "/Users/otto/Downloads/image.jpeg", "/Users/otto/Downloads/a6f9cd09-c864-4cf9-b782-87b4a97204a7.png", "/Users/otto/Downloads/neutral.png", "/Users/otto/Downloads/download (8).png", "/Users/otto/Downloads/lut-small.png", "/Users/otto/Downloads/0aa31084-c5cd-4cdc-b8c3-d59b76c9132b.pdf", "/Users/otto/Downloads/b9b9e4c1-ed7d-4ba6-a5a6-73b4b36f17ff.pdf", "/Users/otto/Downloads/47214bf2-f774-4330-b12e-ce1e9f403cc0.pdf", "/Users/otto/Library/CloudStorage/GoogleDrive-hanso…apchat filters UAntwerpen/iphone x/middelheim.psd", "/Users/otto/Library/CloudStorage/GoogleDrive-hanso…hat filters UAntwerpen/iphone x/hof-van-liere.psd", "/Users/otto/Library/CloudStorage/GoogleDrive-hanso…hat filters UAntwerpen/iphone x/groenenborger.psd", "/Users/otto/Library/CloudStorage/GoogleDrive-hanso…Snapchat filters UAntwerpen/iphone x/mutsaard.psd", "/Users/otto/Library/CloudStorage/GoogleDrive-hanso…apchat filters UAntwerpen/iphone x/drie-eiken.psd", "/Users/otto/Library/CloudStorage/GoogleDrive-hanso…rk/Snapchat filters UAntwerpen/pdfs/all-large.pdf", "/Users/otto/Library/CloudStorage/GoogleDrive-hanso…k/Snapchat filters UAntwerpen/pdfs/all-phones.pdf", "/Users/otto/Downloads/7dda084a-cb3e-42f7-aaeb-c1b423d5c32b.png", "/Users/otto/capture-out.pdf", "/Users/otto/Downloads/8f5c1131-ff95-42f2-836c-7e2274614f84.pdf", "/Users/otto/Downloads/1425a6a2-8131-4fab-9df0-c7442673ffcf.png", "/Users/otto/Downloads/a1d52b98-7d30-42ce-a125-dd1e170c2a65.png", "/Users/otto/Downloads/425e8760-c975-484f-9d25-a729a118c921.pdf", "/Users/otto/Downloads/1458ecc2-0447-4ad7-a2af-d82952546fd6.pdf", "/Users/otto/Downloads/968cd85f-0efb-4542-9676-c292df3d8b05.pdf", "/Users/otto/BubblyDoo Dropbox/NAS/Asset Library/Pe…Assets/peppaPigCanBeAnything_characterPreview.psd", "/Users/otto/Documents/mask test.psd", "/Users/otto/Downloads/bubbyBiographyTaylor_coverPreview.psd", "/Users/otto/Downloads/kid (1).psd", "/Users/otto/Downloads/kid.psd", "/Users/otto/Downloads/taylor spread 1.psd", "/Users/otto/Code/projects/spicesapp/public/sources/kohlers-medizinal-pflanzen.png", "/Users/otto/Downloads/ezgif-66a3acd86715ed.png", "/Users/otto/Downloads/download (1).avif", "/Users/otto/Downloads/download (3).png", "/Users/otto/Downloads/download (4).png", "/Users/otto/BubblyDoo Dropbox/NAS/Asset Library/Pe…Peppa Style v0 in progress/Assets/Pose Normal.psd", "/Users/otto/BubblyDoo Dropbox/NAS/Products/Peppa P…ck/V2/Art/Original/peppaPig_backpackSquare_v2.psd", "/Users/otto/BubblyDoo Dropbox/NAS/Products/PAW Pat… - dec/PAW RRR 22 - 05/PAW_DAD_big_spread 1V2.psd", "/Users/otto/Pictures/Screenshots/Screenshot 2024-12-11 at 13.04.59.png", "/Users/otto/BubblyDoo Dropbox/NAS/Products/PAW Pat…atshirt_contentBackgroundScaledToView_newTmpl.psd", "/Users/otto/BubblyDoo Dropbox/NAS/Products/PAW Pat…istmasAOPSweatshirt_contentBackground_newTmpl.psd", "/Users/otto/BubblyDoo Dropbox/NAS/Products/PAW Pat…d/pawChristmasAOPSweatshirt_contentBackground.psd", "/Users/otto/Downloads/image (17).png", "/Users/otto/Downloads/image (16).png", "/Users/otto/Library/CloudStorage/SynologyDrive-syn…atshirt_contentBackgroundScaledToView_newTmpl.psd", "/Users/otto/Library/CloudStorage/SynologyDrive-syn…interSweatshirt_contentBackgroundScaledToView.psd", "/Users/otto/Downloads/152-158.pdf", "/Users/otto/Library/CloudStorage/SynologyDrive-syn…ound/pawAOPWinterSweatshirt_contentBackground.psd", "/Users/otto/Downloads/29b26ae3-4e03-43be-b145-835ee962fae7.pdf", "/Users/otto/Documents/altvelo.psd", "/Users/otto/Pictures/Screenshots/Screenshot 2024-11-06 at 22.06.39.png", "/Users/otto/Downloads/Paw Patrol_AOP Sweatshirt_Winter.png", "/Users/otto/Downloads/Paw Patrol_AOP Sweatshirt_Winter.pdf", "/Users/otto/Code/projects/bubbly/doo/packages/tran…res/color-mask-alignment/color-mask-alignment.psd", "/Users/otto/Code/projects/bubbly/doo/packages/tran…res/color-mask-alignment/color-mask-alignment.png", "/Users/otto/Downloads/5e3dc28a-4294-43ef-bf68-9cf4169224b5.pdf", "/Users/otto/Downloads/d45dca38-c7be-4a6f-bbc1-d1239cf52c3a.jpg", "/Users/otto/Downloads/0000e917-93bc-477c-a66c-1e18d06f3e57.pdf", "/Users/otto/Downloads/102a43ad-1da5-48fe-ab51-dfc91fa568cc.pdf", "/Users/otto/Downloads/7904a124-aee6-4de0-b64b-c1b3e022f29d.pdf", "/Users/otto/Downloads/ef96debf-dbcf-4895-adf9-78fe5e5d0e8a.pdf", "/Users/otto/Library/CloudStorage/SynologyDrive-syn…y Book/Pages/Done/Page 1/PAW_BDAY_big_spread1.psd", "/Users/otto/Library/CloudStorage/SynologyDrive-syn…n/Art/Done/pawActionBlanket_contentBackground.psd", "/Users/otto/Downloads/bb5804b0-fe61-42ed-8eaa-d4f4c70d0748.png", "/Users/otto/Downloads/7ad893d5-ac6d-474a-8ddc-fcb847872016.png", "/Users/otto/Downloads/f2bb7ada-3183-482f-a326-c5dca3b81b29.pdf", "/Users/otto/Downloads/f556932a-347e-4449-b952-e2ab7395a891.pdf", "/Users/otto/Downloads/gtg-omw.gif", "/Users/otto/Downloads/rgb-DisplayP3HDR.png", "/Users/otto/Downloads/rgb-DisplayP3HDR.avif", "/Users/otto/Code/projects/bubbly/doo/packages/tran…ecolormatrix-bug-repro/rgb-DisplayP3-UltraHDR.jpg", "/Users/otto/Downloads/rgb-ProPhotoRGB.jpg", "/private/var/folders/zq/kmwpbcs50y31p80v9x6bt0ww0000gn/T/Fa97cRx_d.webp", "/Users/otto/Code/projects/bubbly/doo/packages/tran…ormatrix-bug-repro/rgb-DisplayP3-UltraHDR-ps2.jpg", "/Users/otto/Code/projects/bubbly/doo/packages/tran…lormatrix-bug-repro/rgb-DisplayP3-UltraHDR-ps.jpg", "/Users/otto/Downloads/rgb-ProPhotoRGB-xs.jpg", "/Users/otto/Downloads/65x100 Blanket (1).pdf", "/Users/otto/Downloads/100x150 Blanket (2).pdf", "/Users/otto/Library/CloudStorage/SynologyDrive-syn…cts/In-house/Inhouse Towel Summer/Colors/skin.psd", "/Users/otto/Downloads/Screenshot_20240718-120437.png", "/Users/otto/Downloads/Screenshot_2024-07-18-12-05-55-29_e4424258c8b8649f6e67d283a50a2cbc.jpg", "/Users/otto/Downloads/Screenshot 2024-07-18 at 12.03.02.png", "/Users/otto/Downloads/capture.pdf", "/Users/otto/Library/CloudStorage/SynologyDrive-syn…box/Spreads/Done/brezo_bumbaLunchbox_lidCover.psd", "/Users/otto/Library/CloudStorage/SynologyDrive-syn…eads/Done/brezo_bumbaLunchbox_lidCover_merged.psd", "/Users/otto/Downloads/out.png"]
|
|
146
|
+
// regionCode: 0
|
|
147
|
+
// rulerUnits: {_enum: "rulerUnits", _value: "rulerPixels"}
|
|
148
|
+
// scratchDiskPreferences: {_obj: "scratchDiskPreferences", scratchDisks: Array(1)}
|
|
149
|
+
// showToolTips: true
|
|
150
|
+
// size: 64
|
|
151
|
+
// tileSize: 1048576
|
|
152
|
+
// tool: {_enum: "marqueeRectTool", _value: "targetEnum"}
|
|
153
|
+
// toolBarVisible: false
|
|
154
|
+
// toolSupportsBrushPresets: false
|
|
155
|
+
// toolSupportsBrushes: false
|
|
156
|
+
// tools: (108) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]
|
|
157
|
+
// toolsPreferences: {_obj: "toolsPreferences", showToolTips: true, enableGestures: true, overscrollEnabled: true, resizeWindowsOnZoom: true, …}
|
|
158
|
+
// transparencyGamutPreferences: {_enum: "checkerboardSize", _value: "checkerboardMedium"}
|
|
159
|
+
// transparencyPrefs: {_obj: "transparencyPrefs", transparencyGamutPreferences: {…}, transparencyGridColors: {…}, gamutWarning: {…}, opacity: {…}}
|
|
160
|
+
// typePreferences: {_obj: "typePreferences", smartQuotes: true, textComposerChoice: {…}, enableFontFallback: true, enableGlyphAlternate: false, …}
|
|
161
|
+
// unitsPrefs: {_obj: "unitsPrefs", rulerUnits: {…}, typeUnits: {…}, columnWidth: {…}, gutterWidth: {…}, …}
|
|
162
|
+
// useCacheForHistograms: false
|
|
163
|
+
// used: 836602160
|
|
164
|
+
// vectorToolSettings: {_obj: "toolPreset", $SCrT: true, toolUserSelectionRecencyRank: 296, mode: {…}, opacity: 100, …}
|
|
165
|
+
// watchSuspension: 0
|
|
166
|
+
// workspaceList: (6) [{…}, {…}, {…}, {…}, {…}, {…}]
|
|
167
|
+
// workspacePreferences: {_obj: "workspacePreferences", enableNarrowOptionBar: false, autoCollapseDrawers: false, enableLargeTabs: true, autoShowRevealStrips: true, …}
|
|
168
|
+
// _warning: "hostVersion property is now available via require('uxp').host.version"
|
|
169
|
+
// [[Prototype]]: Object
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { photoshopGetApplicationInfo } from "./applicationInfo";
|
|
2
|
+
import type { Test } from "@bubblydoo/uxp-test-framework";
|
|
3
|
+
import { expect } from "chai";
|
|
4
|
+
|
|
5
|
+
export const applicationInfoTest: Test = {
|
|
6
|
+
name: "Application Info",
|
|
7
|
+
async run() {
|
|
8
|
+
const info = await photoshopGetApplicationInfo();
|
|
9
|
+
expect(info.hostName).to.include("Adobe Photoshop");
|
|
10
|
+
},
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export async function copyToClipboard(text: string): Promise<void> {
|
|
2
|
+
await navigator.clipboard.writeText({
|
|
3
|
+
"text/plain": text,
|
|
4
|
+
} as any);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export async function readFromClipboard(): Promise<string> {
|
|
8
|
+
const clipboard = await navigator.clipboard.readText();
|
|
9
|
+
return (clipboard as any)["text/plain"];
|
|
10
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Test } from "@bubblydoo/uxp-test-framework";
|
|
2
|
+
import { copyToClipboard, readFromClipboard } from "./clipboard";
|
|
3
|
+
import { expect } from "chai";
|
|
4
|
+
|
|
5
|
+
export const clipboardTest: Test = {
|
|
6
|
+
name: "should copy and read from clipboard",
|
|
7
|
+
async run() {
|
|
8
|
+
const originalClipboard = await readFromClipboard();
|
|
9
|
+
try {
|
|
10
|
+
await copyToClipboard("test");
|
|
11
|
+
const clipboard = await readFromClipboard();
|
|
12
|
+
expect(clipboard).to.eq("test");
|
|
13
|
+
} finally {
|
|
14
|
+
await copyToClipboard(originalClipboard);
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { getLayerProperties } from "./getLayerProperties";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { batchPlayCommands, createCommand } from "../core/command";
|
|
4
|
+
|
|
5
|
+
// export interface LayerDescriptor {
|
|
6
|
+
// name: string;
|
|
7
|
+
// layerID: number;
|
|
8
|
+
// layerSection?: string | { _value: string; _enum: string };
|
|
9
|
+
// [key: string]: any;
|
|
10
|
+
// }
|
|
11
|
+
|
|
12
|
+
const layerDescriptorSchema = z.object({
|
|
13
|
+
name: z.string(),
|
|
14
|
+
// id: z.number(),
|
|
15
|
+
layerID: z.number(),
|
|
16
|
+
// _docId: z.number(),
|
|
17
|
+
mode: z.object({
|
|
18
|
+
_enum: z.literal("blendMode"),
|
|
19
|
+
_value: z.string(), // passThrough, normal, multiply, screen, overlay, etc.
|
|
20
|
+
}),
|
|
21
|
+
background: z.boolean(),
|
|
22
|
+
itemIndex: z.number(),
|
|
23
|
+
visible: z.boolean(),
|
|
24
|
+
layerKind: z.number(),
|
|
25
|
+
layerSection: z.object({
|
|
26
|
+
_value: z.enum([
|
|
27
|
+
"layerSectionStart",
|
|
28
|
+
"layerSectionEnd",
|
|
29
|
+
"layerSectionContent",
|
|
30
|
+
]),
|
|
31
|
+
_enum: z.literal("layerSectionType"),
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export type LayerDescriptor = z.infer<typeof layerDescriptorSchema> & {
|
|
36
|
+
docId: number;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// get all layers (including nested in groups)
|
|
40
|
+
export const getFlattenedLayerDescriptorsList = async (
|
|
41
|
+
documentId: number
|
|
42
|
+
) => {
|
|
43
|
+
const layerProperties = await getLayerProperties(documentId);
|
|
44
|
+
|
|
45
|
+
const commands = layerProperties.map((layerProp) =>
|
|
46
|
+
createCommand({
|
|
47
|
+
modifying: false,
|
|
48
|
+
descriptor: {
|
|
49
|
+
_obj: "get",
|
|
50
|
+
_target: [
|
|
51
|
+
{
|
|
52
|
+
_ref: "layer",
|
|
53
|
+
_id: layerProp.layerID,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
makeVisible: false,
|
|
57
|
+
layerID: [layerProp.layerID],
|
|
58
|
+
_isCommand: false,
|
|
59
|
+
},
|
|
60
|
+
schema: layerDescriptorSchema,
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const layerDescriptors = await batchPlayCommands(commands);
|
|
65
|
+
|
|
66
|
+
return layerDescriptors.map((desc) => {
|
|
67
|
+
return {
|
|
68
|
+
...desc,
|
|
69
|
+
docId: documentId,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
import { type PsLayerRef } from "./psLayerRef";
|
|
3
|
+
import { batchPlayCommand, createCommand } from "../core/command";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
export function createGetLayerCommand(layerRef: PsLayerRef) {
|
|
7
|
+
return createCommand({
|
|
8
|
+
modifying: false,
|
|
9
|
+
descriptor: {
|
|
10
|
+
_obj: "get",
|
|
11
|
+
_target: [
|
|
12
|
+
{ _ref: "layer", _id: layerRef.id },
|
|
13
|
+
{ _ref: "document", _id: layerRef.docId },
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
schema: z.object({
|
|
17
|
+
layerID: z.number(),
|
|
18
|
+
group: z.boolean().optional(),
|
|
19
|
+
layerEffects: z.record(z.string(), z.object({
|
|
20
|
+
// "scale" does not have an "enabled" property, that's why it's optional
|
|
21
|
+
enabled: z.boolean().optional(),
|
|
22
|
+
}).or(z.array(z.object({
|
|
23
|
+
enabled: z.boolean(),
|
|
24
|
+
})))).optional(),
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function getLayerEffects(layerRef: PsLayerRef) {
|
|
30
|
+
const result = await batchPlayCommand(createGetLayerCommand(layerRef));
|
|
31
|
+
|
|
32
|
+
const data = result.layerEffects || {};
|
|
33
|
+
|
|
34
|
+
const effects: Record<string, boolean> = {};
|
|
35
|
+
|
|
36
|
+
for (const effect in data) {
|
|
37
|
+
if (effect !== "scale") effects[effect] = Array.isArray(data[effect]) ? data[effect].some((e) => e.enabled) : !!data[effect]?.enabled;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return effects;
|
|
41
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { batchPlayCommand, createCommand } from "../core/command";
|
|
3
|
+
|
|
4
|
+
export function createGetLayerPropertiesCommand(docId: number) {
|
|
5
|
+
return createCommand({
|
|
6
|
+
modifying: false,
|
|
7
|
+
descriptor: {
|
|
8
|
+
_obj: "multiGet",
|
|
9
|
+
_target: { _ref: [{ _ref: "document", _id: docId }] },
|
|
10
|
+
extendedReference: [
|
|
11
|
+
["name", "layerID", "visible"],
|
|
12
|
+
{ _obj: "layer", index: 1, count: -1 },
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
schema: z.object({
|
|
16
|
+
list: z.array(
|
|
17
|
+
z.object({
|
|
18
|
+
name: z.string(),
|
|
19
|
+
layerID: z.number(),
|
|
20
|
+
visible: z.boolean().optional(),
|
|
21
|
+
})
|
|
22
|
+
)
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// get layer properties like name and layerID for all layers in the document (by index)
|
|
28
|
+
export const getLayerProperties = async (documentId: number) => {
|
|
29
|
+
const command = createGetLayerPropertiesCommand(documentId);
|
|
30
|
+
|
|
31
|
+
const result = await batchPlayCommand(command);
|
|
32
|
+
|
|
33
|
+
// Reverse to get bottom-up order
|
|
34
|
+
return [...result.list].reverse();
|
|
35
|
+
};
|