🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

nostics

Package Overview
Dependencies
Maintainers
2
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nostics - npm Package Compare versions

Comparing version
1.1.3
to
1.1.4
+2
-3
dist/index.d.mts

@@ -34,5 +34,4 @@ import { a as Diagnostic, c as DiagnosticHandle, d as Diagnostics, f as createConsoleReporter, i as DefineDiagnosticsOptions, l as DiagnosticInit, m as ValueOrFn, n as ConsoleMethod, o as DiagnosticCallParams, p as defineDiagnostics, r as ConsoleReporterOptions, s as DiagnosticDefinition, t as AnyDiagnosticReporter, u as DiagnosticReporter } from "./diagnostic-CtJfaJhc.mjs";

* builds a minimal {@link Diagnostic} for any accessed code: the code becomes
* the `message` (`why`), `name` stays the default `'Diagnostic'`, and `docs` is
* derived from `docsBase`. It carries no catalog text, so it stays tiny in a
* bundle.
* both the `message` (`why`) and the instance `name`, and `docs` is derived
* from `docsBase`. It carries no catalog text, so it stays tiny in a bundle.
*

@@ -39,0 +38,0 @@ * The strip plugin (`@nostics/unplugin`) can rewrite a `defineDiagnostics()`

+3
-3

@@ -144,5 +144,4 @@ //#region src/formatters/plain.ts

* builds a minimal {@link Diagnostic} for any accessed code: the code becomes
* the `message` (`why`), `name` stays the default `'Diagnostic'`, and `docs` is
* derived from `docsBase`. It carries no catalog text, so it stays tiny in a
* bundle.
* both the `message` (`why`) and the instance `name`, and `docs` is derived
* from `docsBase`. It carries no catalog text, so it stays tiny in a bundle.
*

@@ -171,2 +170,3 @@ * The strip plugin (`@nostics/unplugin`) can rewrite a `defineDiagnostics()`

}, handle);
diagnostic.name = code;
for (const reporter of reporters) reporter(diagnostic, reporterOptions);

@@ -173,0 +173,0 @@ return diagnostic;

@@ -1,1 +0,1 @@

{"version":3,"file":"index.mjs","names":[],"sources":["../src/formatters/plain.ts","../src/utils.ts","../src/diagnostic.ts","../src/prod-diagnostics.ts"],"sourcesContent":["import type { Diagnostic } from '../diagnostic'\n\n/**\n * Renders a diagnostic into a multi-line, unicode-decorated string suitable\n * for terminal output. The first line is `[<name>] <message>`; optional\n * details (`fix`, `sources`, `docs`) follow with `├▶`/`╰▶` connectors.\n */\nexport function formatDiagnostic(diagnostic: Diagnostic): string {\n const header = `[${diagnostic.name}] ${diagnostic.message}`\n\n const details: string[] = []\n if (diagnostic.fix) {\n details.push(`fix: ${diagnostic.fix}`)\n }\n if (diagnostic.sources?.length) {\n details.push(`sources: ${diagnostic.sources.join(', ')}`)\n }\n if (diagnostic.docs) {\n details.push(`see: ${diagnostic.docs}`)\n }\n\n if (details.length === 0) {\n return header\n }\n\n const lines = details.map((detail, i) => {\n const connector = i < details.length - 1 ? '├▶' : '╰▶'\n return `${connector} ${detail}`\n })\n\n return [header, ...lines].join('\\n')\n}\n","/**\n * Transforms a value or a function that returns a value to a value.\n *\n * @param valFn either a value or a function that returns a value\n * @param args arguments to pass to the function if `valFn` is a function\n *\n * @internal\n */\nexport function toValueWithArgs<T, Args extends any[]>(\n valFn: T | ((...args: Args) => T),\n ...args: Args\n): T {\n return typeof valFn === 'function' ? (valFn as (...args: Args) => T)(...args) : valFn\n}\n\n/**\n * A value of type T, or a function that resolves T from a single params object.\n *\n * @internal\n */\nexport type ValueOrFn<T, P = any> = T | ((params: P) => T)\n\n/**\n * Extracts the param type from a single-arg function, or `never` for\n * non-function inputs. Pairs with {@link ValueOrFn}.\n *\n * @internal\n */\nexport type ExtractFnParam<T> = T extends (params: infer P) => any ? P : never\n\n/**\n * Converts a union of types to their intersection.\n *\n * @internal\n */\nexport type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never\n\n/**\n * `true` when `T` is the `any` type.\n *\n * @internal\n */\nexport type IsAny<Type> = 0 extends 1 & Type ? true : false\n\n/**\n * `true` when `T` is the `unknown` type (and not `any`).\n *\n * @internal\n */\nexport type IsUnknown<Type> = IsAny<Type> extends true ? false : unknown extends Type ? true : false\n\n/**\n * Expands a type to its property listing so editor hovers show the resolved\n * shape instead of a chain of aliases / intersections.\n *\n * @internal\n */\nexport type Prettify<Type> = {\n [Key in keyof Type]: Type[Key]\n}\n","/* eslint-disable ts/no-empty-object-type -- `{}` is used as the neutral element when intersecting reporter option shapes */\n/* eslint-disable ts/no-unsafe-function-type -- used by captureStackTrace */\n\nimport type { ExtractFnParam, IsUnknown, Prettify, UnionToIntersection, ValueOrFn } from './utils'\nimport { formatDiagnostic } from './formatters/plain'\nimport { toValueWithArgs } from './utils'\n\n/**\n * Define-time shape of a diagnostic. Each field can be a static value or a\n * function that resolves it from a shared `params` object passed at call\n * time. Runtime-only fields (`cause`, `sources`) from {@link DiagnosticInit}\n * are intentionally omitted: they're only meaningful at the call site.\n */\nexport interface DiagnosticDefinition<P = any> {\n /**\n * The error message: why this failed. String, or a function of `params`.\n *\n * @example\n * ```ts\n * why: (p: { name: string }) => `module \"${p.name}\" failed to load`\n * ```\n */\n why: ValueOrFn<string, P>\n\n /**\n * Actionable instructions on how to resolve the problem. String, or a\n * function of `params`.\n *\n * @example\n * ```ts\n * fix: (p: { name: string }) => `run \"npm install ${p.name}\"`\n * ```\n */\n fix?: ValueOrFn<string, P>\n\n /**\n * Per-code docs URL. A string overrides\n * {@link DefineDiagnosticsOptions.docsBase} for this code; `false` opts this\n * code out entirely, even when `docsBase` is set. When omitted, the URL is\n * derived from `docsBase`.\n */\n docs?: string | false\n}\n\n/**\n * Runtime-only fields that can be passed alongside the interpolation params\n * at call time. Merged into the same object so callers pass everything in\n * one place.\n */\nexport interface DiagnosticCallParams {\n /**\n * Original error or exception that triggered this diagnostic. Pass it\n * through when re-throwing so the original stack trace is preserved.\n */\n cause?: unknown\n\n /**\n * Locations in user code that contributed to this diagnostic, in\n * `file:line:column` format. Useful for compilers and other tools where the\n * JS stack trace doesn't reflect the user's source.\n */\n sources?: string[]\n}\n\n/**\n * Structured initializer for a {@link Diagnostic}. `why` is the only required\n * field: it becomes the {@link Diagnostic.message}. The remaining fields are\n * optional metadata that reporters and consumers can render or forward.\n */\nexport interface DiagnosticInit extends DiagnosticCallParams {\n /**\n * The actual error message: why this failed.\n * Mirrored to `Error.message`.\n */\n why: string\n\n /**\n * Optional actionable instructions on how to resolve the problem.\n */\n fix?: string\n\n /**\n * URL to extended documentation for this diagnostic.\n */\n docs?: string\n}\n\n/**\n * Represents how to report a diagnostic. Could call `console.log()`, send the\n * diagnostic to a server, or something else. Reporters declare the shape of\n * options they need via `ReporterOpts`; `defineDiagnostics` intersects every\n * reporter's options into a single object passed at the call site.\n */\nexport type DiagnosticReporter<ReporterOpts extends object = {}> = (\n diagnostic: Diagnostic,\n options: ReporterOpts,\n) => void\n\n/**\n * Permissive reporter constraint used internally so reporters with 1 arg,\n * required options, or optional options all satisfy the array constraint.\n *\n * @internal\n */\nexport type AnyDiagnosticReporter = (diagnostic: Diagnostic, options: any) => void\n\n/**\n * The `console` methods a log reporter can route to.\n */\nexport type ConsoleMethod = 'log' | 'error' | 'warn'\n\n/**\n * Options for {@link createConsoleReporter}.\n */\nexport interface ConsoleReporterOptions {\n /**\n * `console` method used to print the diagnostic. Defaults to `'warn'`. The\n * returned reporter still accepts a per-call `{ method }` override through\n * the call-site reporter options.\n */\n method?: ConsoleMethod\n\n /**\n * Renders the diagnostic into the string handed to `console`. Defaults to\n * {@link formatDiagnostic}, the plain unicode-decorated formatter.\n */\n formatter?: (diagnostic: Diagnostic) => string\n}\n\n/**\n * Creates a console reporter that renders each diagnostic with `formatter` and\n * prints the result via `console[method]`. Both default sensibly (`'warn'` and\n * {@link formatDiagnostic}); `method` can also be overridden per call through\n * the reporter options.\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function createConsoleReporter({\n method: defaultMethod = 'warn',\n formatter = formatDiagnostic,\n}: ConsoleReporterOptions = {}): DiagnosticReporter<{ method?: ConsoleMethod }> {\n return (diagnostic, { method = defaultMethod } = {}) => {\n // eslint-disable-next-line no-console\n console[method](formatter(diagnostic))\n }\n}\n\n/**\n * Resolves the `params` type a code expects from the intersection of params\n * across all function-typed fields, falling back to `{}` when every field is\n * static. Merged with {@link DiagnosticCallParams} at the call site.\n *\n * @internal\n */\ntype InferCodeParams<Def> = [ExtractFnParam<Def[keyof Def]>] extends [never]\n ? {}\n : UnionToIntersection<ExtractFnParam<Def[keyof Def]>>\n\n/**\n * Options for {@link defineDiagnostics}.\n */\nexport interface DefineDiagnosticsOptions<\n Codes extends Record<string, DiagnosticDefinition>,\n Reporters extends readonly AnyDiagnosticReporter[],\n> {\n /**\n * Base URL or resolver for documentation links. When a string, the code is\n * appended as a lowercase path segment (e.g. `\"https://docs.example.com\"` →\n * `\"https://docs.example.com/math_e001\"`). When a function, receives the\n * code and returns a URL or `undefined`.\n */\n docsBase?: string | ((code: keyof Codes) => string | undefined)\n\n /**\n * Map of diagnostic codes to their definitions.\n */\n codes: Codes\n\n /**\n * Reporters called every time a diagnostic is produced. Can be used to\n * integrate with custom logging.\n */\n reporters?: Reporters\n}\n\n/**\n * The first positional argument of a {@link DiagnosticHandle} call:\n * interpolation params merged with the runtime-only call-site fields\n * (`cause`, `sources`).\n *\n * @internal\n */\ntype CallSiteParams<Params> = Params & DiagnosticCallParams\n\n/**\n * Resolves the full argument tuple for a {@link DiagnosticHandle} call.\n * Branches on whether params and reporter options each have required fields.\n * Required positions become required tuple elements, all-optional ones\n * become `?`, and when no reporter declares any options the parameter is\n * omitted entirely.\n *\n * @internal\n */\ntype ActionArgs<Params, ReporterOpts> = keyof ReporterOpts extends never\n ? {} extends Params\n ? [params?: CallSiteParams<Params>]\n : [params: CallSiteParams<Params>]\n : {} extends ReporterOpts\n ? {} extends Params\n ? [params?: CallSiteParams<Params>, reporterOptions?: ReporterOpts]\n : [params: CallSiteParams<Params>, reporterOptions?: ReporterOpts]\n : {} extends Params\n ? [params: CallSiteParams<Params> | undefined, reporterOptions: ReporterOpts]\n : [params: CallSiteParams<Params>, reporterOptions: ReporterOpts]\n\n/**\n * Per-code handle exposed by {@link defineDiagnostics}. Each code is a\n * callable: invoke it to build the diagnostic and run every reporter, or\n * prefix the call with `throw` to raise it.\n *\n * @example\n * ```ts\n * diagnostics.MATH_E001({ name: 'x' }) // report\n * throw diagnostics.MATH_E001({ name: 'x' }) // throw\n * ```\n */\nexport interface DiagnosticHandle<Params, ReporterOpts> {\n /**\n * Builds the diagnostic, runs every reporter, and returns the diagnostic\n * instance. The returned diagnostic can be inspected, attached as `cause`,\n * or thrown with `throw`.\n */\n (...args: ActionArgs<Params, ReporterOpts>): Diagnostic\n}\n\n/**\n * Return type of {@link defineDiagnostics}.\n */\nexport type Diagnostics<\n Codes extends Record<string, DiagnosticDefinition>,\n Reporters extends readonly AnyDiagnosticReporter[],\n> = {\n [Code in keyof Codes]: DiagnosticHandle<\n InferCodeParams<Codes[Code]>,\n Prettify<ExtractReportersOptions<Reporters>>\n >\n}\n\nconst captureStackTrace = (\n Error as { captureStackTrace?: (target: object, frame: Function) => void }\n).captureStackTrace\n\nexport class Diagnostic extends Error {\n name: string = 'Diagnostic'\n\n /**\n * URL to extended documentation for this diagnostic code.\n * Auto-generated from {@link DefineDiagnosticsOptions.docsBase}.\n */\n docs?: string\n\n /**\n * Optional actionable instructions on how to resolve the problem.\n */\n fix?: string\n\n /**\n * Locations in user code that contributed to this diagnostic, in\n * `file:line:column` format. Relevant when the stack trace doesn't reflect\n * the user's source (e.g. compilers, bundlers), otherwise redundant with the\n * stack and should be omitted.\n */\n sources?: string[]\n\n /**\n * Alias for {@link Error.message}: the reason this diagnostic was raised.\n */\n get why(): string {\n return this.message\n }\n\n /**\n * @param init structured initializer; `why` is required\n * @param captureFrom V8 stack-cutoff frame. Defaults to {@link Diagnostic}\n * so the top of the trace is the `new Diagnostic(...)` call site.\n * `defineDiagnostics` passes its action method to strip its own frames too.\n * Ignored on engines without `Error.captureStackTrace`.\n */\n constructor(init: DiagnosticInit, captureFrom: Function = Diagnostic) {\n super(init.why, { cause: init.cause })\n this.fix = init.fix\n this.docs = init.docs\n this.sources = init.sources\n // V8-only API, but also implemented pretty much everywhere. Worst case\n // scenario, we fall back to the stack `Error` captures by default, which\n // includes a couple of extra internal frames but is still usable.\n captureStackTrace?.(this, captureFrom)\n }\n\n /**\n * Converts the diagnostic into a serializable structured object.\n */\n toJSON(): object {\n return {\n name: this.name,\n why: this.why,\n fix: this.fix,\n docs: this.docs,\n sources: this.sources,\n cause: this.cause,\n stack: this.stack,\n }\n }\n}\n\n/**\n * Resolves the docs URL for a code from a `docsBase` (string template or\n * resolver function). Shared by {@link defineDiagnostics} and\n * {@link defineProdDiagnostics}. Per-code `docs` overrides are handled by the\n * caller; this only covers the `docsBase`-derived case.\n *\n * @internal\n */\nexport function deriveDocs(\n docsBase: string | ((code: any) => string | undefined) | undefined,\n code: string,\n): string | undefined {\n return typeof docsBase === 'string' ? `${docsBase}/${code.toLowerCase()}` : docsBase?.(code)\n}\n\n/**\n * Creates a typed diagnostics object from a set of code definitions. Each\n * code becomes a callable {@link DiagnosticHandle}: invoke to report, or\n * `throw` the result to raise. No `new` required, no proxy.\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function defineDiagnostics<\n const Codes extends Record<string, DiagnosticDefinition>,\n const Reporters extends readonly AnyDiagnosticReporter[],\n>(options: DefineDiagnosticsOptions<Codes, Reporters>): Diagnostics<Codes, Reporters> {\n const reporters = options.reporters ?? []\n const result = {} as Diagnostics<Codes, Reporters>\n\n const { docsBase } = options\n\n for (const code of Object.keys(options.codes) as Extract<keyof Codes, string>[]) {\n const def = options.codes[code]\n // skip docs if set to false, otherwise use it or derive it from docsBase\n const docs = def.docs === false ? undefined : def.docs || deriveDocs(docsBase, code)\n\n const handle = (\n params: DiagnosticCallParams & Record<string, unknown> = {},\n reporterOptions: any = {},\n ): Diagnostic => {\n const diagnostic = new Diagnostic(\n {\n why: toValueWithArgs(def.why, params),\n fix: toValueWithArgs(def.fix, params),\n docs,\n cause: params.cause,\n sources: params.sources,\n },\n handle,\n )\n diagnostic.name = code\n for (const reporter of reporters) reporter(diagnostic, reporterOptions)\n return diagnostic\n }\n\n result[code] = handle as unknown as Diagnostics<Codes, Reporters>[typeof code]\n }\n\n return result\n}\n\n/**\n * Extracts the options object a reporter accepts as its 2nd argument. Returns\n * `{}` when the reporter has no 2nd arg (so it contributes nothing to the\n * merged shape).\n */\ntype ExtractSingleReporterOptions<Reporter> = Reporter extends (\n diagnostic: Diagnostic,\n options: infer ReporterOpts,\n) => any\n ? IsUnknown<ReporterOpts> extends true\n ? {}\n : Exclude<ReporterOpts, undefined>\n : {}\n\n/**\n * Intersects every reporter's options shape into a single object. If any\n * reporter has a required field, the merged shape has a required field, and\n * {@link ActionArgs} flips `reporterOptions` from optional to required via\n * `{} extends Merged`.\n */\ntype ExtractReportersOptions<Reporters extends readonly any[]> = Reporters extends readonly [\n infer First,\n ...infer Rest,\n]\n ? ExtractSingleReporterOptions<First> & ExtractReportersOptions<Rest>\n : {}\n","import type {\n AnyDiagnosticReporter,\n DiagnosticCallParams,\n DiagnosticDefinition,\n Diagnostics,\n} from './diagnostic'\nimport { deriveDocs, Diagnostic } from './diagnostic'\n\n/**\n * Options for {@link defineProdDiagnostics}. A lean subset of\n * {@link DefineDiagnosticsOptions}: no `codes` map (the proxy serves any code),\n * only what is needed to keep behaviour correct in production.\n */\nexport interface DefineProdDiagnosticsOptions<\n Reporters extends readonly AnyDiagnosticReporter[] = readonly AnyDiagnosticReporter[],\n> {\n /**\n * Base URL or resolver for documentation links, identical to\n * {@link DefineDiagnosticsOptions.docsBase}. The docs URL is derived from the\n * accessed code at call time, so links survive even without the catalog.\n */\n docsBase?: string | ((code: string) => string | undefined)\n\n /**\n * Reporters called every time a diagnostic is produced. Omitted by default in\n * production builds; the strip plugin can copy them into the prod branch when\n * prod-time reporting (e.g. telemetry) is desired.\n */\n reporters?: Reporters\n}\n\n/**\n * Production counterpart to {@link defineDiagnostics}. Returns a `Proxy` that\n * builds a minimal {@link Diagnostic} for any accessed code: the code becomes\n * the `message` (`why`), `name` stays the default `'Diagnostic'`, and `docs` is\n * derived from `docsBase`. It carries no catalog text, so it stays tiny in a\n * bundle.\n *\n * The strip plugin (`@nostics/unplugin`) can rewrite a `defineDiagnostics()`\n * call into a `process.env.NODE_ENV === 'production'` ternary that selects this\n * factory in production, dropping every `why`/`fix` string from the bundle.\n *\n * @example\n * ```ts\n * const diagnostics = defineProdDiagnostics({ docsBase: 'https://docs.example.com' })\n * throw diagnostics.NUXT_B2011() // Error: NUXT_B2011, docs derived from docsBase\n * ```\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function defineProdDiagnostics<\n const Codes extends Record<string, DiagnosticDefinition> = Record<string, DiagnosticDefinition>,\n const Reporters extends readonly AnyDiagnosticReporter[] = readonly AnyDiagnosticReporter[],\n>(options: DefineProdDiagnosticsOptions<Reporters> = {}): Diagnostics<Codes, Reporters> {\n const { docsBase, reporters = [] } = options\n\n return new Proxy({} as Diagnostics<Codes, Reporters>, {\n get(_target, code) {\n // ignore symbol / non-string probes (e.g. `then`, `Symbol.toPrimitive`)\n if (typeof code !== 'string')\n return undefined\n\n const handle = (\n params: DiagnosticCallParams & Record<string, unknown> = {},\n reporterOptions: any = {},\n ): Diagnostic => {\n const diagnostic = new Diagnostic(\n {\n why: code,\n docs: deriveDocs(docsBase, code),\n cause: params.cause,\n sources: params.sources,\n },\n handle,\n )\n for (const reporter of reporters) reporter(diagnostic, reporterOptions)\n return diagnostic\n }\n\n return handle\n },\n })\n}\n"],"mappings":"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"}
{"version":3,"file":"index.mjs","names":[],"sources":["../src/formatters/plain.ts","../src/utils.ts","../src/diagnostic.ts","../src/prod-diagnostics.ts"],"sourcesContent":["import type { Diagnostic } from '../diagnostic'\n\n/**\n * Renders a diagnostic into a multi-line, unicode-decorated string suitable\n * for terminal output. The first line is `[<name>] <message>`; optional\n * details (`fix`, `sources`, `docs`) follow with `├▶`/`╰▶` connectors.\n */\nexport function formatDiagnostic(diagnostic: Diagnostic): string {\n const header = `[${diagnostic.name}] ${diagnostic.message}`\n\n const details: string[] = []\n if (diagnostic.fix) {\n details.push(`fix: ${diagnostic.fix}`)\n }\n if (diagnostic.sources?.length) {\n details.push(`sources: ${diagnostic.sources.join(', ')}`)\n }\n if (diagnostic.docs) {\n details.push(`see: ${diagnostic.docs}`)\n }\n\n if (details.length === 0) {\n return header\n }\n\n const lines = details.map((detail, i) => {\n const connector = i < details.length - 1 ? '├▶' : '╰▶'\n return `${connector} ${detail}`\n })\n\n return [header, ...lines].join('\\n')\n}\n","/**\n * Transforms a value or a function that returns a value to a value.\n *\n * @param valFn either a value or a function that returns a value\n * @param args arguments to pass to the function if `valFn` is a function\n *\n * @internal\n */\nexport function toValueWithArgs<T, Args extends any[]>(\n valFn: T | ((...args: Args) => T),\n ...args: Args\n): T {\n return typeof valFn === 'function' ? (valFn as (...args: Args) => T)(...args) : valFn\n}\n\n/**\n * A value of type T, or a function that resolves T from a single params object.\n *\n * @internal\n */\nexport type ValueOrFn<T, P = any> = T | ((params: P) => T)\n\n/**\n * Extracts the param type from a single-arg function, or `never` for\n * non-function inputs. Pairs with {@link ValueOrFn}.\n *\n * @internal\n */\nexport type ExtractFnParam<T> = T extends (params: infer P) => any ? P : never\n\n/**\n * Converts a union of types to their intersection.\n *\n * @internal\n */\nexport type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never\n\n/**\n * `true` when `T` is the `any` type.\n *\n * @internal\n */\nexport type IsAny<Type> = 0 extends 1 & Type ? true : false\n\n/**\n * `true` when `T` is the `unknown` type (and not `any`).\n *\n * @internal\n */\nexport type IsUnknown<Type> = IsAny<Type> extends true ? false : unknown extends Type ? true : false\n\n/**\n * Expands a type to its property listing so editor hovers show the resolved\n * shape instead of a chain of aliases / intersections.\n *\n * @internal\n */\nexport type Prettify<Type> = {\n [Key in keyof Type]: Type[Key]\n}\n","/* eslint-disable ts/no-empty-object-type -- `{}` is used as the neutral element when intersecting reporter option shapes */\n/* eslint-disable ts/no-unsafe-function-type -- used by captureStackTrace */\n\nimport type { ExtractFnParam, IsUnknown, Prettify, UnionToIntersection, ValueOrFn } from './utils'\nimport { formatDiagnostic } from './formatters/plain'\nimport { toValueWithArgs } from './utils'\n\n/**\n * Define-time shape of a diagnostic. Each field can be a static value or a\n * function that resolves it from a shared `params` object passed at call\n * time. Runtime-only fields (`cause`, `sources`) from {@link DiagnosticInit}\n * are intentionally omitted: they're only meaningful at the call site.\n */\nexport interface DiagnosticDefinition<P = any> {\n /**\n * The error message: why this failed. String, or a function of `params`.\n *\n * @example\n * ```ts\n * why: (p: { name: string }) => `module \"${p.name}\" failed to load`\n * ```\n */\n why: ValueOrFn<string, P>\n\n /**\n * Actionable instructions on how to resolve the problem. String, or a\n * function of `params`.\n *\n * @example\n * ```ts\n * fix: (p: { name: string }) => `run \"npm install ${p.name}\"`\n * ```\n */\n fix?: ValueOrFn<string, P>\n\n /**\n * Per-code docs URL. A string overrides\n * {@link DefineDiagnosticsOptions.docsBase} for this code; `false` opts this\n * code out entirely, even when `docsBase` is set. When omitted, the URL is\n * derived from `docsBase`.\n */\n docs?: string | false\n}\n\n/**\n * Runtime-only fields that can be passed alongside the interpolation params\n * at call time. Merged into the same object so callers pass everything in\n * one place.\n */\nexport interface DiagnosticCallParams {\n /**\n * Original error or exception that triggered this diagnostic. Pass it\n * through when re-throwing so the original stack trace is preserved.\n */\n cause?: unknown\n\n /**\n * Locations in user code that contributed to this diagnostic, in\n * `file:line:column` format. Useful for compilers and other tools where the\n * JS stack trace doesn't reflect the user's source.\n */\n sources?: string[]\n}\n\n/**\n * Structured initializer for a {@link Diagnostic}. `why` is the only required\n * field: it becomes the {@link Diagnostic.message}. The remaining fields are\n * optional metadata that reporters and consumers can render or forward.\n */\nexport interface DiagnosticInit extends DiagnosticCallParams {\n /**\n * The actual error message: why this failed.\n * Mirrored to `Error.message`.\n */\n why: string\n\n /**\n * Optional actionable instructions on how to resolve the problem.\n */\n fix?: string\n\n /**\n * URL to extended documentation for this diagnostic.\n */\n docs?: string\n}\n\n/**\n * Represents how to report a diagnostic. Could call `console.log()`, send the\n * diagnostic to a server, or something else. Reporters declare the shape of\n * options they need via `ReporterOpts`; `defineDiagnostics` intersects every\n * reporter's options into a single object passed at the call site.\n */\nexport type DiagnosticReporter<ReporterOpts extends object = {}> = (\n diagnostic: Diagnostic,\n options: ReporterOpts,\n) => void\n\n/**\n * Permissive reporter constraint used internally so reporters with 1 arg,\n * required options, or optional options all satisfy the array constraint.\n *\n * @internal\n */\nexport type AnyDiagnosticReporter = (diagnostic: Diagnostic, options: any) => void\n\n/**\n * The `console` methods a log reporter can route to.\n */\nexport type ConsoleMethod = 'log' | 'error' | 'warn'\n\n/**\n * Options for {@link createConsoleReporter}.\n */\nexport interface ConsoleReporterOptions {\n /**\n * `console` method used to print the diagnostic. Defaults to `'warn'`. The\n * returned reporter still accepts a per-call `{ method }` override through\n * the call-site reporter options.\n */\n method?: ConsoleMethod\n\n /**\n * Renders the diagnostic into the string handed to `console`. Defaults to\n * {@link formatDiagnostic}, the plain unicode-decorated formatter.\n */\n formatter?: (diagnostic: Diagnostic) => string\n}\n\n/**\n * Creates a console reporter that renders each diagnostic with `formatter` and\n * prints the result via `console[method]`. Both default sensibly (`'warn'` and\n * {@link formatDiagnostic}); `method` can also be overridden per call through\n * the reporter options.\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function createConsoleReporter({\n method: defaultMethod = 'warn',\n formatter = formatDiagnostic,\n}: ConsoleReporterOptions = {}): DiagnosticReporter<{ method?: ConsoleMethod }> {\n return (diagnostic, { method = defaultMethod } = {}) => {\n // eslint-disable-next-line no-console\n console[method](formatter(diagnostic))\n }\n}\n\n/**\n * Resolves the `params` type a code expects from the intersection of params\n * across all function-typed fields, falling back to `{}` when every field is\n * static. Merged with {@link DiagnosticCallParams} at the call site.\n *\n * @internal\n */\ntype InferCodeParams<Def> = [ExtractFnParam<Def[keyof Def]>] extends [never]\n ? {}\n : UnionToIntersection<ExtractFnParam<Def[keyof Def]>>\n\n/**\n * Options for {@link defineDiagnostics}.\n */\nexport interface DefineDiagnosticsOptions<\n Codes extends Record<string, DiagnosticDefinition>,\n Reporters extends readonly AnyDiagnosticReporter[],\n> {\n /**\n * Base URL or resolver for documentation links. When a string, the code is\n * appended as a lowercase path segment (e.g. `\"https://docs.example.com\"` →\n * `\"https://docs.example.com/math_e001\"`). When a function, receives the\n * code and returns a URL or `undefined`.\n */\n docsBase?: string | ((code: keyof Codes) => string | undefined)\n\n /**\n * Map of diagnostic codes to their definitions.\n */\n codes: Codes\n\n /**\n * Reporters called every time a diagnostic is produced. Can be used to\n * integrate with custom logging.\n */\n reporters?: Reporters\n}\n\n/**\n * The first positional argument of a {@link DiagnosticHandle} call:\n * interpolation params merged with the runtime-only call-site fields\n * (`cause`, `sources`).\n *\n * @internal\n */\ntype CallSiteParams<Params> = Params & DiagnosticCallParams\n\n/**\n * Resolves the full argument tuple for a {@link DiagnosticHandle} call.\n * Branches on whether params and reporter options each have required fields.\n * Required positions become required tuple elements, all-optional ones\n * become `?`, and when no reporter declares any options the parameter is\n * omitted entirely.\n *\n * @internal\n */\ntype ActionArgs<Params, ReporterOpts> = keyof ReporterOpts extends never\n ? {} extends Params\n ? [params?: CallSiteParams<Params>]\n : [params: CallSiteParams<Params>]\n : {} extends ReporterOpts\n ? {} extends Params\n ? [params?: CallSiteParams<Params>, reporterOptions?: ReporterOpts]\n : [params: CallSiteParams<Params>, reporterOptions?: ReporterOpts]\n : {} extends Params\n ? [params: CallSiteParams<Params> | undefined, reporterOptions: ReporterOpts]\n : [params: CallSiteParams<Params>, reporterOptions: ReporterOpts]\n\n/**\n * Per-code handle exposed by {@link defineDiagnostics}. Each code is a\n * callable: invoke it to build the diagnostic and run every reporter, or\n * prefix the call with `throw` to raise it.\n *\n * @example\n * ```ts\n * diagnostics.MATH_E001({ name: 'x' }) // report\n * throw diagnostics.MATH_E001({ name: 'x' }) // throw\n * ```\n */\nexport interface DiagnosticHandle<Params, ReporterOpts> {\n /**\n * Builds the diagnostic, runs every reporter, and returns the diagnostic\n * instance. The returned diagnostic can be inspected, attached as `cause`,\n * or thrown with `throw`.\n */\n (...args: ActionArgs<Params, ReporterOpts>): Diagnostic\n}\n\n/**\n * Return type of {@link defineDiagnostics}.\n */\nexport type Diagnostics<\n Codes extends Record<string, DiagnosticDefinition>,\n Reporters extends readonly AnyDiagnosticReporter[],\n> = {\n [Code in keyof Codes]: DiagnosticHandle<\n InferCodeParams<Codes[Code]>,\n Prettify<ExtractReportersOptions<Reporters>>\n >\n}\n\nconst captureStackTrace = (\n Error as { captureStackTrace?: (target: object, frame: Function) => void }\n).captureStackTrace\n\nexport class Diagnostic extends Error {\n name: string = 'Diagnostic'\n\n /**\n * URL to extended documentation for this diagnostic code.\n * Auto-generated from {@link DefineDiagnosticsOptions.docsBase}.\n */\n docs?: string\n\n /**\n * Optional actionable instructions on how to resolve the problem.\n */\n fix?: string\n\n /**\n * Locations in user code that contributed to this diagnostic, in\n * `file:line:column` format. Relevant when the stack trace doesn't reflect\n * the user's source (e.g. compilers, bundlers), otherwise redundant with the\n * stack and should be omitted.\n */\n sources?: string[]\n\n /**\n * Alias for {@link Error.message}: the reason this diagnostic was raised.\n */\n get why(): string {\n return this.message\n }\n\n /**\n * @param init structured initializer; `why` is required\n * @param captureFrom V8 stack-cutoff frame. Defaults to {@link Diagnostic}\n * so the top of the trace is the `new Diagnostic(...)` call site.\n * `defineDiagnostics` passes its action method to strip its own frames too.\n * Ignored on engines without `Error.captureStackTrace`.\n */\n constructor(init: DiagnosticInit, captureFrom: Function = Diagnostic) {\n super(init.why, { cause: init.cause })\n this.fix = init.fix\n this.docs = init.docs\n this.sources = init.sources\n // V8-only API, but also implemented pretty much everywhere. Worst case\n // scenario, we fall back to the stack `Error` captures by default, which\n // includes a couple of extra internal frames but is still usable.\n captureStackTrace?.(this, captureFrom)\n }\n\n /**\n * Converts the diagnostic into a serializable structured object.\n */\n toJSON(): object {\n return {\n name: this.name,\n why: this.why,\n fix: this.fix,\n docs: this.docs,\n sources: this.sources,\n cause: this.cause,\n stack: this.stack,\n }\n }\n}\n\n/**\n * Resolves the docs URL for a code from a `docsBase` (string template or\n * resolver function). Shared by {@link defineDiagnostics} and\n * {@link defineProdDiagnostics}. Per-code `docs` overrides are handled by the\n * caller; this only covers the `docsBase`-derived case.\n *\n * @internal\n */\nexport function deriveDocs(\n docsBase: string | ((code: any) => string | undefined) | undefined,\n code: string,\n): string | undefined {\n return typeof docsBase === 'string' ? `${docsBase}/${code.toLowerCase()}` : docsBase?.(code)\n}\n\n/**\n * Creates a typed diagnostics object from a set of code definitions. Each\n * code becomes a callable {@link DiagnosticHandle}: invoke to report, or\n * `throw` the result to raise. No `new` required, no proxy.\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function defineDiagnostics<\n const Codes extends Record<string, DiagnosticDefinition>,\n const Reporters extends readonly AnyDiagnosticReporter[],\n>(options: DefineDiagnosticsOptions<Codes, Reporters>): Diagnostics<Codes, Reporters> {\n const reporters = options.reporters ?? []\n const result = {} as Diagnostics<Codes, Reporters>\n\n const { docsBase } = options\n\n for (const code of Object.keys(options.codes) as Extract<keyof Codes, string>[]) {\n const def = options.codes[code]\n // skip docs if set to false, otherwise use it or derive it from docsBase\n const docs = def.docs === false ? undefined : def.docs || deriveDocs(docsBase, code)\n\n const handle = (\n params: DiagnosticCallParams & Record<string, unknown> = {},\n reporterOptions: any = {},\n ): Diagnostic => {\n const diagnostic = new Diagnostic(\n {\n why: toValueWithArgs(def.why, params),\n fix: toValueWithArgs(def.fix, params),\n docs,\n cause: params.cause,\n sources: params.sources,\n },\n handle,\n )\n diagnostic.name = code\n for (const reporter of reporters) reporter(diagnostic, reporterOptions)\n return diagnostic\n }\n\n result[code] = handle as unknown as Diagnostics<Codes, Reporters>[typeof code]\n }\n\n return result\n}\n\n/**\n * Extracts the options object a reporter accepts as its 2nd argument. Returns\n * `{}` when the reporter has no 2nd arg (so it contributes nothing to the\n * merged shape).\n */\ntype ExtractSingleReporterOptions<Reporter> = Reporter extends (\n diagnostic: Diagnostic,\n options: infer ReporterOpts,\n) => any\n ? IsUnknown<ReporterOpts> extends true\n ? {}\n : Exclude<ReporterOpts, undefined>\n : {}\n\n/**\n * Intersects every reporter's options shape into a single object. If any\n * reporter has a required field, the merged shape has a required field, and\n * {@link ActionArgs} flips `reporterOptions` from optional to required via\n * `{} extends Merged`.\n */\ntype ExtractReportersOptions<Reporters extends readonly any[]> = Reporters extends readonly [\n infer First,\n ...infer Rest,\n]\n ? ExtractSingleReporterOptions<First> & ExtractReportersOptions<Rest>\n : {}\n","import type {\n AnyDiagnosticReporter,\n DiagnosticCallParams,\n DiagnosticDefinition,\n Diagnostics,\n} from './diagnostic'\nimport { deriveDocs, Diagnostic } from './diagnostic'\n\n/**\n * Options for {@link defineProdDiagnostics}. A lean subset of\n * {@link DefineDiagnosticsOptions}: no `codes` map (the proxy serves any code),\n * only what is needed to keep behaviour correct in production.\n */\nexport interface DefineProdDiagnosticsOptions<\n Reporters extends readonly AnyDiagnosticReporter[] = readonly AnyDiagnosticReporter[],\n> {\n /**\n * Base URL or resolver for documentation links, identical to\n * {@link DefineDiagnosticsOptions.docsBase}. The docs URL is derived from the\n * accessed code at call time, so links survive even without the catalog.\n */\n docsBase?: string | ((code: string) => string | undefined)\n\n /**\n * Reporters called every time a diagnostic is produced. Omitted by default in\n * production builds; the strip plugin can copy them into the prod branch when\n * prod-time reporting (e.g. telemetry) is desired.\n */\n reporters?: Reporters\n}\n\n/**\n * Production counterpart to {@link defineDiagnostics}. Returns a `Proxy` that\n * builds a minimal {@link Diagnostic} for any accessed code: the code becomes\n * both the `message` (`why`) and the instance `name`, and `docs` is derived\n * from `docsBase`. It carries no catalog text, so it stays tiny in a bundle.\n *\n * The strip plugin (`@nostics/unplugin`) can rewrite a `defineDiagnostics()`\n * call into a `process.env.NODE_ENV === 'production'` ternary that selects this\n * factory in production, dropping every `why`/`fix` string from the bundle.\n *\n * @example\n * ```ts\n * const diagnostics = defineProdDiagnostics({ docsBase: 'https://docs.example.com' })\n * throw diagnostics.NUXT_B2011() // Error: NUXT_B2011, docs derived from docsBase\n * ```\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function defineProdDiagnostics<\n const Codes extends Record<string, DiagnosticDefinition> = Record<string, DiagnosticDefinition>,\n const Reporters extends readonly AnyDiagnosticReporter[] = readonly AnyDiagnosticReporter[],\n>(options: DefineProdDiagnosticsOptions<Reporters> = {}): Diagnostics<Codes, Reporters> {\n const { docsBase, reporters = [] } = options\n\n return new Proxy({} as Diagnostics<Codes, Reporters>, {\n get(_target, code) {\n // ignore symbol / non-string probes (e.g. `then`, `Symbol.toPrimitive`)\n if (typeof code !== 'string')\n return undefined\n\n const handle = (\n params: DiagnosticCallParams & Record<string, unknown> = {},\n reporterOptions: any = {},\n ): Diagnostic => {\n const diagnostic = new Diagnostic(\n {\n why: code,\n docs: deriveDocs(docsBase, code),\n cause: params.cause,\n sources: params.sources,\n },\n handle,\n )\n diagnostic.name = code\n for (const reporter of reporters) reporter(diagnostic, reporterOptions)\n return diagnostic\n }\n\n return handle\n },\n })\n}\n"],"mappings":"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"}
{
"name": "nostics",
"type": "module",
"version": "1.1.3",
"version": "1.1.4",
"description": "Structured diagnostic code library",

@@ -58,3 +58,3 @@ "author": "Anthony Fu <anthonyfu117@hotmail.com>",

"vitest": "^4.1.8",
"nostics": "1.1.3"
"nostics": "1.1.4"
},

@@ -118,5 +118,9 @@ "simple-git-hooks": {

"size": "size-limit",
"test": "pnpm run build && vitest run --coverage && pnpm -C demo-lib run build && pnpm -C playground run build && pnpm run typecheck && pnpm run lint",
"test": "pnpm run build && pnpm run \"/^test:/\"",
"test:unit": "vitest run --coverage",
"test:types": "pnpm run typecheck",
"test:lint": "pnpm run lint",
"test:demo": "pnpm -C demo-lib run build && pnpm -C demo-lib run test && pnpm -C playground run build",
"typecheck": "tsc && pnpm --filter \"./packages/*\" run typecheck"
}
}