diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..a0f24c9 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "bracketSpacing": false +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a10d9b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2019 The Polymer Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/package-lock.json b/package-lock.json index e356a58..1aad43a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -227,6 +227,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "prettier": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", + "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==", + "dev": true + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", diff --git a/package.json b/package.json index 6e7027c..b51d9de 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "A file format for describing custom elements", "main": "index.js", "scripts": { - "generate-json-schema": "typescript-json-schema --required --ignoreErrors schema.ts -o schema.json PackageDoc" + "format": "prettier schema.ts --write", + "generate-json-schema": "typescript-json-schema --required --ignoreErrors schema.ts -o schema.json Package" }, "repository": { "type": "git", @@ -18,6 +19,7 @@ }, "homepage": "https://github.com/webcomponents/custom-elements-json#readme", "devDependencies": { + "prettier": "^2.1.2", "typescript": "^3.7.2", "typescript-json-schema": "^0.40.0" } diff --git a/schema.json b/schema.json index e9e0260..9869918 100644 --- a/schema.json +++ b/schema.json @@ -1,7 +1,38 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { - "ClassDoc": { + "Attribute": { + "properties": { + "defaultValue": { + "description": "The default value of the attribute, if any.\n\nAs attributes are always strings, this is the actual value, not a human\nreadable description.", + "type": "string" + }, + "description": { + "description": "A markdown description.", + "type": "string" + }, + "fieldName": { + "description": "The name of the field this attribute is associated with, if any.", + "type": "string" + }, + "name": { + "type": "string" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type", + "description": "The type that the attribute will be serialized/deserialized as." + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "ClassDeclaration": { "properties": { "description": { "description": "A markdown description of the class.", @@ -17,10 +48,10 @@ "items": { "anyOf": [ { - "$ref": "#/definitions/FieldDoc" + "$ref": "#/definitions/ClassField" }, { - "$ref": "#/definitions/MethodDoc" + "$ref": "#/definitions/ClassMethod" } ] }, @@ -36,7 +67,7 @@ "type": "string" }, "summary": { - "description": "A markdown summary suitable for display in a listing.\nTODO: restrictions on markdown/markup. ie, no headings, only inline\n formatting?", + "description": "A markdown summary suitable for display in a listing.", "type": "string" }, "superclass": { @@ -49,137 +80,308 @@ ], "type": "object" }, - "CustomElementDefinitionDoc": { + "ClassField": { "properties": { - "declaration": { - "$ref": "#/definitions/Reference", - "description": "Reference to the class this custom element is registered with, and its module" + "default": { + "type": "string" + }, + "description": { + "description": "A markdown description of the field.", + "type": "string" + }, + "inheritedFrom": { + "$ref": "#/definitions/Reference" }, "kind": { "enum": [ - "definition" + "field" ], "type": "string" }, "name": { - "description": "Custom-element name", "type": "string" + }, + "privacy": { + "$ref": "#/definitions/Privacy" + }, + "static": { + "type": "boolean" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type" } }, "required": [ - "declaration", "kind", "name" ], "type": "object" }, - "FieldDoc": { + "ClassMethod": { "properties": { "description": { - "description": "A markdown description of the field.", + "description": "A markdown description.", "type": "string" }, + "inheritedFrom": { + "$ref": "#/definitions/Reference" + }, "kind": { "enum": [ - "field" + "method" ], "type": "string" }, "name": { "type": "string" }, + "parameters": { + "items": { + "$ref": "#/definitions/Parameter" + }, + "type": "array" + }, "privacy": { "$ref": "#/definitions/Privacy" }, + "return": { + "properties": { + "description": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type" + } + }, + "type": "object" + }, "static": { "type": "boolean" }, "summary": { - "description": "A markdown summary suitable for display in a listing.\nTODO: restrictions on markdown/markup. ie, no headings, only inline\n formatting?", + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object" + }, + "CssCustomProperty": { + "properties": { + "defaultValue": { "type": "string" }, - "type": { + "description": { + "description": "A markdown description.", + "type": "string" + }, + "name": { + "description": "The name of the property, including leading `--`.", + "type": "string" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "CssPart": { + "description": "The description of a CSS Part", + "properties": { + "description": { + "description": "A markdown description.", + "type": "string" + }, + "name": { + "type": "string" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", "type": "string" } }, "required": [ - "kind", "name" ], "type": "object" }, - "FunctionDoc": { + "CustomElement": { + "description": "Description of a custom element class.\n\nCustom elements are JavaScript classes, so this extends from\n`ClassDeclaration` and adds custom-element-specific features like\nattributes, events, and slots.\n\nNote that `tagName` in this interface is optional. Tag names are not\nneccessarily part of a custom element class, but belong to the definition\n(often called the \"registration\") or the `customElements.define()` call.\n\nBecause classes and tag anmes can only be registered once, there's a\none-to-one relationship between classes and tag names. For ease of use,\nwe allow the tag name here.\n\nSome packages define and register custom elements in separate modules. In\nthese cases one `Module` should contain the `CustomElement` without a\ntagName, and another `Module` should contain the\n`CustomElement`.", "properties": { + "attributes": { + "description": "The attributes that this element is known to understand.", + "items": { + "$ref": "#/definitions/Attribute" + }, + "type": "array" + }, + "cssProperties": { + "items": { + "$ref": "#/definitions/CssCustomProperty" + }, + "type": "array" + }, + "demos": { + "items": { + "$ref": "#/definitions/Demo" + }, + "type": "array" + }, "description": { "description": "A markdown description of the class.", "type": "string" }, + "events": { + "description": "The events that this element fires.", + "items": { + "$ref": "#/definitions/Event" + }, + "type": "array" + }, "kind": { "enum": [ - "function" + "class" ], "type": "string" }, - "name": { - "type": "string" - }, - "parameters": { + "members": { "items": { - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" + "anyOf": [ + { + "$ref": "#/definitions/ClassField" }, - "type": { - "type": "string" + { + "$ref": "#/definitions/ClassMethod" } - }, - "required": [ - "name" - ], - "type": "object" + ] }, "type": "array" }, - "privacy": { - "$ref": "#/definitions/Privacy" + "mixins": { + "items": { + "$ref": "#/definitions/Reference" + }, + "type": "array" }, - "return": { - "properties": { - "description": { - "type": "string" - }, - "type": { - "type": "string" - } + "name": { + "type": "string" + }, + "parts": { + "items": { + "$ref": "#/definitions/CssPart" }, - "type": "object" + "type": "array" + }, + "slots": { + "description": "The shadow dom content slots that this element accepts.", + "items": { + "$ref": "#/definitions/Slot" + }, + "type": "array" }, "summary": { "description": "A markdown summary suitable for display in a listing.", "type": "string" }, - "type": { + "superclass": { + "$ref": "#/definitions/Reference" + }, + "tagName": { + "description": "An optional tag name that should be specified if this is a\nself-registering element.\n\nSelf-registering elements must also include a CustomElementExport\nin the module's exports.", + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object" + }, + "CustomElementExport": { + "description": "A global custom element defintion, ie the result of a\n`customElements.define()` call.\n\nThis is represented as an export because a definition makes the element\navailable outside of the module it's defined it.", + "properties": { + "declaration": { + "$ref": "#/definitions/Reference", + "description": "A reference to the class or other declaration that implements the\ncustom element." + }, + "kind": { + "enum": [ + "custom-element-definition" + ], + "type": "string" + }, + "name": { + "description": "The tag name of the custom element.", "type": "string" } }, "required": [ + "declaration", "kind", "name" ], "type": "object" }, - "MethodDoc": { + "Demo": { "properties": { "description": { - "description": "A markdown description of the class.", + "description": "A markdown description of the demo.", + "type": "string" + }, + "url": { + "description": "Relative URL of the demo if it's published with the package. Absolute URL\nif it's hosted.", + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" + }, + "Event": { + "properties": { + "description": { + "description": "A markdown description.", + "type": "string" + }, + "name": { + "type": "string" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type", + "description": "The type of the event object that's fired." + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "FunctionDeclaration": { + "properties": { + "description": { + "description": "A markdown description.", "type": "string" }, "kind": { "enum": [ - "method" + "function" ], "type": "string" }, @@ -188,80 +390,102 @@ }, "parameters": { "items": { - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "name" - ], - "type": "object" + "$ref": "#/definitions/Parameter" }, "type": "array" }, - "privacy": { - "$ref": "#/definitions/Privacy" - }, "return": { "properties": { "description": { "type": "string" }, "type": { - "type": "string" + "$ref": "#/definitions/Type" } }, "type": "object" }, - "static": { - "type": "boolean" - }, "summary": { "description": "A markdown summary suitable for display in a listing.", "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object" + }, + "JavaScriptExport": { + "properties": { + "declaration": { + "$ref": "#/definitions/Reference", + "description": "A reference to the exported declaration.\n\nIn the case of aggregating exports, the reference's `module` field must be\ndefined and the `name` field must be `\"*\"`." }, - "type": { + "kind": { + "enum": [ + "js" + ], + "type": "string" + }, + "name": { + "description": "The name of the exported symbol.\n\nJavaScript has a number of ways to export objects which determine the\ncorrect name to use.\n\n- Default exports must use the name \"default\".\n- Named exports use the name that is exported. If the export is renamed\n with the \"as\" clause, use the exported name.\n- Aggregating exports (`* from`) should use the name `*`", "type": "string" } }, "required": [ + "declaration", "kind", "name" ], "type": "object" }, - "ModuleDoc": { + "JavaScriptModule": { "properties": { + "declarations": { + "description": "The declarations of a module.\n\nFor documentation purposes, all declarations that are reachable from\nexports should be described here. Ie, functions and objects that may be\nproperties of exported objects, or passed as arguments to functions.", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ClassDeclaration" + }, + { + "$ref": "#/definitions/FunctionDeclaration" + }, + { + "$ref": "#/definitions/VariableDeclaration" + }, + { + "$ref": "#/definitions/CustomElement" + } + ] + }, + "type": "array" + }, "description": { "description": "A markdown description of the module.", "type": "string" }, "exports": { + "description": "The exports of a module. This includes JavaScript exports and\ncustom element definitions.", "items": { "anyOf": [ { - "$ref": "#/definitions/ClassDoc" - }, - { - "$ref": "#/definitions/FunctionDoc" + "$ref": "#/definitions/JavaScriptExport" }, { - "$ref": "#/definitions/VariableDoc" - }, - { - "$ref": "#/definitions/CustomElementDefinitionDoc" + "$ref": "#/definitions/CustomElementExport" } ] }, "type": "array" }, + "kind": { + "enum": [ + "javascript-module" + ], + "type": "string" + }, "path": { "type": "string" }, @@ -271,10 +495,41 @@ } }, "required": [ + "declarations", + "kind", "path" ], "type": "object" }, + "Parameter": { + "properties": { + "default": { + "type": "string" + }, + "description": { + "description": "A markdown description of the field.", + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "description": "Whether the parameter is optional. Undefined implies non-optional.", + "type": "boolean" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type" + } + }, + "required": [ + "name" + ], + "type": "object" + }, "Privacy": { "enum": [ "private", @@ -284,7 +539,7 @@ "type": "string" }, "Reference": { - "description": "A reference to an export of a module.\n\nAll references are required to be publically accessible, so the canonical\nrepresentation of a reference is the export it's available from.", + "description": "A reference to an export of a module.\n\nAll references are required to be publically accessible, so the canonical\nrepresentation of a reference is the export it's available from.\n\nReferrences to global symbols like `Array`, `HTMLElement`, or `Event`", "properties": { "module": { "type": "string" @@ -301,10 +556,76 @@ ], "type": "object" }, - "VariableDoc": { + "Slot": { "properties": { "description": { - "description": "A markdown description of the class.", + "description": "A markdown description.", + "type": "string" + }, + "name": { + "description": "The slot name, or the empty string for an unnamed slot.", + "type": "string" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "Type": { + "properties": { + "references": { + "description": "An array of references to the types in the type string.\n\nThese references have optional indices into the type string so that tools\ncan understand the references in the type string independently of the type\nsystem and syntax. For example, a documentation viewer could display the\ntype `Array` with cross-references to `FooElement`\nand `BarElement` without understanding arrays, generics, or union types.", + "items": { + "$ref": "#/definitions/TypeReference" + }, + "type": "array" + }, + "type": { + "description": "The full string representation of the type, in whatever type syntax is\nused, such as JSDoc, Closure, or TypeScript.", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "TypeReference": { + "description": "A reference that is associated with a type string and optionally a range\nwithin the string.\n\nStart and end must both be present or not present. If they're present, they\nare indices into the associated type string. If they are missing, the entire\ntype string is the symbol referenced and the name should match the type\nstring.", + "properties": { + "end": { + "type": "number" + }, + "module": { + "type": "string" + }, + "name": { + "type": "string" + }, + "package": { + "type": "string" + }, + "start": { + "type": "number" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "VariableDeclaration": { + "properties": { + "default": { + "type": "string" + }, + "description": { + "description": "A markdown description of the field.", "type": "string" }, "kind": { @@ -321,7 +642,7 @@ "type": "string" }, "type": { - "type": "string" + "$ref": "#/definitions/Type" } }, "required": [ @@ -331,22 +652,27 @@ "type": "object" } }, - "description": "The top-level interface of a custom-elements.json file.\n\ncustom-elements.json documents all the elements in a single npm package,\nacross all modules within the package. Elements may be exported from multiple\nmodules with re-exports, but as a rule, elements in this file should be\nincluded once in the \"canonical\" module that they're exported from.", + "description": "The top-level interface of a custom-elements.json file.\n\nBecause custom elements are JavaScript classes, describing a custom element\nmay require describing arbitrary JavaScript concepts like modules, classes,\nfunctions, etc. So custom-elements.json documents are capable of documenting\nthe elements in a package, as well as those JavaScript concepts.\n\nThe modules described in a package should be the public entrypoints that\nother packages may import from. Multiple modules may export the same object\nvia re-exports, but in most cases a package should document the single\ncanonical export that should be used.", "properties": { "modules": { "description": "An array of the modules this package contains.", "items": { - "$ref": "#/definitions/ModuleDoc" + "$ref": "#/definitions/JavaScriptModule" }, "type": "array" }, - "version": { + "readme": { + "description": "The Markdown to use for the main readme of this package.\n\nThis can be used to override the readme used by Github or npm if that\nfile contains information irrelevant to custom element catalogs and\ndocumentation viewers.", + "type": "string" + }, + "schemaVersion": { + "description": "The version of the custom-elements.json schema used in this file.", "type": "string" } }, "required": [ "modules", - "version" + "schemaVersion" ], "type": "object" } diff --git a/schema.ts b/schema.ts index cd61699..d5eb896 100644 --- a/schema.ts +++ b/schema.ts @@ -1,21 +1,54 @@ +/** + * @license + * Copyright (c) 2019 The Polymer Project Authors. All rights reserved. + * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt + * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt + * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt + * Code distributed by Google as part of the polymer project is also + * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + */ + /** * The top-level interface of a custom-elements.json file. * - * custom-elements.json documents all the elements in a single npm package, - * across all modules within the package. Elements may be exported from multiple - * modules with re-exports, but as a rule, elements in this file should be - * included once in the "canonical" module that they're exported from. + * Because custom elements are JavaScript classes, describing a custom element + * may require describing arbitrary JavaScript concepts like modules, classes, + * functions, etc. So custom-elements.json documents are capable of documenting + * the elements in a package, as well as those JavaScript concepts. + * + * The modules described in a package should be the public entrypoints that + * other packages may import from. Multiple modules may export the same object + * via re-exports, but in most cases a package should document the single + * canonical export that should be used. */ -export interface PackageDoc { - version: string; +export interface Package { + /** + * The version of the custom-elements.json schema used in this file. + */ + schemaVersion: string; + + /** + * The Markdown to use for the main readme of this package. + * + * This can be used to override the readme used by Github or npm if that + * file contains information irrelevant to custom element catalogs and + * documentation viewers. + */ + readme?: string; /** * An array of the modules this package contains. */ - modules: Array; + modules: Array; } -export interface ModuleDoc { +// This type may expand in the future to include JSON, CSS, or HTML +// modules. +type Module = JavaScriptModule; + +export interface JavaScriptModule { + kind: 'javascript-module'; + path: string; /** @@ -28,24 +61,85 @@ export interface ModuleDoc { */ description?: string; - exports?: Array; + /** + * The declarations of a module. + * + * For documentation purposes, all declarations that are reachable from + * exports should be described here. Ie, functions and objects that may be + * properties of exported objects, or passed as arguments to functions. + */ + declarations: Array; + + /** + * The exports of a module. This includes JavaScript exports and + * custom element definitions. + */ + exports?: Array; } -export type ExportDoc = ClassDoc | FunctionDoc | VariableDoc | CustomElementDefinitionDoc; +export type Export = JavaScriptExport | CustomElementExport; + +export interface JavaScriptExport { + kind: 'js'; -export interface CustomElementDefinitionDoc { - kind: 'definition'; - /** Custom-element name */ + /** + * The name of the exported symbol. + * + * JavaScript has a number of ways to export objects which determine the + * correct name to use. + * + * - Default exports must use the name "default". + * - Named exports use the name that is exported. If the export is renamed + * with the "as" clause, use the exported name. + * - Aggregating exports (`* from`) should use the name `*` + */ name: string; - /** Reference to the class this custom element is registered with, and its module */ + + /** + * A reference to the exported declaration. + * + * In the case of aggregating exports, the reference's `module` field must be + * defined and the `name` field must be `"*"`. + */ declaration: Reference; } +/** + * A global custom element defintion, ie the result of a + * `customElements.define()` call. + * + * This is represented as an export because a definition makes the element + * available outside of the module it's defined it. + */ +export interface CustomElementExport { + kind: 'custom-element-definition'; + + /** + * The tag name of the custom element. + */ + name: string; + + /** + * A reference to the class or other declaration that implements the + * custom element. + */ + declaration: Reference; +} + +export type Declaration = + | ClassDeclaration + | FunctionDeclaration + | VariableDeclaration + | CustomElement; + /** * A reference to an export of a module. * * All references are required to be publically accessible, so the canonical * representation of a reference is the export it's available from. + * + * Referrences to global symbols like `Array`, `HTMLElement`, or `Event` + * */ export interface Reference { name: string; @@ -55,29 +149,30 @@ export interface Reference { /** * Description of a custom element class. - * - * Custom elements are JavaScript classes, so this extends from `ClassDoc` and - * adds custom-element-specific features like attributes, events, and slots. - * + * + * Custom elements are JavaScript classes, so this extends from + * `ClassDeclaration` and adds custom-element-specific features like + * attributes, events, and slots. + * * Note that `tagName` in this interface is optional. Tag names are not * neccessarily part of a custom element class, but belong to the definition * (often called the "registration") or the `customElements.define()` call. - * + * * Because classes and tag anmes can only be registered once, there's a * one-to-one relationship between classes and tag names. For ease of use, * we allow the tag name here. - * + * * Some packages define and register custom elements in separate modules. In - * these cases one `ModuleDoc` should contain the `CustomElementDoc` without a - * tagName, and another `ModuleDoc` should contain the - * `CustomElementDefintionDoc`. + * these cases one `Module` should contain the `CustomElement` without a + * tagName, and another `Module` should contain the + * `CustomElement`. */ -export interface CustomElementDoc extends ClassDoc { +export interface CustomElement extends ClassDeclaration { /** * An optional tag name that should be specified if this is a * self-registering element. - * - * Self-registering elements must also include a CustomElementDefintionDoc + * + * Self-registering elements must also include a CustomElementExport * in the module's exports. */ tagName?: string; @@ -85,31 +180,42 @@ export interface CustomElementDoc extends ClassDoc { /** * The attributes that this element is known to understand. */ - attributes?: AttributeDoc[]; + attributes?: Attribute[]; - /** The events that this element fires. */ - events?: EventDoc[]; + /** + * The events that this element fires. + */ + events?: Event[]; /** * The shadow dom content slots that this element accepts. */ - slots?: SlotDoc[]; + slots?: Slot[]; + + parts?: CssPart[]; + + cssProperties?: CssCustomProperty[]; demos?: Demo[]; } -export interface AttributeDoc { +export interface Attribute { name: string; /** - * A markdown description for the attribute. + * A markdown summary suitable for display in a listing. + */ + summary?: string; + + /** + * A markdown description. */ description?: string; /** * The type that the attribute will be serialized/deserialized as. */ - type?: string; + type?: Type; /** * The default value of the attribute, if any. @@ -125,37 +231,38 @@ export interface AttributeDoc { fieldName?: string; } -export interface EventDoc { +export interface Event { name: string; /** - * A markdown description of the event. + * A markdown summary suitable for display in a listing. */ - description?: string; + summary?: string; /** - * The type of the event object that's fired. - * - * If the event type is built-in, this is a string, e.g. `Event`, - * `CustomEvent`, `KeyboardEvent`. If the event type is an event class defined - * in a module, the reference to it. + * A markdown description. */ - type: Reference|string; + description?: string; /** - * If the event is a CustomEvent, the type of `detail` field. + * The type of the event object that's fired. */ - detailType?: string; + type: Type; } -export interface SlotDoc { +export interface Slot { /** * The slot name, or the empty string for an unnamed slot. */ name: string; /** - * A markdown description of the part. + * A markdown summary suitable for display in a listing. + */ + summary?: string; + + /** + * A markdown description. */ description?: string; } @@ -163,16 +270,21 @@ export interface SlotDoc { /** * The description of a CSS Part */ -export interface CssPartDoc { +export interface CssPart { name: string; /** - * A markdown description for the CSS property. + * A markdown summary suitable for display in a listing. + */ + summary?: string; + + /** + * A markdown description. */ description?: string; } -export interface CssCustomPropertyDoc { +export interface CssCustomProperty { /** * The name of the property, including leading `--`. */ @@ -181,19 +293,57 @@ export interface CssCustomPropertyDoc { defaultValue?: string; /** - * A markdown description for the attribute. + * A markdown summary suitable for display in a listing. + */ + summary?: string; + + /** + * A markdown description. */ description?: string; } -export interface ClassDoc { - kind: 'class'; +export interface Type { + /** + * The full string representation of the type, in whatever type syntax is + * used, such as JSDoc, Closure, or TypeScript. + */ + type: string; + + /** + * An array of references to the types in the type string. + * + * These references have optional indices into the type string so that tools + * can understand the references in the type string independently of the type + * system and syntax. For example, a documentation viewer could display the + * type `Array` with cross-references to `FooElement` + * and `BarElement` without understanding arrays, generics, or union types. + */ + references?: TypeReference[]; +} + +/** + * A reference that is associated with a type string and optionally a range + * within the string. + * + * Start and end must both be present or not present. If they're present, they + * are indices into the associated type string. If they are missing, the entire + * type string is the symbol referenced and the name should match the type + * string. + */ +export interface TypeReference extends Reference { + start?: number; + end?: number; +} + +/** + * The common interface of classes and mixins. + */ +export interface ClassLike { name: string; /** * A markdown summary suitable for display in a listing. - * TODO: restrictions on markdown/markup. ie, no headings, only inline - * formatting? */ summary?: string; @@ -206,17 +356,21 @@ export interface ClassDoc { members?: Array; } -export type ClassMember = FieldDoc|MethodDoc; +export interface ClassDeclaration extends ClassLike { + kind: 'class'; +} + +export type ClassMember = ClassField | ClassMethod; -export interface FieldDoc { - kind: 'field'; +/** + * The common interface of variables, class fields, and function + * parameters. + */ +export interface PropertyLike { name: string; - static?: boolean; /** * A markdown summary suitable for display in a listing. - * TODO: restrictions on markdown/markup. ie, no headings, only inline - * formatting? */ summary?: string; @@ -224,43 +378,46 @@ export interface FieldDoc { * A markdown description of the field. */ description?: string; + + type?: Type; + + default?: string; +} + +export interface ClassField extends PropertyLike { + kind: 'field'; + static?: boolean; privacy?: Privacy; - type?: string; + inheritedFrom?: Reference; } -export interface MethodDoc extends FunctionLike { +export interface ClassMethod extends FunctionLike { kind: 'method'; - static?: boolean; + privacy?: Privacy; + inheritedFrom?: Reference; } /** - * TODO: tighter definition of mixin: - * - Should it only accept a single argument? - * - Should it not extend ClassDoc so it doesn't has a superclass? - * - What's TypeScript's exact definition? + * */ -export interface MixinDoc extends ClassDoc {} +export interface MixinDeclaration extends ClassLike, FunctionLike { + kind: 'mixin'; +} -export interface VariableDoc { +export interface VariableDeclaration extends PropertyLike { kind: 'variable'; +} - name: string; - - /** - * A markdown summary suitable for display in a listing. - */ - summary?: string; +export interface FunctionDeclaration extends FunctionLike { + kind: 'function'; +} +export interface Parameter extends PropertyLike { /** - * A markdown description of the class. + * Whether the parameter is optional. Undefined implies non-optional. */ - description?: string; - type?: string; -} - -export interface FunctionDoc extends FunctionLike { - kind: 'function'; + optional?: boolean; } export interface FunctionLike { @@ -272,26 +429,19 @@ export interface FunctionLike { summary?: string; /** - * A markdown description of the class. + * A markdown description. */ description?: string; - parameters?: { - name: string, - type?: string, - description?: string, - }[]; + parameters?: Parameter[]; return?: { - type?: string, - description?: string, + type?: Type; + description?: string; }; - - privacy?: Privacy; - type?: string; } -export type Privacy = 'public'|'private'|'protected'; +export type Privacy = 'public' | 'private' | 'protected'; export interface Demo { /**