Skip to content

Commit

Permalink
Draft: processing logical containers without mapping them.
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinTail committed Jan 22, 2025
1 parent 4ccd7de commit 108241c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 29 deletions.
16 changes: 9 additions & 7 deletions src/documentation-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -836,11 +836,11 @@ type SecurityHelper<K extends Security["type"]> = (
inputSources?: InputSource[],
) => SecuritySchemeObject;

const depictBasicSecurity: SecurityHelper<"basic"> = () => ({
export const depictBasicSecurity: SecurityHelper<"basic"> = () => ({
type: "http",
scheme: "basic",
});
const depictBearerSecurity: SecurityHelper<"bearer"> = ({
export const depictBearerSecurity: SecurityHelper<"bearer"> = ({
format: bearerFormat,
}) => {
const result: SecuritySchemeObject = {
Expand All @@ -850,7 +850,7 @@ const depictBearerSecurity: SecurityHelper<"bearer"> = ({
if (bearerFormat) result.bearerFormat = bearerFormat;
return result;
};
const depictInputSecurity: SecurityHelper<"input"> = (
export const depictInputSecurity: SecurityHelper<"input"> = (
{ name },
inputSources,
) => {
Expand All @@ -870,23 +870,25 @@ const depictInputSecurity: SecurityHelper<"input"> = (
}
return result;
};
const depictHeaderSecurity: SecurityHelper<"header"> = ({ name }) => ({
export const depictHeaderSecurity: SecurityHelper<"header"> = ({ name }) => ({
type: "apiKey",
in: "header",
name,
});
const depictCookieSecurity: SecurityHelper<"cookie"> = ({ name }) => ({
export const depictCookieSecurity: SecurityHelper<"cookie"> = ({ name }) => ({
type: "apiKey",
in: "cookie",
name,
});
const depictOpenIdSecurity: SecurityHelper<"openid"> = ({
export const depictOpenIdSecurity: SecurityHelper<"openid"> = ({
url: openIdConnectUrl,
}) => ({
type: "openIdConnect",
openIdConnectUrl,
});
const depictOAuth2Security: SecurityHelper<"oauth2"> = ({ flows = {} }) => ({
export const depictOAuth2Security: SecurityHelper<"oauth2"> = ({
flows = {},
}) => ({
type: "oauth2",
flows: map(
(flow): OAuthFlowObject => ({ ...flow, scopes: flow.scopes || {} }),
Expand Down
87 changes: 68 additions & 19 deletions src/documentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,38 @@ import { z } from "zod";
import { responseVariants } from "./api-response";
import { contentTypes } from "./content-type";
import { DocumentationError } from "./errors";
import { defaultInputSources, makeCleanId } from "./common-helpers";
import {
combinations,
defaultInputSources,
makeCleanId,
} from "./common-helpers";
import { CommonConfig } from "./config-type";
import { combineContainers, mapLogicalContainer } from "./logical-container";
import {
isLogicalAnd,
isLogicalOr,
LogicalContainer,
} from "./logical-container";
import { Method } from "./method";
import {
OpenAPIContext,
depictBody,
depictRequestParams,
depictResponse,
depictSecurity,
depictSecurityRefs,
depictTags,
ensureShortDescription,
reformatParamsInPath,
depictBasicSecurity,
depictBearerSecurity,
depictInputSecurity,
depictHeaderSecurity,
depictCookieSecurity,
depictOpenIdSecurity,
depictOAuth2Security,
} from "./documentation-helpers";
import { Routing } from "./routing";
import { OnEndpoint, walkRouting } from "./routing-walker";
import { HandlingRules } from "./schema-walker";
import { Security } from "./security";

type Component =
| "positiveResponse"
Expand Down Expand Up @@ -224,28 +238,63 @@ export class Documentation extends OpenApiBuilder {
})
: undefined;

const securityRefs = depictSecurityRefs(
mapLogicalContainer(
depictSecurity(
endpoint
.getSecurity()
.reduce((acc, entry) => combineContainers(acc, entry), {
and: [],
}),
inputSources,
),
(securitySchema) => {
const containers = endpoint.getSecurity();
const mapper = (subj: Security) => {
if (subj.type === "basic") return depictBasicSecurity(subj);
else if (subj.type === "bearer") return depictBearerSecurity(subj);
else if (subj.type === "input")
return depictInputSecurity(subj, inputSources);
else if (subj.type === "header") return depictHeaderSecurity(subj);
else if (subj.type === "cookie") return depictCookieSecurity(subj);
else if (subj.type === "openid") return depictOpenIdSecurity(subj);
else return depictOAuth2Security(subj);
};
const isSimple = (entry: LogicalContainer<Security>): entry is Security =>
!isLogicalAnd(entry) && !isLogicalOr(entry);
const simples = containers.filter(isSimple);
let ttt = [simples.flatMap(mapper)];

Check warning on line 255 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.9.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 255 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 255 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.0.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 255 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

flatMap() is about 1.3x slower than R.chain()
const ands = containers.filter((entry) => isLogicalAnd(entry));
ttt[0].push(
...ands.flatMap((entry) => entry.and.filter(isSimple).map(mapper)),

Check warning on line 258 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.9.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 258 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 258 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.0.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 258 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

flatMap() is about 1.3x slower than R.chain()
);
ttt = combinations(
ttt,
ands.map((entry) =>
entry.and

Check warning on line 263 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.9.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 263 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 263 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.0.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 263 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

flatMap() is about 1.3x slower than R.chain()
.filter((entry) => isLogicalOr(entry))
.flatMap((entry) => entry.or.map(mapper)),
),
([a, b]) => a.concat(b),
);
const ors = containers.filter((entry) => isLogicalOr(entry));
const simpleOrs = ors.flatMap((entry) =>

Check warning on line 270 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.9.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 270 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 270 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.0.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 270 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

flatMap() is about 1.3x slower than R.chain()
entry.or.filter(isSimple).map((v) => [mapper(v)]),
);
ttt = combinations(ttt, simpleOrs, ([a, b]) => a.concat(b));
ttt = combinations(
ttt,
ors.map((entry) =>
entry.or

Check warning on line 277 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.9.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 277 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 277 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.0.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 277 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

flatMap() is about 1.3x slower than R.chain()
.filter((entry) => isLogicalAnd(entry))
.flatMap((entry) => entry.and.flatMap(mapper)),

Check warning on line 279 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.9.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 279 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 279 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.0.0)

flatMap() is about 1.3x slower than R.chain()

Check warning on line 279 in src/documentation.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

flatMap() is about 1.3x slower than R.chain()
),
([a, b]) => a.concat(b),
);

const securityRefs = ttt
.filter((sss) => sss.length)
.map((sss) =>
sss.reduce<Record<string, string[]>>((agg, securitySchema) => {
const name = this.ensureUniqSecuritySchemaName(securitySchema);
const scopes = ["oauth2", "openIdConnect"].includes(
securitySchema.type,
)
? endpoint.getScopes().slice()
: [];
this.addSecurityScheme(name, securitySchema);
return { name, scopes };
},
),
);
return Object.assign(agg, { [name]: scopes });
}, {}),
);

this.addPath(reformatParamsInPath(path), {
[method]: {
Expand Down
7 changes: 4 additions & 3 deletions src/logical-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ export type LogicalContainer<T> =
| LogicalAnd<T | LogicalOr<T>>
| T;

const isLogicalOr = (subject: unknown): subject is LogicalOr<unknown> =>
export const isLogicalOr = (subject: unknown): subject is LogicalOr<unknown> =>
isObject(subject) && "or" in subject;

const isLogicalAnd = (subject: unknown): subject is LogicalAnd<unknown> =>
isObject(subject) && "and" in subject;
export const isLogicalAnd = (
subject: unknown,
): subject is LogicalAnd<unknown> => isObject(subject) && "and" in subject;

/** @desc combines several LogicalAnds into a one */
const flattenAnds = <T>(subject: (T | LogicalAnd<T>)[]): LogicalAnd<T> => ({
Expand Down

0 comments on commit 108241c

Please sign in to comment.