Skip to content

Commit c76003c

Browse files
refactor: use internal validate when avaliable
1 parent fa79731 commit c76003c

2 files changed

Lines changed: 49 additions & 173 deletions

File tree

src/index.js

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
const mime = require("mime-types");
2-
const { validate } = require("schema-utils");
32

43
const middleware = require("./middleware");
5-
const schema = require("./options.json");
64
const getFilenameFromUrl = require("./utils/getFilenameFromUrl");
75
const ready = require("./utils/ready");
86
const setupHooks = require("./utils/setupHooks");
@@ -194,15 +192,42 @@ const noop = () => {};
194192
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
195193
* @template {ServerResponse} [ResponseInternal=ServerResponse]
196194
* @param {Compiler | MultiCompiler} compiler compiler
197-
* @param {Options<RequestInternal, ResponseInternal>=} options options
198-
* @param {boolean} isPlugin true when will use as a plugin, otherwise false
199-
* @returns {API<RequestInternal, ResponseInternal>} webpack dev middleware
195+
* @param {Options<RequestInternal, ResponseInternal>} options options
200196
*/
201-
function wdm(compiler, options = {}, isPlugin = false) {
197+
const internalValidate = (compiler, options) => {
198+
const schema = require("./options.json");
199+
200+
const firstCompiler = Array.isArray(compiler)
201+
? compiler[0]
202+
: /** @type {Compiler} */ compiler;
203+
204+
if (typeof firstCompiler.validate === "function") {
205+
firstCompiler.validate(schema, options, {
206+
name: "Dev Middleware",
207+
baseDataPath: "options",
208+
});
209+
return;
210+
}
211+
212+
// TODO bump minimum supported webpack version and remove it in favor of `compiler.validate` (above)
213+
const { validate } = require("schema-utils");
214+
202215
validate(/** @type {Schema} */ (schema), options, {
203216
name: "Dev Middleware",
204217
baseDataPath: "options",
205218
});
219+
};
220+
221+
/**
222+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
223+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
224+
* @param {Compiler | MultiCompiler} compiler compiler
225+
* @param {Options<RequestInternal, ResponseInternal>=} options options
226+
* @param {boolean} isPlugin true when will use as a plugin, otherwise false
227+
* @returns {API<RequestInternal, ResponseInternal>} webpack dev middleware
228+
*/
229+
function wdm(compiler, options = {}, isPlugin = false) {
230+
internalValidate(compiler, options);
206231

207232
const { mimeTypes } = options;
208233

types/index.d.ts

Lines changed: 18 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,4 @@
11
export = wdm;
2-
/** @typedef {import("schema-utils/declarations/validate").Schema} Schema */
3-
/** @typedef {import("webpack").Compiler} Compiler */
4-
/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
5-
/** @typedef {import("webpack").Configuration} Configuration */
6-
/** @typedef {import("webpack").Stats} Stats */
7-
/** @typedef {import("webpack").MultiStats} MultiStats */
8-
/** @typedef {import("fs").ReadStream} ReadStream */
9-
/**
10-
* @typedef {object} ExtendedServerResponse
11-
* @property {{ webpack?: { devMiddleware?: Context<IncomingMessage, ServerResponse> } }=} locals locals
12-
*/
13-
/** @typedef {import("http").IncomingMessage} IncomingMessage */
14-
/** @typedef {import("http").ServerResponse & ExtendedServerResponse} ServerResponse */
15-
/** @typedef {any} EXPECTED_ANY */
16-
/** @typedef {Function} EXPECTED_FUNCTION */
17-
/**
18-
* @callback NextFunction
19-
* @param {EXPECTED_ANY=} err error
20-
* @returns {void}
21-
*/
22-
/**
23-
* @typedef {NonNullable<Configuration["watchOptions"]>} WatchOptions
24-
*/
25-
/**
26-
* @typedef {Compiler["watching"]} Watching
27-
*/
28-
/**
29-
* @typedef {ReturnType<MultiCompiler["watch"]>} MultiWatching
30-
*/
31-
/**
32-
* @typedef {import("webpack").OutputFileSystem & { createReadStream?: import("fs").createReadStream, statSync: import("fs").statSync, readFileSync: import("fs").readFileSync }} OutputFileSystem
33-
*/
34-
/** @typedef {ReturnType<Compiler["getInfrastructureLogger"]>} Logger */
35-
/**
36-
* @callback Callback
37-
* @param {(Stats | MultiStats)=} stats
38-
*/
39-
/**
40-
* @typedef {object} ResponseData
41-
* @property {Buffer | ReadStream} data data
42-
* @property {number} byteLength byte length
43-
*/
44-
/**
45-
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
46-
* @template {ServerResponse} [ResponseInternal=ServerResponse]
47-
* @callback ModifyResponseData
48-
* @param {RequestInternal} req req
49-
* @param {ResponseInternal} res res
50-
* @param {Buffer | ReadStream} data data
51-
* @param {number} byteLength byte length
52-
* @returns {ResponseData}
53-
*/
54-
/**
55-
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
56-
* @template {ServerResponse} [ResponseInternal=ServerResponse]
57-
* @typedef {object} Context
58-
* @property {boolean} state state
59-
* @property {Stats | MultiStats | undefined} stats stats
60-
* @property {Callback[]} callbacks callbacks
61-
* @property {Options<RequestInternal, ResponseInternal>} options options
62-
* @property {Compiler | MultiCompiler} compiler compiler
63-
* @property {Watching | MultiWatching | undefined} watching watching
64-
* @property {Logger} logger logger
65-
* @property {OutputFileSystem} outputFileSystem output file system
66-
*/
67-
/**
68-
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
69-
* @template {ServerResponse} [ResponseInternal=ServerResponse]
70-
* @typedef {WithoutUndefined<Context<RequestInternal, ResponseInternal>, "watching">} FilledContext
71-
*/
72-
/** @typedef {Record<string, string | number> | { key: string, value: number | string }[]} NormalizedHeaders */
73-
/**
74-
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
75-
* @template {ServerResponse} [ResponseInternal=ServerResponse]
76-
* @typedef {NormalizedHeaders | ((req: RequestInternal, res: ResponseInternal, context: Context<RequestInternal, ResponseInternal>) => void | undefined | NormalizedHeaders) | undefined} Headers
77-
*/
78-
/**
79-
* @template {IncomingMessage} [RequestInternal = IncomingMessage]
80-
* @template {ServerResponse} [ResponseInternal = ServerResponse]
81-
* @typedef {object} Options
82-
* @property {{ [key: string]: string }=} mimeTypes mime types
83-
* @property {(string | undefined)=} mimeTypeDefault mime type default
84-
* @property {(boolean | ((targetPath: string) => boolean))=} writeToDisk write to disk
85-
* @property {string[]=} methods methods
86-
* @property {Headers<RequestInternal, ResponseInternal>=} headers headers
87-
* @property {NonNullable<Configuration["output"]>["publicPath"]=} publicPath public path
88-
* @property {Configuration["stats"]=} stats stats
89-
* @property {boolean=} serverSideRender is server side render
90-
* @property {OutputFileSystem=} outputFileSystem output file system
91-
* @property {(boolean | string)=} index index
92-
* @property {ModifyResponseData<RequestInternal, ResponseInternal>=} modifyResponseData modify response data
93-
* @property {"weak" | "strong"=} etag options to generate etag header
94-
* @property {boolean=} lastModified options to generate last modified header
95-
* @property {(boolean | number | string | { maxAge?: number, immutable?: boolean })=} cacheControl options to generate cache headers
96-
* @property {boolean=} cacheImmutable is cache immutable
97-
* @property {boolean=} forwardError forward error to next middleware
98-
*/
99-
/**
100-
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
101-
* @template {ServerResponse} [ResponseInternal=ServerResponse]
102-
* @callback Middleware
103-
* @param {RequestInternal} req request
104-
* @param {ResponseInternal} res response
105-
* @param {NextFunction} next next function
106-
* @returns {Promise<void>}
107-
*/
108-
/** @typedef {import("./utils/getFilenameFromUrl").Extra} Extra */
109-
/**
110-
* @callback GetFilenameFromUrl
111-
* @param {string} url request URL
112-
* @returns {{ filename: string, extra: Extra } | undefined} a filename with additional information, or `undefined` if nothing is found
113-
*/
114-
/**
115-
* @callback WaitUntilValid
116-
* @param {Callback} callback
117-
*/
118-
/**
119-
* @callback Invalidate
120-
* @param {Callback} callback
121-
*/
122-
/**
123-
* @callback Close
124-
* @param {(err: Error | null | undefined) => void} callback
125-
*/
126-
/**
127-
* @template {IncomingMessage} RequestInternal
128-
* @template {ServerResponse} ResponseInternal
129-
* @typedef {object} AdditionalMethods
130-
* @property {GetFilenameFromUrl} getFilenameFromUrl get filename from url
131-
* @property {WaitUntilValid} waitUntilValid wait until valid
132-
* @property {Invalidate} invalidate invalidate
133-
* @property {Close} close close
134-
* @property {Context<RequestInternal, ResponseInternal>} context context
135-
*/
136-
/**
137-
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
138-
* @template {ServerResponse} [ResponseInternal=ServerResponse]
139-
* @typedef {Middleware<RequestInternal, ResponseInternal> & AdditionalMethods<RequestInternal, ResponseInternal>} API
140-
*/
141-
/**
142-
* @template T
143-
* @template {keyof T} K
144-
* @typedef {Omit<T, K> & Partial<T>} WithOptional
145-
*/
146-
/**
147-
* @template T
148-
* @template {keyof T} K
149-
* @typedef {T & { [P in K]: NonNullable<T[P]> }} WithoutUndefined
150-
*/
1512
/**
1523
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
1534
* @template {ServerResponse} [ResponseInternal=ServerResponse]
@@ -169,6 +20,9 @@ declare namespace wdm {
16920
hapiWrapper,
17021
koaWrapper,
17122
honoWrapper,
23+
HapiPluginBase,
24+
HapiPlugin,
25+
HapiOptions,
17226
Schema,
17327
Compiler,
17428
MultiCompiler,
@@ -205,9 +59,6 @@ declare namespace wdm {
20559
API,
20660
WithOptional,
20761
WithoutUndefined,
208-
HapiPluginBase,
209-
HapiPlugin,
210-
HapiOptions,
21162
};
21263
}
21364
/**
@@ -266,6 +117,21 @@ declare function honoWrapper<
266117
options?: Options<RequestInternal, ResponseInternal> | undefined,
267118
usePlugin?: boolean | undefined,
268119
): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void;
120+
type HapiPluginBase<S, O> = {
121+
/**
122+
* register
123+
*/
124+
register: (server: S, options: O) => void | Promise<void>;
125+
};
126+
type HapiPlugin<S, O> = HapiPluginBase<S, O> & {
127+
pkg: {
128+
name: string;
129+
};
130+
multiple: boolean;
131+
};
132+
type HapiOptions = Options & {
133+
compiler: Compiler | MultiCompiler;
134+
};
269135
type Schema = import("schema-utils/declarations/validate").Schema;
270136
type Compiler = import("webpack").Compiler;
271137
type MultiCompiler = import("webpack").MultiCompiler;
@@ -514,18 +380,3 @@ type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
514380
type WithoutUndefined<T, K extends keyof T> = T & {
515381
[P in K]: NonNullable<T[P]>;
516382
};
517-
type HapiPluginBase<S, O> = {
518-
/**
519-
* register
520-
*/
521-
register: (server: S, options: O) => void | Promise<void>;
522-
};
523-
type HapiPlugin<S, O> = HapiPluginBase<S, O> & {
524-
pkg: {
525-
name: string;
526-
};
527-
multiple: boolean;
528-
};
529-
type HapiOptions = Options & {
530-
compiler: Compiler | MultiCompiler;
531-
};

0 commit comments

Comments
 (0)