From ad1dad6ce68168e92573bdb2c97193867da19884 Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Thu, 11 Jul 2024 19:21:37 +1000 Subject: [PATCH] docs(cli,csv,datetime,fmt,fs,http,ini,semver,testing): assert optional properties on types/interfaces have `@default` tag (#4933) * docs: assert optional properties on types/interfaces have `@default` tag * work * work * work * work * work * work * fix * fix * Update fs/expand_glob.ts * cleanups * cleanups --------- Co-authored-by: Yoshiya Hinosawa --- _tools/check_docs.ts | 31 +++++++++++++++++++++++++++++++ cli/parse_args.ts | 25 ++++++++++++++++++++++--- csv/parse.ts | 2 ++ csv/parse_stream.ts | 2 ++ csv/stringify_stream.ts | 2 ++ datetime/format.ts | 6 +++++- fmt/bytes.ts | 8 ++++++-- fs/expand_glob.ts | 12 ++++++++++-- fs/walk.ts | 4 ---- http/cookie.ts | 41 ++++++++++++++++++++++++++++++++++------- http/etag.ts | 8 ++++++-- http/file_server.ts | 10 +++++++--- ini/_ini_map.ts | 30 +++++++++++++++++++++++++----- semver/types.ts | 12 ++++++++++-- testing/time.ts | 8 ++++++-- 15 files changed, 168 insertions(+), 33 deletions(-) diff --git a/_tools/check_docs.ts b/_tools/check_docs.ts index f65e21c80..59a5e59de 100644 --- a/_tools/check_docs.ts +++ b/_tools/check_docs.ts @@ -15,6 +15,7 @@ import { type DocNodeBase, type DocNodeClass, type DocNodeFunction, + type DocNodeInterface, type DocNodeModuleDoc, type JsDoc, type JsDocTagDocRequired, @@ -419,6 +420,34 @@ function assertModuleDoc(document: DocNodeWithJsDoc) { assertSnippetsWork(document.jsDoc.doc!, document); } +/** + * Ensures an interface document: + * - Has `@default` tags for all optional properties. + */ +// deno-lint-ignore no-unused-vars +function assertHasDefaultTags(document: DocNodeWithJsDoc) { + for (const prop of document.interfaceDef.properties) { + if (!prop.optional) continue; + if (!prop.jsDoc?.tags?.find((tag) => tag.kind === "default")) { + diagnostics.push( + new DocumentError( + "Optional interface properties should have default values", + document, + ), + ); + } + } +} + +// deno-lint-ignore no-unused-vars +function assertInterfaceDocs(document: DocNodeWithJsDoc) { + // TODO(iuioiua): This is currently disabled deliberately, as it throws errors + // for interface properties that don't have a `@default` tag. Re-enable this + // when checking for `@default` tags again, or when a solution is found for + // ignoring some properties (those that don't require a `@default` tag). + // assertHasDefaultTags(document); +} + function resolve(specifier: string, referrer: string): string { if (specifier.startsWith("@std/")) { specifier = specifier.replace("@std/", "../").replaceAll("-", "_"); @@ -450,6 +479,8 @@ async function checkDocs(specifier: string) { assertClassDocs(document); break; } + case "interface": + assertInterfaceDocs(document); } } } diff --git a/cli/parse_args.ts b/cli/parse_args.ts index b3aabbd27..0610569d4 100644 --- a/cli/parse_args.ts +++ b/cli/parse_args.ts @@ -293,6 +293,8 @@ export interface ParseOptions< /** * An object mapping string names to strings or arrays of string argument * names to use as aliases. + * + * @default {{}} */ alias?: TAliases; @@ -301,19 +303,31 @@ export interface ParseOptions< * `true` will treat all double hyphenated arguments without equal signs as * `boolean` (e.g. affects `--foo`, not `-f` or `--foo=bar`). * All `boolean` arguments will be set to `false` by default. + * + * @default {false} */ boolean?: TBooleans | ReadonlyArray>; - /** An object mapping string argument names to default values. */ + /** + * An object mapping string argument names to default values. + * + * @default {{}} + */ default?: TDefault & Defaults; /** * When `true`, populate the result `_` with everything after the first * non-option. + * + * @default {false} */ stopEarly?: boolean; - /** A string or array of strings argument names to always treat as strings. */ + /** + * A string or array of strings argument names to always treat as strings. + * + * @default {[]} + */ string?: TStrings | ReadonlyArray>; /** @@ -321,13 +335,16 @@ export interface ParseOptions< * Collectable options can be used multiple times. All values will be * collected into one array. If a non-collectable option is used multiple * times, the last value is used. - * All Collectable arguments will be set to `[]` by default. + * + * @default {[]} */ collect?: TCollectable | ReadonlyArray>; /** * A string or array of strings argument names which can be negated * by prefixing them with `--no-`, like `--no-config`. + * + * @default {[]} */ negatable?: TNegatable | ReadonlyArray>; @@ -335,6 +352,8 @@ export interface ParseOptions< * A function which is invoked with a command line parameter not defined in * the `options` configuration object. If the function returns `false`, the * unknown option is not added to `parsedArgs`. + * + * @default {unknown} */ unknown?: (arg: string, key?: string, value?: unknown) => unknown; } diff --git a/csv/parse.ts b/csv/parse.ts index 8a78322e7..d610b6a44 100644 --- a/csv/parse.ts +++ b/csv/parse.ts @@ -289,6 +289,8 @@ export interface ParseOptions { * skipped. * If you provide `skipFirstRow: true` but not `columns`, the first line will * be skipped and used as header definitions. + * + * @default {false} */ skipFirstRow?: boolean; diff --git a/csv/parse_stream.ts b/csv/parse_stream.ts index ce00b6199..82c686ce3 100644 --- a/csv/parse_stream.ts +++ b/csv/parse_stream.ts @@ -58,6 +58,8 @@ export interface CsvParseStreamOptions { * skipped. * If you provide `skipFirstRow: true` but not `columns`, the first line will * be skipped and used as header definitions. + * + * @default {false} */ skipFirstRow?: boolean; /** List of names used for header definition. */ diff --git a/csv/stringify_stream.ts b/csv/stringify_stream.ts index 5c8021b8c..f13b7220e 100644 --- a/csv/stringify_stream.ts +++ b/csv/stringify_stream.ts @@ -15,6 +15,8 @@ export interface CsvStringifyStreamOptions { * A list of columns to be included in the output. * * If you want to stream objects, this option is required. + * + * @default {[]} */ readonly columns?: Array; } diff --git a/datetime/format.ts b/datetime/format.ts index dcf38473e..39a0c7619 100644 --- a/datetime/format.ts +++ b/datetime/format.ts @@ -5,7 +5,11 @@ import { DateTimeFormatter } from "./_date_time_formatter.ts"; /** Options for {@linkcode format}. */ export interface FormatOptions { - /** Whether returns the formatted date in UTC instead of local time. */ + /** + * Whether returns the formatted date in UTC instead of local time. + * + * @default {false} + */ utc?: boolean; } diff --git a/fmt/bytes.ts b/fmt/bytes.ts index 0048b264a..8e8dcc669 100644 --- a/fmt/bytes.ts +++ b/fmt/bytes.ts @@ -56,13 +56,17 @@ export interface FormatOptions { /** * The minimum number of fraction digits to display. If neither * {@linkcode minimumFractionDigits} or {@linkcode maximumFractionDigits} - * are set, the default behavior is to round to 3 significant digits. + * are set. + * + * @default {3} */ minimumFractionDigits?: number; /** * The maximum number of fraction digits to display. If neither * {@linkcode minimumFractionDigits} or {@linkcode maximumFractionDigits} - * are set, the default behavior is to round to 3 significant digits. + * are set. + * + * @default {3} */ maximumFractionDigits?: number; } diff --git a/fs/expand_glob.ts b/fs/expand_glob.ts index 0b3107617..228f9766d 100644 --- a/fs/expand_glob.ts +++ b/fs/expand_glob.ts @@ -19,9 +19,17 @@ const isWindows = Deno.build.os === "windows"; /** Options for {@linkcode expandGlob} and {@linkcode expandGlobSync}. */ export interface ExpandGlobOptions extends Omit { - /** File path where to expand from. */ + /** + * File path where to expand from. + * + * @default {Deno.cwd()} + */ root?: string; - /** List of glob patterns to be excluded from the expansion. */ + /** + * List of glob patterns to be excluded from the expansion. + * + * @default {[]} + */ exclude?: string[]; /** * Whether to include directories in entries. diff --git a/fs/walk.ts b/fs/walk.ts index b0eb72db0..aa507972b 100644 --- a/fs/walk.ts +++ b/fs/walk.ts @@ -145,16 +145,12 @@ export interface WalkOptions { * List of regular expression patterns used to filter entries. * If specified, entries that do not match the patterns specified by this * option are excluded. - * - * @default {undefined} */ match?: RegExp[]; /** * List of regular expression patterns used to filter entries. * If specified, entries matching the patterns specified by this option are * excluded. - * - * @default {undefined} */ skip?: RegExp[]; } diff --git a/http/cookie.ts b/http/cookie.ts index a7fdaf834..5e2a4f03e 100644 --- a/http/cookie.ts +++ b/http/cookie.ts @@ -13,7 +13,11 @@ export interface Cookie { name: string; /** Value of the cookie. */ value: string; - /** The cookie's `Expires` attribute, either as an explicit date or UTC milliseconds. + /** + * The cookie's `Expires` attribute, either as an explicit date or UTC + * milliseconds. If `undefined`, the cookie will expire when the client's + * session ends. + * * @example Explicit date: * * ```ts @@ -39,15 +43,34 @@ export interface Cookie { * ``` */ expires?: Date | number; - /** The cookie's `Max-Age` attribute, in seconds. Must be a non-negative integer. A cookie with a `maxAge` of `0` expires immediately. */ + /** + * The cookie's `Max-Age` attribute, in seconds. Must be a non-negative + * integer. A cookie with a `maxAge` of `0` expires immediately. + */ maxAge?: number; - /** The cookie's `Domain` attribute. Specifies those hosts to which the cookie will be sent. */ + /** + * The cookie's `Domain` attribute. Specifies those hosts to which the cookie + * will be sent. + */ domain?: string; - /** The cookie's `Path` attribute. A cookie with a path will only be included in the `Cookie` request header if the requested URL matches that path. */ + /** + * The cookie's `Path` attribute. A cookie with a path will only be included + * in the `Cookie` request header if the requested URL matches that path. + */ path?: string; - /** The cookie's `Secure` attribute. If `true`, the cookie will only be included in the `Cookie` request header if the connection uses SSL and HTTPS. */ + /** + * The cookie's `Secure` attribute. If `true`, the cookie will only be + * included in the `Cookie` request header if the connection uses SSL and + * HTTPS. + * + * @default {false} + */ secure?: boolean; - /** The cookie's `HTTPOnly` attribute. If `true`, the cookie cannot be accessed via JavaScript. */ + /** + * The cookie's `HTTPOnly` attribute. If `true`, the cookie cannot be accessed via JavaScript. + * + * @default {false} + */ httpOnly?: boolean; /** * The cookie's `Partitioned` attribute. @@ -66,7 +89,11 @@ export interface Cookie { * be sent along with cross-site requests. */ sameSite?: "Strict" | "Lax" | "None"; - /** Additional key value pairs with the form "key=value" */ + /** + * Additional key value pairs with the form "key=value". + * + * @default {[]} + */ unparsed?: string[]; } diff --git a/http/etag.ts b/http/etag.ts index c4b2ca8fa..94310b6fb 100644 --- a/http/etag.ts +++ b/http/etag.ts @@ -45,8 +45,12 @@ export interface ETagOptions { */ algorithm?: AlgorithmIdentifier; - /** Override the default behavior of calculating the `ETag`, either forcing - * a tag to be labelled weak or not. */ + /** + * Override the default behavior of calculating the `ETag`, either forcing + * a tag to be labelled weak or not. + * + * Defaults to `true` when the entity is a `FileInfo` and `false` otherwise. + */ weak?: boolean; } diff --git a/http/file_server.ts b/http/file_server.ts index 151eb3e42..23df0607f 100644 --- a/http/file_server.ts +++ b/http/file_server.ts @@ -141,7 +141,13 @@ export interface ServeFileOptions { * @default {"SHA-256"} */ etagAlgorithm?: AlgorithmIdentifier; - /** An optional FileInfo object returned by Deno.stat. It is used for optimization purposes. */ + /** + * An optional object returned by {@linkcode Deno.stat}. It is used for + * optimization purposes. + * + * Defaults to the result of calling {@linkcode Deno.stat} with the provided + * `filePath`. + */ fileInfo?: Deno.FileInfo; } @@ -544,8 +550,6 @@ export interface ServeDirOptions { */ fsRoot?: string; /** Specified that part is stripped from the beginning of the requested pathname. - * - * @default {undefined} */ urlRoot?: string; /** Enable directory listing. diff --git a/ini/_ini_map.ts b/ini/_ini_map.ts index dc0a30e80..1177fd26b 100644 --- a/ini/_ini_map.ts +++ b/ini/_ini_map.ts @@ -3,15 +3,35 @@ /** Options for providing formatting marks. */ export interface FormattingOptions { - /** The character used to assign a value to a key; defaults to '='. */ + /** + * The character used to assign a value to a key; defaults to '='. + * + * @default {"="} + */ assignment?: string; - /** Character(s) used to break lines in the config file; defaults to '\n'. Ignored on parse. */ + /** + * Character(s) used to break lines in the config file. Ignored on parse. + * + * @default {"\n"} + */ lineBreak?: "\n" | "\r\n" | "\r"; - /** Mark to use for setting comments; expects '#', ';', '//', defaults to '#' unless another mark is found. */ + /** + * Mark to use for setting comments. + * + * @default {"#"} + */ commentChar?: "#" | ";" | "//"; - /** Use a plain assignment char or pad with spaces; defaults to false. Ignored on parse. */ + /** + * Use a plain assignment char or pad with spaces. Ignored on parse. + * + * @default {false} + */ pretty?: boolean; - /** Filter duplicate keys from INI string output; defaults to false to preserve data parity. */ + /** + * Filter duplicate keys from INI string output. + * + * @default {false} + */ deduplicate?: boolean; } diff --git a/semver/types.ts b/semver/types.ts index 2d17c6dd7..f88d99fd6 100644 --- a/semver/types.ts +++ b/semver/types.ts @@ -46,9 +46,17 @@ export interface SemVer { minor: number; /** The patch version */ patch: number; - /** The prerelease version */ + /** + * The prerelease version + * + * @default {[]} + */ prerelease?: (string | number)[]; - /** The build metadata */ + /** + * The build metadata + * + * @default {[]} + */ build?: string[]; } diff --git a/testing/time.ts b/testing/time.ts index d1863eb47..50f362909 100644 --- a/testing/time.ts +++ b/testing/time.ts @@ -114,11 +114,15 @@ export interface FakeTimeOptions { * The rate relative to real time at which fake time is updated. * By default time only moves forward through calling tick or setting now. * Set to 1 to have the fake time automatically tick forward at the same rate in milliseconds as real time. + * + * @default {0} */ advanceRate: number; /** * The frequency in milliseconds at which fake time is updated. * If advanceRate is set, we will update the time every 10 milliseconds by default. + * + * @default {10} */ advanceFrequency?: number; } @@ -338,11 +342,11 @@ export class FakeTime { advanceRate = Math.max( 0, - options?.advanceRate ? options.advanceRate : 0, + options?.advanceRate ?? 0, ); advanceFrequency = Math.max( 0, - options?.advanceFrequency ? options.advanceFrequency : 10, + options?.advanceFrequency ?? 10, ); advanceIntervalId = advanceRate > 0 ? _internals.setInterval.call(null, () => {