From 4284909f0f41db54237d1cf6bb34136410cbfc10 Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Sun, 10 Nov 2019 22:23:29 -0800 Subject: [PATCH 01/10] Initial attempt at a schema --- package-lock.json | 346 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 24 ++++ schema.json | 326 +++++++++++++++++++++++++++++++++++++++++++ schema.ts | 246 ++++++++++++++++++++++++++++++++ tsconfig.json | 19 +++ 5 files changed, 961 insertions(+) create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 schema.json create mode 100644 schema.ts create mode 100644 tsconfig.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..51727b2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,346 @@ +{ + "name": "custom-elements-json", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/json-schema": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz", + "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "typescript": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", + "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==", + "dev": true + }, + "typescript-json-schema": { + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.40.0.tgz", + "integrity": "sha512-C8D3Ca6+1x3caWOR+u45Shn3KqkRZi5M3+E8ePpEmYMqOh3xhhLdq+39pqT0Bf8+fCgAmpTFSJMT6Xwqbm0Tkw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "glob": "~7.1.4", + "json-stable-stringify": "^1.0.1", + "typescript": "^3.5.3", + "yargs": "^14.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.0.tgz", + "integrity": "sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.0" + } + }, + "yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6e7027c --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "custom-elements-json", + "version": "0.0.0", + "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" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/webcomponents/custom-elements-json.git" + }, + "keywords": [], + "author": "", + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/webcomponents/custom-elements-json/issues" + }, + "homepage": "https://github.com/webcomponents/custom-elements-json#readme", + "devDependencies": { + "typescript": "^3.7.2", + "typescript-json-schema": "^0.40.0" + } +} diff --git a/schema.json b/schema.json new file mode 100644 index 0000000..18502c4 --- /dev/null +++ b/schema.json @@ -0,0 +1,326 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "ClassDoc": { + "properties": { + "description": { + "description": "A markdown description of the class.", + "type": "string" + }, + "kind": { + "enum": [ + "class" + ], + "type": "string" + }, + "members": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/FieldDoc" + }, + { + "$ref": "#/definitions/MethodDoc" + } + ] + }, + "type": "array" + }, + "mixins": { + "items": { + "$ref": "#/definitions/Reference" + }, + "type": "array" + }, + "name": { + "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?", + "type": "string" + }, + "superclass": { + "$ref": "#/definitions/Reference" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object" + }, + "FieldDoc": { + "properties": { + "description": { + "description": "A markdown description of the field.", + "type": "string" + }, + "kind": { + "enum": [ + "field" + ], + "type": "string" + }, + "name": { + "type": "string" + }, + "privacy": { + "$ref": "#/definitions/Privacy" + }, + "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?", + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object" + }, + "FunctionDoc": { + "properties": { + "description": { + "description": "A markdown description of the class.", + "type": "string" + }, + "kind": { + "enum": [ + "function" + ], + "type": "string" + }, + "name": { + "type": "string" + }, + "parameters": { + "items": { + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "privacy": { + "$ref": "#/definitions/Privacy" + }, + "return": { + "properties": { + "description": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object" + }, + "MethodDoc": { + "properties": { + "description": { + "description": "A markdown description of the class.", + "type": "string" + }, + "kind": { + "enum": [ + "method" + ], + "type": "string" + }, + "name": { + "type": "string" + }, + "parameters": { + "items": { + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "privacy": { + "$ref": "#/definitions/Privacy" + }, + "return": { + "properties": { + "description": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "static": { + "type": "boolean" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object" + }, + "ModuleDoc": { + "properties": { + "description": { + "description": "A markdown description of the module.", + "type": "string" + }, + "exports": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ClassDoc" + }, + { + "$ref": "#/definitions/FunctionDoc" + }, + { + "$ref": "#/definitions/VariableDoc" + } + ] + }, + "type": "array" + }, + "path": { + "type": "string" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "Privacy": { + "enum": [ + "private", + "protected", + "public" + ], + "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 refernce it the export it's available from.", + "properties": { + "module": { + "type": "string" + }, + "name": { + "type": "string" + }, + "package": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "VariableDoc": { + "properties": { + "description": { + "description": "A markdown description of the class.", + "type": "string" + }, + "kind": { + "enum": [ + "variable" + ], + "type": "string" + }, + "name": { + "type": "string" + }, + "summary": { + "description": "A markdown summary suitable for display in a listing.", + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "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.", + "properties": { + "modules": { + "description": "An array of the modules this package contains.", + "items": { + "$ref": "#/definitions/ModuleDoc" + }, + "type": "array" + }, + "version": { + "type": "string" + } + }, + "required": [ + "modules", + "version" + ], + "type": "object" +} + diff --git a/schema.ts b/schema.ts new file mode 100644 index 0000000..d0d4210 --- /dev/null +++ b/schema.ts @@ -0,0 +1,246 @@ +/** + * 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. + */ +export interface PackageDoc { + version: string; + + /** + * An array of the modules this package contains. + */ + modules: Array; +} + +export interface ModuleDoc { + path: string; + + /** + * A markdown summary suitable for display in a listing. + */ + summary?: string; + + /** + * A markdown description of the module. + */ + description?: string; + + exports?: Array; +} + +export type ExportDoc = ClassDoc|FunctionDoc|VariableDoc; + +/** + * A reference to an export of a module. + * + * All references are required to be publically accessible, so the canonical + * representation of a refernce it the export it's available from. + */ +export interface Reference { + name: string; + package?: string; + module?: string; +} + +export interface CustomElementDoc extends ClassDoc { + tagName: string; + /** + * The attributes that this element is known to understand. + */ + attributes?: AttributeDoc[]; + + /** The events that this element fires. */ + events?: EventDoc[]; + + /** + * The shadow dom content slots that this element accepts. + */ + slots?: SlotDoc[]; + + demos?: Demo[]; +} + +export interface AttributeDoc { + name: string; + + /** + * A markdown description for the attribute. + */ + description?: string; + + /** + * The type that the attribute will be serialized/deserialized as. + */ + type?: string; + + /** + * The default value of the attribute, if any. + * + * As attributes are always strings, this is the actual value, not a human + * readable description. + */ + defaultValue?: string; + + /** + * The name of the field this attribute is associated with, if any. + */ + fieldName?: string; +} + +export interface EventDoc { + name: string; + + /** + * A markdown description of the event. + */ + description: 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. + */ + type: Reference|string; + + /** + * If the event is a CustomEvent, the type of `detail` field. + */ + detailType?: string; +} + +export interface SlotDoc { + /** + * The slot name, or the empty string for an unnamed slot. + */ + name: string; + + /** + * A markdown description of the slot. + */ + description?: string; +} + +export interface ClassDoc { + kind: 'class'; + name: string; + + /** + * A markdown summary suitable for display in a listing. + * TODO: restrictions on markdown/markup. ie, no headings, only inline + * formatting? + */ + summary?: string; + + /** + * A markdown description of the class. + */ + description?: string; + superclass?: Reference; + mixins?: Array; + members?: Array; +} + +export type ClassMember = FieldDoc|MethodDoc; + +export interface FieldDoc { + kind: 'field'; + 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; + + /** + * A markdown description of the field. + */ + description?: string; + privacy?: Privacy; + type?: string; +} + +export interface MethodDoc extends FunctionLike { + kind: 'method'; + + static?: boolean; +} + +/** + * 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 VariableDoc { + kind: 'variable'; + + name: string; + + /** + * A markdown summary suitable for display in a listing. + */ + summary?: string; + + /** + * A markdown description of the class. + */ + description?: string; + type?: string; +} + +export interface FunctionDoc extends FunctionLike { + kind: 'function'; +} + +export interface FunctionLike { + name: string; + + /** + * A markdown summary suitable for display in a listing. + */ + summary?: string; + + /** + * A markdown description of the class. + */ + description?: string; + + parameters?: { + name: string, + type?: string, + description?: string, + }[]; + + return?: { + type?: string, + description?: string, + }; + + privacy?: Privacy; + type?: string; +} + +export type Privacy = 'public'|'private'|'protected'; + +export interface Demo { + /** + * A markdown description of the demo. + */ + description?: string; + + /** + * Relative URL of the demo if it's published with the package. Absolute URL + * if it's hosted. + */ + url: string; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6a4fd2e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "esnext", + "lib": ["es2017"], + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + }, + "include": ["*.ts"], + "exclude": [] +} From ad1ca5d29f5524c7f9d3f7ee6b5bd10f391e0cb0 Mon Sep 17 00:00:00 2001 From: thepassle Date: Fri, 25 Sep 2020 13:03:45 +0200 Subject: [PATCH 02/10] chore: add inheritedFrom --- schema.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/schema.ts b/schema.ts index d0d4210..292a9ae 100644 --- a/schema.ts +++ b/schema.ts @@ -1,6 +1,6 @@ /** * 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 @@ -35,7 +35,7 @@ export type ExportDoc = ClassDoc|FunctionDoc|VariableDoc; /** * A reference to an export of a module. - * + * * All references are required to be publically accessible, so the canonical * representation of a refernce it the export it's available from. */ @@ -88,6 +88,7 @@ export interface AttributeDoc { * The name of the field this attribute is associated with, if any. */ fieldName?: string; + inheritedFrom?: Reference; } export interface EventDoc { @@ -111,6 +112,7 @@ export interface EventDoc { * If the event is a CustomEvent, the type of `detail` field. */ detailType?: string; + inheritedFrom?: Reference; } export interface SlotDoc { @@ -165,12 +167,14 @@ export interface FieldDoc { description?: string; privacy?: Privacy; type?: string; + inheritedFrom?: Reference; } export interface MethodDoc extends FunctionLike { kind: 'method'; static?: boolean; + inheritedFrom?: Reference; } /** From b09c9d967b316d7d871f2ce207c8c01a09365661 Mon Sep 17 00:00:00 2001 From: thepassle Date: Fri, 25 Sep 2020 13:20:38 +0200 Subject: [PATCH 03/10] Revert "chore: add inheritedFrom" This reverts commit ad1ca5d29f5524c7f9d3f7ee6b5bd10f391e0cb0. --- schema.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/schema.ts b/schema.ts index 292a9ae..d0d4210 100644 --- a/schema.ts +++ b/schema.ts @@ -1,6 +1,6 @@ /** * 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 @@ -35,7 +35,7 @@ export type ExportDoc = ClassDoc|FunctionDoc|VariableDoc; /** * A reference to an export of a module. - * + * * All references are required to be publically accessible, so the canonical * representation of a refernce it the export it's available from. */ @@ -88,7 +88,6 @@ export interface AttributeDoc { * The name of the field this attribute is associated with, if any. */ fieldName?: string; - inheritedFrom?: Reference; } export interface EventDoc { @@ -112,7 +111,6 @@ export interface EventDoc { * If the event is a CustomEvent, the type of `detail` field. */ detailType?: string; - inheritedFrom?: Reference; } export interface SlotDoc { @@ -167,14 +165,12 @@ export interface FieldDoc { description?: string; privacy?: Privacy; type?: string; - inheritedFrom?: Reference; } export interface MethodDoc extends FunctionLike { kind: 'method'; static?: boolean; - inheritedFrom?: Reference; } /** From 9f00a063c3090d2ee13174dc3cd02cf3ee30f21f Mon Sep 17 00:00:00 2001 From: thepassle Date: Fri, 25 Sep 2020 13:22:06 +0200 Subject: [PATCH 04/10] chore: add definition doc --- schema.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/schema.ts b/schema.ts index d0d4210..2c48e63 100644 --- a/schema.ts +++ b/schema.ts @@ -1,6 +1,6 @@ /** * 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 @@ -31,13 +31,19 @@ export interface ModuleDoc { exports?: Array; } -export type ExportDoc = ClassDoc|FunctionDoc|VariableDoc; +export type ExportDoc = ClassDoc | FunctionDoc | VariableDoc | DefinitionDoc; + +export interface DefinitionDoc { + kind: string; + name: string; + declaration: Reference; +} /** * A reference to an export of a module. - * + * * All references are required to be publically accessible, so the canonical - * representation of a refernce it the export it's available from. + * representation of a reference is the export it's available from. */ export interface Reference { name: string; From db7492a7242aaf575e4419a390ac50bd47a76313 Mon Sep 17 00:00:00 2001 From: thepassle Date: Fri, 25 Sep 2020 15:47:29 +0200 Subject: [PATCH 05/10] chore: description for events should be optional --- schema.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schema.ts b/schema.ts index d0d4210..b5fb23e 100644 --- a/schema.ts +++ b/schema.ts @@ -1,6 +1,6 @@ /** * 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 @@ -35,7 +35,7 @@ export type ExportDoc = ClassDoc|FunctionDoc|VariableDoc; /** * A reference to an export of a module. - * + * * All references are required to be publically accessible, so the canonical * representation of a refernce it the export it's available from. */ @@ -96,7 +96,7 @@ export interface EventDoc { /** * A markdown description of the event. */ - description: string; + description?: string; /** * The type of the event object that's fired. From ab70d5d7202b5a50d067b653a8cb037d638baa19 Mon Sep 17 00:00:00 2001 From: thepassle Date: Fri, 25 Sep 2020 18:23:24 +0200 Subject: [PATCH 06/10] chore: review comments and regenerate schema --- package-lock.json | 2 +- schema.json | 29 ++++++++++++++++++++++++++++- schema.ts | 8 +++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 51727b2..e356a58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "custom-elements-json", - "version": "1.0.0", + "version": "0.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/schema.json b/schema.json index 18502c4..e9e0260 100644 --- a/schema.json +++ b/schema.json @@ -49,6 +49,30 @@ ], "type": "object" }, + "CustomElementDefinitionDoc": { + "properties": { + "declaration": { + "$ref": "#/definitions/Reference", + "description": "Reference to the class this custom element is registered with, and its module" + }, + "kind": { + "enum": [ + "definition" + ], + "type": "string" + }, + "name": { + "description": "Custom-element name", + "type": "string" + } + }, + "required": [ + "declaration", + "kind", + "name" + ], + "type": "object" + }, "FieldDoc": { "properties": { "description": { @@ -230,6 +254,9 @@ }, { "$ref": "#/definitions/VariableDoc" + }, + { + "$ref": "#/definitions/CustomElementDefinitionDoc" } ] }, @@ -257,7 +284,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 refernce it 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.", "properties": { "module": { "type": "string" diff --git a/schema.ts b/schema.ts index 2c48e63..f82a2e6 100644 --- a/schema.ts +++ b/schema.ts @@ -31,11 +31,13 @@ export interface ModuleDoc { exports?: Array; } -export type ExportDoc = ClassDoc | FunctionDoc | VariableDoc | DefinitionDoc; +export type ExportDoc = ClassDoc | FunctionDoc | VariableDoc | CustomElementDefinitionDoc; -export interface DefinitionDoc { - kind: string; +export interface CustomElementDefinitionDoc { + kind: 'definition'; + /** Custom-element name */ name: string; + /** Reference to the class this custom element is registered with, and its module */ declaration: Reference; } From 376fb46dc134fb6a4d942a2a51a52dde5c5017b4 Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Fri, 25 Sep 2020 11:03:42 -0700 Subject: [PATCH 07/10] Make CustomElementDoc.tagName optional --- schema.ts | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/schema.ts b/schema.ts index a71cd7c..cd61699 100644 --- a/schema.ts +++ b/schema.ts @@ -53,8 +53,35 @@ export interface Reference { module?: string; } +/** + * 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. + * + * 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`. + */ export interface CustomElementDoc extends ClassDoc { - tagName: string; + /** + * An optional tag name that should be specified if this is a + * self-registering element. + * + * Self-registering elements must also include a CustomElementDefintionDoc + * in the module's exports. + */ + tagName?: string; + /** * The attributes that this element is known to understand. */ @@ -128,7 +155,33 @@ export interface SlotDoc { name: string; /** - * A markdown description of the slot. + * A markdown description of the part. + */ + description?: string; +} + +/** + * The description of a CSS Part + */ +export interface CssPartDoc { + name: string; + + /** + * A markdown description for the CSS property. + */ + description?: string; +} + +export interface CssCustomPropertyDoc { + /** + * The name of the property, including leading `--`. + */ + name: string; + + defaultValue?: string; + + /** + * A markdown description for the attribute. */ description?: string; } From 0a465c9a14e9c987ebd512ec93a7cb92c496491e Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Sun, 27 Sep 2020 10:10:44 -0700 Subject: [PATCH 08/10] A lot of cleanup and renaming --- .prettierrc.json | 4 + LICENSE | 27 +++ package-lock.json | 6 + package.json | 4 +- schema.json | 508 +++++++++++++++++++++++++++++++++++++--------- schema.ts | 338 +++++++++++++++++++++--------- 6 files changed, 701 insertions(+), 186 deletions(-) create mode 100644 .prettierrc.json create mode 100644 LICENSE 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 { /** From 043c541fb2ed9eace48a12a9cefa3ed450a327e9 Mon Sep 17 00:00:00 2001 From: thepassle Date: Sun, 4 Oct 2020 15:45:58 +0200 Subject: [PATCH 09/10] chore: mixin is declaration --- schema.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/schema.ts b/schema.ts index d5eb896..b75c8d2 100644 --- a/schema.ts +++ b/schema.ts @@ -129,6 +129,7 @@ export interface CustomElementExport { export type Declaration = | ClassDeclaration | FunctionDeclaration + | MixinDeclaration | VariableDeclaration | CustomElement; From 399e0e5ba175c0d59da256c39e81b0a0b8265103 Mon Sep 17 00:00:00 2001 From: thepassle Date: Sun, 4 Oct 2020 18:08:43 +0200 Subject: [PATCH 10/10] chore: attrs and events can be inherited --- schema.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/schema.ts b/schema.ts index b75c8d2..8369cd1 100644 --- a/schema.ts +++ b/schema.ts @@ -213,6 +213,8 @@ export interface Attribute { */ description?: string; + inheritedFrom?: Reference; + /** * The type that the attribute will be serialized/deserialized as. */ @@ -249,6 +251,8 @@ export interface Event { * The type of the event object that's fired. */ type: Type; + + inheritedFrom?: Reference; } export interface Slot {