TS support for UXP and Photoshop

Hi,
do you have any plan for creating TypeScript typing for uxp and photoshop package, same as XD have them https://github.com/AdobeXD/typings?

2 Likes

@pklaschka provided the original TS support for UXP and Adobe XD. Including him in this thread.

1 Like

I’m currently recovering from an ear infection. It will be a few more days until I’m back to full strength, which is when I’ll look into this more (I think there might be some info from the prerelease which is under NDA, so I’ll leave that part up to Adobe folks to mention here).

Overall, I probably won’t be capable of maintaining another set of type definitions (I’m already behind on the XD side of things), and hope that we’ll find some more “officially” maintained approach (to which I’d be happy to contribute documentation and whatnot, but not all the definitions and doc comments themselves).

1 Like

Working on some TS stuff; we had it in the prerelease, but need to bring it out in the public repos. Probably next week we’ll have an intial drop.

3 Likes

Are there plans for providing Descriptor Typings as well in the long term? I mean the structure of the internal Descriptors for certain things, not just the photoshop and uxp objects/classes. This would make coding so much more efficient and bulletproof. I’d be happy to contribute some things there, I already did it for some things like Path Descriptors:

export interface PathDescriptor {
  ID: number
  count: number
  itemIndex: number
  kind: {
    _enum: 'pathKind',
    _value: 'vectorMask' | 'workPath' | 'activePath' | 'clippingPath' | 'normalPath' | 'textMask'
  }
  pathContents: {
    _obj: 'pathClass',
    pathComponents: PathComponentDescriptor[]
  }
  pathName: string
  targetPath: boolean
}

export interface PathComponentDescriptor {
  _obj: 'pathComponent'
  shapeOperation: {
    _enum: 'shapeOperation',
    _value: 'add' | 'subtract' | 'intersect' | 'interfaceIconFrameDimmed' | 'xor'
  }
  subpathListKey: SubpathDescriptor[]
}

export interface SubpathDescriptor {
  _obj: 'subpathsList'
  closedSubpath: boolean
  points: PathPointDescriptor[]
}

export interface PathPointDescriptor {
  _obj: 'pathPoint'
  anchor: PointDescriptor
  backward?: PointDescriptor
  forward?: PointDescriptor
  smooth?: boolean
}

export interface PointDescriptor {
  _obj: 'paint' | 'point'
  horizontal: UnitValue
  vertical:  UnitValue
}

Theoretically, this could be done for Text Descriptors (yes, I know they’re complex), Layers/Documents in general and other objects of the internal structure. Then we could easily “navigate” through the Descriptors returned from BatchPlay via the dot-notation (+autocomplete) and wouldn’t have to log everything just to make sure we got the structure right. I think these typings would be an awesome update!

1 Like

@pklaschka @kerrishotts @Velara Over the last days I created complete typings for the TextKey Descriptor (all the text-related properties of a TextLayer) and Layer Effects Descriptor, including all the possible Enums etc.
This makes it alot easier to work with and edit these objects, so I might keep extending it until a Layer (, Document, Application, …) Descriptor is fully typed.
It’s already 1000+ lines of type definitions right now, so just let me know when there’s an official place for the typings and you want to reuse them / let me contribute them.

3 Likes

I think your own public GitHub repo could be a good start. Just make clear it can be moved elsewhere later.

1 Like

Also, it could be useful to add those data types into Alchemist. Maybe there could be one more tab with “data model” showing all possible object options when the model is known.

And perhaps there could option to generate code for TypeScript with the types in it.

Yes I think that’s a good idea, I’ll probably open the repo tomorrow. I’m still wondering how I should treat the types I imported from the prerelease type repo. Maybe I just copy them as I only used very few like UnitValue and other Unit types. Those overlaps could get removed at a later point easily.

Alchemist + Typescript sounds awesome :ok_hand:

1 Like

Here’s the repo:

3 Likes

Good job. Regarding to colors there is one more type… book colors e.g. pantone
image

Regarding to color stops in gradients
image

Regarding to generatorSettings descriptor. I think this is always empty… there is nothing todo.

legacyContentData in adjustment layers… I think this will be always ArrayBuffer in case of UXP.

link for cloud documents
image

placed _enum in SO
image

videoLayer
image

Second _path _kind is
image

image

image

image

image

Also text can be on vector path which gives us more properties:

Also PS has 3D layers but trust me… you really don’t want to look what is inside :smiley:

Anyway those types looks very good mine wouldn’t have such a nice organization structure. I personally perfer string literals over enums in PS enums. This is easier for me to work with and I am not aware of any problem with it. And sometimes I do use /** Instellisense comments */ because when you work with it you know what values mean but later it is easy to forget. This is usefull for enums.

Thanks @Jarda, that’s really helpful at completing the types :ok_hand:

Ahh, never seen that one, it’s interesting how much you can still learn about Photoshop. Shouldn’t have just checked the “mode” menu-command for possible colors. Just found the book colors under “Color Libraries” on the picker. I was a bit confused by the structure. It has the same properties and “_obj” as the RGBColor, so I’ll probably just extend that one.

I knew it had to be something trivial like that, just couldn’t figure out those other enums in the moment :smiley:

Alright, I’ll remove the TODO then. I never worked with the Generator, so I had absolutely no clue what would get filled in there.

Is ArrayBuffer something I can use as a type? I’ll have to check later. I was wondering why Adjustment Layers have this veiling data structure instead of easy to read Descriptor/Object model. Probably some perfomance or legacy code thing? :thinking: I gotta play around with those another day. Have you edited/manipulated Adjustment-Layer data yet?

:+1: :+1:

Ah, is that for placing SVG-Files or similar? Forgot about those

Is that part of some other Descriptor or where should it be inserted? I also never used Video Layers, so I’ll have to play around with those later

Would the string type be fine for the path? Looks like it has some properties inside, it’s stringified though…

Nice, how did you find out about those? I literally clicked every text setting possible and couldn’t find them. Maybe I had to switch my PS to japanese, for which I was too lazy :smiley:

Another thing I forgot, thanks!

Indeed :smiley: To be honest, types are just meant to be an assistance and I don’t think that many people tackle 3D layers in scripts/plugins. I’ve never touched them in my everyday use of PS over many years - They just make my computer slow :smiley: I’d rather use blender or some other software then, which seems to run smoother ironically.

Thanks. I definitely tried to be as organized and precised as careful with the types so that they can be useful for everyone else, too. Concerning the Enums and string literals… I was wondering how to approach those. I think string literals offer more room for error, as you just have to spell them out manually. Also, when you use them, they’re just random strings and nobody knows where they come from. That’s why I think FigureStyle.proportionalLining is better to comprehend than just" "proportionalLining". Then you can also click on the Enum to see the other possible values.

Regarding the comments: I agree, they would help for sure. Many things are self-explaining, some others aren’t - So I didn’t bother with any comments yet, maybe in the future.

I’ll update the types later with all your suggestions :slight_smile:

Got it now. It’s not a new color mode, just addtional information that gets added to any of the existing modes. I’ll just extend the ColorSpace interface with optional props then

generatorSettings to be more precise… it is AcionDescriptor any inside can be whatever descriptor can hold. Anyway _obj property will be always same in that place.

ArrayBuffer is its own datatype. It is more compact (in terms of bytes) and fast (in terms of performance) compared to regular buffer or just string. ArrayBuffer is here as a replacement for raw data type. You cannot set those legacy data this is read only here. Alchemist has option in settings to convert arrayBuffer into array so you can see content. But you can in ExtendScript use raw data in action that has to be played but I have no idea how to do that in UXP see How to use Raw data type in batchPlay

videoLayer is when you place video into PS document. It is part of the layer descriptor.

cloud path - yes I think this is just a string

enums - I have my private collection of them.

3D - yes just ignore it if you can

In my IDE when I have typo in string literals then it shows error before I transpile. Also IntelliSense will offer you list of choices by default therefore you don’t need to figure out what is enum type to import. And you can see where it comes from when you Ctrl+Click on method name and then again on the argument data type. But that is my personal preference. I can’t say what is better. You can try both and stick with what feels better. You can do it like this: export type Align = "left" | "center" | "right

image

image

image

…also I think this could allow me to convert d.ts definitions into JSON so JS could easily parse them and compare with object recorded in Alchemist. https://github.com/lbovet/typson Therefore I think we could possibly add a feature to highlight properties and values that are not in types definition and also possibly harvest and automatically collect those types.

Mysterious :thinking: :smile:

For some of these, I feel like there aren’t even options available from the Apps UserInterface… I legit have never seen something like RainbowEffect or StairStepEffect. Did I overloook the PathTypeEffect setting somehow, if so, where is it. I don’t even find anything on google related to these words.

Do you have examples of the raw data use in extendscript? Or what specifically are the differences to UXP, or what are the errors / fail behaviours? I had not contact with that topic yet, but it’s definitely interesting, maybe I’ll have an idea when I take a closer look.

That’s a good idea. How would you try to match the events / descriptor results with their respective type? Right now I can only think of manually pairing vairous ActionDescriptors with the expected result type.

Use old ScriptListener plugin and record “liquify” compare that in ExScript vs UXP

For listener it would based on event name. For inspector it would manually paired based on reference in “get” command.

One thing to keep in mind is that the Descriptor Objects often have optional properties, or in other words different variants of itself (linked vs. placed SmartObject for example). If you want to compare the results with an object parsed from the types, this could be a bit tricky - or at least you’d have to test for the different variants, too.