diff --git a/README.md b/README.md index 64261a1..6489363 100644 --- a/README.md +++ b/README.md @@ -5,4 +5,3 @@ - [ ] Add lots of JSDoc comments. - [ ] A Prettier plugin for Svelte inside Markdown. - [ ] Should the `declarationMap` option be set to `true` in `tsconfig.json`. -- [ ] Add back the `declaration` option to `tsconfig.json` and fix type issues. diff --git a/src/isFileIgnored.ts b/src/isFileIgnored.ts index e7065bf..37f87e9 100644 --- a/src/isFileIgnored.ts +++ b/src/isFileIgnored.ts @@ -16,7 +16,7 @@ export const isFileIgnored = ( return true } - for (const extension of config?.extensions ?? []) { + for (const extension of config.extensions) { if (!filename.endsWith(extension)) { return true } diff --git a/src/main.ts b/src/main.ts index 997e7cd..5b0e24a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,6 +3,7 @@ import * as v from "valibot" import { type ConfigInput, + type ConfigOutput, type ConfigCallbacks, ConfigSchema, } from "./types.js" @@ -13,7 +14,8 @@ export const svelteInMarkdown = ( callbacks?: ConfigCallbacks ) => { // NOTE: I created this new variable because TypeScript is stupid and complains about types. We receive the expected values and their types by parsing, but when assigning the variable to the parsed result, TypeScript still complains that the values may be nullable. - const finalConfig = v.parse(ConfigSchema, config) + // NOTE: Added the explicit type because generating Valibot schema with TypeScript types is impossible. Some of the types are added the schema and some other by TypeScript. https://github.com/fabian-hiller/valibot/discussions/477 + const finalConfig: ConfigOutput = v.parse(ConfigSchema, config) return { name: "svelte-in-markdown", diff --git a/src/transformer.ts b/src/transformer.ts index 984e802..0eb01f2 100644 --- a/src/transformer.ts +++ b/src/transformer.ts @@ -23,7 +23,7 @@ export const transformer = async ( processor.use(remarkParse) - if (config?.builtInPlugins?.remarkFrontmatter?.enable) { + if (config.builtInPlugins.remarkFrontmatter.enable) { processor.use(remarkFrontmatter, { type: config.builtInPlugins.remarkFrontmatter.lang, fence: { open: "---", close: "---" }, @@ -35,37 +35,37 @@ export const transformer = async ( // NOTE: The content is striped no matter the value of this option (`strip`). // NOTE: The content won't be striped if the `type` option in `remarkFrontmatter` is set to anything other than `"yaml"`. strip: true, - yaml: config?.builtInPlugins?.vfileMatter?.options, + yaml: config.builtInPlugins.vfileMatter.options, }) } }) } - if (config?.builtInPlugins?.remarkGfm?.enable) { + if (config.builtInPlugins.remarkGfm.enable) { processor.use(remarkGfm, config.builtInPlugins.remarkGfm.options) } - if (config?.builtInPlugins?.remarkUnwrapImages?.enable) { + if (config.builtInPlugins.remarkUnwrapImages.enable) { processor.use(remarkUnwrapImages) } processor.use(remarkRehype, { - ...config?.builtInPlugins?.remarkRehype?.options, + ...config.builtInPlugins.remarkRehype.options, allowDangerousHtml: true, }) - if (config?.builtInPlugins?.rehypeSlug?.enable) { + if (config.builtInPlugins.rehypeSlug.enable) { processor.use(rehypeSlug, config.builtInPlugins.rehypeSlug.options) } - if (config?.builtInPlugins?.rehypeAutolinkHeadings?.enable) { + if (config.builtInPlugins.rehypeAutolinkHeadings.enable) { processor.use( rehypeAutolinkHeadings, config.builtInPlugins.rehypeAutolinkHeadings.options ) } - if (config?.builtInPlugins?.rehypeShiki?.enable) { + if (config.builtInPlugins.rehypeShiki.enable) { processor.use(rehypeShiki, { themes: { light: "vitesse-light", @@ -75,7 +75,7 @@ export const transformer = async ( }) } - if (config?.builtInPlugins?.rehypeExternalLinks?.enable) { + if (config.builtInPlugins.rehypeExternalLinks.enable) { processor.use(rehypeExternalLinks, { rel: (element) => { if (isHrefExternal(element.properties.href?.toString())) { @@ -92,7 +92,7 @@ export const transformer = async ( } processor.use(rehypeStringify, { - ...config?.builtInPlugins?.rehypeStringify?.options, + ...config.builtInPlugins.rehypeStringify.options, allowDangerousCharacters: true, allowDangerousHtml: true, }) diff --git a/src/types.ts b/src/types.ts index 6d5a1f0..c769f6a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -54,13 +54,7 @@ export const ConfigSchema = v.optional( * [View on NPM](https://npmjs.com/package/vfile-matter). * Can be disabled by disabling the `remarkFrontmatter` plugin. */ - vfileMatter: v.optional( - v.object({ - options: v.optional( - v.special(() => true) - ), - }) - ), + vfileMatter: v.optional(v.object({}), {}), /** * [View on NPM](https://npmjs.com/package/remark-frontmatter). @@ -72,12 +66,9 @@ export const ConfigSchema = v.optional( // TODO: Add `"toml"`, `"json"`, `"jsonc"` and `"json5"` support. /** Only `"yaml"` is supported for now. */ lang: v.optional(v.union([v.literal("yaml")]), "yaml"), - options: v.optional( - v.special( - () => true - ) - ), - }) + options: v.optional(v.object({}), {}), + }), + {} ), /** @@ -87,10 +78,8 @@ export const ConfigSchema = v.optional( v.object({ /** @default true */ enable: v.optional(v.boolean(), true), - options: v.optional( - v.special(() => true) - ), - }) + }), + {} ), /** @@ -100,20 +89,15 @@ export const ConfigSchema = v.optional( v.object({ /** @default true */ enable: v.optional(v.boolean(), true), - }) + }), + {} ), /** * [View on NPM](https://npmjs.com/package/remark-rehype). * Can't be disabled. */ - remarkRehype: v.optional( - v.object({ - options: v.optional( - v.special(() => true) - ), - }) - ), + remarkRehype: v.optional(v.object({}), {}), /** * [View on NPM](https://npmjs.com/package/rehype-slug). @@ -122,10 +106,8 @@ export const ConfigSchema = v.optional( v.object({ /** @default false */ enable: v.optional(v.boolean(), false), - options: v.optional( - v.special(() => true) - ), - }) + }), + {} ), /** @@ -135,10 +117,8 @@ export const ConfigSchema = v.optional( v.object({ /** @default false */ enable: v.optional(v.boolean(), false), - options: v.optional( - v.special(() => true) - ), - }) + }), + {} ), /** @@ -148,11 +128,8 @@ export const ConfigSchema = v.optional( v.object({ /** @default true */ enable: v.optional(v.boolean(), true), - options: v.optional( - v.special(() => true), - undefined - ), - }) + }), + {} ), /** @@ -163,26 +140,20 @@ export const ConfigSchema = v.optional( v.object({ /** @default true */ enable: v.optional(v.boolean(), true), - options: v.optional( - v.special(() => true) - ), - }) + }), + {} ), /** * [View on NPM](https://npmjs.com/package/rehype-stringify). * Can't be disabled. */ - rehypeStringify: v.optional( - v.object({ - options: v.optional( - v.special(() => true) - ), - }) - ), - }) + rehypeStringify: v.optional(v.object({}), {}), + }), + {} ), - }) + }), + {} ) // The original types for options suck, this way users will have easier type configuring their custom options. @@ -213,5 +184,69 @@ type OmittedRehypeStringifyOptions = Omit< "allowDangerousCharacters" | "allowDangerousHtml" > -export type ConfigInput = v.Input -export type ConfigOutput = v.Output +// NOTE: Generating Valibot schema with TypeScript types is impossible. https://github.com/fabian-hiller/valibot/discussions/477 +export type ConfigInput = v.Input & { + builtInPlugins?: { + vfileMatter?: { + options?: VfileMatterYamlOptions + } + remarkFrontmatter?: { + options?: RemarkFrontmatterCustomOptions + } + remarkGfm?: { + options?: RemarkGfmOptions + } + remarkRehype?: { + options?: OmittedRemarkRehypeOptions + } + rehypeSlug?: { + options?: RehypeSlugOptions + } + rehypeAutolinkHeadings?: { + options?: RehypeAutolinkHeadingsOptions + } + rehypeShiki?: { + options?: RehypeShikiOptions + } + rehypeExternalLinks?: { + options?: RehypeExternalLinksOptions + } + rehypeStringify?: { + options?: OmittedRehypeStringifyOptions + } + } +} +// NOTE: Generating Valibot schema with TypeScript types is impossible. https://github.com/fabian-hiller/valibot/discussions/477 +export type ConfigOutput = v.Output & { + builtInPlugins: { + vfileMatter: { + options?: VfileMatterYamlOptions + } + remarkFrontmatter: { + options?: RemarkFrontmatterCustomOptions + } + remarkGfm: { + options?: RemarkGfmOptions + } + remarkRehype: { + options?: OmittedRemarkRehypeOptions + } + rehypeSlug: { + options?: RehypeSlugOptions + } + rehypeAutolinkHeadings: { + options?: RehypeAutolinkHeadingsOptions + } + rehypeShiki: { + options?: RehypeShikiOptions + } + rehypeExternalLinks: { + options?: RehypeExternalLinksOptions + } + rehypeStringify: { + options?: OmittedRehypeStringifyOptions + } + } +} + +// TODO: Whenever [this issue](https://github.com/microsoft/TypeScript/issues/42873) resolves, I can move the extra types from `ConfigInput` and `ConfigOutput` to the schema itself. diff --git a/tsconfig.json b/tsconfig.json index f1592bb..eba03d9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "moduleResolution": "NodeNext", "outDir": "dist", "sourceMap": true, - "strict": true + "strict": true, + "declaration": true }, "include": ["./src/**/*"] }