Détail du package

@custom-elements-manifest/helpers

open-wc417MIT0.0.3

⚠️ Very experimental and very unfinished

custom-elements, custom-elements-json, custom-elements-manifest, customelements

readme

@custom-elements-json/helpers

⚠️ Very experimental and very unfinished

Custom-elements.json is a file format that describes custom elements. This format will allow tooling and IDEs to give rich information about the custom elements in a given project. It is, however, very experimental and things are subject to change. Follow the discussion here.

This library aims to ship some helpers to ease working with the custom-elements.json format.

Usage

// Node
import { CustomElementsJson } from '@custom-elements-json/helpers';

const foo = JSON.parse(fs.readFileSync('./custom-elements.json', 'utf-8'));
const customElementsJson = new CustomElementsJson(json);

// Browser
import { CustomElementsJson } from 'https://unpkg.com/@custom-elements-json/helpers/dist/esm/index.js';

const json = await (await fetch('./custom-elements.json')).json();
const customElementsJson = new CustomElementsJson(json);

Methods


getByTagName

Returns all information for element <my-element>.

customElementsJson.getByTagName('my-element');
<summary>custom-elements.json</summary> json { "version": "experimental", "modules": [ { "path": "./src/MyMixinB.js", "exports": [ { "kind": "variable", "name": "MyMixinB", "text": "(klass: any) => typeof MyMixinB" } ] }, { "path": "./src/MySuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MySuperClass", "mixins": [ { "name": "MyMixinB", "module": "./src/MyMixinB.js" } ], "members": [ { "kind": "field", "name": "text", "type": "string", "default": "\"b\"" } ] } ] }, { "path": "./src/AnotherSuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "MySuperClass", "module": "./src/MySuperClass.js" }, "name": "AnotherSuperClass", "members": [ { "kind": "field", "name": "label", "type": "string", "default": "\"d\"" }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ] } ] }, { "path": "./src/my-element.js", "exports": [ { "kind": "definition", "name": "my-element", "declaration": { "name": "MyElement", "module": "./src/my-element.js" } }, { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MyElement", "members": [ { "kind": "field", "name": "foo", "type": "string", "default": "\"bar\"" } ], "tagName": "my-element" } ] }, { "path": "./src/another-component.js", "exports": [ { "kind": "definition", "name": "another-component", "declaration": { "name": "AnotherComponent", "module": "./src/another-component.js" } }, { "kind": "class", "superclass": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" }, "name": "AnotherComponent", "members": [ { "kind": "field", "name": "baz", "type": "string", "default": "\"bar\"" }, { "kind": "field", "name": "label", "type": "string", "default": "\"d\"", "inheritedFrom": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" } }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ], "tagName": "another-component" } ] } ] }
<summary>Result</summary> js { kind: 'class', superclass: { name: 'HTMLElement' }, name: 'MyElement', members: [ { kind: 'field', name: 'foo', type: 'string', default: '"bar"' } ], tagName: 'my-element' }

getByClassName

Returns all information for class MyElement.

customElementsJson.getByClassName('MyElement');
<summary>custom-elements.json</summary> json { "version": "experimental", "modules": [ { "path": "./src/MyMixinB.js", "exports": [ { "kind": "variable", "name": "MyMixinB", "type": "(klass: any) => typeof MyMixinB" } ] }, { "path": "./src/MySuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MySuperClass", "mixins": [ { "name": "MyMixinB", "module": "./src/MyMixinB.js" } ], "members": [ { "kind": "field", "name": "text", "type": "string", "default": "\"b\"" } ] } ] }, { "path": "./src/AnotherSuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "MySuperClass", "module": "./src/MySuperClass.js" }, "name": "AnotherSuperClass", "members": [ { "kind": "field", "name": "label", "type": "string", "default": "\"d\"" }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ] } ] }, { "path": "./src/my-element.js", "exports": [ { "kind": "definition", "name": "my-element", "declaration": { "name": "MyElement", "module": "./src/my-element.js" } }, { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MyElement", "members": [ { "kind": "field", "name": "foo", "type": "string", "default": "\"bar\"" } ], "tagName": "my-element" } ] }, { "path": "./src/another-component.js", "exports": [ { "kind": "definition", "name": "another-component", "declaration": { "name": "AnotherComponent", "module": "./src/another-component.js" } }, { "kind": "class", "superclass": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" }, "name": "AnotherComponent", "members": [ { "kind": "field", "name": "baz", "type": "string", "default": "\"bar\"" }, { "kind": "field", "name": "label", "type": "string", "default": "\"d\"", "inheritedFrom": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" } }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ], "tagName": "another-component" } ] } ] }
<summary>Result</summary> js { kind: 'class', superclass: { name: 'HTMLElement' }, name: 'MyElement', members: [ { kind: 'field', name: 'foo', type: 'string', default: '"bar"' } ], tagName: 'my-element' }

getClasses

Returns all classes in a custom-elements.json

customElementsJson.getClasses();
<summary>custom-elements.json</summary> json { "version": "experimental", "modules": [ { "path": "./src/MyMixinB.js", "exports": [ { "kind": "variable", "name": "MyMixinB", "type": "(klass: any) => typeof MyMixinB" } ] }, { "path": "./src/MySuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MySuperClass", "mixins": [ { "name": "MyMixinB", "module": "./src/MyMixinB.js" } ], "members": [ { "kind": "field", "name": "text", "type": "string", "default": "\"b\"" } ] } ] }, { "path": "./src/AnotherSuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "MySuperClass", "module": "./src/MySuperClass.js" }, "name": "AnotherSuperClass", "members": [ { "kind": "field", "name": "label", "type": "string", "default": "\"d\"" }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ] } ] }, { "path": "./src/my-element.js", "exports": [ { "kind": "definition", "name": "my-element", "declaration": { "name": "MyElement", "module": "./src/my-element.js" } }, { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MyElement", "members": [ { "kind": "field", "name": "foo", "type": "string", "default": "\"bar\"" } ], "tagName": "my-element" } ] }, { "path": "./src/another-component.js", "exports": [ { "kind": "definition", "name": "another-component", "declaration": { "name": "AnotherComponent", "module": "./src/another-component.js" } }, { "kind": "class", "superclass": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" }, "name": "AnotherComponent", "members": [ { "kind": "field", "name": "baz", "type": "string", "default": "\"bar\"" }, { "kind": "field", "name": "label", "type": "string", "default": "\"d\"", "inheritedFrom": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" } }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ], "tagName": "another-component" } ] } ] }
<summary>Result</summary> js [ { kind: 'class', superclass: { name: 'HTMLElement' }, name: 'MySuperClass', mixins: [[Object]], members: [[Object]], }, { kind: 'class', superclass: { name: 'MySuperClass', module: './src/MySuperClass.js' }, name: 'AnotherSuperClass', members: [[Object], [Object]], }, { kind: 'class', superclass: { name: 'HTMLElement' }, name: 'MyElement', members: [[Object]], tagName: 'my-element', }, { kind: 'class', superclass: { name: 'AnotherSuperClass', module: './src/AnotherSuperClass.js' }, name: 'AnotherComponent', members: [[Object], [Object], [Object]], tagName: 'another-component', }, ];

getMixins

Returns all mixins in a custom-elements.json

customElementsJson.getMixins();
<summary>custom-elements.json</summary> json { "version": "experimental", "modules": [ { "path": "./src/MyMixinB.js", "exports": [ { "kind": "variable", "name": "MyMixinB", "type": "(klass: any) => typeof MyMixinB" } ] }, { "path": "./src/MySuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MySuperClass", "mixins": [ { "name": "MyMixinB", "module": "./src/MyMixinB.js" } ], "members": [ { "kind": "field", "name": "text", "type": "string", "default": "\"b\"" } ] } ] }, { "path": "./src/AnotherSuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "MySuperClass", "module": "./src/MySuperClass.js" }, "name": "AnotherSuperClass", "members": [ { "kind": "field", "name": "label", "type": "string", "default": "\"d\"" }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ] } ] }, { "path": "./src/my-element.js", "exports": [ { "kind": "definition", "name": "my-element", "declaration": { "name": "MyElement", "module": "./src/my-element.js" } }, { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MyElement", "members": [ { "kind": "field", "name": "foo", "type": "string", "default": "\"bar\"" } ], "tagName": "my-element" } ] }, { "path": "./src/another-component.js", "exports": [ { "kind": "definition", "name": "another-component", "declaration": { "name": "AnotherComponent", "module": "./src/another-component.js" } }, { "kind": "class", "superclass": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" }, "name": "AnotherComponent", "members": [ { "kind": "field", "name": "baz", "type": "string", "default": "\"bar\"" }, { "kind": "field", "name": "label", "type": "string", "default": "\"d\"", "inheritedFrom": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" } }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ], "tagName": "another-component" } ] } ] }
<summary>Result</summary> js [ { name: 'MyMixinB', module: './src/MyMixinB.js', kind: 'variable', type: '(klass: any) => typeof MyMixinB', }, ];

getDefinitions

Returns all custom element definitions in a custom-elements.json

customElementsJson.getDefinitions();
<summary>custom-elements.json</summary> json { "version": "experimental", "modules": [ { "path": "./src/MyMixinB.js", "exports": [ { "kind": "variable", "name": "MyMixinB", "type": "(klass: any) => typeof MyMixinB" } ] }, { "path": "./src/MySuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MySuperClass", "mixins": [ { "name": "MyMixinB", "module": "./src/MyMixinB.js" } ], "members": [ { "kind": "field", "name": "text", "type": "string", "default": "\"b\"" } ] } ] }, { "path": "./src/AnotherSuperClass.js", "exports": [ { "kind": "class", "superclass": { "name": "MySuperClass", "module": "./src/MySuperClass.js" }, "name": "AnotherSuperClass", "members": [ { "kind": "field", "name": "label", "type": "string", "default": "\"d\"" }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ] } ] }, { "path": "./src/my-element.js", "exports": [ { "kind": "definition", "name": "my-element", "declaration": { "name": "MyElement", "module": "./src/my-element.js" } }, { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "MyElement", "members": [ { "kind": "field", "name": "foo", "type": "string", "default": "\"bar\"" } ], "tagName": "my-element" } ] }, { "path": "./src/another-component.js", "exports": [ { "kind": "definition", "name": "another-component", "declaration": { "name": "AnotherComponent", "module": "./src/another-component.js" } }, { "kind": "class", "superclass": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" }, "name": "AnotherComponent", "members": [ { "kind": "field", "name": "baz", "type": "string", "default": "\"bar\"" }, { "kind": "field", "name": "label", "type": "string", "default": "\"d\"", "inheritedFrom": { "name": "AnotherSuperClass", "module": "./src/AnotherSuperClass.js" } }, { "kind": "field", "name": "text", "type": "string", "default": "\"b\"", "inheritedFrom": { "name": "MySuperClass", "module": "./src/MySuperClass.js" } } ], "tagName": "another-component" } ] } ] }
<summary>Result</summary> js [ { kind: 'definition', name: 'my-element', declaration: { name: 'MyElement', module: './src/my-element.js' }, }, { kind: 'definition', name: 'another-component', declaration: { name: 'AnotherComponent', module: './src/another-component.js' }, }, ];

getInheritanceTree

Returns inheritance for class MyComponent.

customElementsJson.getInheritanceTree('MyComponent');
<summary>custom-elements.json</summary> json { "version": "experimental", "modules": [ { "path": "./dev/src/custom-element/LitElement.js", "exports": [ { "kind": "class", "superclass": { "name": "UpdatingElement", "module": "./dev/src/custom-element/UpdatingElement.js" }, "name": "LitElement" } ] }, { "path": "./dev/src/custom-element/MyComponent.js", "exports": [ { "kind": "definition", "name": "my-component", "declaration": { "name": "LitElement", "module": "./dev/src/custom-element/LitElement.js" } }, { "kind": "class", "superclass": { "name": "LitElement", "module": "./dev/src/custom-element/LitElement.js" }, "mixins": [ { "name": "TabindexMixin", "module": "./dev/src/custom-element/MyComponent.js" }, { "name": "LocalizeMixin", "module": "./dev/src/custom-element/MyComponent.js" } ], "name": "MyComponent" }, { "kind": "class", "name": "TabindexMixin" }, { "kind": "class", "name": "LocalizeMixin" }, { "kind": "variable", "name": "LocalizeMixin", "type": "(klass: any) => typeof LocalizeMixin" }, { "kind": "variable", "name": "TabindexMixin", "type": "(klass: any) => typeof TabindexMixin" } ] }, { "path": "./dev/src/custom-element/UpdatingElement.js", "exports": [ { "kind": "class", "superclass": { "name": "HTMLElement" }, "name": "UpdatingElement" } ] } ] }
<summary>Result</summary> js [ { kind: 'class', superclass: { name: 'LitElement', module: './dev/src/custom-element/LitElement.js', }, mixins: [[Object], [Object]], name: 'MyComponent', }, { name: 'TabindexMixin', module: './dev/src/custom-element/MyComponent.js', kind: 'variable', type: '(klass: any) => typeof TabindexMixin', }, { name: 'LocalizeMixin', module: './dev/src/custom-element/MyComponent.js', kind: 'variable', type: '(klass: any) => typeof LocalizeMixin', }, { kind: 'class', superclass: { name: 'UpdatingElement', module: './dev/src/custom-element/UpdatingElement.js', }, name: 'LitElement', }, { kind: 'class', superclass: { name: 'HTMLElement' }, name: 'UpdatingElement', }, ];

Helper functions

Additionally the following helper functions are available. These functions can help you when developing custom tooling for custom-elements.json, and make your code more declarative.

Demo:

import * as h from '@custom-elements-json/helpers';

const json = require('./custom-elements.json');

if (h.hasModules(json)) {
  json.modules.forEach(_module => {
    if (h.hasExports(_module)) {
      _module.exports.forEach(_export => {
        if (h.isClass(_export) && h.hasAttributes(_export)) {
          const attrs = _export.attributes;
          // do something with attributes
        }
      });
    }
  });
});

Package

  • hasModules(package: PackageDoc) => boolean

Module

  • hasExports(module: ModuleDoc) => boolean

Export

  • isClass(export: ExportDoc) => boolean
  • isFunction(export: ExportDoc) => boolean
  • isVariable(export: ExportDoc) => boolean
  • isDefinition(export: ExportDoc) => boolean

CustomElement

  • hasAttributes(customElement: CustomElementDoc) => boolean
  • hasEvents(customElement: CustomElementDoc) => boolean
  • hasSlots(customElement: CustomElementDoc) => boolean
  • hasMethods(customElement: CustomElementDoc) => boolean
  • hasFields(customElement: CustomElementDoc) => boolean
  • hasMixins(customElement: CustomElementDoc) => boolean

ClassMember

  • isField(member: ClassMember) => boolean
  • isMethod(member: ClassMember) => boolean

Contributing

Developing:

npm run tsc:watch
# in a separate terminal
npm run start

Testing:

npm test

Usecases

  • [x] Get all information for a given class (this should include the information of any superclasses or mixins)
  • [x] Get all information for a given tagName (this should include the information of any superclasses or mixins)
  • [x] Get all mixins
  • [x] Get all classes
  • [x] Get all definitions
  • [ ] Get attributes for a given class or tagName
  • [ ] Get properties for a given class or tagName
  • [ ] Get cssProperties for a given class or tagName
  • [ ] Get cssParts for a given class or tagName
  • [ ] Get events for a given class or tagName
  • [ ] Get slots for a given class or tagName
  • more? What sort of things would be helpful? Create an issue if you have any ideas

Goals

  • It'd be nice to have this library be fully isomorphic (runs in node and the browser)