Skip to content

Commit

Permalink
fix(swagger): mismatch docs api.
Browse files Browse the repository at this point in the history
  • Loading branch information
chizukicn committed Jun 28, 2023
1 parent 92e7a06 commit c36e937
Show file tree
Hide file tree
Showing 30 changed files with 405 additions and 253 deletions.
6 changes: 3 additions & 3 deletions bench/unit/path.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { relativePath, slash } from "@fourze/core";
import { normalizeURL, withoutBase } from "@fourze/core";
import { suite } from "../lib/suite";

// const source = new Array(100).fill(0).map((_, i) => i);
suite("relativePath", 100000, () => {
relativePath("/api/abc", "/api");
withoutBase("/api/abc", "/api");
});

suite("replace", 100000, () => {
const a = "/api/abc";
const b = "/api";
slash((a.replace(b, "")));
normalizeURL((a.replace(b, "")));
});

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
"@fourze/swagger": "workspace:*",
"@types/fs-extra": "^11.0.1",
"@types/node": "^18.16.18",
"@vitest/coverage-v8": "^0.32.0",
"@vitest/ui": "^0.32.0",
"@vitest/coverage-v8": "^0.32.2",
"@vitest/ui": "^0.32.2",
"autocannon": "^7.11.0",
"bumpp": "^9.1.1",
"chokidar": "^3.5.3",
Expand All @@ -67,6 +67,6 @@
"tsx": "^3.12.7",
"typescript": "^5.1.0",
"unbuild": "^1.2.1",
"vitest": "^0.32.0"
"vitest": "^0.32.2"
}
}
50 changes: 30 additions & 20 deletions packages/core/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { MaybePromise, MaybeRegex } from "maybe-types";
import { withBase, withTrailingSlash, withoutBase, withoutTrailingSlash } from "ufo";
import { isArray, isFunction, isUndef } from "./utils/is";
import { createLogger } from "./logger";
import type {
Expand All @@ -11,22 +12,20 @@ import type {
FourzeNext,
FourzePlugin
} from "./shared";
import { FOURZE_VERSION, createServiceContext } from "./shared";
import {
FOURZE_VERSION
,
createServiceContext
} from "./shared";
import {
createSingletonPromise, deleteBy, isMatch,
createSingletonPromise,
deleteBy,
isMatch,
isObject,
isString,
relativePath,
resolves,
restoreArray
} from "./utils";
import { injectMeta } from "./shared/meta";

export type FourzeAppSetup = (app: FourzeApp) => MaybePromise<void | FourzeModule[] | FourzeAppOptions>;
export type FourzeAppSetup = (
app: FourzeApp
) => MaybePromise<void | FourzeModule[] | FourzeAppOptions>;

export interface FourzeAppOptions {
base?: string
Expand Down Expand Up @@ -63,14 +62,16 @@ export function createApp(setup: FourzeAppSetup): FourzeApp;

export function createApp(options: FourzeAppOptions): FourzeApp;

export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeApp {
export function createApp(
args: FourzeAppOptions | FourzeAppSetup = {}
): FourzeApp {
const isSetup = isFunction(args);
const isRoutes = Array.isArray(args);
const isOptions = !isSetup && !isRoutes && isObject(args);
const logger = createLogger("@fourze/core");

const options = isOptions ? args : {};
const setup = isSetup ? args : options.setup ?? (() => { });
const setup = isSetup ? args : options.setup ?? (() => {});

const { fallback } = options;

Expand Down Expand Up @@ -105,14 +106,14 @@ export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeA
const nextNode = ms.shift();
if (nextNode) {
const [path, middleware] = nextNode;
const req = request.withScope(resolves(app.base, path));
const req = request.withScope(withBase(path, app.base));
await middleware(req, response, doNext);
} else {
await next?.();
}
}
await doNext();
// await response.done();
// await response.done();
} else {
await next?.();
}
Expand All @@ -129,7 +130,7 @@ export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeA
return middlewareStore
.sort((a, b) => a.order - b.order)
.filter((r) => isMatch(url, r.path))
.map(r => [r.path, r.middleware] as [string, FourzeMiddleware]);
.map((r) => [r.path, r.middleware] as [string, FourzeMiddleware]);
}
return [];
};
Expand All @@ -140,7 +141,7 @@ export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeA
) {
const arg0 = args[0];
const isPath = isString(arg0);
const path = isPath ? arg0 : "/";
const path = withoutTrailingSlash(isPath ? arg0 : "/");
const ms = (isPath ? args.slice(1) : args) as FourzeModule[];

for (let i = 0; i < ms.length; i++) {
Expand All @@ -149,7 +150,11 @@ export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeA
continue;
}
if (typeof middleware === "function") {
const node = { path, middleware, order: middleware.order ?? middlewareStore.length };
const node = {
path,
middleware,
order: middleware.order ?? middlewareStore.length
};
if (!this.isReadying) {
persistenceMiddlewareStore.push(node);
}
Expand All @@ -174,7 +179,11 @@ export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeA
return this;
};

app.service = async function (this: FourzeApp, options: FourzeContextOptions, next?: FourzeHandle) {
app.service = async function (
this: FourzeApp,
options: FourzeContextOptions,
next?: FourzeHandle
) {
const { request, response } = createServiceContext(options);
await this(request, response, async () => {
await next?.(request, response);
Expand Down Expand Up @@ -225,6 +234,7 @@ export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeA
} else if (setupReturn) {
Object.assign(options, setupReturn);
}
options.base = withTrailingSlash(options.base);
} catch (e) {
logger.error(e);
}
Expand All @@ -243,7 +253,7 @@ export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeA
}

// 装载插件
const installPlugins = pluginStore.map(async r => {
const installPlugins = pluginStore.map(async (r) => {
if (r.install) {
try {
await r.install(this);
Expand Down Expand Up @@ -281,13 +291,13 @@ export function createApp(args: FourzeAppOptions | FourzeAppSetup = {}): FourzeA
};

app.relative = function (url: string) {
return relativePath(url, this.base);
return withoutBase(url, this.base);
};

Object.defineProperties(app, {
middlewares: {
get() {
return middlewareStore.map(r => r.middleware);
return middlewareStore.map((r) => r.middleware);
},
enumerable: true
},
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type FourzeLogLevelKey = Uncapitalize<keyof typeof FourzeLogLevel>;

export type FourzeLogger = Consola;

let globalLoggerLevel: FourzeLogLevelKey | FourzeLogLevel = "info";
let globalLoggerLevel: FourzeLogLevelKey | FourzeLogLevel = "fatal";

const loggerStore = new Map<string, FourzeLogger>();

Expand Down
14 changes: 8 additions & 6 deletions packages/core/src/shared/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import type { IncomingMessage } from "http";
import qs from "query-string";
import type { MaybeRegex } from "maybe-types";
import { safeParse } from "fast-content-type-parse";
import { getQuery, parseURL } from "ufo";
import { getQuery, parseURL, withoutBase } from "ufo";
import type { PolyfillHeaderInit } from "../polyfill";
import { decodeFormData, flatHeaders, getHeaderValue } from "../polyfill";
import { isString, isUint8Array, memoize, parseJson, relativePath } from "../utils";
import { isString, isUint8Array, parseJson } from "../utils";
import type { DefaultData, ExtractPropTypes, ExtractPropTypesWithIn, ObjectProps } from "./props";
import { validateProps, withDefaults } from "./props";
import type { FourzeRoute } from "./route";
Expand Down Expand Up @@ -35,6 +35,7 @@ export interface FourzeRequestOptions {
body?: any
params?: Record<string, any>
query?: Record<string, any>
meta?: Record<string, any>
request?: IncomingMessage
contentTypeParsers?: Map<MaybeRegex, (body: any) => any>
}
Expand Down Expand Up @@ -90,7 +91,7 @@ export function createRequest(options: FourzeRequestOptions) {
request.url = options.url ?? request.url;
request.method = request.method ?? "GET";

request.meta = {};
request.meta = options.meta ?? {};

const headers = {
...flatHeaders(request.headers),
Expand Down Expand Up @@ -162,12 +163,13 @@ export function createRequest(options: FourzeRequestOptions) {
validateProps(route.props, data);
};

request.withScope = memoize((scope) => {
request.withScope = (scope) => {
return createRequest({
...options,
url: relativePath(request.url, scope) ?? request.url
meta: request.meta,
url: withoutBase(request.url, scope) ?? request.url
});
});
};

Object.defineProperties(request, {
[FOURZE_REQUEST_SYMBOL]: {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/shared/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { resolves } from "../utils";
import { withBase } from "../utils";
import type { DefaultData, ObjectProps } from "./props";
import type { RequestMethod } from "./request";
import { FOURZE_METHODS } from "./request";
import type { FourzeRouteMeta } from "./meta";
import type { FourzeHandle } from ".";
import type { FourzeHandle } from "./interface";

const FOURZE_ROUTE_SYMBOL = Symbol("FourzeRoute");

Expand Down Expand Up @@ -76,7 +76,7 @@ export function defineRoute<
}
}

path = base ? resolves(base, path) : path;
path = base ? withBase(path, base) : path;

return {
method,
Expand Down
73 changes: 13 additions & 60 deletions packages/core/src/utils/path.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,28 @@
import minimatch from "minimatch";
import type { MaybeRegex } from "maybe-types";
import { resolveURL } from "ufo";
import { hasProtocol, isEmptyURL, isRelative, joinURL, normalizeURL, withLeadingSlash, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash } from "ufo";
import minimatch from "minimatch";
import { isRegExp } from "./is";

export function slash(...paths: string[]): string {
let path = paths
.map((p) => p.replace(/\\/g, "/"))
.join("/")
.replace(/\/+/g, "/");

if (path.length > 1 && path.endsWith("/")) {
path = path.slice(0, -1);
}

if (!path.startsWith("/")) {
path = "/".concat(path);
}

return path;
}

export function relativePath(path: string, base?: string): string | null {
if (!hasProtocol(path)) {
if (base) {
if (base.endsWith("/")) {
base = base.slice(0, -1);
}
if (path.startsWith(base)) {
path = path.slice(base.length);
} else {
return null;
}
}
return path;
}
return null;
}

const protocolReg = /^(\w+):\/\//i;

export function hasProtocol(path: string) {
return protocolReg.test(path);
}

export function isMatch(path: string, ...pattern: MaybeRegex[]) {
return pattern.some((r) => {
if (isRegExp(r)) {
return r.test(path);
}
return path.startsWith(r) || minimatch(path, r, { matchBase: true, partial: true });

return path.startsWith(r) || minimatch(path, r, { matchBase: true });
});
}

/**
* 格式化路径
* @param path
*/
export function normalize(path: string) {
if (!path.startsWith("/")) {
path = "/".concat(path);
}
path = path.replace(/\\/g, "/").replace(/\/+/g, "/");
if (path.length > 1 && path.endsWith("/")) {
path = path.slice(0, -1);
export function withBase(input: string, base: string, trailingSlash = true) {
if (isEmptyURL(base) || hasProtocol(input)) {
return input;
}
return path;
}
const _base = trailingSlash ? withTrailingSlash(base) : base;

export function resolves(...paths: string[]) {
if (paths.length === 0) {
return "/";
if (input.startsWith(_base)) {
return input;
}
return resolveURL(paths[0], ...paths.slice(1));
return joinURL(_base, input);
}

export { withoutBase, normalizeURL, isEmptyURL, isRelative, joinURL, hasProtocol, withTrailingSlash, withoutTrailingSlash, withLeadingSlash, withoutLeadingSlash };
3 changes: 3 additions & 0 deletions packages/core/test/utils/faker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ test("test-faker-object", () => {
g: "{false}",
h: "{null}",
i: "{undefined}",
j: {
$type: "number"
},
tof: "{true|false}",
num: "{100|200|300}",
mixin: "{'a'|b|c}-{100-200|300-600|700-900}"
Expand Down
Loading

0 comments on commit c36e937

Please sign in to comment.