Giter Site home page Giter Site logo

typings's People

Contributors

jfontanez-bw avatar kerrishotts avatar pklaschka avatar tato123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typings's Issues

RenditionSettings.outputFile

Maybe I got it wrong but RenditionSettings.outputFile must point to the same type as uxp.storage.Folder.createFile return type (uxp.storage.File) not generic File (which is Blob).

Add support for publishing in definitely-typed repository

Enhancement request

Overview

For projects that utilize typescript and npm, types can be associated to a project by downloading the library via npm and exposeing a typings key. The request is to create the necessary values and expose the library on npm as a published package

Changes required within repository

  • Create a package.json
  • Add "typings": "./types/index.d.ts" key/value

Additional owner / contributor changes

  • publish changes to npm
  • stretch goal: use a build system to publish changes upon merge to master

SceneNodeList "type" should move to scenegraph.d.ts

The SceneNodeList class should not be in the global context. Actual attempts to access the SceneNodeList directly in a command script results in undefined (it's not actually a global).

Further, this should probably be an interface rather than a class as there does not appear to be a way to create new instances yourself.

Therefore I would recommend moving the SceneNodeList declaration into scenegraph.d.ts, (the only location the type is actually referenced) and simultaneously convert it to an interface.

Missed properties for RadialGradientFill

I know that it doesn't have official documentation but we still need to work with it. Please add currently existing properties to unblock current development:

  "isCentered": true,
  "flipScale": { "sx": 1, "sy": 1 },
  "rotationHandle": { "x": 1, "y": 0.5 },
  "degreeRotation": 0,
  "scaleFactors": { "scaleX": 1, "scaleY": 1 },
  "linkId": "",
  "endR": 0.5,
  "endY": 0.5,
  "endX": 0.5,
  "startR": 0,
  "startY": 0.5,
  "startX": 0.5,
  "transformHeight": 0,
  "transformWidth": 0,
  "gradientTransform": { "a": 1, "b": 0, "c": 0, "d": 1, "e": 0, "f": 0 },
  "colorStops": [
    {
      "color": { "a": 255, "r": 255, "g": 255, "b": 255, "linkId": "", "value": 4294967295 },
      "stop": 0
    },
    {
       "color": { "a": 255, "r": 88, "g": 58, "b": 168, "linkId": "", "value": 4283972264 },
       "stop": 1
    }
  ],
  "rotationHandleX": 1,
  "rotationHandleY": 0.5,
  "rotation": 0,
  "scaleX": 1,
  "scaleY": 1
}```

Fix type declarations for options objects in uxp.d.ts

While TypeScript theoretically supports declaring one-off types with the JSDoc format, it doesn't work terribly well for ambient type declarations (*.d.ts). It appears to mainly provide context for type checking the usage of that type in the body of a function's definition.

Let's look at an example with the Entry.copyTo function. Here is how it's currently defined:

/**
 * Copies this entry to the specified `folder`.
 * @param folder the folder to which to copy this entry
 * @param {object} options additional options
 * @param {boolean=false} options.overwrite if `true`, allows overwriting existing entries
 *
 * @throws errors.EntryExistsError if the attempt would overwrite an entry and `overwrite` is `false`
 * @throws errors.PermissionDeniedError if the underlying file system rejects the attempt
 * @throws errors.OutOfSpaceError if the file system is out of storage space
 */
copyTo(folder: Folder, options?): Promise<void>;

As written, the TypeScript language service is already confused about the use of the @param directive. See:

image

Whoops! It didn't identify the options.overwrite parameter correctly. To do this in a way that satisfies TypeScript, we would write the following:

/**
 * @param {boolean} [options.overwrite=false] if `true`, allows overwriting existing entries
 */

Oddly, once you write it "correctly" for TypeScript, the option object's parameters disappear from the IntelliSense entirely:

image

Unfortunately, constructing the parameters in this way also doesn't help the language service with type checking. If you look at the type of the options parameter in that declaration it is considered any.

Oh no!

A much better and safer way to handle this is to implement the options parameters inline inside the declaration. Here's an example that uses the copyTo function:

/**
 * Copies this entry to the specified `folder`.
 * 
 * The Entry object passed to this function will continue to reference the original item - it is _not_ updated to reference the copy.
 * 
 * @param folder the folder to which to copy this entry
 * @param options
 *
 * @throws errors.EntryExistsError if the attempt would overwrite an entry and `overwrite` is `false`
 * @throws errors.PermissionDeniedError if the underlying file system rejects the attempt
 * @throws errors.OutOfSpaceError if the file system is out of storage space
 */
copyTo(folder: Folder, options?: {
    /**
     * if `true`, allows overwriting existing entries
     */
    overwrite?: boolean = false;
}): Promise<void>;

[Note: The above version includes an updated body based on the current docs.]

With this approach we get the following three benefits:

  1. IntelliSense for options fields:
    image
  2. Auto-completion when authoring:
    image
  3. Error reporting when an incorrect type is used:
    image

Another Option...

If inline parameter documentation is unappealing, there is one other method that could be used. It's more flexible, but less "precise" when it comes to Adobe's documentation. Specifically, you could define your own interface:

interface CopyToOptions {
     /**
     * if `true`, allows overwriting existing entries
     */
    overwrite?: boolean = false;
}

With the above, you would change the declaration of copyTo to the following:

copyTo(folder: Folder, options?: CopyToOptions): Promise<void>;

This provides the same exact benefits as the inline approach with one additional benefit: you can reuse that type!

/** @type {import("uxp").storage.CopyToOptions} */
let copyOptions = {
    overwrite: true
};
anEntry.copyTo(null, copyOptions);

That said, it is unlikely that many people would use such a feature...

Fix Symbol definitions in uxp.d.ts

The symbol declarations for storage.formats, storage.modes, and storage.types are defined too "loosely".

First of all, the type Symbol refers to the constructor for symbol instances. At the very least, all symbols defined in the uxp.d.ts file should use the lowercase version.

Second, as each symbol being referenced here is a unique symbol, the unique keyword should be applied. As an example, this is how formats should be defined:

/**
 * This namespace describes the file content formats supported in FS methods like read and write.
 */
namespace formats {
    /**
     * UTF8 File encoding
     */
    const utf8: unique symbol;
    /**
     * Binary file encoding
     */
    const binary: unique symbol;
}

This allows us to do something extremely cool. We can now use those symbols to restrict options for other fields. Let's say we had an options object with a format field. By default you might define that format field as type symbol so that it would be restricted to symbols in general. That's decent as you can no longer say something like options.format = 5. But options.format = Symbol("5") is no better, right?

These unique symbol types allow us to do this:

interface Options
{
    format: typeof formats.utf8 | typeof formats.binary;
}

Now the only symbols allowed are specifically formats.utf8 or formats.binary. That's much better!

With this in mind, the type declarations for some options object fields in uxp.d.ts (example) can be updated to be more strict (and helpful!).

Property definitions are public by default, remove the `public` keyword?

Property definitions are all public by default in TypeScript. Adding the public keyword in front of every declaration is distracting and makes it more difficult to identify the standout private or protected parameters.

Removing the public keyword from the type declarations would make them far more readable and help them better match most other type declaration files.

[I understand that this is a style thing, but it does have an impact on readability and maintainability...]

tsconfig.json incorrectly relies upon browser DOM types

UXP supports a specific subset of browser DOM APIs. TypeScript's DOM lib, on the other hand, is extremely comprehensive. Configuring an environment with TypeScript's built-in DOM library leads to confusing bugs and causes tools to incorrectly suggest types.

Recommendation:

  1. Remove the dom entry from the tsconfig.json lib array.
  2. Create UXP-specific type declaration files for the following:
    1. UI Classes (e.g. Attr and friends)
    2. HTML Elements (e.g. HTMLAnchorElement and friends)
    3. Events (e.g. BaseUIEvent and friends)

As Adobe incorporates more HTML and standard browser DOM APIs into UXP, the type declaration files can be updated to reflect the enhancements. This will help resolve an entire class of typo/error/etc.

Declaration Errors in assets.d.ts

If you convert the jsconfig.json file to a tsconfig.json file, set strict: true, and then open the assets.d.ts file (in VSCode, at least), you are presented with the following errors:

  • A 'declare' modifier cannot be used in an already ambient context. ts(1038) [119, 5]
  • A 'declare' modifier cannot be used in an already ambient context. ts(1038) [155, 5]

These refer to the fact that the colors and characterStyles classes are declared inside an already declared module.

Removing those declare statements results in further errors related to the definition of the static class. As both the colors and characterStyles "classes" are actually interfaces that allow you to access information (you never have an "instance" of those "classes"), they should simply be converted to interfaces and the static keyword removed from all function definitions. Then a constant should be added that implements that interface so that it is accessible as a name and not just a type. Taken together, the two "class"es should look something like this:

interface colors {
    get(): Array<ColorAsset | GradientAsset>;
    add(...): number;
    delete(...): number;
}

const colors: colors;

JSDoc / TSDoc / Comment Spec

A space for discussions about

  1. What tags can/should get used in the doc comments
  2. What spec can be taken to ensure compatibility with editors and still have a productive experience

'SceneNode' refers to a value, but is being used as a type here ts(2749)

I'm getting this message after importing the new type defs directory (today Sept 28).

'SceneNode' refers to a value, but is being used as a type here.ts(2749)

And this error:

Property 'SceneNode' does not exist on type 'typeof import("/Users/user/Library/Application Support/Adobe/Adobe XD/develop/myplugin/types/scenegraph")'.ts(2339)

It happens on the const line and the @param line:

// there's a red underline under scene node
const {SceneNode} = require("scenegraph");

/**
 * Adds interaction
 * @param {SceneNode} item
 **/
function addInteractions(item, model) {

}

Declarations Errors in cloud.d.ts

If you convert the jsconfig.json file to a tsconfig.json file, set strict: true, and then open the assets.d.ts file (in VSCode, at least), you are presented with the following errors:

  • Enum type 'ArtifactType' has members with initializers that are not literals. ts(2535) [9, 15]
  • Enum type 'ArtifactType' has members with initializers that are not literals. ts(2535) [52, 15]

These refer to the fact that you have the following in a type declaration:

type PrototypeArtifact = {
    type: ArtifactType.PROTOTYPE,  // <-- Can't do this with ambient enums!

The problem here is that you are assigning a value to the type PrototypeArtifact.type but that you have not explicitly said what ArtifactType.PROTOTYPE is actually equivalent to. When you declare an ambient enum, you provide information on the names of each valid type but not the value. While this works for usage of that enum entry, you cannot use it in another ambient type declaration as you do above.

That said, enums in JavaScript are simple objects and we can easily see what their values are with a quick test (though it would be nice if Adobe simply documented them...):

// Outputs:
// { PROTOTYPE: 'prototype', SPECS: 'specs' }
console.log(require('cloud').ArtifactType);
// Outputs:
// { WEB: 'Web', IOS: 'iOS', ANDROID: 'Android' }
console.log(require('cloud').TargetPlatform);
// Outputs:
// { LINKABLE: 'linkable',
//   PASSWORD_PROTECTED: 'passwordProtected',
//   INVITE_ONLY: 'inviteOnly' }
console.log(require('cloud').AccessLevel);

Cool. With that information in hand, we can write the enums as follows:

export enum ArtifactType {
    PROTOTYPE   = 'prototype',
    SPECS       = 'specs'
}

export enum TargetPlatform  {
    WEB     = 'Web',
    IOS     = 'iOS',
    ANDROID = 'Android'
}

export enum AccessLevel {
    LINKABLE            = 'linkable',
    PASSWORD_PROTECTED  = 'passwordProtected',
    INVITE_ONLY         = 'inviteOnly'
}

Once those definitions are added the errors go away!

Definitions Out-of-Sync, Though...

It should also be noted that the declarations in cloud.d.ts appear to be out-of-sync with those in the current documentation.

In the current version, the PrototypeArtifact and SpecsArtifact types are effectively "extensions" of a new BaseSharedArtifact. It also appears that there's a documentation bug for the description of the BaseSharedArtifact.type member in that it appears to suggest that it is constantly ArtifactType.PROTOTYPE. I'd be willing to bet my hat that that is a copy-pasta error.

While it is possible to "extend" a type declaration, I would highly recommend converting these types into interfaces. Adobe's use of "typedef" in the documentation simply suggests that "this is the shape of an object". You can use a TypeScript interface to match that purpose (especially when typedef 'inheritance' is suggested).

Note that if you do adjust the declarations and unify the two Artifact types with the BaseSharedArtifact, you could get away without adding the enum values as explained above. It might be better, however, to do something like:

interface BaseSharedArtifact {
    type: ArtifactType;
    // Other common declarations...
}

interface PrototypeArtifact extends BaseSharedArtifact {
    type: ArtifactType.PROTOTYPE;
    // Prototype-specific declarations...
}

interface SpecsArtifact extends BaseSharedArtifact {
    type: ArtifactType.SPECS;
    // Specs-specific declarations...
}

At which point you would still need those enum values.

Reimagine structure with samles etc.

As proposed by @ericdrobinson in #54 (comment):

Repo Structure - New Issue?
I would like to suggest that the jsconfig.json and sample.js file get moved into a sample or
example folder that's separate from the top level. A tsconfig.json file at the top level then makes > the most sense. This will allow a clear separation of TypeScript and JavaScript files while allowing > you to have a tsconfig.json file that's designed specifically for writing the declaration files.

Thoughts?

Fixing Issues in the `sample.js` File

I downloaded this repository, unzipped it, opened the folder in Visual Studio Code (v1.33.0), opened the sample.js file, and was greeted to the following two errors:

image

These are pretty simple to fix.

Fixing the RootNode Type Error

This problem occurs because the sample.js scope doesn't have the RootNode type imported yet, even though it's used in a JSDoc parameter declaration:

/**
 * @param {Selection} selection
 * @param {RootNode} documentRoot
 */

There are two ways to fix this:

  1. Import the RootNode type (class).
  2. Use TypeScript's "import types".

If you chose the second route, the code excerpt above would become:

/**
 * @param {Selection} selection
 * @param {import('scenegraph').RootNode} documentRoot
 */

Note that this does not actually import the type into the sample.js "module"'s scope, but enables it and consumers to get proper type handling.

Fixing the File | Folder Type Error

This problem refers to this code from line 23:

newFile.write("Hello, world!");

This is actually a bit more complicated than the previous error as there are three things going on:

  1. There is no Folder type defined in the current scope.
  2. The File type specified refers to the global Web DOM File type.
  3. The Folder.createEntry method returns either a UXP File or a UXP Folder (and the code assumes it returns a UXP File instance).

To handle all of these issues and provide a safer usage example, do the following:

  1. Import the UXP File type.
  2. Add a type guard to the call to write().

Put together the above looks like this:

// At the top of sample.js
const UXPFile = require("uxp").storage.File;

// ...

// Replace Line 23 with this:
if (newFile instanceof UXPFile) {
    newFile.write("Hello, world!");
}

With these changes you will find that your JavaScript sample is now error-free! Hurray!

I decided to explain these here in the hopes that it will be more instructive than a simple PR. Hope this helps!

Add support for editor: Brackets

Currently, the open source editor "Brackets" is not supported. Instructions on how to use the typings with this editor (if possible) should be added to the wiki.

Compilation errors when using `tsc`

When importing individual classes like this:

import { Ellipse as Ellipse, 
    Rectangle as Rectangle, 
    Color as Color } from "../node_modules/@adobexd/typings/types/scenegraph";

and compiling using tsc, the compiler throws the following errors:


306     public constructor(fileOrDataURI: string | uxp.storage.File);
                                                   ~~~

node_modules/@adobexd/typings/types/scenegraph.d.ts:341:74 - error TS2371: A parameter initializer is only allowed in a function or constructor implementation.

341     public constructor(x: number, y: number, blur: number, color: Color, visible: boolean = true)
                                                                             ~~~~~~~~~~~~~~~~~~~~~~~

node_modules/@adobexd/typings/types/scenegraph.d.ts:413:31 - error TS2304: Cannot find name 'SceneNodeList'.

413     public readonly children: SceneNodeList;

importing using require works, but doing so means you can't use the types as intended in your code:

const {Rectangle, Ellipse, Color} = require('scenegraph');

Here is an example project: https://github.com/mattThousand/typings

please let me know if I can provide additional information or help out in any way

make RenditionSettings.type strongly types

RenditionSettings.type can have only specific value so I suppose it must be strongly typed, like:

/**
  * File type: RenditionType.PNG, JPG, PDF, or SVG
  */
    type: "PNG" | "JPG" | "PDF" | "SVG";

Really documentation is unclear if RenditionType stands for specific type or just a way to describe values.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.