From 54114699b7edfddd60b9a99d50c93b665353c299 Mon Sep 17 00:00:00 2001 From: jannikac Date: Fri, 12 Apr 2024 12:52:31 +0200 Subject: [PATCH 01/19] add barebones typescript config --- package-lock.json | 85 +++++++++++++++++++++++++++++++++++++++-------- package.json | 2 ++ tsconfig.json | 15 +++++++++ 3 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 tsconfig.json diff --git a/package-lock.json b/package-lock.json index ddd48f93..c6428c6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,8 @@ "karma-spec-reporter": "^0.0.36", "mocha": "^10.3.0", "node-fetch": "^3.3.2", + "rollup-plugin-terser": "^7.0.2", + "typescript": "^5.4.5", "yauzl-promise": "^4.0.0" } }, @@ -5684,15 +5686,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.3.0.tgz", - "integrity": "sha512-niBqk8iwv96+yuTwjM6bWg8ovzAPF9qkICsGtcoa5/dmqcEMfdwNAX7+/OHcJHc7wj7XqPxH98oAHytFYlw6Sw==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7354,6 +7347,41 @@ "node": ">= 4" } }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8050,6 +8078,12 @@ "node": ">= 0.6" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -9628,7 +9662,6 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, - "optional": true, "peer": true, "bin": { "rollup": "dist/bin/rollup" @@ -9640,6 +9673,31 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -10487,11 +10545,10 @@ } }, "node_modules/typescript": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", - "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index d9e6277a..7dfb843a 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,8 @@ "karma-spec-reporter": "^0.0.36", "mocha": "^10.3.0", "node-fetch": "^3.3.2", + "rollup-plugin-terser": "^7.0.2", + "typescript": "^5.4.5", "yauzl-promise": "^4.0.0" }, "license": "MPL-2.0", diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..265a4034 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "include": ["dist/ical.js"], + "compilerOptions": { + // Tells TypeScript to read JS files, as + // normally they are ignored as source files + "allowJs": true, + // Generate d.ts files + "declaration": true, + // only output d.ts files + "emitDeclarationOnly": true, + // go to js file when using IDE functions like + // "Go to Definition" in VSCode + "declarationMap": true + } +} \ No newline at end of file From e39ce1d62d4e623d14430a7a3d1ee440ddb6c6d3 Mon Sep 17 00:00:00 2001 From: jannikac Date: Fri, 12 Apr 2024 13:18:17 +0200 Subject: [PATCH 02/19] updated component to work correctly with generated d.ts --- lib/ical/component.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/ical/component.js b/lib/ical/component.js index 4e25980d..d4969f2d 100644 --- a/lib/ical/component.js +++ b/lib/ical/component.js @@ -18,11 +18,10 @@ const COMPONENT_INDEX = 2; * properties. * * @class - * @alias ICAL.Component */ class Component { /** - * Create an {@link ICAL.Component} by parsing the passed iCalendar string. + * Create an {@link Component} by parsing the passed iCalendar string. * * @param {String} str The iCalendar string to parse */ @@ -31,11 +30,11 @@ class Component { } /** - * Creates a new ICAL.Component instance. + * Creates a new Component instance. * * @param {Array|String} jCal Raw jCal component data OR name of new * component - * @param {ICAL.Component} parent Parent component to associate + * @param {Component} parent Parent component to associate */ constructor(jCal, parent) { if (typeof(jCal) === 'string') { @@ -143,7 +142,7 @@ class Component { * Finds first sub component, optionally filtered by name. * * @param {String=} name Optional name to filter by - * @return {?ICAL.Component} The found subcomponent + * @return {?Component} The found subcomponent */ getFirstSubcomponent(name) { if (name) { @@ -171,7 +170,7 @@ class Component { * Finds all sub components, optionally filtering by name. * * @param {String=} name Optional name to filter by - * @return {ICAL.Component[]} The found sub components + * @return {Component[]} The found sub components */ getAllSubcomponents(name) { let jCalLen = this.jCal[COMPONENT_INDEX].length; @@ -359,8 +358,8 @@ class Component { /** * Adds a single sub component. * - * @param {ICAL.Component} component The component to add - * @return {ICAL.Component} The passed in component + * @param {Component} component The component to add + * @return {Component} The passed in component */ addSubcomponent(component) { if (!this._components) { @@ -383,7 +382,7 @@ class Component { * Removes a single component by name or the instance of a specific * component. * - * @param {ICAL.Component|String} nameOrComp Name of component, or component + * @param {Component|String} nameOrComp Name of component, or component * @return {Boolean} True when comp is removed */ removeSubcomponent(nameOrComp) { From 8b44b4cdbff05285a5e49272ef6c6c3fd6a4359e Mon Sep 17 00:00:00 2001 From: jannikac Date: Fri, 12 Apr 2024 16:07:26 +0200 Subject: [PATCH 03/19] replace typescript with @rollup/plugin-typescript, integrate into build and add types to package.json --- package-lock.json | 263 +++++----------------------------------------- package.json | 4 +- rollup.config.js | 4 +- tsconfig.json | 4 +- 4 files changed, 36 insertions(+), 239 deletions(-) diff --git a/package-lock.json b/package-lock.json index c6428c6b..379063c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@octokit/core": "^6.0.1", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^11.1.6", "@stylistic/eslint-plugin": "^2.1.0", "benchmark": "^2.1.4", "c8": "^9.1.0", @@ -31,7 +32,6 @@ "mocha": "^10.3.0", "node-fetch": "^3.3.2", "rollup-plugin-terser": "^7.0.2", - "typescript": "^5.4.5", "yauzl-promise": "^4.0.0" } }, @@ -1767,26 +1767,6 @@ "node": ">=0.1.90" } }, - "node_modules/@emnapi/core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.1.0.tgz", - "integrity": "sha512-gNEVZo0HhUfVjhr6rFG//HZXbauclxueiDxaKGBZHcK5h8i9pslABNPfG8kMwYTubAn3mV7AyOZN8gfPRgbU8A==", - "dev": true, - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.1.0.tgz", - "integrity": "sha512-gCGlE0fJGWalfy+wbFApjhKn6uoSVvopru77IPyxNKkjkaiSx2HxDS7eOYSmo9dcMIhmmIvoxiC3N9TM1c3EaA==", - "dev": true, - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -1983,18 +1963,6 @@ "node": ">=v12.0.0" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.1.2.tgz", - "integrity": "sha512-8JuczewTFIZ/XIjHQ+YlQUydHvlKx2hkcxtuGwh+t/t5zWyZct6YG4+xjHcq8xyc/e7FmFwf42Zj2YgICwmlvA==", - "dev": true, - "optional": true, - "dependencies": { - "@emnapi/core": "^1.1.0", - "@emnapi/runtime": "^1.1.0", - "@tybys/wasm-util": "^0.8.1" - } - }, "node_modules/@node-rs/crc32": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@node-rs/crc32/-/crc32-1.10.0.tgz", @@ -2024,38 +1992,6 @@ "@node-rs/crc32-win32-x64-msvc": "1.10.0" } }, - "node_modules/@node-rs/crc32-android-arm-eabi": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm-eabi/-/crc32-android-arm-eabi-1.10.0.tgz", - "integrity": "sha512-IRas7ylc8nB3988nnaT4PC5ZuaK3VOrLbTyg1Y/5ZHlxsYpqLpCb7VMf/oRrHxkSzSTlluD+inv3J8UE3i5Ojg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-android-arm64": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm64/-/crc32-android-arm64-1.10.0.tgz", - "integrity": "sha512-4vX1gB+rf3sYma/LLycmYsuFKolWdZX7tQOwLQ6PDwE7dAoN3mWAgS3RBw2G6PerGD9r90vSXWXPLJnF3OAhlw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@node-rs/crc32-darwin-arm64": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-arm64/-/crc32-darwin-arm64-1.10.0.tgz", @@ -2088,166 +2024,6 @@ "node": ">= 10" } }, - "node_modules/@node-rs/crc32-freebsd-x64": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-freebsd-x64/-/crc32-freebsd-x64-1.10.0.tgz", - "integrity": "sha512-BE0IeHn59GzaebTM85Dpe+ErPV8E+WuXd/sNyLLS8jZUuNoOJwFUKotm8CUFG+MI40N0U9PzvZjQSwaeMsyMsQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm-gnueabihf": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm-gnueabihf/-/crc32-linux-arm-gnueabihf-1.10.0.tgz", - "integrity": "sha512-R3mN3uSZaslJtXW3NXdropB9tHCnOgbrvq7MtmCRpHi2Ie3E46Ohi8cW0HgHjihptafTf8NWsoYzErm39BTY0Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm64-gnu": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-gnu/-/crc32-linux-arm64-gnu-1.10.0.tgz", - "integrity": "sha512-2zZ2RQLVhjCWRWiLvz/CoP5BFld/zE/uD2Z9Nk+Y5zmJ11CD1RC3lqKG1M3MgEiQq9CnWJxwyy5kM2q4jDeXkg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm64-musl": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-musl/-/crc32-linux-arm64-musl-1.10.0.tgz", - "integrity": "sha512-WEIavGFHMAFe8NIKhbYnM6k2x7y6M/NQewXE8cqeV03Q8mLzCDBr34i/MzpW+M42NvEYgcM8c3Ayn2FijHb64Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-x64-gnu": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-gnu/-/crc32-linux-x64-gnu-1.10.0.tgz", - "integrity": "sha512-K/7aY/h8QngsLk0KsalQ3AlZ8ljXRisZgc20RcbB4UZkjl5AN6TeHQlVbx9U2MSBE5f6ViiZEr8c8CcID3W2Mg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-x64-musl": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-musl/-/crc32-linux-x64-musl-1.10.0.tgz", - "integrity": "sha512-GyCSm+Dp96qUvqrsxKgfd3TFrE8v5sRUYiMgNKK6G1m7nQb/VXvab9UoBSKeFw131odt3LlIuBAuhMnbb4za5w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-wasm32-wasi": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-wasm32-wasi/-/crc32-wasm32-wasi-1.10.0.tgz", - "integrity": "sha512-C+2IK5HwNUz2aiMGiN0RTijb80X5V1jo/o8bsHqi8ukoRyO6HLMhVn+xptqY+RRSf4VUzzNR5eHqD+WLcLId0g==", - "cpu": [ - "wasm32" - ], - "dev": true, - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.1.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@node-rs/crc32-win32-arm64-msvc": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-arm64-msvc/-/crc32-win32-arm64-msvc-1.10.0.tgz", - "integrity": "sha512-RaVo4edbEM3DyQkvXGKdPizUmr2A4NjLMk/1x9b/tz/k2rdd+QaPAauDwWAzs7SKoDBV9H4qc3hNFuKGjjRhjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-win32-ia32-msvc": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-ia32-msvc/-/crc32-win32-ia32-msvc-1.10.0.tgz", - "integrity": "sha512-5KqJFdzRXELpXcdNgahafjkc9MxZJfKDVkFPBMkQIjjkv8PQ49DVw15/7yuhAN0pyYccNaUil4vtVoo7WTIVgQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-win32-x64-msvc": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-x64-msvc/-/crc32-win32-x64-msvc-1.10.0.tgz", - "integrity": "sha512-6b99QpwNCQube1xleD+9IcF6foEWHYQYjuZrHAR5diuP/uqM7i+KCgMU9fbCFLs5zmssYHO3CQSZ8G+V0eC59g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2547,6 +2323,32 @@ "randombytes": "^2.1.0" } }, + "node_modules/@rollup/plugin-typescript": { + "version": "11.1.6", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", + "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0||^3.0.0||^4.0.0", + "tslib": "*", + "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } + } + }, "node_modules/@rollup/pluginutils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", @@ -2788,16 +2590,6 @@ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", "dev": true }, - "node_modules/@tybys/wasm-util": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.8.1.tgz", - "integrity": "sha512-GSsTwyBl4pIzsxAY5wroZdyQKyhXk0d8PCRZtrSZ2WEB1cBdrp2EgGBwHOGCZtIIPun/DL3+AykCv+J6fyRH4Q==", - "dev": true, - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@types/cacheable-request": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", @@ -10549,6 +10341,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 7dfb843a..fa34b56c 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ ], "description": "Javascript parser for ics (rfc5545) and vcard (rfc6350) data", "main": "dist/ical.js", + "types": "dist/types/module.d.ts", "type": "module", "repository": { "type": "git", @@ -26,6 +27,7 @@ "@octokit/core": "^6.0.1", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^11.1.6", "@stylistic/eslint-plugin": "^2.1.0", "benchmark": "^2.1.4", "c8": "^9.1.0", @@ -43,7 +45,6 @@ "mocha": "^10.3.0", "node-fetch": "^3.3.2", "rollup-plugin-terser": "^7.0.2", - "typescript": "^5.4.5", "yauzl-promise": "^4.0.0" }, "license": "MPL-2.0", @@ -73,6 +74,7 @@ "dist/ical.min.js", "dist/ical.es5.cjs", "dist/ical.es5.min.cjs", + "dist/types/*.d.ts", "lib/ical/*.js" ], "mocha": { diff --git a/rollup.config.js b/rollup.config.js index ce5181e1..326216ba 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,5 +1,6 @@ import { babel } from '@rollup/plugin-babel'; import terser from '@rollup/plugin-terser'; +import typescript from '@rollup/plugin-typescript'; const LICENSE = `/* This Source Code Form is subject to the terms of the Mozilla Public @@ -50,6 +51,7 @@ export default [{ } ], plugins: [ - babel({ babelHelpers: 'bundled', presets: ['@babel/preset-env'] }) + babel({ babelHelpers: 'bundled', presets: ['@babel/preset-env'] }), + typescript({ include: ["lib/ical/*.js"], noForceEmit: true }) ] }]; diff --git a/tsconfig.json b/tsconfig.json index 265a4034..b30608ed 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,4 @@ { - "include": ["dist/ical.js"], "compilerOptions": { // Tells TypeScript to read JS files, as // normally they are ignored as source files @@ -10,6 +9,7 @@ "emitDeclarationOnly": true, // go to js file when using IDE functions like // "Go to Definition" in VSCode - "declarationMap": true + "declarationMap": true, + "declarationDir": "dist/types" } } \ No newline at end of file From e3147857eca2ddfd562d3fbb33453dbacb4296b4 Mon Sep 17 00:00:00 2001 From: Philipp Kewisch Date: Tue, 21 May 2024 22:51:03 +0200 Subject: [PATCH 04/19] Augment generated jsdoc to make modules more explicit --- eslint.config.js | 1 + jsdoc.json | 2 +- tools/jsdoc-ical.cjs | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tools/jsdoc-ical.cjs diff --git a/eslint.config.js b/eslint.config.js index b865dd0a..d7871808 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -11,6 +11,7 @@ export default [ "!test/**/*.{js,cjs}", "!tools/scriptutils.js", "!tools/ICALTester/**/*.js", + "!tools/jsdoc-ical.cjs", "!eslint.config.js", "!rollup.config.js", "!karma.conf.cjs" diff --git a/jsdoc.json b/jsdoc.json index 7f280b2e..55e10064 100644 --- a/jsdoc.json +++ b/jsdoc.json @@ -3,7 +3,7 @@ "include": "lib/ical", "includePattern": ".js$" }, - "plugins": ["plugins/markdown"], + "plugins": ["plugins/markdown", "tools/jsdoc-ical.cjs"], "opts": { "encoding": "utf8", "readme": "README.md", diff --git a/tools/jsdoc-ical.cjs b/tools/jsdoc-ical.cjs new file mode 100644 index 00000000..331fa9c5 --- /dev/null +++ b/tools/jsdoc-ical.cjs @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch, 2024 */ + +let gIcalClasses = new Set(); + +function augmentTypes(obj) { + if (obj.type?.names?.length) { + for (let i = 0; i < obj.type.names.length; i++) { + if (gIcalClasses.has(obj.type.names[i]) && !obj.type.names[i].startsWith("ICAL.")) { + obj.type.names[i] = "ICAL." + obj.type.names[i]; + } + } + } +} + +exports.handlers = { + newDoclet: function({ doclet }) { + if (doclet.kind == "class" && doclet.longname.startsWith("ICAL.")) { + gIcalClasses.add(doclet.name); + } + + if (doclet.returns) { + for (let ret of doclet.returns) { + augmentTypes(ret); + } + } + if (doclet.params) { + for (let param of doclet.params) { + augmentTypes(param); + } + } + } +}; From 3059d26d6e9f269f234580b2baa5a54b6345e24f Mon Sep 17 00:00:00 2001 From: Philipp Kewisch Date: Tue, 21 May 2024 22:52:23 +0200 Subject: [PATCH 05/19] JSDoc improvements for typescript --- lib/ical/component.js | 49 +++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/lib/ical/component.js b/lib/ical/component.js index d4969f2d..4c570410 100644 --- a/lib/ical/component.js +++ b/lib/ical/component.js @@ -17,7 +17,7 @@ const COMPONENT_INDEX = 2; * Wraps a jCal component, adding convenience methods to add, remove and update subcomponents and * properties. * - * @class + * @memberof ICAL */ class Component { /** @@ -34,7 +34,7 @@ class Component { * * @param {Array|String} jCal Raw jCal component data OR name of new * component - * @param {Component} parent Parent component to associate + * @param {Component=} parent Parent component to associate */ constructor(jCal, parent) { if (typeof(jCal) === 'string') { @@ -81,8 +81,20 @@ class Component { */ _timezoneCache = null; + /** + * @private + */ + _components = null; + + /** + * @private + */ + _properties = null; + /** * The name of this component + * + * @type {String} * @readonly */ get name() { @@ -100,6 +112,9 @@ class Component { return parentDesign || design.getDesignSet(this.name); } + /** + * @private + */ _hydrateComponent(index) { if (!this._components) { this._components = []; @@ -119,6 +134,9 @@ class Component { return (this._components[index] = comp); } + /** + * @private + */ _hydrateProperty(index) { if (!this._properties) { this._properties = []; @@ -225,7 +243,7 @@ class Component { * Finds the first property, optionally with the given name. * * @param {String=} name Lowercase property name - * @return {?ICAL.Property} The found property + * @return {?Property} The found property */ getFirstProperty(name) { if (name) { @@ -267,7 +285,7 @@ class Component { * Get all properties in the component, optionally filtered by name. * * @param {String=} name Lowercase property name - * @return {ICAL.Property[]} List of properties + * @return {Property[]} List of properties */ getAllProperties(name) { let jCalLen = this.jCal[PROPERTY_INDEX].length; @@ -297,6 +315,9 @@ class Component { } } + /** + * @private + */ _removeObjectByIndex(jCalIndex, cache, index) { cache = cache || []; // remove cached version @@ -313,6 +334,9 @@ class Component { this.jCal[jCalIndex].splice(index, 1); } + /** + * @private + */ _removeObject(jCalIndex, cache, nameOrObject) { let i = 0; let objects = this.jCal[jCalIndex]; @@ -338,6 +362,9 @@ class Component { return false; } + /** + * @private + */ _removeAllObjects(jCalIndex, cache, name) { let cached = this[cache]; @@ -406,10 +433,10 @@ class Component { } /** - * Adds an {@link ICAL.Property} to the component. + * Adds an {@link Property} to the component. * - * @param {ICAL.Property} property The property to add - * @return {ICAL.Property} The passed in property + * @param {Property} property The property to add + * @return {Property} The passed in property */ addProperty(property) { if (!(property instanceof Property)) { @@ -437,7 +464,7 @@ class Component { * * @param {String} name Property name to add * @param {String|Number|Object} value Property value - * @return {ICAL.Property} The created property + * @return {Property} The created property */ addPropertyWithValue(name, value) { let prop = new Property(name); @@ -455,7 +482,7 @@ class Component { * * @param {String} name Property name to update * @param {String|Number|Object} value Property value - * @return {ICAL.Property} The created property + * @return {Property} The created property */ updatePropertyWithValue(name, value) { let prop = this.getFirstProperty(name); @@ -473,7 +500,7 @@ class Component { * Removes a single property by name or the instance of the specific * property. * - * @param {String|ICAL.Property} nameOrProp Property name or instance to remove + * @param {String|Property} nameOrProp Property name or instance to remove * @return {Boolean} True, when deleted */ removeProperty(nameOrProp) { @@ -522,7 +549,7 @@ class Component { * matched, returns null. * * @param {String} tzid The ID of the time zone to retrieve - * @return {ICAL.Timezone} The time zone corresponding to the ID, or null + * @return {Timezone} The time zone corresponding to the ID, or null */ getTimeZoneByID(tzid) { // VTIMEZONE components can only appear as a child of the VCALENDAR From 314f4cfc595ea40ab45b2245a7d7c2b17d779de4 Mon Sep 17 00:00:00 2001 From: Philipp Kewisch Date: Tue, 21 May 2024 22:59:29 +0200 Subject: [PATCH 06/19] Use long name in jsdoc links --- lib/ical/component.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ical/component.js b/lib/ical/component.js index 4c570410..586e5aea 100644 --- a/lib/ical/component.js +++ b/lib/ical/component.js @@ -21,7 +21,7 @@ const COMPONENT_INDEX = 2; */ class Component { /** - * Create an {@link Component} by parsing the passed iCalendar string. + * Create an {@link ICAL.Component} by parsing the passed iCalendar string. * * @param {String} str The iCalendar string to parse */ @@ -433,7 +433,7 @@ class Component { } /** - * Adds an {@link Property} to the component. + * Adds an {@link ICAL.Property} to the component. * * @param {Property} property The property to add * @return {Property} The passed in property From 0c9ab5935579de20b71904359fd561f3e04d1027 Mon Sep 17 00:00:00 2001 From: jannikac Date: Thu, 23 May 2024 10:02:52 +0200 Subject: [PATCH 07/19] move tsconfig to rollup typescript plugin config --- rollup.config.js | 12 +++++++++++- tsconfig.json | 17 ++++------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index 326216ba..b107fd95 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -52,6 +52,16 @@ export default [{ ], plugins: [ babel({ babelHelpers: 'bundled', presets: ['@babel/preset-env'] }), - typescript({ include: ["lib/ical/*.js"], noForceEmit: true }) + typescript({ + include: ['lib/ical/*.js'], + noForceEmit: true, + compilerOptions: { + allowJs: true, + declaration: true, + emitDeclarationOnly: true, + declarationMap: true, + declarationDir: 'dist/types', + }, + }) ] }]; diff --git a/tsconfig.json b/tsconfig.json index b30608ed..7342895c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,6 @@ { - "compilerOptions": { - // Tells TypeScript to read JS files, as - // normally they are ignored as source files - "allowJs": true, - // Generate d.ts files - "declaration": true, - // only output d.ts files - "emitDeclarationOnly": true, - // go to js file when using IDE functions like - // "Go to Definition" in VSCode - "declarationMap": true, - "declarationDir": "dist/types" - } + // dont compile types directly with tsc, use npm run build instead + // type generation is handled by @rollup/plugin-typescript + + // this file exists because of https://github.com/rollup/plugins/issues/1572 } \ No newline at end of file From dc1483705117d96cfd0018d28ec398c2a0b2cb21 Mon Sep 17 00:00:00 2001 From: jannikac Date: Thu, 23 May 2024 12:54:19 +0200 Subject: [PATCH 08/19] fix incorrect parameter name --- lib/ical/timezone_service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ical/timezone_service.js b/lib/ical/timezone_service.js index 6b405acd..ef3ae6f0 100644 --- a/lib/ical/timezone_service.js +++ b/lib/ical/timezone_service.js @@ -72,7 +72,7 @@ const TimezoneService = { * @param {String=} name * The name of the timezone. Defaults to the component's TZID if not * passed. - * @param {ICAL.Component|ICAL.Timezone} zone + * @param {ICAL.Component|ICAL.Timezone} timezone * The initialized zone or vtimezone. */ register: function(name, timezone) { From 1278610d2b08c524edc9d81ffa0af721475f3b6d Mon Sep 17 00:00:00 2001 From: jannikac Date: Thu, 23 May 2024 13:08:45 +0200 Subject: [PATCH 09/19] improve jsdoc types to allow for generation of .d.ts files --- lib/ical/binary.js | 5 ++- lib/ical/component_parser.js | 9 +++-- lib/ical/duration.js | 15 ++++---- lib/ical/event.js | 20 ++++++----- lib/ical/helpers.js | 7 ++-- lib/ical/parse.js | 1 - lib/ical/period.js | 34 ++++++++++--------- lib/ical/property.js | 10 +++--- lib/ical/recur.js | 23 ++++++------- lib/ical/recur_expansion.js | 18 +++++----- lib/ical/recur_iterator.js | 13 ++++--- lib/ical/time.js | 66 +++++++++++++++++++----------------- lib/ical/timezone.js | 27 +++++++-------- lib/ical/timezone_service.js | 8 ++--- lib/ical/utc_offset.js | 12 ++++--- lib/ical/vcard_time.js | 9 +++-- 16 files changed, 141 insertions(+), 136 deletions(-) diff --git a/lib/ical/binary.js b/lib/ical/binary.js index 7b2590f2..57c9dee7 100644 --- a/lib/ical/binary.js +++ b/lib/ical/binary.js @@ -6,15 +6,14 @@ /** * Represents the BINARY value type, which contains extra methods for encoding and decoding. * - * @class - * @alias ICAL.Binary + * @memberof ICAL */ class Binary { /** * Creates a binary value from the given string. * * @param {String} aString The binary value string - * @return {ICAL.Binary} The binary value instance + * @return {Binary} The binary value instance */ static fromString(aString) { return new Binary(aString); diff --git a/lib/ical/component_parser.js b/lib/ical/component_parser.js index f9993a4e..71f1575a 100644 --- a/lib/ical/component_parser.js +++ b/lib/ical/component_parser.js @@ -33,8 +33,7 @@ import Timezone from "./timezone.js"; * * parser.process(stringOrComponent); * - * @class - * @alias ICAL.ComponentParser + * @memberof ICAL */ class ComponentParser { /** @@ -89,7 +88,7 @@ class ComponentParser { * Fired when a top level component (VTIMEZONE) is found * * @callback - * @param {ICAL.Timezone} component Timezone object + * @param {Timezone} component Timezone object */ ontimezone = /* c8 ignore next */ function(component) {}; @@ -97,7 +96,7 @@ class ComponentParser { * Fired when a top level component (VEVENT) is found. * * @callback - * @param {ICAL.Event} component Top level component + * @param {Event} component Top level component */ onevent = /* c8 ignore next */ function(component) {}; @@ -107,7 +106,7 @@ class ComponentParser { * * Events must be registered prior to calling this method. * - * @param {ICAL.Component|String|Object} ical The component to process, + * @param {Component|String|Object} ical The component to process, * either in its final form, as a jCal Object, or string representation */ process(ical) { diff --git a/lib/ical/duration.js b/lib/ical/duration.js index 1f6789a2..9f72a01e 100644 --- a/lib/ical/duration.js +++ b/lib/ical/duration.js @@ -12,15 +12,14 @@ const DATA_PROPS_TO_COPY = ["weeks", "days", "hours", "minutes", "seconds", "isN * This class represents the "duration" value type, with various calculation * and manipulation methods. * - * @class - * @alias ICAL.Duration + * @memberof ICAL */ class Duration { /** * Returns a new ICAL.Duration instance from the passed seconds value. * * @param {Number} aSeconds The seconds to create the instance from - * @return {ICAL.Duration} The newly created duration instance + * @return {Duration} The newly created duration instance */ static fromSeconds(aSeconds) { return (new Duration()).fromSeconds(aSeconds); @@ -41,7 +40,7 @@ class Duration { * Creates a new {@link ICAL.Duration} instance from the passed string. * * @param {String} aStr The string to parse - * @return {ICAL.Duration} The created duration instance + * @return {Duration} The created duration instance */ static fromString(aStr) { let pos = 0; @@ -76,7 +75,7 @@ class Duration { * @param {Number} aData.minutes Duration in minutes * @param {Number} aData.seconds Duration in seconds * @param {Boolean} aData.isNegative If true, the duration is negative - * @return {ICAL.Duration} The createad duration instance + * @return {Duration} The createad duration instance */ static fromData(aData) { return new Duration(aData); @@ -159,7 +158,7 @@ class Duration { /** * Returns a clone of the duration object. * - * @return {ICAL.Duration} The cloned object + * @return {Duration} The cloned object */ clone() { return Duration.fromData(this); @@ -182,7 +181,7 @@ class Duration { * accordingly. * * @param {Number} aSeconds The duration value in seconds - * @return {ICAL.Duration} Returns this instance + * @return {Duration} Returns this instance */ fromSeconds(aSeconds) { let secs = Math.abs(aSeconds); @@ -246,7 +245,7 @@ class Duration { /** * Compares the duration instance with another one. * - * @param {ICAL.Duration} aOther The instance to compare with + * @param {Duration} aOther The instance to compare with * @return {Number} -1, 0 or 1 for less/equal/greater */ compare(aOther) { diff --git a/lib/ical/event.js b/lib/ical/event.js index f0212ee4..ccd6a297 100644 --- a/lib/ical/event.js +++ b/lib/ical/event.js @@ -7,6 +7,9 @@ import { binsearchInsert } from "./helpers.js"; import Component from "./component.js"; import Property from "./property.js"; import Timezone from "./timezone.js"; +// needed for typescript type resolution +// eslint-disable-next-line no-unused-vars +import Time from "./time.js"; import RecurExpansion from "./recur_expansion.js"; /** @@ -15,14 +18,13 @@ import RecurExpansion from "./recur_expansion.js"; * event representation, which this class is part of. See the * {@tutorial layers} guide for more details. * - * @class - * @alias ICAL.Event + * @memberof ICAL */ class Event { /** * Creates a new ICAL.Event instance. * - * @param {ICAL.Component=} component The ICAL.Component to base this event on + * @param {Component=} component The ICAL.Component to base this event on * @param {Object} options Options for this event * @param {Boolean} options.strictExceptions When true, will verify exceptions are related by * their UUID @@ -87,7 +89,7 @@ class Event { * If this component is an exception it cannot have other exceptions * related to it. * - * @param {ICAL.Component|ICAL.Event} obj Component or event + * @param {Component|Event} obj Component or event */ relateException(obj) { if (this.isRecurrenceException()) { @@ -145,8 +147,8 @@ class Event { /** * Finds the range exception nearest to the given date. * - * @param {ICAL.Time} time usually an occurrence time of an event - * @return {?ICAL.Event} the related event/exception or null + * @param {Time} time usually an occurrence time of an event + * @return {?Event} the related event/exception or null */ findRangeException(time) { if (!this.rangeExceptions.length) { @@ -196,7 +198,7 @@ class Event { * NOTE: this method is intend to be used in conjunction * with the {@link ICAL.Event#iterator iterator} method. * - * @param {ICAL.Time} occurrence time occurrence + * @param {Time} occurrence time occurrence * @return {ICAL.Event.occurrenceDetails} Information about the occurrence */ getOccurrenceDetails(occurrence) { @@ -275,8 +277,8 @@ class Event { * Builds a recur expansion instance for a specific point in time (defaults * to startDate). * - * @param {ICAL.Time} startTime Starting point for expansion - * @return {ICAL.RecurExpansion} Expansion object + * @param {Time} startTime Starting point for expansion + * @return {RecurExpansion} Expansion object */ iterator(startTime) { return new RecurExpansion({ diff --git a/lib/ical/helpers.js b/lib/ical/helpers.js index 850d5c59..ba3cf6cf 100644 --- a/lib/ical/helpers.js +++ b/lib/ical/helpers.js @@ -4,6 +4,9 @@ * Portions Copyright (C) Philipp Kewisch */ import TimezoneService from "./timezone_service.js"; +// needed for typescript type resolution +// eslint-disable-next-line no-unused-vars +import Component from "./component.js"; import ICALmodule from "./module.js"; /** @@ -17,8 +20,8 @@ import ICALmodule from "./module.js"; * are referenced by a component, but a VTIMEZONE does not exist, * an attempt will be made to generate a VTIMEZONE using ICAL.TimezoneService. * - * @param {ICAL.Component} vcal The top-level VCALENDAR component. - * @return {ICAL.Component} The ICAL.Component that was passed in. + * @param {Component} vcal The top-level VCALENDAR component. + * @return {Component} The ICAL.Component that was passed in. */ export function updateTimezones(vcal) { let allsubs, properties, vtimezones, reqTzid, i; diff --git a/lib/ical/parse.js b/lib/ical/parse.js index aff4446f..a42f547a 100644 --- a/lib/ical/parse.js +++ b/lib/ical/parse.js @@ -91,7 +91,6 @@ parse.component = function(str) { * @param {String} message The error message * @memberof ICAL.parse * @extends {Error} - * @class */ class ParserError extends Error { name = this.constructor.name; diff --git a/lib/ical/period.js b/lib/ical/period.js index c8e44be0..254170c0 100644 --- a/lib/ical/period.js +++ b/lib/ical/period.js @@ -5,20 +5,22 @@ import Time from "./time.js"; import Duration from "./duration.js"; +// needed for typescript type resolution +// eslint-disable-next-line no-unused-vars +import Property from "./property.js"; /** * This class represents the "period" value type, with various calculation and manipulation methods. * - * @class - * @alias ICAL.Period + * @memberof ICAL */ class Period { /** * Creates a new {@link ICAL.Period} instance from the passed string. * * @param {String} str The string to parse - * @param {ICAL.Property} prop The property this period will be on - * @return {ICAL.Period} The created period instance + * @param {Property} prop The property this period will be on + * @return {Period} The created period instance */ static fromString(str, prop) { let parts = str.split('/'); @@ -49,10 +51,10 @@ class Period { * The passed data object cannot contain both and end date and a duration. * * @param {Object} aData An object with members of the period - * @param {ICAL.Time=} aData.start The start of the period - * @param {ICAL.Time=} aData.end The end of the period - * @param {ICAL.Duration=} aData.duration The duration of the period - * @return {ICAL.Period} The period instance + * @param {Time=} aData.start The start of the period + * @param {Time=} aData.end The end of the period + * @param {Duration=} aData.duration The duration of the period + * @return {Period} The period instance */ static fromData(aData) { return new Period(aData); @@ -64,9 +66,9 @@ class Period { * duration or end date string. * * @param {Array} aData The jCal data array - * @param {ICAL.Property} aProp The property this jCal data is on + * @param {Property} aProp The property this jCal data is on * @param {Boolean} aLenient If true, data value can be both date and date-time - * @return {ICAL.Period} The period instance + * @return {Period} The period instance */ static fromJSON(aData, aProp, aLenient) { function fromDateOrDateTimeString(aValue, dateProp) { @@ -95,9 +97,9 @@ class Period { * a duration. * * @param {Object} aData An object with members of the period - * @param {ICAL.Time=} aData.start The start of the period - * @param {ICAL.Time=} aData.end The end of the period - * @param {ICAL.Duration=} aData.duration The duration of the period + * @param {Time=} aData.start The start of the period + * @param {Time=} aData.end The end of the period + * @param {Duration=} aData.duration The duration of the period */ constructor(aData) { this.wrappedJSObject = this; @@ -166,7 +168,7 @@ class Period { /** * Returns a clone of the duration object. * - * @return {ICAL.Period} The cloned object + * @return {Period} The cloned object */ clone() { return Period.fromData({ @@ -180,7 +182,7 @@ class Period { * Calculates the duration of the period, either directly or by subtracting * start from end date. * - * @return {ICAL.Duration} The calculated duration + * @return {Duration} The calculated duration */ getDuration() { if (this.duration) { @@ -194,7 +196,7 @@ class Period { * Calculates the end date of the period, either directly or by adding * duration to start date. * - * @return {ICAL.Time} The calculated end date + * @return {Time} The calculated end date */ getEnd() { if (this.end) { diff --git a/lib/ical/property.js b/lib/ical/property.js index 9b19fbec..3dabe8ab 100644 --- a/lib/ical/property.js +++ b/lib/ical/property.js @@ -9,6 +9,9 @@ const TYPE_INDEX = 2; const VALUE_INDEX = 3; import design from "./design.js"; +// needed for typescript type resolution +// eslint-disable-next-line no-unused-vars +import Component from "./component.js"; import ICALStringify from "./stringify.js"; import ICALParse from "./parse.js"; @@ -16,8 +19,7 @@ import ICALParse from "./parse.js"; * Provides a layer on top of the raw jCal object for manipulating a single property, with its * parameters and value. * - * @class - * @alias ICAL.Property + * @memberof ICAL */ class Property { /** @@ -25,7 +27,7 @@ class Property { * * @param {String} str The iCalendar string to parse * @param {ICAL.design.designSet=} designSet The design data to use for this property - * @return {ICAL.Property} The created iCalendar property + * @return {Property} The created iCalendar property */ static fromString(str, designSet) { return new Property(ICALParse.property(str, designSet)); @@ -40,7 +42,7 @@ class Property { * Can also be used to create new properties by passing the name of the property (as a String). * * @param {Array|String} jCal Raw jCal representation OR the new name of the property - * @param {ICAL.Component=} parent Parent component + * @param {Component=} parent Parent component */ constructor(jCal, parent) { this._parent = parent || null; diff --git a/lib/ical/recur.js b/lib/ical/recur.js index ba750081..54d11ece 100644 --- a/lib/ical/recur.js +++ b/lib/ical/recur.js @@ -37,15 +37,14 @@ const ALLOWED_FREQ = ['SECONDLY', 'MINUTELY', 'HOURLY', * This class represents the "recur" value type, used for example by RRULE. It provides methods to * calculate occurrences among others. * - * @class - * @alias ICAL.Recur + * @memberof ICAL */ class Recur { /** * Creates a new {@link ICAL.Recur} instance from the passed string. * * @param {String} string The string to parse - * @return {ICAL.Recur} The created recurrence instance + * @return {Recur} The created recurrence instance */ static fromString(string) { let data = this._stringToData(string, false); @@ -60,7 +59,7 @@ class Recur { * @param {ICAL.Recur.frequencyValues=} aData.freq The frequency value * @param {Number=} aData.interval The INTERVAL value * @param {ICAL.Time.weekDay=} aData.wkst The week start value - * @param {ICAL.Time=} aData.until The end of the recurrence set + * @param {Time=} aData.until The end of the recurrence set * @param {Number=} aData.count The number of occurrences * @param {Array.=} aData.bysecond The seconds for the BYSECOND part * @param {Array.=} aData.byminute The minutes for the BYMINUTE part @@ -165,7 +164,7 @@ class Recur { * @param {ICAL.Recur.frequencyValues=} data.freq The frequency value * @param {Number=} data.interval The INTERVAL value * @param {ICAL.Time.weekDay=} data.wkst The week start value - * @param {ICAL.Time=} data.until The end of the recurrence set + * @param {Time=} data.until The end of the recurrence set * @param {Number=} data.count The number of occurrences * @param {Array.=} data.bysecond The seconds for the BYSECOND part * @param {Array.=} data.byminute The minutes for the BYMINUTE part @@ -256,8 +255,8 @@ class Recur { * console.log(next.toString()); * } * - * @param {ICAL.Time} aStart The item's start date - * @return {ICAL.RecurIterator} The recurrence iterator + * @param {Time} aStart The item's start date + * @return {RecurIterator} The recurrence iterator */ iterator(aStart) { return new RecurIterator({ @@ -269,7 +268,7 @@ class Recur { /** * Returns a clone of the recurrence object. * - * @return {ICAL.Recur} The cloned object + * @return {Recur} The cloned object */ clone() { return new Recur(this.toJSON()); @@ -342,9 +341,9 @@ class Recur { * occurrences manually, see the example on the * {@link ICAL.Recur#iterator iterator} method. * - * @param {ICAL.Time} aStartTime The start of the event series - * @param {ICAL.Time} aRecurrenceId The date of the last occurrence - * @return {ICAL.Time} The next occurrence after + * @param {Time} aStartTime The start of the event series + * @param {Time} aRecurrenceId The date of the last occurrence + * @return {Time} The next occurrence after */ getNextOccurrence(aStartTime, aRecurrenceId) { let iter = this.iterator(aStartTime); @@ -368,7 +367,7 @@ class Recur { * @param {ICAL.Recur.frequencyValues=} data.freq The frequency value * @param {Number=} data.interval The INTERVAL value * @param {ICAL.Time.weekDay=} data.wkst The week start value - * @param {ICAL.Time=} data.until The end of the recurrence set + * @param {Time=} data.until The end of the recurrence set * @param {Number=} data.count The number of occurrences * @param {Array.=} data.bysecond The seconds for the BYSECOND part * @param {Array.=} data.byminute The minutes for the BYMINUTE part diff --git a/lib/ical/recur_expansion.js b/lib/ical/recur_expansion.js index 2694b3a1..db259172 100644 --- a/lib/ical/recur_expansion.js +++ b/lib/ical/recur_expansion.js @@ -5,6 +5,9 @@ import Time from "./time.js"; import RecurIterator from "./recur_iterator.js"; +// needed for typescript type resolution +// eslint-disable-next-line no-unused-vars +import Component from "./component.js"; import { formatClassType, binsearchInsert } from "./helpers.js"; /** @@ -45,8 +48,7 @@ import { formatClassType, binsearchInsert } from "./helpers.js"; * // over. This only works when the component's recurrence info is the same. * var expand = new ICAL.RecurExpansion(JSON.parse(json)); * - * @class - * @alias ICAL.RecurExpansion + * @memberof ICAL */ class RecurExpansion { /** @@ -56,13 +58,11 @@ class RecurExpansion { * additional members, as a result of serializing a previous expansion state, as shown in the * example. * - * @class - * @alias ICAL.RecurExpansion * @param {Object} options * Recurrence expansion options - * @param {ICAL.Time} options.dtstart + * @param {Time} options.dtstart * Start time of the event - * @param {ICAL.Component=} options.component + * @param {Component=} options.component * Component for expansion, required if not resuming. */ constructor(options) { @@ -152,9 +152,9 @@ class RecurExpansion { * * @param {Object} options * Recurrence expansion options - * @param {ICAL.Time} options.dtstart + * @param {Time} options.dtstart * Start time of the event - * @param {ICAL.Component=} options.component + * @param {Component=} options.component * Component for expansion, required if not resuming. */ fromData(options) { @@ -200,7 +200,7 @@ class RecurExpansion { /** * Retrieve the next occurrence in the series. - * @return {ICAL.Time} + * @return {Time} */ next() { let iter; diff --git a/lib/ical/recur_iterator.js b/lib/ical/recur_iterator.js index feb36e1e..543c5d7e 100644 --- a/lib/ical/recur_iterator.js +++ b/lib/ical/recur_iterator.js @@ -11,8 +11,7 @@ import Time from "./time.js"; * An iterator for a single recurrence rule. This class usually doesn't have to be instanciated * directly, the convenience method {@link ICAL.Recur#iterator} can be used. * - * @class - * @alias ICAL.RecurIterator + * @memberof ICAL */ class RecurIterator { static _indexMap = { @@ -47,8 +46,8 @@ class RecurIterator { * when resuming iteration from a previous run. * * @param {Object} options The iterator options - * @param {ICAL.Recur} options.rule The rule to iterate. - * @param {ICAL.Time} options.dtstart The start date of the event. + * @param {Recur} options.rule The rule to iterate. + * @param {Time} options.dtstart The start date of the event. * @param {Boolean=} options.initialized When true, assume that options are * from a previously constructed iterator. Initialization will not be * repeated. @@ -129,8 +128,8 @@ class RecurIterator { * through the constructor. * * @param {Object} options The iterator options - * @param {ICAL.Recur} options.rule The rule to iterate. - * @param {ICAL.Time} options.dtstart The start date of the event. + * @param {Recur} options.rule The rule to iterate. + * @param {Time} options.dtstart The start date of the event. * @param {Boolean=} options.initialized When true, assume that options are * from a previously constructed iterator. Initialization will not be * repeated. @@ -367,7 +366,7 @@ class RecurIterator { /** * Retrieve the next occurrence from the iterator. - * @return {ICAL.Time} + * @return {Time} */ next(again = false) { let before = (this.last ? this.last.clone() : null); diff --git a/lib/ical/time.js b/lib/ical/time.js index 0ba05e7c..1a4f1fd4 100644 --- a/lib/ical/time.js +++ b/lib/ical/time.js @@ -6,6 +6,9 @@ import Timezone from "./timezone.js"; import Duration from "./duration.js"; import design from "./design.js"; +// needed for typescript type resolution +// eslint-disable-next-line no-unused-vars +import Property from "./property.js"; import TimezoneService from "./timezone_service.js"; import { strictParseInt, trunc, pad2 } from "./helpers.js"; @@ -26,8 +29,7 @@ import { strictParseInt, trunc, pad2 } from "./helpers.js"; * }); * * - * @alias ICAL.Time - * @class + * @memberof ICAL */ class Time { static _dowCache = {}; @@ -75,7 +77,7 @@ class Time { * * @param {Number} aDayOfYear The day of year * @param {Number} aYear The year to create the instance in - * @return {ICAL.Time} The created instance with the calculated date + * @return {Time} The created instance with the calculated date */ static fromDayOfYear(aDayOfYear, aYear) { let year = aYear; @@ -116,7 +118,7 @@ class Time { * * @deprecated Use {@link ICAL.Time.fromDateString} instead * @param {String} str The string to create from - * @return {ICAL.Time} The date/time instance + * @return {Time} The date/time instance */ static fromStringv2(str) { return new Time({ @@ -131,7 +133,7 @@ class Time { * Returns a new ICAL.Time instance from a date string, e.g 2015-01-02. * * @param {String} aValue The string to create from - * @return {ICAL.Time} The date/time instance + * @return {Time} The date/time instance */ static fromDateString(aValue) { // Dates should have no timezone. @@ -154,8 +156,8 @@ class Time { * from the property's TZID parameter. * * @param {String} aValue The string to create from - * @param {ICAL.Property=} prop The property the date belongs to - * @return {ICAL.Time} The date/time instance + * @param {Property=} prop The property the date belongs to + * @return {Time} The date/time instance */ static fromDateTimeString(aValue, prop) { if (aValue.length < 19) { @@ -210,8 +212,8 @@ class Time { * Returns a new ICAL.Time instance from a date or date-time string, * * @param {String} aValue The string to create from - * @param {ICAL.Property=} prop The property the date belongs to - * @return {ICAL.Time} The date/time instance + * @param {Property=} prop The property the date belongs to + * @return {Time} The date/time instance */ static fromString(aValue, aProperty) { if (aValue.length > 10) { @@ -244,7 +246,7 @@ class Time { * @param {Number=} aData.second The second for this date * @param {Boolean=} aData.isDate If true, the instance represents a date * (as opposed to a date-time) - * @param {ICAL.Timezone=} aZone Timezone this position occurs in + * @param {Timezone=} aZone Timezone this position occurs in */ static fromData = function fromData(aData, aZone) { let t = new Time(); @@ -256,7 +258,7 @@ class Time { * The instance is “floating” - has no timezone relation. * To create an instance considering the time zone, call * ICAL.Time.fromJSDate(new Date(), true) - * @return {ICAL.Time} + * @return {Time} */ static now() { return Time.fromJSDate(new Date(), false); @@ -268,7 +270,7 @@ class Time { * @see ICAL.Time#weekNumber * @param {Number} aYear The year to search in * @param {ICAL.Time.weekDay=} aWeekStart The week start weekday, used for calculation. - * @return {ICAL.Time} The date on which week number 1 starts + * @return {Time} The date on which week number 1 starts */ static weekOneStarts(aYear, aWeekStart) { let t = Time.fromData({ @@ -388,7 +390,7 @@ class Time { * @param {Number=} data.second The second for this date * @param {Boolean=} data.isDate If true, the instance represents a date (as * opposed to a date-time) - * @param {ICAL.Timezone} zone timezone this position occurs in + * @param {Timezone} zone timezone this position occurs in */ constructor(data, zone) { this.wrappedJSObject = this; @@ -445,7 +447,7 @@ class Time { /** * Returns a clone of the time object. * - * @return {ICAL.Time} The cloned object + * @return {Time} The cloned object */ clone() { return new Time(this._time, this.zone); @@ -468,7 +470,7 @@ class Time { * @param {Number} hour The hour to set * @param {Number} minute The minute to set * @param {Number} second The second to set - * @param {ICAL.Timezone} timezone The timezone to set + * @param {Timezone} timezone The timezone to set */ resetTo(year, month, day, hour, minute, second, timezone) { this.fromData({ @@ -526,7 +528,7 @@ class Time { * @param {Number=} aData.second The second for this date * @param {Boolean=} aData.isDate If true, the instance represents a date * (as opposed to a date-time) - * @param {ICAL.Timezone=} aZone Timezone this position occurs in + * @param {Timezone=} aZone Timezone this position occurs in */ fromData(aData, aZone) { if (aData) { @@ -616,7 +618,7 @@ class Time { * * @param {ICAL.Time.weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY - * @return {ICAL.Time} The start of the week (cloned) + * @return {Time} The start of the week (cloned) */ startOfWeek(aWeekStart) { let firstDow = aWeekStart || Time.SUNDAY; @@ -636,7 +638,7 @@ class Time { * * @param {ICAL.Time.weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY - * @return {ICAL.Time} The end of the week (cloned) + * @return {Time} The end of the week (cloned) */ endOfWeek(aWeekStart) { let firstDow = aWeekStart || Time.SUNDAY; @@ -654,7 +656,7 @@ class Time { * month. The resulting ICAL.Time instance is of icaltype date, even if * this is a date-time. * - * @return {ICAL.Time} The start of the month (cloned) + * @return {Time} The start of the month (cloned) */ startOfMonth() { let result = this.clone(); @@ -671,7 +673,7 @@ class Time { * month. The resulting ICAL.Time instance is of icaltype date, even if * this is a date-time. * - * @return {ICAL.Time} The end of the month (cloned) + * @return {Time} The end of the month (cloned) */ endOfMonth() { let result = this.clone(); @@ -688,7 +690,7 @@ class Time { * year. The resulting ICAL.Time instance is of icaltype date, even if * this is a date-time. * - * @return {ICAL.Time} The start of the year (cloned) + * @return {Time} The start of the year (cloned) */ startOfYear() { let result = this.clone(); @@ -706,7 +708,7 @@ class Time { * year. The resulting ICAL.Time instance is of icaltype date, even if * this is a date-time. * - * @return {ICAL.Time} The end of the year (cloned) + * @return {Time} The end of the year (cloned) */ endOfYear() { let result = this.clone(); @@ -910,7 +912,7 @@ class Time { * Adds the duration to the current time. The instance is modified in * place. * - * @param {ICAL.Duration} aDuration The duration to add + * @param {Duration} aDuration The duration to add */ addDuration(aDuration) { let mult = (aDuration.isNegative ? -1 : 1); @@ -943,8 +945,8 @@ class Time { * the relative difference between two time objects excluding their * timezone differences. * - * @param {ICAL.Time} aDate The date to subtract - * @return {ICAL.Duration} The difference as a duration + * @param {Time} aDate The date to subtract + * @return {Duration} The difference as a duration */ subtractDate(aDate) { let unixTime = this.toUnixTime() + this.utcOffset(); @@ -955,8 +957,8 @@ class Time { /** * Subtract the date details, taking timezones into account. * - * @param {ICAL.Time} aDate The date to subtract - * @return {ICAL.Duration} The difference in duration + * @param {Time} aDate The date to subtract + * @return {Duration} The difference in duration */ subtractDateTz(aDate) { let unixTime = this.toUnixTime(); @@ -967,7 +969,7 @@ class Time { /** * Compares the ICAL.Time instance with another one. * - * @param {ICAL.Duration} aOther The instance to compare with + * @param {Duration} aOther The instance to compare with * @return {Number} -1, 0 or 1 for less/equal/greater */ compare(other) { @@ -982,8 +984,8 @@ class Time { /** * Compares only the date part of this instance with another one. * - * @param {ICAL.Duration} other The instance to compare with - * @param {ICAL.Timezone} tz The timezone to compare in + * @param {Duration} other The instance to compare with + * @param {Timezone} tz The timezone to compare in * @return {Number} -1, 0 or 1 for less/equal/greater */ compareDateOnlyTz(other, tz) { @@ -1002,8 +1004,8 @@ class Time { * Convert the instance into another timezone. The returned ICAL.Time * instance is always a copy. * - * @param {ICAL.Timezone} zone The zone to convert to - * @return {ICAL.Time} The copy, converted to the zone + * @param {Timezone} zone The zone to convert to + * @return {Time} The copy, converted to the zone */ convertToZone(zone) { let copy = this.clone(); diff --git a/lib/ical/timezone.js b/lib/ical/timezone.js index 176e1175..39c89c08 100644 --- a/lib/ical/timezone.js +++ b/lib/ical/timezone.js @@ -23,8 +23,7 @@ const OPTIONS = ["tzid", "location", "tznames", "latitude", "longitude"]; * tzid * }); * - * @class - * @alias ICAL.Timezone + * @memberof ICAL */ class Timezone { static _compare_change_fn(a, b) { @@ -52,10 +51,10 @@ class Timezone { /** * Convert the date/time from one zone to the next. * - * @param {ICAL.Time} tt The time to convert - * @param {ICAL.Timezone} from_zone The source zone to convert from - * @param {ICAL.Timezone} to_zone The target zone to convert to - * @return {ICAL.Time} The converted date/time object + * @param {Time} tt The time to convert + * @param {Timezone} from_zone The source zone to convert from + * @param {Timezone} to_zone The target zone to convert to + * @return {Time} The converted date/time object */ static convert_time(tt, from_zone, to_zone) { if (tt.isDate || @@ -78,8 +77,8 @@ class Timezone { /** * Creates a new ICAL.Timezone instance from the passed data object. * - * @param {ICAL.Component|Object} aData options for class - * @param {String|ICAL.Component} aData.component + * @param {Component|Object} aData options for class + * @param {String|Component} aData.component * If aData is a simple object, then this member can be set to either a * string containing the component data, or an already parsed * ICAL.Component @@ -153,8 +152,8 @@ class Timezone { /** * Creates a new ICAL.Timezone instance, by passing in a tzid and component. * - * @param {ICAL.Component|Object} data options for class - * @param {String|ICAL.Component} data.component + * @param {Component|Object} data options for class + * @param {String|Component} data.component * If data is a simple object, then this member can be set to either a * string containing the component data, or an already parsed * ICAL.Component @@ -227,8 +226,8 @@ class Timezone { /** * Sets up the current instance using members from the passed data object. * - * @param {ICAL.Component|Object} aData options for class - * @param {String|ICAL.Component} aData.component + * @param {Component|Object} aData options for class + * @param {String|Component} aData.component * If aData is a simple object, then this member can be set to either a * string containing the component data, or an already parsed * ICAL.Component @@ -282,8 +281,8 @@ class Timezone { /** * Finds the utcOffset the given time would occur in this timezone. * - * @param {ICAL.Time} tt The time to check for - * @return {Number} utc offset in seconds + * @param {Time} tt The time to check for + * @return {Number} utc offset in seconds */ utcOffset(tt) { if (this == Timezone.utcTimezone || this == Timezone.localTimezone) { diff --git a/lib/ical/timezone_service.js b/lib/ical/timezone_service.js index ef3ae6f0..06df6da7 100644 --- a/lib/ical/timezone_service.js +++ b/lib/ical/timezone_service.js @@ -15,7 +15,7 @@ let zones = null; * loading pre-expanded timezones. * * @exports module:ICAL.TimezoneService - * @alias ICAL.TimezoneService + * @memberof ICAL */ const TimezoneService = { get count() { @@ -56,7 +56,7 @@ const TimezoneService = { * Returns a timezone by its tzid if present. * * @param {String} tzid Timezone identifier (e.g. America/Los_Angeles) - * @return {?ICAL.Timezone} The timezone, or null if not found + * @return {?Timezone} The timezone, or null if not found */ get: function(tzid) { if (zones === null) { @@ -72,7 +72,7 @@ const TimezoneService = { * @param {String=} name * The name of the timezone. Defaults to the component's TZID if not * passed. - * @param {ICAL.Component|ICAL.Timezone} timezone + * @param {Component|Timezone} timezone * The initialized zone or vtimezone. */ register: function(name, timezone) { @@ -98,7 +98,7 @@ const TimezoneService = { * Removes a timezone by its tzid from the list. * * @param {String} tzid Timezone identifier (e.g. America/Los_Angeles) - * @return {?ICAL.Timezone} The removed timezone, or null if not registered + * @return {?Timezone} The removed timezone, or null if not registered */ remove: function(tzid) { if (zones === null) { diff --git a/lib/ical/utc_offset.js b/lib/ical/utc_offset.js index 726fc9d4..75806f57 100644 --- a/lib/ical/utc_offset.js +++ b/lib/ical/utc_offset.js @@ -4,21 +4,23 @@ * Portions Copyright (C) Philipp Kewisch */ import { strictParseInt, trunc, pad2 } from "./helpers.js"; +// needed for typescript type resolution +// eslint-disable-next-line no-unused-vars +import Duration from "./duration.js"; import design from "./design.js"; /** * This class represents the "utc-offset" value type, with various calculation and manipulation * methods. * - * @class - * @alias ICAL.UtcOffset + * @memberof ICAL */ class UtcOffset { /** * Creates a new {@link ICAL.UtcOffset} instance from the passed string. * * @param {String} aString The string to parse - * @return {ICAL.Duration} The created utc-offset instance + * @return {Duration} The created utc-offset instance */ static fromString(aString) { // -05:00 @@ -85,7 +87,7 @@ class UtcOffset { /** * Returns a clone of the utc offset object. * - * @return {ICAL.UtcOffset} The cloned object + * @return {UtcOffset} The cloned object */ clone() { return UtcOffset.fromSeconds(this.toSeconds()); @@ -138,7 +140,7 @@ class UtcOffset { /** * Compare this utc offset with another one. * - * @param {ICAL.UtcOffset} other The other offset to compare with + * @param {UtcOffset} other The other offset to compare with * @return {Number} -1, 0 or 1 for less/equal/greater */ compare(other) { diff --git a/lib/ical/vcard_time.js b/lib/ical/vcard_time.js index a122942f..85765b78 100644 --- a/lib/ical/vcard_time.js +++ b/lib/ical/vcard_time.js @@ -20,9 +20,8 @@ import { pad2, strictParseInt } from "./helpers.js"; * * Also, normalization is not yet implemented for this class! * - * @alias ICAL.VCardTime + * @memberof ICAL * @extends {ICAL.Time} - * @class */ class VCardTime extends Time { /** @@ -30,7 +29,7 @@ class VCardTime extends Time { * * @param {String} aValue The string to create from * @param {String} aIcalType The type for this instance, e.g. date-and-or-time - * @return {ICAL.VCardTime} The date/time instance + * @return {VCardTime} The date/time instance */ static fromDateAndOrTimeString(aValue, aIcalType) { function part(v, s, e) { @@ -79,7 +78,7 @@ class VCardTime extends Time { * @param {Number=} data.hour The hour for this date * @param {Number=} data.minute The minute for this date * @param {Number=} data.second The second for this date - * @param {ICAL.Timezone|ICAL.UtcOffset} zone The timezone to use + * @param {Timezone|UtcOffset} zone The timezone to use * @param {String} icaltype The type for this date/time object */ constructor(data, zone, icaltype) { @@ -105,7 +104,7 @@ class VCardTime extends Time { /** * Returns a clone of the vcard date/time object. * - * @return {ICAL.VCardTime} The cloned object + * @return {VCardTime} The cloned object */ clone() { return new VCardTime(this._time, this.zone, this.icaltype); From 094385419550b583840ae1453dc69f75161f63c1 Mon Sep 17 00:00:00 2001 From: jannikac Date: Thu, 23 May 2024 15:18:24 +0200 Subject: [PATCH 10/19] improve ts generation for everything that uses @types and complex @params or @returns --- lib/ical/event.js | 22 ++++++++++++---------- lib/ical/period.js | 6 +++--- lib/ical/property.js | 2 +- lib/ical/recur.js | 24 ++++++++++++------------ lib/ical/recur_expansion.js | 22 +++++++++++----------- lib/ical/recur_iterator.js | 10 +++++----- lib/ical/time.js | 24 ++++++++++++------------ lib/ical/timezone.js | 6 +++--- tools/jsdoc-ical.cjs | 36 ++++++++++++++++++++++++++++++------ 9 files changed, 89 insertions(+), 63 deletions(-) diff --git a/lib/ical/event.js b/lib/ical/event.js index ccd6a297..0f5561d3 100644 --- a/lib/ical/event.js +++ b/lib/ical/event.js @@ -10,6 +10,8 @@ import Timezone from "./timezone.js"; // needed for typescript type resolution // eslint-disable-next-line no-unused-vars import Time from "./time.js"; +// eslint-disable-next-line no-unused-vars +import Duration from "./duration.js"; import RecurExpansion from "./recur_expansion.js"; /** @@ -28,7 +30,7 @@ class Event { * @param {Object} options Options for this event * @param {Boolean} options.strictExceptions When true, will verify exceptions are related by * their UUID - * @param {Array} options.exceptions + * @param {Array} options.exceptions * Exceptions to this event, either as components or events. If not * specified exceptions will automatically be set in relation of * component's parent @@ -70,7 +72,7 @@ class Event { /** * List of related event exceptions. * - * @type {ICAL.Event[]} + * @type {Event[]} */ exceptions = null; @@ -199,7 +201,7 @@ class Event { * with the {@link ICAL.Event#iterator iterator} method. * * @param {Time} occurrence time occurrence - * @return {ICAL.Event.occurrenceDetails} Information about the occurrence + * @return {Event.occurrenceDetails} Information about the occurrence */ getOccurrenceDetails(occurrence) { let id = occurrence.toString(); @@ -319,7 +321,7 @@ class Event { * - MINUTELY * - SECONDLY * - * @return {Object.} + * @return {Object.} * Object of recurrence flags */ getRecurrenceTypes() { @@ -350,7 +352,7 @@ class Event { /** * The start date - * @type {ICAL.Time} + * @type {Time} */ get startDate() { return this._firstProp('dtstart'); @@ -364,7 +366,7 @@ class Event { * The end date. This can be the result directly from the property, or the * end date calculated from start date and duration. Setting the property * will remove any duration properties. - * @type {ICAL.Time} + * @type {Time} */ get endDate() { let endDate = this._firstProp('dtend'); @@ -391,7 +393,7 @@ class Event { * The duration. This can be the result directly from the property, or the * duration calculated from start date and end date. Setting the property * will remove any `dtend` properties. - * @type {ICAL.Duration} + * @type {Duration} */ get duration() { let duration = this._firstProp('duration'); @@ -423,7 +425,7 @@ class Event { /** * The attendees in the event - * @type {ICAL.Property[]} + * @type {Property[]} * @readonly */ get attendees() { @@ -496,7 +498,7 @@ class Event { /** * The recurrence id for this event. See {@tutorial terminology} for details. - * @type {ICAL.Time} + * @type {Time} */ get recurrenceId() { return this._firstProp('recurrence-id'); @@ -519,7 +521,7 @@ class Event { * leading to invalid ICAL data... * @private * @param {String} propName The property name - * @param {ICAL.Time} time The time to set + * @param {Time} time The time to set */ _setTime(propName, time) { let prop = this.component.getFirstProperty(propName); diff --git a/lib/ical/period.js b/lib/ical/period.js index 254170c0..b4c6b731 100644 --- a/lib/ical/period.js +++ b/lib/ical/period.js @@ -133,19 +133,19 @@ class Period { /** * The start of the period - * @type {ICAL.Time} + * @type {Time} */ start = null; /** * The end of the period - * @type {ICAL.Time} + * @type {Time} */ end = null; /** * The duration of the period - * @type {ICAL.Duration} + * @type {Duration} */ duration = null; diff --git a/lib/ical/property.js b/lib/ical/property.js index 3dabe8ab..3e894743 100644 --- a/lib/ical/property.js +++ b/lib/ical/property.js @@ -77,7 +77,7 @@ class Property { /** * The parent component for this property. - * @type {ICAL.Component} + * @type {Component} */ get parent() { return this._parent; diff --git a/lib/ical/recur.js b/lib/ical/recur.js index 54d11ece..eeef0a68 100644 --- a/lib/ical/recur.js +++ b/lib/ical/recur.js @@ -56,9 +56,9 @@ class Recur { * data object. * * @param {Object} aData An object with members of the recurrence - * @param {ICAL.Recur.frequencyValues=} aData.freq The frequency value + * @param {Recur.frequencyValues=} aData.freq The frequency value * @param {Number=} aData.interval The INTERVAL value - * @param {ICAL.Time.weekDay=} aData.wkst The week start value + * @param {Time.weekDay=} aData.wkst The week start value * @param {Time=} aData.until The end of the recurrence set * @param {Number=} aData.count The number of occurrences * @param {Array.=} aData.bysecond The seconds for the BYSECOND part @@ -83,7 +83,7 @@ class Recur { * @param {String} string The string to parse * @param {Boolean} fmtIcal If true, the string is considered to be an * iCalendar string - * @return {ICAL.Recur} The recurrence instance + * @return {Recur} The recurrence instance */ static _stringToData(string, fmtIcal) { let dict = Object.create(null); @@ -126,7 +126,7 @@ class Recur { * into a numeric value of that day. * * @param {String} string The iCalendar day name - * @param {ICAL.Time.weekDay=} aWeekStart + * @param {Time.weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY * @return {Number} Numeric value of given day */ @@ -141,7 +141,7 @@ class Recur { * Convert a numeric day value into its ical representation (SU, MO, etc..) * * @param {Number} num Numeric value of given day - * @param {ICAL.Time.weekDay=} aWeekStart + * @param {Time.weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY * @return {String} The ICAL day value, e.g SU,MO,... */ @@ -161,9 +161,9 @@ class Recur { * Create a new instance of the Recur class. * * @param {Object} data An object with members of the recurrence - * @param {ICAL.Recur.frequencyValues=} data.freq The frequency value + * @param {Recur.frequencyValues=} data.freq The frequency value * @param {Number=} data.interval The INTERVAL value - * @param {ICAL.Time.weekDay=} data.wkst The week start value + * @param {Time.weekDay=} data.wkst The week start value * @param {Time=} data.until The end of the recurrence set * @param {Number=} data.count The number of occurrences * @param {Array.=} data.bysecond The seconds for the BYSECOND part @@ -200,14 +200,14 @@ class Recur { /** * The week start day * - * @type {ICAL.Time.weekDay} + * @type {Time.weekDay} * @default ICAL.Time.MONDAY */ wkst = Time.MONDAY; /** * The end of the recurrence - * @type {?ICAL.Time} + * @type {?Time} */ until = null; @@ -219,7 +219,7 @@ class Recur { /** * The frequency value. - * @type {ICAL.Recur.frequencyValues} + * @type {Recur.frequencyValues} */ freq = null; @@ -364,9 +364,9 @@ class Recur { * Sets up the current instance using members from the passed data object. * * @param {Object} data An object with members of the recurrence - * @param {ICAL.Recur.frequencyValues=} data.freq The frequency value + * @param {Recur.frequencyValues=} data.freq The frequency value * @param {Number=} data.interval The INTERVAL value - * @param {ICAL.Time.weekDay=} data.wkst The week start value + * @param {Time.weekDay=} data.wkst The week start value * @param {Time=} data.until The end of the recurrence set * @param {Number=} data.count The number of occurrences * @param {Array.=} data.bysecond The seconds for the BYSECOND part diff --git a/lib/ical/recur_expansion.js b/lib/ical/recur_expansion.js index db259172..7c2db678 100644 --- a/lib/ical/recur_expansion.js +++ b/lib/ical/recur_expansion.js @@ -80,7 +80,7 @@ class RecurExpansion { /** * Array of rrule iterators. * - * @type {ICAL.RecurIterator[]} + * @type {RecurIterator[]} * @private */ ruleIterators = null; @@ -88,7 +88,7 @@ class RecurExpansion { /** * Array of rdate instances. * - * @type {ICAL.Time[]} + * @type {Time[]} * @private */ ruleDates = null; @@ -96,7 +96,7 @@ class RecurExpansion { /** * Array of exdate instances. * - * @type {ICAL.Time[]} + * @type {Time[]} * @private */ exDates = null; @@ -118,7 +118,7 @@ class RecurExpansion { /** * Current negative date. * - * @type {ICAL.Time} + * @type {Time} * @private */ exDate = null; @@ -126,7 +126,7 @@ class RecurExpansion { /** * Current additional date. * - * @type {ICAL.Time} + * @type {Time} * @private */ ruleDate = null; @@ -134,14 +134,14 @@ class RecurExpansion { /** * Start date of recurring rules. * - * @type {ICAL.Time} + * @type {Time} */ dtstart = null; /** * Last expanded time * - * @type {ICAL.Time} + * @type {Time} */ last = null; @@ -305,9 +305,9 @@ class RecurExpansion { * properties will be filtered by the property name. * * @private - * @param {ICAL.Component} component The component to search in + * @param {Component} component The component to search in * @param {String} propertyName The property name to search for - * @return {ICAL.Time[]} The extracted dates. + * @return {Time[]} The extracted dates. */ _extractDates(component, propertyName) { let result = []; @@ -333,7 +333,7 @@ class RecurExpansion { * Initialize the recurrence expansion. * * @private - * @param {ICAL.Component} component The component to initialize from. + * @param {Component} component The component to initialize from. */ _init(component) { this.ruleIterators = []; @@ -428,7 +428,7 @@ class RecurExpansion { * return it. * * @private - * @return {?ICAL.RecurIterator} Found iterator. + * @return {?RecurIterator} Found iterator. */ _nextRecurrenceIter() { let iters = this.ruleIterators; diff --git a/lib/ical/recur_iterator.js b/lib/ical/recur_iterator.js index 543c5d7e..a5014e98 100644 --- a/lib/ical/recur_iterator.js +++ b/lib/ical/recur_iterator.js @@ -64,20 +64,20 @@ class RecurIterator { /** * The rule that is being iterated - * @type {ICAL.Recur} + * @type {Recur} */ rule = null; /** * The start date of the event being iterated. - * @type {ICAL.Time} + * @type {Time} */ dtstart = null; /** * The last occurrence that was returned from the - * {@link ICAL.RecurIterator#next} method. - * @type {ICAL.Time} + * {@link RecurIterator#next} method. + * @type {Time} */ last = null; @@ -907,7 +907,7 @@ class RecurIterator { /** * @param dow (eg: '1TU', '-1MO') - * @param {ICAL.Time.weekDay=} aWeekStart The week start weekday + * @param {Time.weekDay=} aWeekStart The week start weekday * @return [pos, numericDow] (eg: [1, 3]) numericDow is relative to aWeekStart */ ruleDayOfWeek(dow, aWeekStart) { diff --git a/lib/ical/time.js b/lib/ical/time.js index 1a4f1fd4..bba1f73c 100644 --- a/lib/ical/time.js +++ b/lib/ical/time.js @@ -267,9 +267,9 @@ class Time { /** * Returns the date on which ISO week number 1 starts. * - * @see ICAL.Time#weekNumber + * @see Time#weekNumber * @param {Number} aYear The year to search in - * @param {ICAL.Time.weekDay=} aWeekStart The week start weekday, used for calculation. + * @param {Time.weekDay=} aWeekStart The week start weekday, used for calculation. * @return {Time} The date on which week number 1 starts */ static weekOneStarts(aYear, aWeekStart) { @@ -315,7 +315,7 @@ class Time { static #epochTime = null; /** * January 1st, 1970 as an ICAL.Time. - * @type {ICAL.Time} + * @type {Time} * @constant * @instance */ @@ -430,7 +430,7 @@ class Time { /** * The timezone for this time. - * @type {ICAL.Timezone} + * @type {Timezone} */ zone = null; @@ -571,9 +571,9 @@ class Time { /** * Calculate the day of week. - * @param {ICAL.Time.weekDay=} aWeekStart + * @param {Time.weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY - * @return {ICAL.Time.weekDay} + * @return {Time.weekDay} */ dayOfWeek(aWeekStart) { let firstDow = aWeekStart || Time.SUNDAY; @@ -616,7 +616,7 @@ class Time { * week. The resulting ICAL.Time instance is of icaltype date, even if this * is a date-time. * - * @param {ICAL.Time.weekDay=} aWeekStart + * @param {Time.weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY * @return {Time} The start of the week (cloned) */ @@ -636,7 +636,7 @@ class Time { * The resulting ICAL.Time instance is of icaltype date, even if this is a * date-time. * - * @param {ICAL.Time.weekDay=} aWeekStart + * @param {Time.weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY * @return {Time} The end of the week (cloned) */ @@ -725,7 +725,7 @@ class Time { * First calculates the start of the week, then returns the day of year for * this date. If the day falls into the previous year, the day is zero or negative. * - * @param {ICAL.Time.weekDay=} aFirstDayOfWeek + * @param {Time.weekDay=} aFirstDayOfWeek * The week start weekday, defaults to SUNDAY * @return {Number} The calculated day of year */ @@ -839,7 +839,7 @@ class Time { * month. Will always return false when rule resolves outside of current * month. * - * @param {ICAL.Time.weekDay} aDayOfWeek Day of week to check + * @param {Time.weekDay} aDayOfWeek Day of week to check * @param {Number} aPos Relative position * @return {Boolean} True, if it is the nth weekday */ @@ -870,8 +870,8 @@ class Time { * different week start is specified, this will also affect the week * number. * - * @see ICAL.Time.weekOneStarts - * @param {ICAL.Time.weekDay} aWeekStart The weekday the week starts with + * @see Time.weekOneStarts + * @param {Time.weekDay} aWeekStart The weekday the week starts with * @return {Number} The ISO week number */ weekNumber(aWeekStart) { diff --git a/lib/ical/timezone.js b/lib/ical/timezone.js index 39c89c08..a59c2165 100644 --- a/lib/ical/timezone.js +++ b/lib/ical/timezone.js @@ -96,7 +96,7 @@ class Timezone { /** * The instance describing the UTC timezone - * @type {ICAL.Timezone} + * @type {Timezone} * @constant * @instance */ @@ -112,7 +112,7 @@ class Timezone { /** * The instance describing the local timezone - * @type {ICAL.Timezone} + * @type {Timezone} * @constant * @instance */ @@ -202,7 +202,7 @@ class Timezone { /** * The vtimezone component for this timezone. - * @type {ICAL.Component} + * @type {Component} */ component = null; diff --git a/tools/jsdoc-ical.cjs b/tools/jsdoc-ical.cjs index 331fa9c5..1e7c141e 100644 --- a/tools/jsdoc-ical.cjs +++ b/tools/jsdoc-ical.cjs @@ -3,24 +3,48 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Portions Copyright (C) Philipp Kewisch, 2024 */ -let gIcalClasses = new Set(); +let gIcalClasses = new Set(["Binary", "Component", "ComponentParser", "Duration", "Event", "Period", "Property", "Recur", "RecurExpansion", "RecurIterator", "Time", "Timezone", "UtcOffset", "VCardTime", "ParserError"]); -function augmentTypes(obj) { - if (obj.type?.names?.length) { - for (let i = 0; i < obj.type.names.length; i++) { - if (gIcalClasses.has(obj.type.names[i]) && !obj.type.names[i].startsWith("ICAL.")) { - obj.type.names[i] = "ICAL." + obj.type.names[i]; +function addPrefix(objNames) { + if (objNames?.length) { + for (let i = 0; i < objNames.length; i++) { + // finds all strings in objNames[i] that include a known class + let classNames = Array.from(gIcalClasses).reduce((acc, curr) => { + if (objNames[i].includes(curr)) acc = [...acc, curr]; + return acc; + }, []); + if ((gIcalClasses.has(objNames[i]) || classNames.length !== 0) && !objNames[i].includes("ICAL.")) { + for (let className of classNames) { + let index = objNames[i].indexOf(className); + // add ICAL. to classnames without ICAL. + objNames[i] = objNames[i].substring(0, index) + "ICAL." + objNames[i].substring(index); + } } } } } +function augmentTypes(obj) { + // handle @type + if (obj.names?.length) { + addPrefix(obj.names); + } + // handle @returns or @params + if (obj.type?.names?.length) { + addPrefix(obj.type?.names); + } +} + exports.handlers = { newDoclet: function({ doclet }) { if (doclet.kind == "class" && doclet.longname.startsWith("ICAL.")) { gIcalClasses.add(doclet.name); } + if (doclet.type) { + augmentTypes(doclet.type); + } + if (doclet.returns) { for (let ret of doclet.returns) { augmentTypes(ret); From 917ba5ec964f9c2c5cb3eb684dd8ce248460e4d4 Mon Sep 17 00:00:00 2001 From: jannikac Date: Tue, 28 May 2024 17:48:43 +0200 Subject: [PATCH 11/19] move `@typedefs` to types.d.js to allow for importing and resolving via ts --- lib/ical/event.js | 12 +----------- lib/ical/recur.js | 9 +-------- lib/ical/recur_iterator.js | 1 + lib/ical/time.js | 9 +-------- lib/ical/types.d.js | 25 +++++++++++++++++++++++++ 5 files changed, 29 insertions(+), 27 deletions(-) create mode 100644 lib/ical/types.d.js diff --git a/lib/ical/event.js b/lib/ical/event.js index 0f5561d3..c6a8891e 100644 --- a/lib/ical/event.js +++ b/lib/ical/event.js @@ -13,6 +13,7 @@ import Time from "./time.js"; // eslint-disable-next-line no-unused-vars import Duration from "./duration.js"; import RecurExpansion from "./recur_expansion.js"; +import "./types.d.js"; /** * ICAL.js is organized into multiple layers. The bottom layer is a raw jCal @@ -182,17 +183,6 @@ class Event { return rangeItem[1]; } - /** - * This object is returned by {@link ICAL.Event#getOccurrenceDetails getOccurrenceDetails} - * - * @typedef {Object} occurrenceDetails - * @memberof ICAL.Event - * @property {ICAL.Time} recurrenceId The passed in recurrence id - * @property {ICAL.Event} item The occurrence - * @property {ICAL.Time} startDate The start of the occurrence - * @property {ICAL.Time} endDate The end of the occurrence - */ - /** * Returns the occurrence details based on its start time. If the * occurrence has an exception will return the details for that exception. diff --git a/lib/ical/recur.js b/lib/ical/recur.js index eeef0a68..8231be1a 100644 --- a/lib/ical/recur.js +++ b/lib/ical/recur.js @@ -7,6 +7,7 @@ import RecurIterator from "./recur_iterator.js"; import Time from "./time.js"; import design from "./design.js"; import { strictParseInt, clone } from "./helpers.js"; +import "./types.d.js"; const VALID_DAY_NAMES = /^(SU|MO|TU|WE|TH|FR|SA)$/; const VALID_BYDAY_PART = /^([+-])?(5[0-3]|[1-4][0-9]|[1-9])?(SU|MO|TU|WE|TH|FR|SA)$/; @@ -22,14 +23,6 @@ const DOW_MAP = { const REVERSE_DOW_MAP = Object.fromEntries(Object.entries(DOW_MAP).map(entry => entry.reverse())); -/** - * Possible frequency values for the FREQ part - * (YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY) - * - * @typedef {String} frequencyValues - * @memberof ICAL.Recur - */ - const ALLOWED_FREQ = ['SECONDLY', 'MINUTELY', 'HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY']; diff --git a/lib/ical/recur_iterator.js b/lib/ical/recur_iterator.js index a5014e98..45abfab6 100644 --- a/lib/ical/recur_iterator.js +++ b/lib/ical/recur_iterator.js @@ -6,6 +6,7 @@ import { formatClassType, clone, trunc } from "./helpers.js"; import Recur from "./recur.js"; import Time from "./time.js"; +import "./types.d.js"; /** * An iterator for a single recurrence rule. This class usually doesn't have to be instanciated diff --git a/lib/ical/time.js b/lib/ical/time.js index bba1f73c..2e3d3761 100644 --- a/lib/ical/time.js +++ b/lib/ical/time.js @@ -11,6 +11,7 @@ import design from "./design.js"; import Property from "./property.js"; import TimezoneService from "./timezone_service.js"; import { strictParseInt, trunc, pad2 } from "./helpers.js"; +import "./types.d.js"; /** * @classdesc @@ -355,14 +356,6 @@ class Time { [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366] ]; - /** - * The weekday, 1 = SUNDAY, 7 = SATURDAY. Access via - * ICAL.Time.MONDAY, ICAL.Time.TUESDAY, ... - * - * @typedef {Number} weekDay - * @memberof ICAL.Time - */ - static SUNDAY = 1; static MONDAY = 2; static TUESDAY = 3; diff --git a/lib/ical/types.d.js b/lib/ical/types.d.js new file mode 100644 index 00000000..710a9576 --- /dev/null +++ b/lib/ical/types.d.js @@ -0,0 +1,25 @@ +/** + * The weekday, 1 = SUNDAY, 7 = SATURDAY. Access via + * ICAL.Time.MONDAY, ICAL.Time.TUESDAY, ... + * + * @typedef {Number} weekDay + * @memberof ICAL.Time + */ + +/** + * Possible frequency values for the FREQ part + * (YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY) + * + * @typedef {String} frequencyValues + * @memberof ICAL.Recur + */ + +/** + * This object is returned by {@link ICAL.Event#getOccurrenceDetails getOccurrenceDetails} + * @memberof ICAL.Event + * @typedef {Object} occurrenceDetails + * @property {ICAL.Time} recurrenceId The passed in recurrence id + * @property {ICAL.Event} item The occurrence + * @property {ICAL.Time} startDate The start of the occurrence + * @property {ICAL.Time} endDate The end of the occurrence + */ From ce1d2d702c04af592ee41a8df632a170933381f7 Mon Sep 17 00:00:00 2001 From: jannikac Date: Tue, 28 May 2024 17:50:32 +0200 Subject: [PATCH 12/19] drop prefix for typdef'd types and hack plugin to allow links to work --- lib/ical/event.js | 4 ++-- lib/ical/recur.js | 20 ++++++++++---------- lib/ical/recur_iterator.js | 2 +- lib/ical/time.js | 16 ++++++++-------- tools/jsdoc-ical.cjs | 12 +++++++++++- 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/lib/ical/event.js b/lib/ical/event.js index c6a8891e..e8397068 100644 --- a/lib/ical/event.js +++ b/lib/ical/event.js @@ -191,7 +191,7 @@ class Event { * with the {@link ICAL.Event#iterator iterator} method. * * @param {Time} occurrence time occurrence - * @return {Event.occurrenceDetails} Information about the occurrence + * @return {occurrenceDetails} Information about the occurrence */ getOccurrenceDetails(occurrence) { let id = occurrence.toString(); @@ -311,7 +311,7 @@ class Event { * - MINUTELY * - SECONDLY * - * @return {Object.} + * @return {Object.} * Object of recurrence flags */ getRecurrenceTypes() { diff --git a/lib/ical/recur.js b/lib/ical/recur.js index 8231be1a..a7878103 100644 --- a/lib/ical/recur.js +++ b/lib/ical/recur.js @@ -49,9 +49,9 @@ class Recur { * data object. * * @param {Object} aData An object with members of the recurrence - * @param {Recur.frequencyValues=} aData.freq The frequency value + * @param {frequencyValues=} aData.freq The frequency value * @param {Number=} aData.interval The INTERVAL value - * @param {Time.weekDay=} aData.wkst The week start value + * @param {weekDay=} aData.wkst The week start value * @param {Time=} aData.until The end of the recurrence set * @param {Number=} aData.count The number of occurrences * @param {Array.=} aData.bysecond The seconds for the BYSECOND part @@ -119,7 +119,7 @@ class Recur { * into a numeric value of that day. * * @param {String} string The iCalendar day name - * @param {Time.weekDay=} aWeekStart + * @param {weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY * @return {Number} Numeric value of given day */ @@ -134,7 +134,7 @@ class Recur { * Convert a numeric day value into its ical representation (SU, MO, etc..) * * @param {Number} num Numeric value of given day - * @param {Time.weekDay=} aWeekStart + * @param {weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY * @return {String} The ICAL day value, e.g SU,MO,... */ @@ -154,9 +154,9 @@ class Recur { * Create a new instance of the Recur class. * * @param {Object} data An object with members of the recurrence - * @param {Recur.frequencyValues=} data.freq The frequency value + * @param {frequencyValues=} data.freq The frequency value * @param {Number=} data.interval The INTERVAL value - * @param {Time.weekDay=} data.wkst The week start value + * @param {weekDay=} data.wkst The week start value * @param {Time=} data.until The end of the recurrence set * @param {Number=} data.count The number of occurrences * @param {Array.=} data.bysecond The seconds for the BYSECOND part @@ -193,7 +193,7 @@ class Recur { /** * The week start day * - * @type {Time.weekDay} + * @type {weekDay} * @default ICAL.Time.MONDAY */ wkst = Time.MONDAY; @@ -212,7 +212,7 @@ class Recur { /** * The frequency value. - * @type {Recur.frequencyValues} + * @type {frequencyValues} */ freq = null; @@ -357,9 +357,9 @@ class Recur { * Sets up the current instance using members from the passed data object. * * @param {Object} data An object with members of the recurrence - * @param {Recur.frequencyValues=} data.freq The frequency value + * @param {frequencyValues=} data.freq The frequency value * @param {Number=} data.interval The INTERVAL value - * @param {Time.weekDay=} data.wkst The week start value + * @param {weekDay=} data.wkst The week start value * @param {Time=} data.until The end of the recurrence set * @param {Number=} data.count The number of occurrences * @param {Array.=} data.bysecond The seconds for the BYSECOND part diff --git a/lib/ical/recur_iterator.js b/lib/ical/recur_iterator.js index 45abfab6..f6e2e5ab 100644 --- a/lib/ical/recur_iterator.js +++ b/lib/ical/recur_iterator.js @@ -908,7 +908,7 @@ class RecurIterator { /** * @param dow (eg: '1TU', '-1MO') - * @param {Time.weekDay=} aWeekStart The week start weekday + * @param {weekDay=} aWeekStart The week start weekday * @return [pos, numericDow] (eg: [1, 3]) numericDow is relative to aWeekStart */ ruleDayOfWeek(dow, aWeekStart) { diff --git a/lib/ical/time.js b/lib/ical/time.js index 2e3d3761..71c618ee 100644 --- a/lib/ical/time.js +++ b/lib/ical/time.js @@ -270,7 +270,7 @@ class Time { * * @see Time#weekNumber * @param {Number} aYear The year to search in - * @param {Time.weekDay=} aWeekStart The week start weekday, used for calculation. + * @param {weekDay=} aWeekStart The week start weekday, used for calculation. * @return {Time} The date on which week number 1 starts */ static weekOneStarts(aYear, aWeekStart) { @@ -564,9 +564,9 @@ class Time { /** * Calculate the day of week. - * @param {Time.weekDay=} aWeekStart + * @param {weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY - * @return {Time.weekDay} + * @return {weekDay} */ dayOfWeek(aWeekStart) { let firstDow = aWeekStart || Time.SUNDAY; @@ -609,7 +609,7 @@ class Time { * week. The resulting ICAL.Time instance is of icaltype date, even if this * is a date-time. * - * @param {Time.weekDay=} aWeekStart + * @param {weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY * @return {Time} The start of the week (cloned) */ @@ -629,7 +629,7 @@ class Time { * The resulting ICAL.Time instance is of icaltype date, even if this is a * date-time. * - * @param {Time.weekDay=} aWeekStart + * @param {weekDay=} aWeekStart * The week start weekday, defaults to SUNDAY * @return {Time} The end of the week (cloned) */ @@ -718,7 +718,7 @@ class Time { * First calculates the start of the week, then returns the day of year for * this date. If the day falls into the previous year, the day is zero or negative. * - * @param {Time.weekDay=} aFirstDayOfWeek + * @param {weekDay=} aFirstDayOfWeek * The week start weekday, defaults to SUNDAY * @return {Number} The calculated day of year */ @@ -832,7 +832,7 @@ class Time { * month. Will always return false when rule resolves outside of current * month. * - * @param {Time.weekDay} aDayOfWeek Day of week to check + * @param {weekDay} aDayOfWeek Day of week to check * @param {Number} aPos Relative position * @return {Boolean} True, if it is the nth weekday */ @@ -864,7 +864,7 @@ class Time { * number. * * @see Time.weekOneStarts - * @param {Time.weekDay} aWeekStart The weekday the week starts with + * @param {weekDay} aWeekStart The weekday the week starts with * @return {Number} The ISO week number */ weekNumber(aWeekStart) { diff --git a/tools/jsdoc-ical.cjs b/tools/jsdoc-ical.cjs index 1e7c141e..3e4cdbfe 100644 --- a/tools/jsdoc-ical.cjs +++ b/tools/jsdoc-ical.cjs @@ -4,13 +4,16 @@ * Portions Copyright (C) Philipp Kewisch, 2024 */ let gIcalClasses = new Set(["Binary", "Component", "ComponentParser", "Duration", "Event", "Period", "Property", "Recur", "RecurExpansion", "RecurIterator", "Time", "Timezone", "UtcOffset", "VCardTime", "ParserError"]); +let typedefs = [{ name: "occurrenceDetails", full: "ICAL.Event.occurrenceDetails" }, + { name: "frequencyValues", full: "ICAL.Recur.frequencyValues" }, + { name: "weekDay", full: "ICAL.Time.weekDay" }]; function addPrefix(objNames) { if (objNames?.length) { for (let i = 0; i < objNames.length; i++) { // finds all strings in objNames[i] that include a known class let classNames = Array.from(gIcalClasses).reduce((acc, curr) => { - if (objNames[i].includes(curr)) acc = [...acc, curr]; + if (objNames[i] === curr) acc = [...acc, curr]; return acc; }, []); if ((gIcalClasses.has(objNames[i]) || classNames.length !== 0) && !objNames[i].includes("ICAL.")) { @@ -20,6 +23,13 @@ function addPrefix(objNames) { objNames[i] = objNames[i].substring(0, index) + "ICAL." + objNames[i].substring(index); } } + // add correct typedef path to anything using a known typedef + let typedef = typedefs.find((val) => objNames[i].includes(val.name)); + if (typedef !== undefined) { + // replace partial name with full path + let result = objNames[i].replace(typedef.name, typedef.full); + objNames[i] = result; + } } } } From fa3074b63dc0910ce5b1a0b319cf7e22dd3ebd1d Mon Sep 17 00:00:00 2001 From: jannikac Date: Wed, 29 May 2024 10:08:37 +0200 Subject: [PATCH 13/19] changed bare import to import type syntax and added plugin to fix jsdoc compatibility --- jsdoc.json | 2 +- lib/ical/event.js | 6 +++++- lib/ical/recur.js | 6 +++++- lib/ical/recur_iterator.js | 5 ++++- lib/ical/time.js | 5 ++++- lib/ical/types.d.js | 2 ++ package-lock.json | 7 +++++++ package.json | 1 + 8 files changed, 29 insertions(+), 5 deletions(-) diff --git a/jsdoc.json b/jsdoc.json index 55e10064..fdb0a6fa 100644 --- a/jsdoc.json +++ b/jsdoc.json @@ -3,7 +3,7 @@ "include": "lib/ical", "includePattern": ".js$" }, - "plugins": ["plugins/markdown", "tools/jsdoc-ical.cjs"], + "plugins": ["plugins/markdown", "tools/jsdoc-ical.cjs", "node_modules/jsdoc-tsimport-plugin/index.js"], "opts": { "encoding": "utf8", "readme": "README.md", diff --git a/lib/ical/event.js b/lib/ical/event.js index e8397068..439183b8 100644 --- a/lib/ical/event.js +++ b/lib/ical/event.js @@ -13,7 +13,11 @@ import Time from "./time.js"; // eslint-disable-next-line no-unused-vars import Duration from "./duration.js"; import RecurExpansion from "./recur_expansion.js"; -import "./types.d.js"; + +/** + * @typedef {import("./types.d.js").frequencyValues} frequencyValues + * @typedef {import("./types.d.js").occurrenceDetails} occurrenceDetails + */ /** * ICAL.js is organized into multiple layers. The bottom layer is a raw jCal diff --git a/lib/ical/recur.js b/lib/ical/recur.js index a7878103..8bacf1a5 100644 --- a/lib/ical/recur.js +++ b/lib/ical/recur.js @@ -7,7 +7,11 @@ import RecurIterator from "./recur_iterator.js"; import Time from "./time.js"; import design from "./design.js"; import { strictParseInt, clone } from "./helpers.js"; -import "./types.d.js"; + +/** + * @typedef {import("./types.d.js").weekDay} weekDay + * @typedef {import("./types.d.js").frequencyValues} frequencyValues + */ const VALID_DAY_NAMES = /^(SU|MO|TU|WE|TH|FR|SA)$/; const VALID_BYDAY_PART = /^([+-])?(5[0-3]|[1-4][0-9]|[1-9])?(SU|MO|TU|WE|TH|FR|SA)$/; diff --git a/lib/ical/recur_iterator.js b/lib/ical/recur_iterator.js index f6e2e5ab..b7b65efa 100644 --- a/lib/ical/recur_iterator.js +++ b/lib/ical/recur_iterator.js @@ -6,7 +6,10 @@ import { formatClassType, clone, trunc } from "./helpers.js"; import Recur from "./recur.js"; import Time from "./time.js"; -import "./types.d.js"; + +/** + * @typedef {import("./types.d.js").weekDay} weekDay + */ /** * An iterator for a single recurrence rule. This class usually doesn't have to be instanciated diff --git a/lib/ical/time.js b/lib/ical/time.js index 71c618ee..fb96efa1 100644 --- a/lib/ical/time.js +++ b/lib/ical/time.js @@ -11,7 +11,10 @@ import design from "./design.js"; import Property from "./property.js"; import TimezoneService from "./timezone_service.js"; import { strictParseInt, trunc, pad2 } from "./helpers.js"; -import "./types.d.js"; + +/** + * @typedef {import("./types.d.js").weekDay} weekDay + */ /** * @classdesc diff --git a/lib/ical/types.d.js b/lib/ical/types.d.js index 710a9576..007c0df6 100644 --- a/lib/ical/types.d.js +++ b/lib/ical/types.d.js @@ -23,3 +23,5 @@ * @property {ICAL.Time} startDate The start of the occurrence * @property {ICAL.Time} endDate The end of the occurrence */ + +export const _ = {}; diff --git a/package-lock.json b/package-lock.json index 379063c3..5171a01b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "eslint-plugin-html": "^8.1.1", "globals": "^15.0.0", "jsdoc": "^4.0.2", + "jsdoc-tsimport-plugin": "^1.0.5", "karma": "^6.4.3", "karma-chai": "^0.1.0", "karma-mocha": "^2.0.1", @@ -7236,6 +7237,12 @@ "node": ">=12.0.0" } }, + "node_modules/jsdoc-tsimport-plugin": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/jsdoc-tsimport-plugin/-/jsdoc-tsimport-plugin-1.0.5.tgz", + "integrity": "sha512-6mvyF+tXdanf3zxEumTF9Uf/sXGlANP+XohSuiJiOVVWPGxi+3f2a2sy5Ew3W+0PMYUkcGYNxfYd5mMZsIHQpg==", + "dev": true + }, "node_modules/jsdoc/node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", diff --git a/package.json b/package.json index fa34b56c..5d8acd48 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "eslint-plugin-html": "^8.1.1", "globals": "^15.0.0", "jsdoc": "^4.0.2", + "jsdoc-tsimport-plugin": "^1.0.5", "karma": "^6.4.3", "karma-chai": "^0.1.0", "karma-mocha": "^2.0.1", From 2cb2c592c24206c1c195027f4fe6aed1a49bceaf Mon Sep 17 00:00:00 2001 From: jannikac Date: Wed, 29 May 2024 10:23:41 +0200 Subject: [PATCH 14/19] added `@ignore` to imports so they are not documented in the generated docs --- lib/ical/event.js | 1 + lib/ical/recur.js | 1 + lib/ical/recur_iterator.js | 1 + lib/ical/time.js | 1 + 4 files changed, 4 insertions(+) diff --git a/lib/ical/event.js b/lib/ical/event.js index 439183b8..9c17d2e2 100644 --- a/lib/ical/event.js +++ b/lib/ical/event.js @@ -15,6 +15,7 @@ import Duration from "./duration.js"; import RecurExpansion from "./recur_expansion.js"; /** + * @ignore * @typedef {import("./types.d.js").frequencyValues} frequencyValues * @typedef {import("./types.d.js").occurrenceDetails} occurrenceDetails */ diff --git a/lib/ical/recur.js b/lib/ical/recur.js index 8bacf1a5..66f08ab0 100644 --- a/lib/ical/recur.js +++ b/lib/ical/recur.js @@ -9,6 +9,7 @@ import design from "./design.js"; import { strictParseInt, clone } from "./helpers.js"; /** + * @ignore * @typedef {import("./types.d.js").weekDay} weekDay * @typedef {import("./types.d.js").frequencyValues} frequencyValues */ diff --git a/lib/ical/recur_iterator.js b/lib/ical/recur_iterator.js index b7b65efa..97ea418e 100644 --- a/lib/ical/recur_iterator.js +++ b/lib/ical/recur_iterator.js @@ -8,6 +8,7 @@ import Recur from "./recur.js"; import Time from "./time.js"; /** + * @ignore * @typedef {import("./types.d.js").weekDay} weekDay */ diff --git a/lib/ical/time.js b/lib/ical/time.js index fb96efa1..2fe79bad 100644 --- a/lib/ical/time.js +++ b/lib/ical/time.js @@ -13,6 +13,7 @@ import TimezoneService from "./timezone_service.js"; import { strictParseInt, trunc, pad2 } from "./helpers.js"; /** + * @ignore * @typedef {import("./types.d.js").weekDay} weekDay */ From 5a19e4ce0a697e9c377573194c56041e8e3910ca Mon Sep 17 00:00:00 2001 From: jannikac Date: Wed, 29 May 2024 11:31:42 +0200 Subject: [PATCH 15/19] removed last `ICAL.` reference for consistency --- lib/ical/parse.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/ical/parse.js b/lib/ical/parse.js index a42f547a..e3cf4a64 100644 --- a/lib/ical/parse.js +++ b/lib/ical/parse.js @@ -4,6 +4,9 @@ * Portions Copyright (C) Philipp Kewisch */ import design from "./design.js"; +// needed for typescript type resolution +// eslint-disable-next-line no-unused-vars +import Component from "./component.js"; import { unescapedIndexOf } from "./helpers.js"; const CHAR = /[^ \t]/; @@ -106,8 +109,8 @@ parse.ParserError = ParserError; * @memberof ICAL.parse * @typedef {Object} parserState * @property {ICAL.design.designSet} designSet The design set to use for parsing - * @property {ICAL.Component[]} stack The stack of components being processed - * @property {ICAL.Component} component The currently active component + * @property {Component[]} stack The stack of components being processed + * @property {Component} component The currently active component */ From a184851132488d7710693ba97dc205c6673dcf8e Mon Sep 17 00:00:00 2001 From: jannikac Date: Wed, 29 May 2024 11:32:45 +0200 Subject: [PATCH 16/19] added `jsdoc-collect-types.cjs` plugin to collect classnames and typedefs for the `jsdoc-ical.cjs` plugin --- .gitignore | 1 + jsdoc.json | 2 +- tools/jsdoc-collect-types.cjs | 15 +++++++++++++++ tools/jsdoc-ical.cjs | 14 ++++---------- 4 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 tools/jsdoc-collect-types.cjs diff --git a/.gitignore b/.gitignore index 795af590..5f0c98e6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ tools/vzic/ tools/tzdb/ tools/libical/ coverage/ +temp.json diff --git a/jsdoc.json b/jsdoc.json index fdb0a6fa..de785eb5 100644 --- a/jsdoc.json +++ b/jsdoc.json @@ -3,7 +3,7 @@ "include": "lib/ical", "includePattern": ".js$" }, - "plugins": ["plugins/markdown", "tools/jsdoc-ical.cjs", "node_modules/jsdoc-tsimport-plugin/index.js"], + "plugins": ["plugins/markdown", "tools/jsdoc-collect-types.cjs", "tools/jsdoc-ical.cjs", "node_modules/jsdoc-tsimport-plugin/index.js"], "opts": { "encoding": "utf8", "readme": "README.md", diff --git a/tools/jsdoc-collect-types.cjs b/tools/jsdoc-collect-types.cjs new file mode 100644 index 00000000..fbc363ca --- /dev/null +++ b/tools/jsdoc-collect-types.cjs @@ -0,0 +1,15 @@ +const fs = require("node:fs"); +let gIcalClasses = new Set(); +let typedefs = new Set(); + +exports.handlers = { + newDoclet: function({ doclet }) { + if (doclet.kind == "class" && doclet.longname.startsWith("ICAL.")) { + gIcalClasses.add(doclet.name); + } + if (doclet.kind === "typedef" && doclet.scope === "static" && doclet.longname.startsWith("ICAL.")) { + typedefs.add({name: doclet.name, full: doclet.longname}) + } + fs.writeFileSync("./temp.json", JSON.stringify({gIcalClasses: Array.from(gIcalClasses), typedefs: Array.from(typedefs)})); + } +}; \ No newline at end of file diff --git a/tools/jsdoc-ical.cjs b/tools/jsdoc-ical.cjs index 3e4cdbfe..51417c08 100644 --- a/tools/jsdoc-ical.cjs +++ b/tools/jsdoc-ical.cjs @@ -3,20 +3,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Portions Copyright (C) Philipp Kewisch, 2024 */ -let gIcalClasses = new Set(["Binary", "Component", "ComponentParser", "Duration", "Event", "Period", "Property", "Recur", "RecurExpansion", "RecurIterator", "Time", "Timezone", "UtcOffset", "VCardTime", "ParserError"]); -let typedefs = [{ name: "occurrenceDetails", full: "ICAL.Event.occurrenceDetails" }, - { name: "frequencyValues", full: "ICAL.Recur.frequencyValues" }, - { name: "weekDay", full: "ICAL.Time.weekDay" }]; +const fs = require("node:fs"); +const { gIcalClasses, typedefs } = JSON.parse(fs.readFileSync("./temp.json", "utf-8")); function addPrefix(objNames) { if (objNames?.length) { for (let i = 0; i < objNames.length; i++) { // finds all strings in objNames[i] that include a known class - let classNames = Array.from(gIcalClasses).reduce((acc, curr) => { + let classNames = gIcalClasses.reduce((acc, curr) => { if (objNames[i] === curr) acc = [...acc, curr]; return acc; }, []); - if ((gIcalClasses.has(objNames[i]) || classNames.length !== 0) && !objNames[i].includes("ICAL.")) { + if ((gIcalClasses.includes(objNames[i]) || classNames.length !== 0) && !objNames[i].includes("ICAL.")) { for (let className of classNames) { let index = objNames[i].indexOf(className); // add ICAL. to classnames without ICAL. @@ -47,10 +45,6 @@ function augmentTypes(obj) { exports.handlers = { newDoclet: function({ doclet }) { - if (doclet.kind == "class" && doclet.longname.startsWith("ICAL.")) { - gIcalClasses.add(doclet.name); - } - if (doclet.type) { augmentTypes(doclet.type); } From 83ba72c45d127a30521318612e0be8bbf76f04f3 Mon Sep 17 00:00:00 2001 From: jannikac Date: Wed, 29 May 2024 12:56:26 +0200 Subject: [PATCH 17/19] update plugin to handle `@properties` and move `parserState` typedef to `types.d.js` for consistency --- lib/ical/parse.js | 23 +++++++---------------- lib/ical/types.d.js | 25 +++++++++++++++++++++---- tools/jsdoc-ical.cjs | 5 +++++ 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/lib/ical/parse.js b/lib/ical/parse.js index e3cf4a64..26c802a8 100644 --- a/lib/ical/parse.js +++ b/lib/ical/parse.js @@ -4,11 +4,13 @@ * Portions Copyright (C) Philipp Kewisch */ import design from "./design.js"; -// needed for typescript type resolution -// eslint-disable-next-line no-unused-vars -import Component from "./component.js"; import { unescapedIndexOf } from "./helpers.js"; +/** + * @ignore + * @typedef {import("./types.d.js").parserState} parserState + */ + const CHAR = /[^ \t]/; const VALUE_DELIMITER = ':'; const PARAM_DELIMITER = ';'; @@ -102,25 +104,14 @@ class ParserError extends Error { // classes & constants parse.ParserError = ParserError; -/** - * The state for parsing content lines from an iCalendar/vCard string. - * - * @private - * @memberof ICAL.parse - * @typedef {Object} parserState - * @property {ICAL.design.designSet} designSet The design set to use for parsing - * @property {Component[]} stack The stack of components being processed - * @property {Component} component The currently active component - */ - /** * Handles a single line of iCalendar/vCard, updating the state. * * @private * @function ICAL.parse._handleContentLine - * @param {String} line The content line to process - * @param {ICAL.parse.parserState} The current state of the line parsing + * @param {String} line The content line to process + * @param {parserState} state The current state of the line parsing */ parse._handleContentLine = function(line, state) { // break up the parts of the line diff --git a/lib/ical/types.d.js b/lib/ical/types.d.js index 007c0df6..82b529c1 100644 --- a/lib/ical/types.d.js +++ b/lib/ical/types.d.js @@ -1,3 +1,9 @@ +/* eslint-disable no-unused-vars */ +// needed for typescript type resolution +import Event from "./event"; +import Time from "./time"; +import Component from "./component"; + /** * The weekday, 1 = SUNDAY, 7 = SATURDAY. Access via * ICAL.Time.MONDAY, ICAL.Time.TUESDAY, ... @@ -18,10 +24,21 @@ * This object is returned by {@link ICAL.Event#getOccurrenceDetails getOccurrenceDetails} * @memberof ICAL.Event * @typedef {Object} occurrenceDetails - * @property {ICAL.Time} recurrenceId The passed in recurrence id - * @property {ICAL.Event} item The occurrence - * @property {ICAL.Time} startDate The start of the occurrence - * @property {ICAL.Time} endDate The end of the occurrence + * @property {Time} recurrenceId The passed in recurrence id + * @property {Event} item The occurrence + * @property {Time} startDate The start of the occurrence + * @property {Time} endDate The end of the occurrence + */ + +/** + * The state for parsing content lines from an iCalendar/vCard string. + * + * @private + * @memberof ICAL.parse + * @typedef {Object} parserState + * @property {ICAL.design.designSet} designSet The design set to use for parsing + * @property {Component[]} stack The stack of components being processed + * @property {Component} component The currently active component */ export const _ = {}; diff --git a/tools/jsdoc-ical.cjs b/tools/jsdoc-ical.cjs index 51417c08..0006340c 100644 --- a/tools/jsdoc-ical.cjs +++ b/tools/jsdoc-ical.cjs @@ -59,5 +59,10 @@ exports.handlers = { augmentTypes(param); } } + if (doclet.properties) { + for (let property of doclet.properties) { + augmentTypes(property); + } + } } }; From e94faad84e18409f8389e18c95cf47390c028813 Mon Sep 17 00:00:00 2001 From: jannikac Date: Fri, 7 Jun 2024 11:44:27 +0200 Subject: [PATCH 18/19] added MPL headers, comments and newlines --- lib/ical/event.js | 5 +++++ lib/ical/parse.js | 5 +++++ lib/ical/recur.js | 6 ++++++ lib/ical/recur_iterator.js | 5 +++++ lib/ical/time.js | 5 +++++ lib/ical/types.d.js | 5 +++++ tools/jsdoc-collect-types.cjs | 14 +++++++++++++- tools/jsdoc-ical.cjs | 6 ++++++ tsconfig.json | 2 +- 9 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lib/ical/event.js b/lib/ical/event.js index 9c17d2e2..6a070ffa 100644 --- a/lib/ical/event.js +++ b/lib/ical/event.js @@ -15,9 +15,14 @@ import Duration from "./duration.js"; import RecurExpansion from "./recur_expansion.js"; /** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. * @ignore * @typedef {import("./types.d.js").frequencyValues} frequencyValues + * Imports the 'frequencyValues' type from the "types.d.js" module * @typedef {import("./types.d.js").occurrenceDetails} occurrenceDetails + * Imports the 'occurrenceDetails' type from the "types.d.js" module */ /** diff --git a/lib/ical/parse.js b/lib/ical/parse.js index 26c802a8..77b1ab0d 100644 --- a/lib/ical/parse.js +++ b/lib/ical/parse.js @@ -7,8 +7,13 @@ import design from "./design.js"; import { unescapedIndexOf } from "./helpers.js"; /** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * * @ignore * @typedef {import("./types.d.js").parserState} parserState + * Imports the 'parserState' type from the "types.d.js" module */ const CHAR = /[^ \t]/; diff --git a/lib/ical/recur.js b/lib/ical/recur.js index 66f08ab0..7719d92a 100644 --- a/lib/ical/recur.js +++ b/lib/ical/recur.js @@ -9,9 +9,15 @@ import design from "./design.js"; import { strictParseInt, clone } from "./helpers.js"; /** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * * @ignore * @typedef {import("./types.d.js").weekDay} weekDay + * Imports the 'weekDay' type from the "types.d.js" module * @typedef {import("./types.d.js").frequencyValues} frequencyValues + * Imports the 'frequencyValues' type from the "types.d.js" module */ const VALID_DAY_NAMES = /^(SU|MO|TU|WE|TH|FR|SA)$/; diff --git a/lib/ical/recur_iterator.js b/lib/ical/recur_iterator.js index 97ea418e..81b28571 100644 --- a/lib/ical/recur_iterator.js +++ b/lib/ical/recur_iterator.js @@ -8,8 +8,13 @@ import Recur from "./recur.js"; import Time from "./time.js"; /** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * * @ignore * @typedef {import("./types.d.js").weekDay} weekDay + * Imports the 'weekDay' type from the "types.d.js" module */ /** diff --git a/lib/ical/time.js b/lib/ical/time.js index 2fe79bad..d4353967 100644 --- a/lib/ical/time.js +++ b/lib/ical/time.js @@ -13,8 +13,13 @@ import TimezoneService from "./timezone_service.js"; import { strictParseInt, trunc, pad2 } from "./helpers.js"; /** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * * @ignore * @typedef {import("./types.d.js").weekDay} weekDay + * Imports the 'weekDay' type from the "types.d.js" module */ /** diff --git a/lib/ical/types.d.js b/lib/ical/types.d.js index 82b529c1..c2a7c97f 100644 --- a/lib/ical/types.d.js +++ b/lib/ical/types.d.js @@ -1,3 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch, 2024 */ + /* eslint-disable no-unused-vars */ // needed for typescript type resolution import Event from "./event"; diff --git a/tools/jsdoc-collect-types.cjs b/tools/jsdoc-collect-types.cjs index fbc363ca..1b462d08 100644 --- a/tools/jsdoc-collect-types.cjs +++ b/tools/jsdoc-collect-types.cjs @@ -1,3 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch, 2024 */ + +/** + * This jsdoc plugin collects all classes and static typedefs defined in the library + * which start with `ICAL.` and writes those to a temporary file which is read + * by the jsdoc-ical plugin. + * This is needed because of jsdoc plugin limitations. + */ + const fs = require("node:fs"); let gIcalClasses = new Set(); let typedefs = new Set(); @@ -12,4 +24,4 @@ exports.handlers = { } fs.writeFileSync("./temp.json", JSON.stringify({gIcalClasses: Array.from(gIcalClasses), typedefs: Array.from(typedefs)})); } -}; \ No newline at end of file +}; diff --git a/tools/jsdoc-ical.cjs b/tools/jsdoc-ical.cjs index 0006340c..567d131e 100644 --- a/tools/jsdoc-ical.cjs +++ b/tools/jsdoc-ical.cjs @@ -3,6 +3,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Portions Copyright (C) Philipp Kewisch, 2024 */ +/** + * This jsdoc plugin add the correct prefix `ICAL.` to everything that + * uses a class or typedef which are collected by the jsdoc-collect-types plugin + * so that the generated API docs link to the correct classes, typedefs, etc. + */ + const fs = require("node:fs"); const { gIcalClasses, typedefs } = JSON.parse(fs.readFileSync("./temp.json", "utf-8")); diff --git a/tsconfig.json b/tsconfig.json index 7342895c..62ab0c2c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,4 +3,4 @@ // type generation is handled by @rollup/plugin-typescript // this file exists because of https://github.com/rollup/plugins/issues/1572 -} \ No newline at end of file +} From bacc31fa457dbb6e9834b3e4c74bd6e1c2f02420 Mon Sep 17 00:00:00 2001 From: jannikac Date: Fri, 7 Jun 2024 11:51:25 +0200 Subject: [PATCH 19/19] updated plugins to work correctly by calling jsdoc twice, once to collect symbols, once to generate docs --- .gitignore | 2 +- jsdoc-prepare.json | 10 ++++++++++ jsdoc.json | 2 +- package.json | 2 +- tools/jsdoc-collect-types.cjs | 4 +++- tools/jsdoc-ical.cjs | 6 +++++- 6 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 jsdoc-prepare.json diff --git a/.gitignore b/.gitignore index 5f0c98e6..9d8ef387 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,5 @@ docs/recur-tester.html tools/vzic/ tools/tzdb/ tools/libical/ +tools/jsdoc-symbols-temp.json coverage/ -temp.json diff --git a/jsdoc-prepare.json b/jsdoc-prepare.json new file mode 100644 index 00000000..f95116e8 --- /dev/null +++ b/jsdoc-prepare.json @@ -0,0 +1,10 @@ +{ + "source": { + "include": "lib/ical", + "includePattern": ".js$" + }, + "plugins": ["tools/jsdoc-collect-types.cjs", "node_modules/jsdoc-tsimport-plugin/index.js"], + "opts": { + "destination": "docs/api/" + } +} diff --git a/jsdoc.json b/jsdoc.json index de785eb5..fdb0a6fa 100644 --- a/jsdoc.json +++ b/jsdoc.json @@ -3,7 +3,7 @@ "include": "lib/ical", "includePattern": ".js$" }, - "plugins": ["plugins/markdown", "tools/jsdoc-collect-types.cjs", "tools/jsdoc-ical.cjs", "node_modules/jsdoc-tsimport-plugin/index.js"], + "plugins": ["plugins/markdown", "tools/jsdoc-ical.cjs", "node_modules/jsdoc-tsimport-plugin/index.js"], "opts": { "encoding": "utf8", "readme": "README.md", diff --git a/package.json b/package.json index 5d8acd48..fc29f308 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "test-all": "npm run test-unit && npm run test-acceptance && npm run test-performance && npm run test-browser", "build": "rollup -c", "lint": "eslint", - "jsdoc": "rm -rf docs/api && jsdoc --configure jsdoc.json --verbose", + "jsdoc": "rm -rf docs/api && jsdoc --configure jsdoc-prepare.json && rm -rf docs/api && jsdoc --configure jsdoc.json --verbose", "validator": "node tools/scriptutils.js replace-unpkg tools/validator.html docs/validator.html", "recurtester": "node tools/scriptutils.js replace-unpkg tools/recur-tester.html docs/recur-tester.html", "ghpages": "npm run jsdoc && npm run validator && npm run recurtester" diff --git a/tools/jsdoc-collect-types.cjs b/tools/jsdoc-collect-types.cjs index 1b462d08..6a79585f 100644 --- a/tools/jsdoc-collect-types.cjs +++ b/tools/jsdoc-collect-types.cjs @@ -22,6 +22,8 @@ exports.handlers = { if (doclet.kind === "typedef" && doclet.scope === "static" && doclet.longname.startsWith("ICAL.")) { typedefs.add({name: doclet.name, full: doclet.longname}) } - fs.writeFileSync("./temp.json", JSON.stringify({gIcalClasses: Array.from(gIcalClasses), typedefs: Array.from(typedefs)})); + }, + processingComplete: function() { + fs.writeFileSync("./tools/jsdoc-symbols-temp.json", JSON.stringify({gIcalClasses: Array.from(gIcalClasses), typedefs: Array.from(typedefs)})); } }; diff --git a/tools/jsdoc-ical.cjs b/tools/jsdoc-ical.cjs index 567d131e..7ab32898 100644 --- a/tools/jsdoc-ical.cjs +++ b/tools/jsdoc-ical.cjs @@ -10,7 +10,8 @@ */ const fs = require("node:fs"); -const { gIcalClasses, typedefs } = JSON.parse(fs.readFileSync("./temp.json", "utf-8")); +let gIcalClasses = []; +let typedefs = []; function addPrefix(objNames) { if (objNames?.length) { @@ -50,6 +51,9 @@ function augmentTypes(obj) { } exports.handlers = { + parseBegin: function() { + ({ gIcalClasses, typedefs } = JSON.parse(fs.readFileSync("./tools/jsdoc-symbols-temp.json", "utf-8"))); + }, newDoclet: function({ doclet }) { if (doclet.type) { augmentTypes(doclet.type);