Skip to content

Commit 4ee6b01

Browse files
feat: add argument validation using joi
1 parent 8e421b1 commit 4ee6b01

File tree

3 files changed

+74
-20
lines changed

3 files changed

+74
-20
lines changed

package-lock.json

Lines changed: 45 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"@babel/generator": "^7.22.9",
6363
"@babel/parser": "^7.22.7",
6464
"@babel/traverse": "^7.22.8",
65-
"@rollup/pluginutils": "^5.0.2"
65+
"@rollup/pluginutils": "^5.0.2",
66+
"joi": "^17.9.2"
6667
}
6768
}

src/index.ts

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { parse } from "@babel/parser";
33
import traverse from "@babel/traverse";
44
import { createFilter } from "@rollup/pluginutils";
55
import fs from "fs/promises";
6+
import Joi from "joi";
67
import path from "path";
78
import { Plugin } from "rollup";
89

@@ -11,15 +12,6 @@ const PREFIX = `\0${PLUGIN_NAME}:`;
1112

1213
export type FilterPattern = string | RegExp | (string | RegExp)[];
1314

14-
export function isFilterPattern(value: unknown): value is FilterPattern {
15-
let tmp: unknown[];
16-
17-
if (Array.isArray(value)) tmp = value;
18-
else tmp = [value];
19-
20-
return tmp.every((e) => typeof e === "string" || e instanceof RegExp);
21-
}
22-
2315
export interface ExternalAssetsOptions {
2416
/** A pattern, or array of patterns, to match files the plugin should ignore. */
2517
include: FilterPattern;
@@ -29,6 +21,29 @@ export interface ExternalAssetsOptions {
2921
resolve?: string;
3022
}
3123

24+
const union = Joi.alternatives(Joi.string(), Joi.object().regex());
25+
const patternSchema = Joi.alternatives<FilterPattern>(
26+
union,
27+
Joi.array().items(union).min(1)
28+
);
29+
const optionsSchema = Joi.object<ExternalAssetsOptions>({
30+
include: patternSchema.required(),
31+
exclude: patternSchema,
32+
resolve: Joi.string(),
33+
});
34+
35+
function validate(arg: unknown): ExternalAssetsOptions {
36+
const pattern = patternSchema.validate(arg);
37+
38+
if (!pattern.error) return { include: pattern.value };
39+
40+
const options = optionsSchema.validate(arg);
41+
42+
if (!options.error) return options.value;
43+
44+
throw new TypeError("Invalid argument");
45+
}
46+
3247
/**
3348
* Make assets external but include them in the output.
3449
* @param options The options object.
@@ -41,15 +56,9 @@ function externalAssets(options: ExternalAssetsOptions): Plugin;
4156
*/
4257
function externalAssets(pattern: FilterPattern): Plugin;
4358

44-
function externalAssets(arg: FilterPattern | ExternalAssetsOptions): Plugin {
45-
let idFilter: ReturnType<typeof createFilter>;
46-
47-
if (isFilterPattern(arg)) {
48-
idFilter = createFilter(arg);
49-
} else {
50-
const { include, exclude, resolve } = arg;
51-
idFilter = createFilter(include, exclude, { resolve });
52-
}
59+
function externalAssets(arg: unknown): Plugin {
60+
const { include, exclude, resolve } = validate(arg);
61+
const idFilter = createFilter(include, exclude, { resolve });
5362

5463
return {
5564
name: PLUGIN_NAME,

0 commit comments

Comments
 (0)