@bubblydoo/uxp-toolkit 0.0.4 → 0.0.6
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 +4 -4
- package/CHANGELOG.md +13 -0
- package/dist/index.d.ts +80 -58
- package/dist/index.js +219 -188
- package/package.json +5 -2
- package/src/commands-library/getDocument.ts +36 -0
- package/src/commands-library/getDocument.txt +62 -0
- package/src/commands-library/getLayer.ts +56 -0
- package/src/commands-library/getLayer.txt +186 -0
- package/src/commands-library/multiGetDocument.ts +47 -0
- package/src/commands-library/renameLayer.uxp-test.ts +4 -4
- package/src/core/command.test-d.ts +25 -0
- package/src/index.ts +26 -17
- package/src/ut-tree/getDocumentLayerDescriptors.ts +29 -0
- package/src/ut-tree/getLayerEffects.ts +3 -26
- package/src/ut-tree/hasBackgroundLayer.uxp-test.ts +42 -0
- package/src/ut-tree/photoshopLayerDescriptorsToUTLayers.test.ts +114 -0
- package/src/ut-tree/photoshopLayerDescriptorsToUTLayers.ts +30 -58
- package/src/ut-tree/photoshopLayerDescriptorsToUTLayers.uxp-test.ts +36 -3
- package/src/ut-tree/utLayersToText.test.ts +94 -0
- package/src/ut-tree/utLayersToText.ts +32 -0
- package/src/ut-tree/utLayersToTree.ts +2 -1
- package/src/util/utLayerPickKeysType.ts +5 -0
- package/test/fixtures/one-layer-with-bg.psd +0 -0
- package/test/index.ts +4 -1
- package/vitest-photoshop-alias-plugin.ts +41 -0
- package/vitest.config.ts +17 -0
- package/src/commands-library/getLayerProperties.ts +0 -32
- package/src/ut-tree/getFlattenedLayerDescriptorsList.ts +0 -72
- package/src/ut-tree/getLayerProperties.ts +0 -35
package/dist/index.js
CHANGED
|
@@ -100,44 +100,105 @@ var executeAsModalAndSuspendHistory = async (commandName, document, fn) => {
|
|
|
100
100
|
});
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
-
// src/commands-library/
|
|
103
|
+
// src/commands-library/renameLayer.ts
|
|
104
104
|
import { z as z2 } from "zod";
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
function createRenameLayerCommand(layerRef, newName) {
|
|
106
|
+
return createCommand({
|
|
107
|
+
modifying: true,
|
|
108
|
+
descriptor: {
|
|
109
|
+
_obj: "set",
|
|
110
|
+
_target: [{ _ref: "layer", _id: layerRef.id }, { _ref: "document", _id: layerRef.docId }],
|
|
111
|
+
to: { _obj: "layer", name: newName }
|
|
112
|
+
},
|
|
113
|
+
schema: z2.unknown()
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/commands-library/getDocument.ts
|
|
118
|
+
import z3 from "zod";
|
|
119
|
+
function createGetDocumentCommand(documentId) {
|
|
120
|
+
return createCommand({
|
|
107
121
|
modifying: false,
|
|
108
122
|
descriptor: {
|
|
109
|
-
_obj: "
|
|
110
|
-
_target: { _ref: [{ _ref: "document", _id:
|
|
111
|
-
extendedReference: [
|
|
112
|
-
["name", "layerID", "visible"],
|
|
113
|
-
{ _obj: "layer", index: 1, count: -1 }
|
|
114
|
-
]
|
|
123
|
+
_obj: "get",
|
|
124
|
+
_target: { _ref: [{ _ref: "document", _id: documentId }] }
|
|
115
125
|
},
|
|
116
|
-
schema:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
visible: z2.boolean().optional()
|
|
122
|
-
})
|
|
123
|
-
)
|
|
126
|
+
schema: z3.object({
|
|
127
|
+
title: z3.string(),
|
|
128
|
+
documentID: z3.number(),
|
|
129
|
+
visible: z3.boolean(),
|
|
130
|
+
hasBackgroundLayer: z3.boolean()
|
|
124
131
|
})
|
|
125
132
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
133
|
+
}
|
|
134
|
+
function createGetDocumentHasBackgroundLayerCommand(documentId) {
|
|
135
|
+
return createCommand({
|
|
136
|
+
modifying: false,
|
|
137
|
+
descriptor: {
|
|
138
|
+
_obj: "get",
|
|
139
|
+
_target: {
|
|
140
|
+
_ref: [
|
|
141
|
+
{ _property: "hasBackgroundLayer" },
|
|
142
|
+
{ _ref: "document", _id: documentId }
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
schema: z3.object({
|
|
147
|
+
hasBackgroundLayer: z3.boolean()
|
|
148
|
+
})
|
|
149
|
+
});
|
|
150
|
+
}
|
|
129
151
|
|
|
130
|
-
// src/commands-library/
|
|
131
|
-
import
|
|
132
|
-
|
|
152
|
+
// src/commands-library/getLayer.ts
|
|
153
|
+
import z4 from "zod";
|
|
154
|
+
var layerSchema = z4.object({
|
|
155
|
+
name: z4.string(),
|
|
156
|
+
visible: z4.boolean(),
|
|
157
|
+
group: z4.boolean(),
|
|
158
|
+
layerSection: z4.object({
|
|
159
|
+
_value: z4.enum([
|
|
160
|
+
"layerSectionStart",
|
|
161
|
+
"layerSectionEnd",
|
|
162
|
+
"layerSectionContent"
|
|
163
|
+
]),
|
|
164
|
+
_enum: z4.literal("layerSectionType")
|
|
165
|
+
}),
|
|
166
|
+
layerKind: z4.number(),
|
|
167
|
+
itemIndex: z4.number(),
|
|
168
|
+
background: z4.boolean(),
|
|
169
|
+
mode: z4.object({
|
|
170
|
+
_enum: z4.literal("blendMode"),
|
|
171
|
+
_value: z4.string()
|
|
172
|
+
}),
|
|
173
|
+
layerID: z4.number(),
|
|
174
|
+
layerEffects: z4.record(z4.string(), z4.object({
|
|
175
|
+
// "scale" does not have an "enabled" property, that's why it's optional
|
|
176
|
+
enabled: z4.boolean().optional()
|
|
177
|
+
}).or(z4.array(z4.object({
|
|
178
|
+
enabled: z4.boolean()
|
|
179
|
+
})))).optional()
|
|
180
|
+
});
|
|
181
|
+
function createGetLayerCommand(layerRef) {
|
|
133
182
|
return createCommand({
|
|
134
|
-
modifying:
|
|
183
|
+
modifying: false,
|
|
135
184
|
descriptor: {
|
|
136
|
-
_obj: "
|
|
137
|
-
_target: [
|
|
138
|
-
|
|
185
|
+
_obj: "get",
|
|
186
|
+
_target: [
|
|
187
|
+
{ _ref: "layer", _id: layerRef.id },
|
|
188
|
+
{ _ref: "document", _id: layerRef.docId }
|
|
189
|
+
]
|
|
139
190
|
},
|
|
140
|
-
schema:
|
|
191
|
+
schema: layerSchema
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function createGetBackgroundLayerCommand(docId) {
|
|
195
|
+
return createCommand({
|
|
196
|
+
modifying: false,
|
|
197
|
+
descriptor: {
|
|
198
|
+
_obj: "get",
|
|
199
|
+
_target: { _ref: [{ _ref: "layer", "_property": "background" }, { _ref: "document", _id: docId }] }
|
|
200
|
+
},
|
|
201
|
+
schema: layerSchema
|
|
141
202
|
});
|
|
142
203
|
}
|
|
143
204
|
|
|
@@ -223,37 +284,37 @@ function mapTreeRef(tree, mapFn) {
|
|
|
223
284
|
}
|
|
224
285
|
|
|
225
286
|
// src/other/applicationInfo.ts
|
|
226
|
-
import { z as
|
|
287
|
+
import { z as z5 } from "zod";
|
|
227
288
|
async function photoshopGetApplicationInfo() {
|
|
228
289
|
return await batchPlayCommand(photoshopApplicationInfoCommand);
|
|
229
290
|
}
|
|
230
|
-
var photoshopAppInfoSchema =
|
|
231
|
-
active:
|
|
232
|
-
autoShowHomeScreen:
|
|
233
|
-
available:
|
|
234
|
-
buildNumber:
|
|
235
|
-
documentArea:
|
|
236
|
-
left:
|
|
237
|
-
top:
|
|
238
|
-
right:
|
|
239
|
-
bottom:
|
|
291
|
+
var photoshopAppInfoSchema = z5.object({
|
|
292
|
+
active: z5.boolean(),
|
|
293
|
+
autoShowHomeScreen: z5.boolean(),
|
|
294
|
+
available: z5.number(),
|
|
295
|
+
buildNumber: z5.string(),
|
|
296
|
+
documentArea: z5.object({
|
|
297
|
+
left: z5.number(),
|
|
298
|
+
top: z5.number(),
|
|
299
|
+
right: z5.number(),
|
|
300
|
+
bottom: z5.number()
|
|
240
301
|
}),
|
|
241
|
-
hostName:
|
|
242
|
-
hostVersion:
|
|
243
|
-
versionMajor:
|
|
244
|
-
versionMinor:
|
|
245
|
-
versionFix:
|
|
302
|
+
hostName: z5.string(),
|
|
303
|
+
hostVersion: z5.object({
|
|
304
|
+
versionMajor: z5.number(),
|
|
305
|
+
versionMinor: z5.number(),
|
|
306
|
+
versionFix: z5.number()
|
|
246
307
|
}),
|
|
247
|
-
localeInfo:
|
|
248
|
-
decimalPoint:
|
|
308
|
+
localeInfo: z5.object({
|
|
309
|
+
decimalPoint: z5.string()
|
|
249
310
|
}),
|
|
250
|
-
osVersion:
|
|
251
|
-
panelList:
|
|
252
|
-
|
|
253
|
-
ID:
|
|
254
|
-
name:
|
|
255
|
-
obscured:
|
|
256
|
-
visible:
|
|
311
|
+
osVersion: z5.string(),
|
|
312
|
+
panelList: z5.array(
|
|
313
|
+
z5.object({
|
|
314
|
+
ID: z5.string(),
|
|
315
|
+
name: z5.string(),
|
|
316
|
+
obscured: z5.boolean(),
|
|
317
|
+
visible: z5.boolean()
|
|
257
318
|
})
|
|
258
319
|
)
|
|
259
320
|
});
|
|
@@ -284,123 +345,82 @@ async function readFromClipboard() {
|
|
|
284
345
|
}
|
|
285
346
|
|
|
286
347
|
// src/other/uxpEntrypoints.ts
|
|
287
|
-
import { z as
|
|
288
|
-
var uxpEntrypointsSchema =
|
|
289
|
-
_pluginInfo:
|
|
290
|
-
id:
|
|
291
|
-
name:
|
|
292
|
-
version:
|
|
348
|
+
import { z as z6 } from "zod";
|
|
349
|
+
var uxpEntrypointsSchema = z6.object({
|
|
350
|
+
_pluginInfo: z6.object({
|
|
351
|
+
id: z6.string(),
|
|
352
|
+
name: z6.string(),
|
|
353
|
+
version: z6.string()
|
|
293
354
|
})
|
|
294
355
|
});
|
|
295
356
|
|
|
296
|
-
// src/
|
|
297
|
-
import { z as
|
|
298
|
-
function
|
|
357
|
+
// src/commands-library/multiGetDocument.ts
|
|
358
|
+
import { z as z7 } from "zod";
|
|
359
|
+
function createMultiGetDocumentCommand(docId) {
|
|
299
360
|
return createCommand({
|
|
300
361
|
modifying: false,
|
|
301
362
|
descriptor: {
|
|
302
363
|
_obj: "multiGet",
|
|
303
364
|
_target: { _ref: [{ _ref: "document", _id: docId }] },
|
|
304
365
|
extendedReference: [
|
|
305
|
-
["name", "layerID", "visible"],
|
|
366
|
+
["name", "layerID", "visible", "group", "layerSection", "layerKind", "itemIndex", "background", "mode", "layerEffects"],
|
|
306
367
|
{ _obj: "layer", index: 1, count: -1 }
|
|
307
368
|
]
|
|
308
369
|
},
|
|
309
|
-
schema:
|
|
310
|
-
list:
|
|
311
|
-
|
|
312
|
-
name:
|
|
313
|
-
layerID:
|
|
314
|
-
visible:
|
|
370
|
+
schema: z7.object({
|
|
371
|
+
list: z7.array(
|
|
372
|
+
z7.object({
|
|
373
|
+
name: z7.string(),
|
|
374
|
+
layerID: z7.number(),
|
|
375
|
+
visible: z7.boolean(),
|
|
376
|
+
group: z7.boolean(),
|
|
377
|
+
layerSection: z7.object({
|
|
378
|
+
_value: z7.enum([
|
|
379
|
+
"layerSectionStart",
|
|
380
|
+
"layerSectionEnd",
|
|
381
|
+
"layerSectionContent"
|
|
382
|
+
]),
|
|
383
|
+
_enum: z7.literal("layerSectionType")
|
|
384
|
+
}),
|
|
385
|
+
layerKind: z7.number(),
|
|
386
|
+
itemIndex: z7.number(),
|
|
387
|
+
background: z7.boolean(),
|
|
388
|
+
mode: z7.object({
|
|
389
|
+
_enum: z7.literal("blendMode"),
|
|
390
|
+
_value: z7.string()
|
|
391
|
+
}),
|
|
392
|
+
layerEffects: z7.record(z7.string(), z7.object({
|
|
393
|
+
// "scale" does not have an "enabled" property, that's why it's optional
|
|
394
|
+
enabled: z7.boolean().optional()
|
|
395
|
+
}).or(z7.array(z7.object({
|
|
396
|
+
enabled: z7.boolean()
|
|
397
|
+
})))).optional()
|
|
315
398
|
})
|
|
316
399
|
)
|
|
317
400
|
})
|
|
318
401
|
});
|
|
319
402
|
}
|
|
320
|
-
var getLayerProperties2 = async (documentId) => {
|
|
321
|
-
const command = createGetLayerPropertiesCommand(documentId);
|
|
322
|
-
const result = await batchPlayCommand(command);
|
|
323
|
-
return [...result.list].reverse();
|
|
324
|
-
};
|
|
325
403
|
|
|
326
|
-
// src/ut-tree/
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
background: z7.boolean(),
|
|
339
|
-
itemIndex: z7.number(),
|
|
340
|
-
visible: z7.boolean(),
|
|
341
|
-
layerKind: z7.number(),
|
|
342
|
-
layerSection: z7.object({
|
|
343
|
-
_value: z7.enum([
|
|
344
|
-
"layerSectionStart",
|
|
345
|
-
"layerSectionEnd",
|
|
346
|
-
"layerSectionContent"
|
|
347
|
-
]),
|
|
348
|
-
_enum: z7.literal("layerSectionType")
|
|
349
|
-
})
|
|
350
|
-
});
|
|
351
|
-
var getFlattenedLayerDescriptorsList = async (documentId) => {
|
|
352
|
-
const layerProperties = await getLayerProperties2(documentId);
|
|
353
|
-
const commands = layerProperties.map(
|
|
354
|
-
(layerProp) => createCommand({
|
|
355
|
-
modifying: false,
|
|
356
|
-
descriptor: {
|
|
357
|
-
_obj: "get",
|
|
358
|
-
_target: [
|
|
359
|
-
{
|
|
360
|
-
_ref: "layer",
|
|
361
|
-
_id: layerProp.layerID
|
|
362
|
-
}
|
|
363
|
-
],
|
|
364
|
-
makeVisible: false,
|
|
365
|
-
layerID: [layerProp.layerID],
|
|
366
|
-
_isCommand: false
|
|
367
|
-
},
|
|
368
|
-
schema: layerDescriptorSchema
|
|
369
|
-
})
|
|
370
|
-
);
|
|
371
|
-
const layerDescriptors = await batchPlayCommands(commands);
|
|
372
|
-
return layerDescriptors.map((desc) => {
|
|
404
|
+
// src/ut-tree/getDocumentLayerDescriptors.ts
|
|
405
|
+
var getDocumentLayerDescriptors = async (documentId) => {
|
|
406
|
+
const [layersResult, documentHasBackgroundLayerResult] = await batchPlayCommands([
|
|
407
|
+
createMultiGetDocumentCommand(documentId),
|
|
408
|
+
createGetDocumentHasBackgroundLayerCommand(documentId)
|
|
409
|
+
]);
|
|
410
|
+
const backgroundLayerResult = documentHasBackgroundLayerResult.hasBackgroundLayer ? await batchPlayCommand(createGetBackgroundLayerCommand(documentId)) : null;
|
|
411
|
+
const list = [...layersResult.list].reverse();
|
|
412
|
+
if (backgroundLayerResult) {
|
|
413
|
+
list.push(backgroundLayerResult);
|
|
414
|
+
}
|
|
415
|
+
return list.map((layerProp) => {
|
|
373
416
|
return {
|
|
374
|
-
...
|
|
417
|
+
...layerProp,
|
|
375
418
|
docId: documentId
|
|
376
419
|
};
|
|
377
420
|
});
|
|
378
421
|
};
|
|
379
422
|
|
|
380
423
|
// src/ut-tree/getLayerEffects.ts
|
|
381
|
-
import { z as z8 } from "zod";
|
|
382
|
-
function createGetLayerCommand(layerRef) {
|
|
383
|
-
return createCommand({
|
|
384
|
-
modifying: false,
|
|
385
|
-
descriptor: {
|
|
386
|
-
_obj: "get",
|
|
387
|
-
_target: [
|
|
388
|
-
{ _ref: "layer", _id: layerRef.id },
|
|
389
|
-
{ _ref: "document", _id: layerRef.docId }
|
|
390
|
-
]
|
|
391
|
-
},
|
|
392
|
-
schema: z8.object({
|
|
393
|
-
layerID: z8.number(),
|
|
394
|
-
group: z8.boolean().optional(),
|
|
395
|
-
layerEffects: z8.record(z8.string(), z8.object({
|
|
396
|
-
// "scale" does not have an "enabled" property, that's why it's optional
|
|
397
|
-
enabled: z8.boolean().optional()
|
|
398
|
-
}).or(z8.array(z8.object({
|
|
399
|
-
enabled: z8.boolean()
|
|
400
|
-
})))).optional()
|
|
401
|
-
})
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
424
|
async function getLayerEffects(layerRef) {
|
|
405
425
|
const result = await batchPlayCommand(createGetLayerCommand(layerRef));
|
|
406
426
|
const data = result.layerEffects || {};
|
|
@@ -458,15 +478,6 @@ var blendModes = [
|
|
|
458
478
|
"luminosity",
|
|
459
479
|
"passThrough"
|
|
460
480
|
];
|
|
461
|
-
var getLayerSectionValue = (layer) => {
|
|
462
|
-
if (typeof layer.layerSection === "string") {
|
|
463
|
-
return layer.layerSection;
|
|
464
|
-
}
|
|
465
|
-
if (layer.layerSection && typeof layer.layerSection === "object" && "_value" in layer.layerSection) {
|
|
466
|
-
return layer.layerSection._value;
|
|
467
|
-
}
|
|
468
|
-
return void 0;
|
|
469
|
-
};
|
|
470
481
|
var getLayerKind = (layer) => {
|
|
471
482
|
const kind = layerKindMap.get(layer.layerKind);
|
|
472
483
|
if (!kind) {
|
|
@@ -481,36 +492,11 @@ var getBlendMode = (layer) => {
|
|
|
481
492
|
}
|
|
482
493
|
return mode;
|
|
483
494
|
};
|
|
484
|
-
|
|
485
|
-
const section = getLayerSectionValue(layer);
|
|
486
|
-
const isGroupEnd = layer.name === "</Layer group>" || layer.name === "</Layer set>" || section === "layerSectionEnd";
|
|
487
|
-
const isGroupStart = section === "layerSectionStart";
|
|
488
|
-
return isGroupStart ? "start" : isGroupEnd ? "end" : "normal";
|
|
489
|
-
};
|
|
490
|
-
var photoshopLayerDescriptorsToUTLayers = async (layers) => {
|
|
495
|
+
function photoshopLayerDescriptorsToUTLayers(layers) {
|
|
491
496
|
const root = [];
|
|
492
497
|
const stack = [{ layers: root }];
|
|
493
|
-
const commands = layers.map((layer) => createGetLayerCommand({ docId: layer.docId, id: layer.layerID }));
|
|
494
|
-
const batchResults = await executeAsModal("Get Layer Effects Data", async (ctx) => {
|
|
495
|
-
return await ctx.batchPlayCommands(commands);
|
|
496
|
-
});
|
|
497
|
-
const effectsMap = /* @__PURE__ */ new Map();
|
|
498
|
-
batchResults.forEach((result, index) => {
|
|
499
|
-
const layerId = layers[index].layerID;
|
|
500
|
-
const data = result.layerEffects;
|
|
501
|
-
const effects = {};
|
|
502
|
-
if (data) {
|
|
503
|
-
for (const effect in data) {
|
|
504
|
-
effects[effect] = Array.isArray(data[effect]) ? data[effect].some((e) => e.enabled) : !!data[effect]?.enabled;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
effectsMap.set(layerId, effects);
|
|
508
|
-
});
|
|
509
498
|
for (const layer of layers) {
|
|
510
499
|
const sectionType = determineLayerSection(layer);
|
|
511
|
-
const isClippingMask = !!batchResults.find((res, index) => {
|
|
512
|
-
return layer.layerID === res.layerID;
|
|
513
|
-
})?.group;
|
|
514
500
|
if (sectionType === "end") {
|
|
515
501
|
if (stack.length > 1) {
|
|
516
502
|
stack.pop();
|
|
@@ -524,8 +510,9 @@ var photoshopLayerDescriptorsToUTLayers = async (layers) => {
|
|
|
524
510
|
visible: layer.visible,
|
|
525
511
|
kind: getLayerKind(layer),
|
|
526
512
|
blendMode: getBlendMode(layer),
|
|
527
|
-
isClippingMask,
|
|
528
|
-
effects:
|
|
513
|
+
isClippingMask: layer.group,
|
|
514
|
+
effects: getEffects(layer),
|
|
515
|
+
background: layer.background
|
|
529
516
|
};
|
|
530
517
|
const current = stack[stack.length - 1];
|
|
531
518
|
current.layers.push(node);
|
|
@@ -535,7 +522,22 @@ var photoshopLayerDescriptorsToUTLayers = async (layers) => {
|
|
|
535
522
|
}
|
|
536
523
|
}
|
|
537
524
|
return root;
|
|
525
|
+
}
|
|
526
|
+
var determineLayerSection = (layer) => {
|
|
527
|
+
const section = layer.layerSection._value;
|
|
528
|
+
const isGroupEnd = layer.name === "</Layer group>" || layer.name === "</Layer set>" || section === "layerSectionEnd";
|
|
529
|
+
const isGroupStart = section === "layerSectionStart";
|
|
530
|
+
return isGroupStart ? "start" : isGroupEnd ? "end" : "normal";
|
|
538
531
|
};
|
|
532
|
+
function getEffects(layer) {
|
|
533
|
+
const effects = {};
|
|
534
|
+
if (layer.layerEffects) {
|
|
535
|
+
for (const effect in layer.layerEffects) {
|
|
536
|
+
effects[effect] = Array.isArray(layer.layerEffects[effect]) ? layer.layerEffects[effect].some((e) => e.enabled) : !!layer.layerEffects[effect]?.enabled;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return effects;
|
|
540
|
+
}
|
|
539
541
|
|
|
540
542
|
// src/ut-tree/utLayersToTree.ts
|
|
541
543
|
function utLayersToTree(layer) {
|
|
@@ -548,13 +550,41 @@ function utLayersToTree(layer) {
|
|
|
548
550
|
kind: layer2.kind,
|
|
549
551
|
blendMode: layer2.blendMode,
|
|
550
552
|
isClippingMask: layer2.isClippingMask,
|
|
551
|
-
effects: layer2.effects
|
|
553
|
+
effects: layer2.effects,
|
|
554
|
+
background: layer2.background
|
|
552
555
|
},
|
|
553
556
|
name: layer2.name,
|
|
554
557
|
children: layer2.layers ? utLayersToTree(layer2.layers) : void 0
|
|
555
558
|
}));
|
|
556
559
|
}
|
|
557
560
|
|
|
561
|
+
// src/ut-tree/utLayersToText.ts
|
|
562
|
+
var VISIBLE_ICON = "\u25EF";
|
|
563
|
+
var INVISIBLE_ICON = "\u2298";
|
|
564
|
+
var CLIPPING_MASK_ICON = "\u2B10";
|
|
565
|
+
var GROUP_ICON = "\u25BE";
|
|
566
|
+
var EFFECTS_ICON = "\u0192";
|
|
567
|
+
var BLEND_ICON = "\u2055";
|
|
568
|
+
function utLayersToText(tree, depth = 0) {
|
|
569
|
+
return tree.map((layer) => {
|
|
570
|
+
const prefix = " ".repeat(depth * 2);
|
|
571
|
+
const name = layer.name;
|
|
572
|
+
const effects = Object.keys(layer.effects).length > 0 ? EFFECTS_ICON : "";
|
|
573
|
+
const blend = isSpecialBlendMode(layer) ? BLEND_ICON : "";
|
|
574
|
+
const clippingMask = layer.isClippingMask ? CLIPPING_MASK_ICON : "";
|
|
575
|
+
const group = layer.kind === "group" ? GROUP_ICON : "";
|
|
576
|
+
const visible = layer.visible ? VISIBLE_ICON : INVISIBLE_ICON;
|
|
577
|
+
const line = [visible, prefix, clippingMask, group, name, effects, blend].filter(Boolean).join(" ");
|
|
578
|
+
if (layer.layers) {
|
|
579
|
+
return line + "\n" + utLayersToText(layer.layers, depth + 1);
|
|
580
|
+
}
|
|
581
|
+
return line;
|
|
582
|
+
}).join("\n");
|
|
583
|
+
}
|
|
584
|
+
function isSpecialBlendMode(layer) {
|
|
585
|
+
return layer.kind === "group" ? layer.blendMode !== "passThrough" : layer.blendMode !== "normal";
|
|
586
|
+
}
|
|
587
|
+
|
|
558
588
|
// src/util/utLayerToLayer.ts
|
|
559
589
|
import { app as app2 } from "photoshop";
|
|
560
590
|
function utLayerToDomLayer(layer) {
|
|
@@ -704,19 +734,19 @@ export {
|
|
|
704
734
|
batchPlayCommands,
|
|
705
735
|
copyToClipboard,
|
|
706
736
|
createCommand,
|
|
707
|
-
|
|
708
|
-
|
|
737
|
+
createGetBackgroundLayerCommand,
|
|
738
|
+
createGetDocumentCommand,
|
|
739
|
+
createGetDocumentHasBackgroundLayerCommand,
|
|
709
740
|
createModifyingBatchPlayContext,
|
|
741
|
+
createMultiGetDocumentCommand,
|
|
710
742
|
createRenameLayerCommand,
|
|
711
743
|
executeAsModal,
|
|
712
744
|
executeAsModalAndSuspendHistory,
|
|
713
745
|
flattenTree,
|
|
714
746
|
getBasicStackFrameAbsoluteFilePath,
|
|
747
|
+
getDocumentLayerDescriptors,
|
|
715
748
|
getFlattenedDomLayersList,
|
|
716
|
-
getFlattenedLayerDescriptorsList,
|
|
717
749
|
getLayerEffects,
|
|
718
|
-
getLayerProperties,
|
|
719
|
-
getLayerProperties2 as getLayerPropertiesFromUtTree,
|
|
720
750
|
mapTree,
|
|
721
751
|
mapTreeRef,
|
|
722
752
|
openFileByPath,
|
|
@@ -729,5 +759,6 @@ export {
|
|
|
729
759
|
utLayerToDomLayer,
|
|
730
760
|
utLayersToDomLayers,
|
|
731
761
|
utLayersToTree,
|
|
762
|
+
utLayersToText as utTreeToText,
|
|
732
763
|
uxpEntrypointsSchema
|
|
733
764
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bubblydoo/uxp-toolkit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Hans Otto Wirtz <hansottowirtz@gmail.com>",
|
|
@@ -33,15 +33,18 @@
|
|
|
33
33
|
"@types/node": "^20.8.7",
|
|
34
34
|
"@types/photoshop": "^25.0.2",
|
|
35
35
|
"chai": "^6.2.2",
|
|
36
|
+
"dedent": "^1.7.1",
|
|
36
37
|
"rollup": "^4.57.0",
|
|
37
38
|
"tsup": "^8.5.1",
|
|
38
39
|
"typescript": "^5.8.3",
|
|
40
|
+
"vitest": "^4.0.18",
|
|
39
41
|
"zod": "^4.3.6",
|
|
40
42
|
"@bubblydoo/tsconfig": "0.0.3",
|
|
41
|
-
"@bubblydoo/uxp-test-framework": "0.0.
|
|
43
|
+
"@bubblydoo/uxp-test-framework": "0.0.6"
|
|
42
44
|
},
|
|
43
45
|
"scripts": {
|
|
44
46
|
"build": "tsup",
|
|
47
|
+
"test": "vitest run",
|
|
45
48
|
"uxp-test:build": "uxp-test build",
|
|
46
49
|
"uxp-test:dev": "uxp-test dev"
|
|
47
50
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { createCommand } from "../core/command";
|
|
3
|
+
|
|
4
|
+
export function createGetDocumentCommand(documentId: number) {
|
|
5
|
+
return createCommand({
|
|
6
|
+
modifying: false,
|
|
7
|
+
descriptor: {
|
|
8
|
+
_obj: "get",
|
|
9
|
+
_target: { _ref: [{ _ref: "document", _id: documentId }] },
|
|
10
|
+
},
|
|
11
|
+
schema: z.object({
|
|
12
|
+
title: z.string(),
|
|
13
|
+
documentID: z.number(),
|
|
14
|
+
visible: z.boolean(),
|
|
15
|
+
hasBackgroundLayer: z.boolean(),
|
|
16
|
+
}),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createGetDocumentHasBackgroundLayerCommand(documentId: number) {
|
|
21
|
+
return createCommand({
|
|
22
|
+
modifying: false,
|
|
23
|
+
descriptor: {
|
|
24
|
+
_obj: "get",
|
|
25
|
+
_target: {
|
|
26
|
+
_ref: [
|
|
27
|
+
{ _property: "hasBackgroundLayer" },
|
|
28
|
+
{ _ref: "document", _id: documentId },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
schema: z.object({
|
|
33
|
+
hasBackgroundLayer: z.boolean(),
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Object
|
|
2
|
+
// EXIF: "EXIF tag 100274 Normal\rEXIF tag 100282 72.0\rEXIF tag 100283 72.0\rEXIF tag 100296 Inches\rEXIF tag 100305 Adobe Photoshop 27.3 (20251221.m.3348 0256c3c) (Macintosh)\rEXIF tag 100306 2026:01:30 11:20:57\rEXIF tag 140961 Uncalibrated\rEXIF tag 140962 100\rEXIF tag 140963 100\r"
|
|
3
|
+
// XMPMetadataAsUTF8: "<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc
|
|
4
|
+
// backgroundSaveInfo: {isPendingNormalSave: false}
|
|
5
|
+
// bigNudgeH: 655360
|
|
6
|
+
// bigNudgeV: 655360
|
|
7
|
+
// center: {_obj: "paint", horizontal: {…}, vertical: {…}}
|
|
8
|
+
// clippingPathInfo: {_obj: "clippingInfo", clippingPathIndex: -1, clippingPathFlatness: 0}
|
|
9
|
+
// contentCredentialsEnabled: false
|
|
10
|
+
// copyright: false
|
|
11
|
+
// count: 3
|
|
12
|
+
// depth: 8
|
|
13
|
+
// documentID: 101
|
|
14
|
+
// duotoneInk: 0
|
|
15
|
+
// extension: (3) ["PSD", "PDD", "PSDT"]
|
|
16
|
+
// fileInfo: {_obj: "fileInfo"}
|
|
17
|
+
// fileReference: {_path: "/Users/otto/Code/projects/bubbly/uxp-toolkit/packa…t/uxp-tests-plugin/fixtures/one-layer-with-bg.psd", _kind: "local"}
|
|
18
|
+
// format: "Photoshop"
|
|
19
|
+
// genTechModelsUsed: []
|
|
20
|
+
// generatorSettings: {_obj: "generatorSettings"}
|
|
21
|
+
// guidesVisibility: true
|
|
22
|
+
// hasBackgroundLayer: true
|
|
23
|
+
// height: {_unit: "distanceUnit", _value: 100}
|
|
24
|
+
// histogram: (256) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1698, 19, 5, 10, 3, 11, 6, 7, 4, 1, 2, 2, 4, 2, 3, 0, 2, 4, 2, 0, 4, 1, 4, 1, 3, 4, 0, …]
|
|
25
|
+
// isCloudDoc: false
|
|
26
|
+
// isDirty: false
|
|
27
|
+
// isUsingGenTech: false
|
|
28
|
+
// itemIndex: 2
|
|
29
|
+
// manage: {_enum: "manage", _value: "none"}
|
|
30
|
+
// measurementScale: {_obj: "measurementScale", _target: Array(2), to: {…}}
|
|
31
|
+
// mimeType: "application/vnd.adobe.photoshop"
|
|
32
|
+
// mode: {_enum: "colorSpace", _value: "RGBColor"}
|
|
33
|
+
// numberOfChannels: 3
|
|
34
|
+
// numberOfLayers: 1
|
|
35
|
+
// numberOfPaths: 0
|
|
36
|
+
// patternPreviewMode: false
|
|
37
|
+
// pixelScaleFactor: {_unit: "noneUnit", _value: 1}
|
|
38
|
+
// printColorHandling: {_enum: "printColorHandling", _value: "printerManaged"}
|
|
39
|
+
// printCopies: 1
|
|
40
|
+
// printCurrentPrinter: "EPSON ET-8500 Series"
|
|
41
|
+
// printOutput: {_obj: "printOutput", postScriptColor: true, intent: {…}, printSixteenBit: false, printerName: "", …}
|
|
42
|
+
// printOutputOptions: {_obj: "printOutputOptions", caption: false, calibrationBars: false, registrationMarks: false, cornerCropMarks: false, …}
|
|
43
|
+
// printerList: ["Brother MFC-L3750CDW series"]
|
|
44
|
+
// quickMask: false
|
|
45
|
+
// resolution: {_unit: "densityUnit", _value: 72}
|
|
46
|
+
// rulerOriginH: 0
|
|
47
|
+
// rulerOriginV: 0
|
|
48
|
+
// rulersVisibility: true
|
|
49
|
+
// selectionEdgesVisible: false
|
|
50
|
+
// slices: {bounds: {…}, slices: Array(1)}
|
|
51
|
+
// smartGuidesVisibility: true
|
|
52
|
+
// targetLayers: [{…}]
|
|
53
|
+
// targetLayersIDs: [{…}]
|
|
54
|
+
// targetLayersIndexes: [{…}]
|
|
55
|
+
// targetPathIndex: -1
|
|
56
|
+
// targetPathVisibility: true
|
|
57
|
+
// title: "one-layer-with-bg.psd"
|
|
58
|
+
// visible: true
|
|
59
|
+
// watermark: false
|
|
60
|
+
// width: {_unit: "distanceUnit", _value: 100}
|
|
61
|
+
// workPathIndex: -1
|
|
62
|
+
// zoom: {_unit: "percentUnit", _value: 30.830188679245282}
|