From c293d8c4b917e00ec0d9e988ad3d9cb4cf7c7dff Mon Sep 17 00:00:00 2001 From: Horie Issei Date: Thu, 19 May 2022 08:43:12 +0900 Subject: [PATCH] fix: correct ListOptions type (#304) --- index.d.ts | 15 +++++++++++---- lib/dirList.js | 12 +++++++++--- test/dir-list.test.js | 18 +++++++++++++++++- test/types/index.ts | 32 +++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 9 deletions(-) diff --git a/index.d.ts b/index.d.ts index 99c2494..043044e 100644 --- a/index.d.ts +++ b/index.d.ts @@ -43,13 +43,20 @@ interface ListRender { } interface ListOptions { - format: 'json' | 'html'; - names: string[]; - render: ListRender; + names?: string[]; extendedFolderInfo?: boolean; +} + +interface ListOptionsJsonFormat extends ListOptions { + format: 'json'; jsonFormat?: 'names' | 'extended'; } +interface ListOptionsHtmlFormat extends ListOptions { + format: 'html'; + render: ListRender; +} + // Passed on to `send` interface SendOptions { acceptRanges?: boolean; @@ -73,7 +80,7 @@ export interface FastifyStaticOptions extends SendOptions { setHeaders?: (...args: any[]) => void; redirect?: boolean; wildcard?: boolean; - list?: boolean | ListOptions; + list?: boolean | ListOptionsJsonFormat | ListOptionsHtmlFormat; allowedPath?: (pathName: string, root?: string) => boolean; /** * @description diff --git a/lib/dirList.js b/lib/dirList.js index af17118..3b5f0cf 100644 --- a/lib/dirList.js +++ b/lib/dirList.js @@ -8,7 +8,7 @@ const dirList = { /** * get files and dirs from dir, or error * @param {string} dir full path fs dir - * @param {ListOptions} options + * @param {(boolean | ListOptionsJsonFormat | ListOptionsHtmlFormat)} options * @param {string} dotfiles * note: can't use glob because don't get error on non existing dir */ @@ -99,7 +99,7 @@ const dirList = { * send dir list content, or 404 on error * @param {Fastify.Reply} reply * @param {string} dir full path fs dir - * @param {ListOptions} options + * @param {(boolean | ListOptionsJsonFormat | ListOptionsHtmlFormat)} options * @param {string} route request route * @param {string} dotfiles */ @@ -151,7 +151,7 @@ const dirList = { /** * say if the route can be handled by dir list or not * @param {string} route request route - * @param {ListOptions} options + * @param {(boolean | ListOptionsJsonFormat | ListOptionsHtmlFormat)} options * @return {boolean} */ handle: function (route, options) { @@ -194,9 +194,15 @@ const dirList = { if (options.list.names && !Array.isArray(options.list.names)) { return new TypeError('The `list.names` option must be an array') } + if (options.list.jsonFormat != null && options.list.jsonFormat !== 'names' && options.list.jsonFormat !== 'extended') { + return new TypeError('The `list.jsonFormat` option must be name or extended') + } if (options.list.format === 'html' && typeof options.list.render !== 'function') { return new TypeError('The `list.render` option must be a function and is required with html format') } + if (options.list.format === 'html' && options.list.jsonFormat != null) { + return new TypeError('The `list.jsonFormat` option must be with json format') + } } } diff --git a/test/dir-list.test.js b/test/dir-list.test.js index 996b756..7572fc4 100644 --- a/test/dir-list.test.js +++ b/test/dir-list.test.js @@ -40,7 +40,7 @@ t.test('throws when `root` is an array', t => { t.equal(err.message, 'multi-root with list option is not supported') }) -t.test('throws when `list.format option` is invalid', t => { +t.test('throws when `list.format` option is invalid', t => { t.plan(2) const err = dirList.validateOptions({ list: { format: 'hello' } }) @@ -56,6 +56,14 @@ t.test('throws when `list.names option` is not an array', t => { t.equal(err.message, 'The `list.names` option must be an array') }) +t.test('throws when `list.jsonFormat` option is invalid', t => { + t.plan(2) + + const err = dirList.validateOptions({ list: { jsonFormat: 'hello' } }) + t.type(err, TypeError) + t.equal(err.message, 'The `list.jsonFormat` option must be name or extended') +}) + t.test('throws when `list.format` is html and `list render` is not a function', t => { t.plan(2) @@ -64,6 +72,14 @@ t.test('throws when `list.format` is html and `list render` is not a function', t.equal(err.message, 'The `list.render` option must be a function and is required with html format') }) +t.test('throws when `list.format` is html and `list.jsonFormat` is given', t => { + t.plan(2) + + const err = dirList.validateOptions({ list: { format: 'html', render: () => '', jsonFormat: 'extended' } }) + t.type(err, TypeError) + t.equal(err.message, 'The `list.jsonFormat` option must be with json format') +}) + t.test('dir list wrong options', t => { t.plan(3) diff --git a/test/types/index.ts b/test/types/index.ts index 4f7918d..c26dace 100644 --- a/test/types/index.ts +++ b/test/types/index.ts @@ -1,5 +1,5 @@ import fastify from 'fastify' -import { expectError } from 'tsd' +import { expectAssignable, expectError } from 'tsd' import fastifyStatic, { FastifyStaticOptions } from '../..' const appWithImplicitHttp = fastify() @@ -32,6 +32,36 @@ expectError({ wildcard: '**/**' }) +expectAssignable({ + root: '', + list: { + format: 'json', + } +}) + +expectError({ + root: '', + list: { + format: 'json', + render: () => '' + } +}) + +expectAssignable({ + root: '', + list: { + format: 'html', + render: () => '' + } +}) + +expectError({ + root: '', + list: { + format: 'html', + } +}) + appWithImplicitHttp .register(fastifyStatic, options) .after(() => {