UNPKG

@scalar/types

Version:

Types to work with Scalar packages

162 lines (161 loc) 7.22 kB
import { z } from "zod"; import { nanoidSchema } from "../utils/nanoid.js"; const commonProps = z.object({ /* A description for security scheme. CommonMark syntax MAY be used for rich text representation. */ description: z.string().optional() }); const extendedSecuritySchema = z.object({ uid: nanoidSchema.brand(), /** The name key that links a security requirement to a security object */ nameKey: z.string().optional().default("") }); const securitySchemeApiKeyIn = ["query", "header", "cookie"]; const oasSecuritySchemeApiKey = commonProps.extend({ type: z.literal("apiKey"), /** REQUIRED. The name of the header, query or cookie parameter to be used. */ name: z.string().optional().default(""), /** REQUIRED. The location of the API key. Valid values are "query", "header" or "cookie". */ in: z.enum(securitySchemeApiKeyIn).optional().default("header").catch("header") }); const apiKeyValueSchema = z.object({ value: z.string().default("") }); const securityApiKeySchema = oasSecuritySchemeApiKey.merge(extendedSecuritySchema).merge(apiKeyValueSchema); const oasSecuritySchemeHttp = commonProps.extend({ type: z.literal("http"), /** * REQUIRED. The name of the HTTP Authorization scheme to be used in the Authorization header as defined in * [RFC7235]. The values used SHOULD be registered in the IANA Authentication Scheme registry. */ scheme: z.string().toLowerCase().pipe(z.enum(["basic", "bearer"])).optional().default("basic"), /** * A hint to the client to identify how the bearer token is formatted. * Bearer tokens are usually generated by an authorization server, so * this information is primarily for documentation purposes. */ bearerFormat: z.union([z.literal("JWT"), z.string()]).optional().default("JWT") }); const httpValueSchema = z.object({ username: z.string().default(""), password: z.string().default(""), token: z.string().default("") }); const securityHttpSchema = oasSecuritySchemeHttp.merge(extendedSecuritySchema).merge(httpValueSchema); const oasSecuritySchemeOpenId = commonProps.extend({ type: z.literal("openIdConnect"), /** * REQUIRED. OpenId Connect URL to discover OAuth2 configuration values. This MUST be in the * form of a URL. The OpenID Connect standard requires the use of TLS. */ openIdConnectUrl: z.string().optional().default("") }); const securityOpenIdSchema = oasSecuritySchemeOpenId.merge(extendedSecuritySchema); const authorizationUrl = z.string().default(""); const tokenUrl = z.string().default(""); const flowsCommon = z.object({ /** * The URL to be used for obtaining refresh tokens. This MUST be in the form of a * URL. The OAuth2 standard requires the use of TLS. */ "refreshUrl": z.string().optional().default(""), /** * REQUIRED. The available scopes for the OAuth2 security scheme. A map * between the scope name and a short description for it. The map MAY be empty. */ "scopes": z.record(z.string(), z.string().optional().default("")).optional().default({}).catch({}), "selectedScopes": z.array(z.string()).optional().default([]), /** Extension to save the client Id associated with an oauth flow */ "x-scalar-client-id": z.string().optional().default(""), /** The auth token */ "token": z.string().default(""), /** Additional query parameters for the OAuth authorization request. Example: { prompt: 'consent', audience: 'scalar' }. */ "x-scalar-security-query": z.record(z.string(), z.string()).optional(), /** Additional body parameters for the OAuth token request. Example: { audience: 'foo' }. */ "x-scalar-security-body": z.record(z.string(), z.string()).optional(), /** Extension to specify custom token name in the response (defaults to 'access_token') */ "x-tokenName": z.string().optional() }); const defaultRedirectUri = typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""; const pkceOptions = ["SHA-256", "plain", "no"]; const credentialsLocationExtension = z.enum(["header", "body"]).optional(); const oasSecuritySchemeOauth2 = commonProps.extend({ type: z.literal("oauth2"), /** The default scopes for the oauth flow */ "x-default-scopes": z.array(z.string()).optional(), /** REQUIRED. An object containing configuration information for the flow types supported. */ flows: z.object({ /** Configuration for the OAuth Implicit flow */ implicit: flowsCommon.extend({ "type": z.literal("implicit").default("implicit"), authorizationUrl, "x-scalar-redirect-uri": z.string().optional().default(defaultRedirectUri) }), /** Configuration for the OAuth Resource Owner Password flow */ password: flowsCommon.extend({ type: z.literal("password").default("password"), tokenUrl, clientSecret: z.string().default(""), username: z.string().default(""), password: z.string().default(""), "x-scalar-credentials-location": credentialsLocationExtension }), /** Configuration for the OAuth Client Credentials flow. Previously called application in OpenAPI 2.0. */ clientCredentials: flowsCommon.extend({ type: z.literal("clientCredentials").default("clientCredentials"), tokenUrl, clientSecret: z.string().default(""), "x-scalar-credentials-location": credentialsLocationExtension }), /** Configuration for the OAuth Authorization Code flow. Previously called accessCode in OpenAPI 2.0.*/ authorizationCode: flowsCommon.extend({ "type": z.literal("authorizationCode").default("authorizationCode"), authorizationUrl, "x-usePkce": z.enum(pkceOptions).optional().default("no"), "x-scalar-redirect-uri": z.string().optional().default(defaultRedirectUri), tokenUrl, clientSecret: z.string().default(""), "x-scalar-credentials-location": credentialsLocationExtension }) }).partial().default({ implicit: { selectedScopes: [], scopes: {}, "x-scalar-client-id": "", refreshUrl: "", token: "", type: "implicit", authorizationUrl: "http://localhost:8080", "x-scalar-redirect-uri": defaultRedirectUri } }) }); const securityOauthSchema = oasSecuritySchemeOauth2.merge(extendedSecuritySchema); const oasSecurityRequirementSchema = z.record(z.string(), z.array(z.string()).optional().default([])); const oasSecuritySchemeSchema = z.union([ oasSecuritySchemeApiKey, oasSecuritySchemeHttp, oasSecuritySchemeOauth2, oasSecuritySchemeOpenId ]); const securitySchemeSchema = z.discriminatedUnion("type", [securityApiKeySchema, securityHttpSchema, securityOpenIdSchema, securityOauthSchema]).transform((data) => { if (data.type === "oauth2" && data["x-default-scopes"]?.length) { const keys = Object.keys(data.flows); keys.forEach((key) => { if (data.flows[key]?.selectedScopes && data["x-default-scopes"]) { data.flows[key].selectedScopes = [data["x-default-scopes"]].flat(); } }); } return data; }); export { oasSecurityRequirementSchema, oasSecuritySchemeSchema, pkceOptions, securityApiKeySchema, securityHttpSchema, securityOauthSchema, securityOpenIdSchema, securitySchemeSchema }; //# sourceMappingURL=security-scheme.js.map