Skip to content

Commit 17e3e27

Browse files
author
Andrea Cosentino
committed
fix: various
1 parent 1f106e0 commit 17e3e27

4 files changed

Lines changed: 40 additions & 12 deletions

File tree

src/models/plugin.model.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1882,7 +1882,20 @@ export type UniversalApiOptions = UniversalApiBaseOptions & (
18821882
);
18831883

18841884
/** @internal */
1885-
export type UniversalApiOptionsRequired = Omit<Required<UniversalApiOptions>, "handlerMiddlewares" | "endpointPrefix"> & { endpointPrefix: string[], fullFsDir: string | null, config: ResolvedConfig, matcher: AntPathMatcher, middlewares: UniversalApiMiddleware[] };
1885+
export type UniversalApiOptionsRequired = Omit<Required<UniversalApiOptions>, "handlerMiddlewares" | "endpointPrefix"> & {
1886+
endpointPrefix: string[];
1887+
/**
1888+
* Prefixes that were provided by the user but rejected because they resolve
1889+
* to the root path ("/") after normalisation. Stored so that runAsyncInit
1890+
* can emit a targeted warning through the logger instead of the generic
1891+
* "prefix empty or invalid" message.
1892+
*/
1893+
rejectedPrefixes: string[];
1894+
fullFsDir: string | null;
1895+
config: ResolvedConfig;
1896+
matcher: AntPathMatcher;
1897+
middlewares: UniversalApiMiddleware[];
1898+
};
18861899

18871900
/** @internal */
18881901
export interface HandledRequestData {

src/plugin/index.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export function universalApiPlugin(opts?: UniversalApiOptions): Plugin {
1313
delay: 0,
1414
gatewayTimeout: 0,
1515
endpointPrefix: [],
16+
rejectedPrefixes: [],
1617
enableWs: false,
1718
enablePreview: true,
1819
fsDir: null,
@@ -41,14 +42,26 @@ export function universalApiPlugin(opts?: UniversalApiOptions): Plugin {
4142
asyncInitPromise = (async () => {
4243
if (!options.fsDir || !(await Utils.files.isDirExists(options.fullFsDir!))) {
4344
options.fullFsDir = null;
44-
logger.info(`Directory with path ${options.fsDir} doesn't exist.`);
45+
logger.debug(`Directory with path ${options.fsDir} doesn't exist.`);
46+
}
47+
if (options.rejectedPrefixes.length > 0) {
48+
logger.warn(
49+
`The following endpointPrefix values resolve to the root path and have been ignored: ` +
50+
`[${options.rejectedPrefixes.map(p => `"${p || "/"}"`).join(", ")}]. ` +
51+
`The root path "/" cannot be used as a prefix because it would intercept every request. ` +
52+
`Use a more specific prefix such as "/api".`
53+
);
4554
}
4655
if (options.endpointPrefix.length === 0) {
47-
logger.warn(`Endpoint prefix empty or invalid`);
56+
logger.warn(
57+
options.rejectedPrefixes.length > 0
58+
? `All configured prefixes were invalid (see warning above) — plugin disabled.`
59+
: `endpointPrefix is empty or was not provided — plugin disabled.`
60+
);
4861
options.disable = true;
4962
}
5063

51-
logger.info(`plugin ${options.disable ? "disabled" : "started"}`);
64+
logger.debug(`plugin ${options.disable ? "disabled" : "started"}`);
5265
logger.debug("Vite configResolved: FINISH");
5366

5467
/* v8 ignore start */
@@ -136,7 +149,7 @@ export function universalApiPlugin(opts?: UniversalApiOptions): Plugin {
136149
options = Utils.plugin.initOptions(opts, conf);
137150
logger = new Logger(Constants.PLUGIN_NAME, options.logLevel);
138151
logger.debug("Vite configResolved: START");
139-
logger.info(`plugin initializing ...`);
152+
logger.debug(`plugin initializing ...`);
140153
},
141154
configureServer(server) {
142155
// INFO Return a function so Vite defers its execution to after the built-in middlewares are registered

src/utils/plugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ async function handlingApiRestRequest(logger: ILogger, matcher: AntPathMatcher,
498498
}
499499
if (handler !== null) {
500500
logger.debug("handlingApiRestRequest: using REST api");
501-
logger.info("Request handling with REST API: handler matched= ", handler.pattern);
501+
logger.debug("Request handling with REST API: handler matched= ", handler.pattern);
502502

503503
if (handler.authenticate) {
504504
try {
@@ -572,7 +572,7 @@ const runPluginInternal = async (req: IncomingMessage, res: ServerResponse, logg
572572
}
573573

574574
if (!Utils.request.matchesEndpointPrefix(req.url, endpointPrefix)) {
575-
logger.info(`runPluginInternal: Request with url ${req.url} doesn't match endpointPrefix option.`);
575+
logger.debug(`runPluginInternal: Request with url ${req.url} doesn't match endpointPrefix option.`);
576576
throw new UniversalApiError("Request doesn't match endpointPrefix", "NO_HANDLER", fullUrl.pathname);
577577
}
578578
const request = Utils.request.createRequest(req);

src/utils/utils.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,20 @@ export const Utils = {
6464
endpoint = Utils.request.removeSlash(endpoint, "trailing");
6565
return endpoint;
6666
};
67-
const endpointPrefix = opts?.endpointPrefix
67+
const rawPrefixes: string[] = opts?.endpointPrefix
6868
? Array.isArray(opts.endpointPrefix) && opts.endpointPrefix.length > 0
6969
? opts.endpointPrefix.map(normalizePrefix)
7070
: Array.isArray(opts.endpointPrefix) ? opts.endpointPrefix : [normalizePrefix(opts.endpointPrefix)]
7171
: ['/api'];
72+
const rejectedPrefixes = rawPrefixes.filter(el => el === "" || el === "/");
73+
const endpointPrefix = rawPrefixes.filter(el => el !== "" && el !== "/");
7274
return {
7375
disable: opts?.disable ?? false,
7476
logLevel: opts?.logLevel || "info",
7577
delay: opts?.delay ? opts.delay : 0,
7678
gatewayTimeout: opts?.gatewayTimeout ?? 0,
77-
endpointPrefix: endpointPrefix.filter(el => el !== "" && el !== "/"),
79+
rejectedPrefixes,
80+
endpointPrefix,
7881
enableWs: opts?.enableWs ?? false,
7982
enablePreview: opts?.enablePreview ?? true,
8083
fsDir: opts?.fsDir ?? null,
@@ -984,9 +987,8 @@ export const Utils = {
984987
return result;
985988
},
986989
applyPaginationAndFilters(request: UniversalApiRequest<any>, paginationHandler: UniversalApiRestFsHandler["pagination"], filtersHandler: UniversalApiRestFsHandler["filters"], paginationPlugin: UniversalApiOptions["pagination"], filtersPlugin: UniversalApiOptions["filters"], dataFile: { originalData: any, data: any, mimeType: string, total: number }) {
987-
const data = JSON.parse(dataFile.data);
988-
dataFile.originalData = JSON.parse(dataFile.data);
989-
dataFile.data = data;
990+
dataFile.data = JSON.parse(dataFile.data);
991+
dataFile.originalData = Utils.plugin.cloneData(dataFile.data);
990992
const IS_ARRAY = Array.isArray(dataFile.data);
991993
if (![null, undefined].includes(dataFile.data)) {
992994
const { pagination, filters } = this.getPaginationAndFilters(request, paginationHandler, filtersHandler, paginationPlugin, filtersPlugin);

0 commit comments

Comments
 (0)