Skip to content

TypeScript types #9

Closed
Closed

Description

@micheleangioni

The TypeScript declaration package is missing in https://www.npmjs.com/~types .

More information on this: https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html

This is very important to ensure a proper diffusion of the cloudevents standards.

Activity

  1. fabiojose commented on Apr 4, 2019

    @fabiojose
    Contributor

    @micheleangioni Could you make a PR with this? If you can't, please write an example using some piece of code from sdk.

  2. micheleangioni commented on Apr 8, 2019

    @micheleangioni
    ContributorAuthor

    I do not have the complete library definitions. I have the definitions of the Spec01, Spec02 and Cloudevent classes.

    These are the definitions I wrote:

    declare module 'cloudevents-sdk' {
      export type SpecPayload = {
        [key: string]: any,
      };
    
      export class Spec01 {
        public payload: SpecPayload & {
          cloudEventsVersion: '0.1',
          eventID: string,
        };
    
        public check(): void;
    
        public type(type: string): Spec01;
        public getType(): string|undefined;
    
        public getSpecversion(): string;
    
        public eventTypeVersion(eventTypeVersion: string): Spec01;
        public getEventTypeVersion(): string|undefined;
    
        public source(source: string): Spec01;
        public getSource(): string|undefined;
    
        public id(id: string): Spec01;
        public getId(): string|undefined;
    
        public schemaurl(schemaurl: string): Spec01;
        public getSchemaurl(): string|undefined;
    
        public contenttype(contenttype: string): Spec01;
        public getContenttype(): string|undefined;
    
        public data(data: any): Spec01;
        public getData(): any;
    
        public time(time: Date): Spec01;
        public getTime(): string|undefined;
    
        public addExtension(key: string, value: any): Spec01;
      }
    
      export class Spec02 {
        public payload: SpecPayload & {
          specversion: '0.2',
          id: string,
        };
    
        public check(): void;
    
        public type(type: string): Spec02;
        public getType(): string|undefined;
    
        public getSpecversion(): string;
    
        public eventTypeVersion(eventTypeVersion: string): Spec02;
        public getEventTypeVersion(): string|undefined;
    
        public source(source: string): Spec02;
        // public getSource(): string|undefined; // TODO Missing getter, to be added. See https://github.com/cloudevents/sdk-javascript/pull/8
    
        public id(id: string): Spec02;
        public getId(): string|undefined;
    
        public time(time: Date): Spec02;
        public getTime(): string|undefined;
    
        public schemaurl(schemaurl: string): Spec02;
        public getSchemaurl(): string|undefined;
    
        public contenttype(contenttype: string): Spec02;
        public getContenttype(): string|undefined;
    
        public data(data: any): Spec02;
        public getData(): any;
    
        public addExtension(key: string, value: any): Spec02;
      }
    
      export type Extensions = {
        [key: string]: any,
      };
    
      export class JSONFormatter01 {
        public format(payload: SpecPayload): SpecPayload;
        public toString(payload: SpecPayload): string;
      }
    
      export default class Cloudevent {
        public static specs: {
          0.1: Spec01,
          0.2: Spec02,
        };
    
        public static formats: {
          'json': JSONFormatter01,
          'json0.1': JSONFormatter01,
        };
    
        public static bindings: {
          'http-structured': any,
          'http-structured0.1': any,
          'http-structured0.2': any,
          'http-binary0.1': any,
          'http-binary0.2': any,
        };
    
        public constructor(spec?: Spec01|Spec02, formatter?: JSONFormatter01);
    
        public format(): SpecPayload;
        public toString(): string;
    
        public type(type: string): Cloudevent;
        public getType(): string|undefined;
    
        public getSpecversion(): string;
    
        public source(type: string): Cloudevent;
        public getSource(): string|undefined;
    
        public id(id: string|number): Cloudevent;
        public getId(): string|undefined;
    
        public time(type: Date): Cloudevent;
        public getTime(): string|undefined;
    
        public schemaurl(schemaurl: string): Cloudevent;
        public getSchemaurl(): string|undefined;
    
        public contenttype(contenttype: string): Cloudevent;
        public getContenttype(): string|undefined;
    
        public data(data: any): Cloudevent;
        public getData(): any;
    
        public addExtension(key: string, value: any): Cloudevent;
        public getExtensions(): Extensions;
      }
    }
    
  3. fabiojose commented on Apr 9, 2019

    @fabiojose
    Contributor

    @micheleangioni Now I understood. Do you want to join us and work in this issue?

  4. micheleangioni commented on Apr 11, 2019

    @micheleangioni
    ContributorAuthor

    Yes, sure. I hope to find some time to write the declarations also of the remaining classes, hopefully in a couple of weeks :)

  5. cwallsfdc commented on Apr 25, 2019

    @cwallsfdc

    @micheleangioni, would be awesome!

    Novice question, how to use the type definition above w/ cloudevents-sdk? I placed the type definition here lib/@types/cloudevents-sdk/index.d.ts, but it's unclear how to create a Cloudevent with a JSON string.

    Thanks.

  6. cwallsfdc commented on Apr 26, 2019

    @cwallsfdc

    @micheleangioni, I had to change the typing to the following to match cloudevents.js's single export of Cloudevent.

    https://gist.github.com/cwallsfdc/183c2df8dad88964efa957217b12c496

  7. fabiojose commented on May 7, 2019

    @fabiojose
    Contributor

    @cwallsfdc Can you help us in how to publish this typing in NPM?

  8. cwallsfdc commented on May 7, 2019

    @cwallsfdc

    Honestly, I think a better approach is to convert to Typescript and include the typings in the cloudevents-sdk npm module. This way the lib and typing stay aligned. Migrating to Typescript shouldn't disrupt users.

    If in agreement, I can post a PR w/ Typescript changes. We'd then publish a new cloudevents-sdk version w/ typings.

    Thoughts?

  9. fabiojose commented on May 14, 2019

    @fabiojose
    Contributor

    LGTM!

    @cwallsfdc, go ahead! Perform your PR!

  10. grant commented on Aug 5, 2019

    @grant
    Member

    Google Cloud Functions uses it's own TypeScript types because this SDK does not have them.

    Google Cloud Functions Framework:
    https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/v1.0.0/src/invoker.ts#L63

  11. grant commented on Aug 8, 2019

    @grant
    Member

    Answering questions from email:

    When the sdk converted to ts, we can use it in pure js projects?

    Yes. When we publish to npm, we publish pure js and we have files for TypeScript types for autocompletion.

    I am comfortable with this approach, using definitely typed.

    We can publish this npm module instead of using DefinitelyTyped. See https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html


    Just let me know when master and dev are the same so I can do the conversion without new changes in the middle. It will take a bit of time.

  12. fabiojose commented on Aug 8, 2019

    @fabiojose
    Contributor

    @grant Thanks for the answers.

    Because of the changes that are coming from the spec, I think that is more prudence to publish the types using Definitely Typed. This will help the projects written in TypeScript and we save time to model the stuff for the future of the sdk (writing in ts) and to work in the incoming spec changes.

    It's fair if we make voting:

    • Vote a if you are in favor of to create just the types and publish to DefinitelyTyped
    • Vote b if you are in favor of to migrate the entire codebase from JavaScript to TypeScript

    What do you thing about that @grant ?

    rigth now, master and develop remains the same

  13. grant commented on Aug 8, 2019

    @grant
    Member

    b is so much better and easier.
    This is what Google does with all JavaScript libraries.

  14. 69 remaining items

  15. johnm commented on May 11, 2020

    @johnm

    Sorry @johnm, I was reacting a bit. This issue has been open for over a year with hundreds of commits to this project directly to master and no progress on issues like this one despite PRs, forks, Slack discussions, calls, etc. The comment of immediately positioning against making progress on this issue via separate repos was surprising and did not suggest a way forward.

    No worries, I understand the frustration as I've been in similar situations previously.

    FWIW, I separated the two different aspects on purpose. There are the problems at technology level but also at the project level (of the impact on the users/etc). I think the context of the project should be keep in mind when dealing with the tradeoffs in making the technology decisions.

  16. johnm commented on May 11, 2020

    @johnm
  17. lance commented on May 11, 2020

    @lance
    Member
    • I must know the exact properties of a CloudEvent before execution.
    • I must never see "undefined" is not a function or equivalent for SDK users.
    • I must have autocompletion in my developer tooling/IDE for CloudEvents.
    • I must be able to click to definition to see the source code of the SDK.
    • I must see linting errors in my code if I use the CloudEvent SDK incorrectly (i.e. invalid type).

    I was under the belief that using tsc and JSDoc would ensure that all of this is possible. Is that not the case?

    Editors like VS Code will do it's best with just js files or just a tsconfig. You're really using TypeScript under-the-hood. At that point, you're really just avoiding the filename rename for some reason.

    If type checking is enabled with tsc and there is a valid tsconfig, then VSCode should be satisfied, I think. I've recently been experimenting with this on my fork, and have found that it's quite effective.

    I am saying that the main issue we're facing is the fear of change.

    I might say reluctance to change. There are existing contributors (including myself) who are reluctant to switch fully to TS for a number of reasons. But I don't know that you are representing them in good faith. A reduced contributor pool and alienation of existing contributors are what I care most about. I really don't like the required transpilation stage in order to actually have a JavaScript engine be capable of reading my code, but I can live with that, I suppose. I do like the fact that tslint can enforce pure JS. But I wonder, what's the point of actually converting to TS in that case if we can achieve the user-facing goals (knowing the properties of a CE, autocompletion, linting, etc) with tsc, JSDoc and other tooling?

    As @johnm has suggested, I would like to consider a path forward that starts small, using tsc to check the code, jsdoc to enable both IDE autocomplete and help tsc, and type declaration generation. Do this with an eye towards eventually moving to TS when this whole thing has simmered down a bit. I understand that there are potential benefits to TS. But there are reasons to take it slowly. I would like to think that this is a fair compromise.

    To be quite honest, I would be surprised if Google immediately started using this project if we did nothing but switch to TypeScript by changing file names and adding a watch command. Those first compromising steps seem necessary in any case.

    Rather than a switch to TypeScript, my most pressing concerns are:

    • Reduce the surface area of the API to be much simpler, e.g. const { CloudEvent, HTTPEmitter, HTTPReceiver } = require('cloudevents-sdk');
    • Add JSDoc to the entire public facing API (those classes above)
    • Design the API so that it is more consistent with the spec
    • Release 2.0.0 soon.

    Honestly, I think these add much more value than renaming a bunch of files. I'd like to focus on these before making any major repository-wide changes if possible.

  18. grant commented on May 12, 2020

    @grant
    Member

    tsc is just a tool to transpile TypeScript to JavaScript.

    One of the big point of TypeScript is to not have to duplicate your code inside of docs. Right now we don't have many comments in the code. The suggestion here is to add JSDoc and annotate types everywhere. That's going to create a lot of boilerplate.

    There are 2 options:

    1. Add JSDoc everywhere. Keep them up-to-date with refactors.
    2. Rename files from .js to .ts and automatically understand types (even without annotations).

    The above comment chooses option 1. I'm suggesting 2.

    Again, switching to TypeScript is not a big change that will prevent you from having to write all that JSDoc.


    To be quite honest, I would be surprised if Google immediately started using this project if we did nothing but switch to TypeScript by changing file names and adding a watch command. Those first compromising steps seem necessary in any case.

    I literally work for Google, for Events, and have said multiple times I'd use this module if it was useful and supported TypeScript. See #9 (comment)

  19. lance commented on May 21, 2020

    @lance
    Member

    Fixed in: #155

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is neededstatus/stalledIssues that have not made progress recentlytype/enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions