@abapify/speci 0.4.36 → 0.4.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-tt7oXC8m.d.mts","names":[],"sources":["../src/rest/server/types.ts","../src/rest/server/create-server.ts"],"mappings":";;;;UAWiB;EACf;EACA;EACA,SAAS;EACT;EACA,OAAO;;;;;UAMQ;EACf;EACA,SAAS;EACT;;;;;;;;UASe;;EAEf;;EAGA;;EAGA;;EAGA;;EAGA,aAAa;;EAGb,iBAAiB,eAAe;;EAGhC,iBAAiB;;EAGjB,kBAAkB;;;;;;;KAQR,iBACV,SAAS,eACT,SAAS,iBACN,QAAQ,kBAAkB;;;;UAKd;;EAEf,OAAO;;EAGP,QAAQ;;EAGR,eAAe,gBAAgB;;;;;UAMhB;;;;;;EAMf;;;;;UAMe;;EAEf,QAAQ;;;;;EAMR,MACE,gBACA,aACA;IACG,OAAO;IAAiB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index-tt7oXC8m.d.mts","names":[],"sources":["../src/rest/server/types.ts","../src/rest/server/create-server.ts"],"mappings":";;;;UAWiB;EACf;EACA;EACA,SAAS;EACT;EACA,OAAO;;;;;UAMQ;EACf;EACA,SAAS;EACT;;;;;;;;UASe;;EAEf;;EAGA;;EAGA;;EAGA;;EAGA,aAAa;;EAGb,iBAAiB,eAAe;;EAGhC,iBAAiB;;EAGjB,kBAAkB;;;;;;;KAQR,iBACV,SAAS,eACT,SAAS,iBACN,QAAQ,kBAAkB;;;;UAKd;;EAEf,OAAO;;EAGP,QAAQ;;EAGR,eAAe,gBAAgB;;;;;UAMhB;;;;;;EAMf;;;;;UAMe;;EAEf,QAAQ;;;;;EAMR,MACE,gBACA,aACA;IACG,OAAO;IAAiB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;iBCsIvB,aAAa,UAAU,qBACrC,UAAU,IACT"}
|
package/dist/rest/index.mjs
CHANGED
|
@@ -82,21 +82,28 @@ function routeFromEndpoint({ descriptor }) {
|
|
|
82
82
|
_regex: regex
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
/** Strip the query string and any configured base path from a request URL. */
|
|
86
|
+
function relativeRequestPath(url, basePath) {
|
|
86
87
|
const pathname = url.split("?")[0];
|
|
87
|
-
|
|
88
|
+
if (basePath && pathname.startsWith(basePath)) return pathname.slice(basePath.length) || "/";
|
|
89
|
+
return pathname;
|
|
90
|
+
}
|
|
91
|
+
/** Build the params record from a regex match against a route. */
|
|
92
|
+
function paramsFromMatch(route, match) {
|
|
93
|
+
const params = {};
|
|
94
|
+
for (let i = 0; i < route.pathParamNames.length; i++) params[route.pathParamNames[i]] = match[i + 1] || "";
|
|
95
|
+
return params;
|
|
96
|
+
}
|
|
97
|
+
function matchRoute(routes, method, url, basePath) {
|
|
98
|
+
const relativePath = relativeRequestPath(url, basePath);
|
|
88
99
|
const targetMethod = method.toUpperCase();
|
|
89
100
|
for (const route of routes) {
|
|
90
101
|
if (route.method !== targetMethod) continue;
|
|
91
102
|
const match = route._regex.exec(relativePath);
|
|
92
|
-
if (match) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
route,
|
|
97
|
-
params
|
|
98
|
-
};
|
|
99
|
-
}
|
|
103
|
+
if (match) return {
|
|
104
|
+
route,
|
|
105
|
+
params: paramsFromMatch(route, match)
|
|
106
|
+
};
|
|
100
107
|
}
|
|
101
108
|
return null;
|
|
102
109
|
}
|
|
@@ -132,4 +139,4 @@ function createServer(contract) {
|
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
export { createServer as t };
|
|
135
|
-
//# sourceMappingURL=server-
|
|
142
|
+
//# sourceMappingURL=server-SVHmvvEB.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-q84R0M2o.mjs","names":[],"sources":["../src/rest/server/create-server.ts"],"sourcesContent":["/**\n * Speci REST - Server Generator\n *\n * Creates server-ready route definitions from REST contracts.\n *\n * This is the server-side counterpart of createClient. It walks a contract\n * tree, extracts endpoint definitions (method, path, body schema, response\n * schemas), and returns structured route definitions that can be used to\n * build HTTP servers with any framework (node:http, Express, Hono, etc.).\n *\n * @example\n * ```typescript\n * import { createServer } from '@abapify/speci/rest';\n * import { adtContract } from '@abapify/adt-contracts';\n *\n * const server = createServer(adtContract);\n *\n * // Use with node:http\n * import { createServer as httpCreate } from 'node:http';\n *\n * httpCreate((req, res) => {\n * const match = server.match(req.method!, req.url!);\n * if (match) {\n * // Forward to downstream SAP, handle JSON↔XML conversion, etc.\n * }\n * });\n * ```\n */\n\nimport type { OperationFunction } from '../../core/types';\nimport type { RestEndpointDescriptor, Serializable } from '../types';\nimport type { RouteDefinition, ServerRoutes } from './types';\n\n/** Sentinel value used to mark parameter positions in resolved paths */\nconst PARAM_MARKER = '\\x00';\n\n/**\n * Check if a value is a RestEndpointDescriptor (has method and path)\n */\nfunction isEndpointDescriptor(value: unknown): value is RestEndpointDescriptor {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'method' in value &&\n 'path' in value &&\n 'responses' in value\n );\n}\n\n/**\n * Check if a schema is Serializable (has parse method)\n */\nfunction isSerializable(schema: unknown): schema is Serializable {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n typeof (schema as any).parse === 'function'\n );\n}\n\n/**\n * Walk a contract tree and extract all endpoint definitions.\n *\n * Calls each operation function with a sentinel value to get the resolved\n * path, then replaces the sentinel with regex capture groups for matching.\n */\nfunction tryExtractEndpoint(\n obj: OperationFunction,\n): { operation: OperationFunction; descriptor: RestEndpointDescriptor } | null {\n try {\n const paramCount = obj.length || 1;\n const sentinelArgs = Array.from({ length: paramCount }, () => PARAM_MARKER);\n const descriptor = obj(...sentinelArgs);\n if (isEndpointDescriptor(descriptor)) {\n return { operation: obj, descriptor };\n }\n } catch {\n // Some functions may need different args - skip\n }\n return null;\n}\n\nfunction walkContract(\n obj: any,\n parentPath: string[],\n): Array<{ operation: OperationFunction; descriptor: RestEndpointDescriptor }> {\n if (typeof obj === 'function') {\n const result = tryExtractEndpoint(obj as OperationFunction);\n return result ? [result] : [];\n }\n\n if (typeof obj === 'object' && obj !== null) {\n const endpoints: Array<{\n operation: OperationFunction;\n descriptor: RestEndpointDescriptor;\n }> = [];\n for (const [key, value] of Object.entries(obj)) {\n endpoints.push(...walkContract(value, [...parentPath, key]));\n }\n return endpoints;\n }\n\n return [];\n}\n\n/**\n * Convert a resolved path with sentinel markers into a regex pattern.\n *\n * Also extracts path parameter names from the original function's parameter list.\n *\n * @example\n * // For path '/users/\\x00/posts/\\x00' with param names ['userId', 'postId']\n * // Returns: /\\/users\\/([^/]+)\\/posts\\/([^/]+)/\n */\nfunction buildPathInfo(resolvedPath: string): {\n regex: RegExp;\n template: string;\n paramNames: string[];\n} {\n const sentinelCount = resolvedPath.split(PARAM_MARKER).length - 1;\n\n // Generate parameter names (p1, p2, ... if we don't know the real names)\n const paramNames = Array.from(\n { length: sentinelCount },\n (_, i) => `p${i + 1}`,\n );\n\n // Build regex by replacing sentinels with capture groups\n const escaped = resolvedPath.replace(/[.*+?^${}()|[\\]\\\\]/g, String.raw`\\$&`);\n const regexStr = escaped.split(PARAM_MARKER).join('([^/]+)');\n\n // Build template by replacing sentinels with ${paramName} syntax\n let template = resolvedPath;\n for (const name of paramNames) {\n template = template.replace(PARAM_MARKER, `\\${${name}}`);\n }\n\n return {\n regex: new RegExp(`^${regexStr}$`),\n template,\n paramNames,\n };\n}\n\ntype WalkedEndpoint = {\n operation: OperationFunction;\n descriptor: RestEndpointDescriptor;\n};\n\nfunction routeFromEndpoint({\n descriptor,\n}: WalkedEndpoint): RouteDefinition & { _regex: RegExp } {\n const resolvedPath = descriptor.path || '';\n const { regex, template, paramNames } = buildPathInfo(resolvedPath);\n\n const bodySchema =\n descriptor.body && isSerializable(descriptor.body)\n ? descriptor.body\n : undefined;\n\n const responseSchemas: Record<number, Serializable> = {};\n if (descriptor.responses) {\n for (const [status, schema] of Object.entries(descriptor.responses)) {\n if (isSerializable(schema)) {\n responseSchemas[Number(status)] = schema;\n }\n }\n }\n\n return {\n method: descriptor.method,\n path: resolvedPath,\n pathTemplate: template,\n pathParamNames: paramNames,\n bodySchema,\n responseSchemas,\n requestHeaders: descriptor.headers as Record<string, string> | undefined,\n _regex: regex,\n } as RouteDefinition & { _regex: RegExp };\n}\n\nfunction matchRoute(\n routes: RouteDefinition[],\n method: string,\n url: string,\n basePath: string,\n): { route: RouteDefinition; params: Record<string, string> } | null {\n const pathname = url.split('?')[0];\n const relativePath =\n basePath && pathname.startsWith(basePath)\n ? pathname.slice(basePath.length) || '/'\n : pathname;\n\n const targetMethod = method.toUpperCase();\n for (const route of routes) {\n if (route.method !== targetMethod) continue;\n const match = (route as RouteDefinition & { _regex: RegExp })._regex.exec(\n relativePath,\n );\n if (match) {\n const params: Record<string, string> = {};\n for (let i = 0; i < route.pathParamNames.length; i++) {\n params[route.pathParamNames[i]] = match[i + 1] || '';\n }\n return { route, params };\n }\n }\n return null;\n}\n\n/**\n * Create server-ready route definitions from a REST contract.\n *\n * Walks the contract tree, extracts endpoint definitions, and returns\n * structured route definitions with:\n * - HTTP method and path\n * - Body schema for request conversion (JSON→XML)\n * - Response schemas for response conversion (XML→JSON)\n * - Path parameter extraction\n *\n * @example\n * ```typescript\n * const server = createServer(adtContract);\n *\n * // Match an incoming request\n * const match = server.match('GET', '/sap/bc/adt/cts/transportrequests/DEVK900001');\n * if (match) {\n * console.log(match.route.method); // 'GET'\n * console.log(match.params); // { p1: 'devk900001' }\n * console.log(match.route.responseSchemas[200]); // Serializable schema\n * }\n * ```\n */\nexport function createServer<T extends Record<string, any>>(\n contract: T,\n): ServerRoutes {\n const routes: RouteDefinition[] = walkContract(contract, []).map(\n routeFromEndpoint,\n );\n\n return {\n routes,\n match: (method, url, basePath = '') =>\n matchRoute(routes, method, url, basePath),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server-SVHmvvEB.mjs","names":[],"sources":["../src/rest/server/create-server.ts"],"sourcesContent":["/**\n * Speci REST - Server Generator\n *\n * Creates server-ready route definitions from REST contracts.\n *\n * This is the server-side counterpart of createClient. It walks a contract\n * tree, extracts endpoint definitions (method, path, body schema, response\n * schemas), and returns structured route definitions that can be used to\n * build HTTP servers with any framework (node:http, Express, Hono, etc.).\n *\n * @example\n * ```typescript\n * import { createServer } from '@abapify/speci/rest';\n * import { adtContract } from '@abapify/adt-contracts';\n *\n * const server = createServer(adtContract);\n *\n * // Use with node:http\n * import { createServer as httpCreate } from 'node:http';\n *\n * httpCreate((req, res) => {\n * const match = server.match(req.method!, req.url!);\n * if (match) {\n * // Forward to downstream SAP, handle JSON↔XML conversion, etc.\n * }\n * });\n * ```\n */\n\nimport type { OperationFunction } from '../../core/types';\nimport type { RestEndpointDescriptor, Serializable } from '../types';\nimport type { RouteDefinition, ServerRoutes } from './types';\n\n/** Sentinel value used to mark parameter positions in resolved paths */\nconst PARAM_MARKER = '\\x00';\n\n/**\n * Check if a value is a RestEndpointDescriptor (has method and path)\n */\nfunction isEndpointDescriptor(value: unknown): value is RestEndpointDescriptor {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'method' in value &&\n 'path' in value &&\n 'responses' in value\n );\n}\n\n/**\n * Check if a schema is Serializable (has parse method)\n */\nfunction isSerializable(schema: unknown): schema is Serializable {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n typeof (schema as any).parse === 'function'\n );\n}\n\n/**\n * Walk a contract tree and extract all endpoint definitions.\n *\n * Calls each operation function with a sentinel value to get the resolved\n * path, then replaces the sentinel with regex capture groups for matching.\n */\nfunction tryExtractEndpoint(\n obj: OperationFunction,\n): { operation: OperationFunction; descriptor: RestEndpointDescriptor } | null {\n try {\n const paramCount = obj.length || 1;\n const sentinelArgs = Array.from({ length: paramCount }, () => PARAM_MARKER);\n const descriptor = obj(...sentinelArgs);\n if (isEndpointDescriptor(descriptor)) {\n return { operation: obj, descriptor };\n }\n } catch {\n // Some functions may need different args - skip\n }\n return null;\n}\n\nfunction walkContract(\n obj: any,\n parentPath: string[],\n): Array<{ operation: OperationFunction; descriptor: RestEndpointDescriptor }> {\n if (typeof obj === 'function') {\n const result = tryExtractEndpoint(obj as OperationFunction);\n return result ? [result] : [];\n }\n\n if (typeof obj === 'object' && obj !== null) {\n const endpoints: Array<{\n operation: OperationFunction;\n descriptor: RestEndpointDescriptor;\n }> = [];\n for (const [key, value] of Object.entries(obj)) {\n endpoints.push(...walkContract(value, [...parentPath, key]));\n }\n return endpoints;\n }\n\n return [];\n}\n\n/**\n * Convert a resolved path with sentinel markers into a regex pattern.\n *\n * Also extracts path parameter names from the original function's parameter list.\n *\n * @example\n * // For path '/users/\\x00/posts/\\x00' with param names ['userId', 'postId']\n * // Returns: /\\/users\\/([^/]+)\\/posts\\/([^/]+)/\n */\nfunction buildPathInfo(resolvedPath: string): {\n regex: RegExp;\n template: string;\n paramNames: string[];\n} {\n const sentinelCount = resolvedPath.split(PARAM_MARKER).length - 1;\n\n // Generate parameter names (p1, p2, ... if we don't know the real names)\n const paramNames = Array.from(\n { length: sentinelCount },\n (_, i) => `p${i + 1}`,\n );\n\n // Build regex by replacing sentinels with capture groups\n const escaped = resolvedPath.replace(/[.*+?^${}()|[\\]\\\\]/g, String.raw`\\$&`);\n const regexStr = escaped.split(PARAM_MARKER).join('([^/]+)');\n\n // Build template by replacing sentinels with ${paramName} syntax\n let template = resolvedPath;\n for (const name of paramNames) {\n template = template.replace(PARAM_MARKER, `\\${${name}}`);\n }\n\n return {\n regex: new RegExp(`^${regexStr}$`),\n template,\n paramNames,\n };\n}\n\ntype WalkedEndpoint = {\n operation: OperationFunction;\n descriptor: RestEndpointDescriptor;\n};\n\nfunction routeFromEndpoint({\n descriptor,\n}: WalkedEndpoint): RouteDefinition & { _regex: RegExp } {\n const resolvedPath = descriptor.path || '';\n const { regex, template, paramNames } = buildPathInfo(resolvedPath);\n\n const bodySchema =\n descriptor.body && isSerializable(descriptor.body)\n ? descriptor.body\n : undefined;\n\n const responseSchemas: Record<number, Serializable> = {};\n if (descriptor.responses) {\n for (const [status, schema] of Object.entries(descriptor.responses)) {\n if (isSerializable(schema)) {\n responseSchemas[Number(status)] = schema;\n }\n }\n }\n\n return {\n method: descriptor.method,\n path: resolvedPath,\n pathTemplate: template,\n pathParamNames: paramNames,\n bodySchema,\n responseSchemas,\n requestHeaders: descriptor.headers as Record<string, string> | undefined,\n _regex: regex,\n } as RouteDefinition & { _regex: RegExp };\n}\n\n/** Strip the query string and any configured base path from a request URL. */\nfunction relativeRequestPath(url: string, basePath: string): string {\n const pathname = url.split('?')[0];\n if (basePath && pathname.startsWith(basePath)) {\n return pathname.slice(basePath.length) || '/';\n }\n return pathname;\n}\n\n/** Build the params record from a regex match against a route. */\nfunction paramsFromMatch(\n route: RouteDefinition,\n match: RegExpExecArray,\n): Record<string, string> {\n const params: Record<string, string> = {};\n for (let i = 0; i < route.pathParamNames.length; i++) {\n params[route.pathParamNames[i]] = match[i + 1] || '';\n }\n return params;\n}\n\nfunction matchRoute(\n routes: RouteDefinition[],\n method: string,\n url: string,\n basePath: string,\n): { route: RouteDefinition; params: Record<string, string> } | null {\n const relativePath = relativeRequestPath(url, basePath);\n const targetMethod = method.toUpperCase();\n for (const route of routes) {\n if (route.method !== targetMethod) continue;\n const match = (route as RouteDefinition & { _regex: RegExp })._regex.exec(\n relativePath,\n );\n if (match) {\n return { route, params: paramsFromMatch(route, match) };\n }\n }\n return null;\n}\n\n/**\n * Create server-ready route definitions from a REST contract.\n *\n * Walks the contract tree, extracts endpoint definitions, and returns\n * structured route definitions with:\n * - HTTP method and path\n * - Body schema for request conversion (JSON→XML)\n * - Response schemas for response conversion (XML→JSON)\n * - Path parameter extraction\n *\n * @example\n * ```typescript\n * const server = createServer(adtContract);\n *\n * // Match an incoming request\n * const match = server.match('GET', '/sap/bc/adt/cts/transportrequests/DEVK900001');\n * if (match) {\n * console.log(match.route.method); // 'GET'\n * console.log(match.params); // { p1: 'devk900001' }\n * console.log(match.route.responseSchemas[200]); // Serializable schema\n * }\n * ```\n */\nexport function createServer<T extends Record<string, any>>(\n contract: T,\n): ServerRoutes {\n const routes: RouteDefinition[] = walkContract(contract, []).map(\n routeFromEndpoint,\n );\n\n return {\n routes,\n match: (method, url, basePath = '') =>\n matchRoute(routes, method, url, basePath),\n };\n}\n"],"mappings":"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"}
|