@contractspec/lib.contracts-runtime-server-rest 3.7.16 → 3.7.18
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.
- package/dist/browser/contracts-adapter-hydration.js +1 -40
- package/dist/browser/contracts-adapter-input.js +1 -99
- package/dist/browser/index.js +1 -346
- package/dist/browser/rest-elysia.js +1 -146
- package/dist/browser/rest-express.js +1 -161
- package/dist/browser/rest-generic.js +1 -129
- package/dist/browser/rest-next-app.js +1 -137
- package/dist/browser/rest-next-pages.js +1 -148
- package/dist/contracts-adapter-hydration.js +1 -40
- package/dist/contracts-adapter-input.js +1 -99
- package/dist/index.js +1 -346
- package/dist/node/contracts-adapter-hydration.js +1 -40
- package/dist/node/contracts-adapter-input.js +1 -99
- package/dist/node/index.js +1 -346
- package/dist/node/rest-elysia.js +1 -146
- package/dist/node/rest-express.js +1 -161
- package/dist/node/rest-generic.js +1 -129
- package/dist/node/rest-next-app.js +1 -137
- package/dist/node/rest-next-pages.js +1 -148
- package/dist/rest-elysia.js +1 -146
- package/dist/rest-express.js +1 -161
- package/dist/rest-generic.js +1 -129
- package/dist/rest-next-app.js +1 -137
- package/dist/rest-next-pages.js +1 -148
- package/package.json +8 -8
|
@@ -1,161 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { defaultRestPath } from "@contractspec/lib.contracts-spec/jsonschema";
|
|
3
|
-
function corsHeaders(opt) {
|
|
4
|
-
const h = {};
|
|
5
|
-
const origin = typeof opt === "object" ? opt.origin ?? "*" : "*";
|
|
6
|
-
h["access-control-allow-origin"] = origin;
|
|
7
|
-
h["vary"] = "Origin";
|
|
8
|
-
if (typeof opt === "object") {
|
|
9
|
-
if (opt.methods)
|
|
10
|
-
h["access-control-allow-methods"] = opt.methods.join(", ");
|
|
11
|
-
if (opt.headers)
|
|
12
|
-
h["access-control-allow-headers"] = opt.headers.join(", ");
|
|
13
|
-
if (opt.credentials)
|
|
14
|
-
h["access-control-allow-credentials"] = "true";
|
|
15
|
-
if (typeof opt.maxAge === "number") {
|
|
16
|
-
h["access-control-max-age"] = String(opt.maxAge);
|
|
17
|
-
}
|
|
18
|
-
} else {
|
|
19
|
-
h["access-control-allow-methods"] = "GET,POST,OPTIONS";
|
|
20
|
-
h["access-control-allow-headers"] = "content-type,x-idempotency-key,x-trace-id";
|
|
21
|
-
}
|
|
22
|
-
return h;
|
|
23
|
-
}
|
|
24
|
-
function joinPath(a, b) {
|
|
25
|
-
const left = (a ?? "").replace(/\/+$/g, "");
|
|
26
|
-
const right = b.replace(/^\/+/g, "");
|
|
27
|
-
return `${left}/${right}`.replace(/\/{2,}/g, "/");
|
|
28
|
-
}
|
|
29
|
-
function createFetchHandler(reg, ctxFactory, options) {
|
|
30
|
-
const opts = {
|
|
31
|
-
basePath: options?.basePath ?? "",
|
|
32
|
-
cors: options?.cors ?? false,
|
|
33
|
-
prettyJson: options?.prettyJson ?? false,
|
|
34
|
-
onError: options?.onError
|
|
35
|
-
};
|
|
36
|
-
const routes = reg.list().map((spec) => ({
|
|
37
|
-
method: spec.transport?.rest?.method ?? (spec.meta.kind === "query" ? "GET" : "POST"),
|
|
38
|
-
path: joinPath(opts.basePath, spec.transport?.rest?.path ?? defaultRestPath(spec.meta.key, spec.meta.version)),
|
|
39
|
-
name: spec.meta.key,
|
|
40
|
-
version: spec.meta.version
|
|
41
|
-
}));
|
|
42
|
-
const routeTable = new Map;
|
|
43
|
-
for (const r of routes)
|
|
44
|
-
routeTable.set(`${r.method} ${r.path}`, r);
|
|
45
|
-
const makeJson = (status, data, extraHeaders) => {
|
|
46
|
-
const body = opts.prettyJson ? JSON.stringify(data, null, opts.prettyJson) : JSON.stringify(data);
|
|
47
|
-
const base = {
|
|
48
|
-
"content-type": "application/json; charset=utf-8"
|
|
49
|
-
};
|
|
50
|
-
return new Response(body, {
|
|
51
|
-
status,
|
|
52
|
-
headers: extraHeaders ? { ...base, ...extraHeaders } : base
|
|
53
|
-
});
|
|
54
|
-
};
|
|
55
|
-
return async function handle(req) {
|
|
56
|
-
const url = new URL(req.url);
|
|
57
|
-
const key = `${req.method.toUpperCase()} ${url.pathname}`;
|
|
58
|
-
if (opts.cors && req.method.toUpperCase() === "OPTIONS") {
|
|
59
|
-
const h = corsHeaders(opts.cors === true ? {} : opts.cors);
|
|
60
|
-
return new Response(null, {
|
|
61
|
-
status: 204,
|
|
62
|
-
headers: { ...h, "content-length": "0" }
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
const route = routeTable.get(key);
|
|
66
|
-
if (!route) {
|
|
67
|
-
const headers = {};
|
|
68
|
-
if (opts.cors)
|
|
69
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
70
|
-
return makeJson(404, { error: "NotFound", path: url.pathname }, headers);
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
let input = {};
|
|
74
|
-
if (route.method === "GET") {
|
|
75
|
-
if (url.searchParams.has("input")) {
|
|
76
|
-
const raw = url.searchParams.get("input");
|
|
77
|
-
input = raw ? JSON.parse(raw) : {};
|
|
78
|
-
} else {
|
|
79
|
-
const obj = {};
|
|
80
|
-
for (const [k, v] of url.searchParams.entries())
|
|
81
|
-
obj[k] = v;
|
|
82
|
-
input = obj;
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
const contentType = req.headers.get("content-type") || "";
|
|
86
|
-
if (contentType.includes("application/json")) {
|
|
87
|
-
input = await req.json();
|
|
88
|
-
} else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
89
|
-
const form = await req.formData();
|
|
90
|
-
input = Object.fromEntries(form.entries());
|
|
91
|
-
} else if (!contentType) {
|
|
92
|
-
input = {};
|
|
93
|
-
} else {
|
|
94
|
-
return makeJson(415, { error: "UnsupportedMediaType", contentType });
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const ctx = ctxFactory(req);
|
|
98
|
-
const result = await reg.execute(route.name, route.version, input, ctx);
|
|
99
|
-
const headers = {};
|
|
100
|
-
if (opts.cors)
|
|
101
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
102
|
-
return makeJson(200, result, headers);
|
|
103
|
-
} catch (err) {
|
|
104
|
-
if (opts.onError) {
|
|
105
|
-
const mapped = opts.onError(err);
|
|
106
|
-
const headers2 = {};
|
|
107
|
-
if (opts.cors)
|
|
108
|
-
Object.assign(headers2, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
109
|
-
return makeJson(mapped.status, mapped.body, headers2);
|
|
110
|
-
}
|
|
111
|
-
const headers = {};
|
|
112
|
-
if (opts.cors)
|
|
113
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
114
|
-
if (err?.issues) {
|
|
115
|
-
return makeJson(400, {
|
|
116
|
-
error: "ValidationError",
|
|
117
|
-
issues: err.issues
|
|
118
|
-
}, headers);
|
|
119
|
-
}
|
|
120
|
-
if (typeof err?.message === "string" && err.message.startsWith("PolicyDenied")) {
|
|
121
|
-
return makeJson(403, { error: "PolicyDenied" }, headers);
|
|
122
|
-
}
|
|
123
|
-
return makeJson(500, { error: "InternalError" }, headers);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// src/rest-express.ts
|
|
129
|
-
function expressRouter(express, reg, ctxFactory, options) {
|
|
130
|
-
const router = express.Router();
|
|
131
|
-
for (const spec of reg.list()) {
|
|
132
|
-
const method = spec.transport?.rest?.method ?? (spec.meta.kind === "query" ? "GET" : "POST");
|
|
133
|
-
const path = (options?.basePath ?? "") + (spec.transport?.rest?.path ?? `/${spec.meta.key.replace(/\./g, "/")}/v${spec.meta.version}`);
|
|
134
|
-
router[method.toLowerCase()](path, async (req, res) => {
|
|
135
|
-
const url = new URL(`${req.protocol}://${req.get("host")}${req.originalUrl}`);
|
|
136
|
-
const request = new Request(url.toString(), {
|
|
137
|
-
method,
|
|
138
|
-
headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, String(v)])),
|
|
139
|
-
body: method === "POST" ? JSON.stringify(req.body ?? {}) : undefined
|
|
140
|
-
});
|
|
141
|
-
const handler = createFetchHandler(reg, () => ctxFactory(req), options);
|
|
142
|
-
const response = await handler(request);
|
|
143
|
-
res.status(response.status);
|
|
144
|
-
response.headers.forEach((v, k) => res.setHeader(k, v));
|
|
145
|
-
const text = await response.text();
|
|
146
|
-
res.send(text);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
if (options?.cors) {
|
|
150
|
-
router.options("*", (_req, res) => {
|
|
151
|
-
const h = new Headers;
|
|
152
|
-
const resp = new Response(null, { status: 204 });
|
|
153
|
-
resp.headers.forEach((v, k) => h.set(k, v));
|
|
154
|
-
res.status(204).send();
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
return router;
|
|
158
|
-
}
|
|
159
|
-
export {
|
|
160
|
-
expressRouter
|
|
161
|
-
};
|
|
1
|
+
import{defaultRestPath as N}from"@contractspec/lib.contracts-spec/jsonschema";function L(E){let O={},x=typeof E==="object"?E.origin??"*":"*";if(O["access-control-allow-origin"]=x,O.vary="Origin",typeof E==="object"){if(E.methods)O["access-control-allow-methods"]=E.methods.join(", ");if(E.headers)O["access-control-allow-headers"]=E.headers.join(", ");if(E.credentials)O["access-control-allow-credentials"]="true";if(typeof E.maxAge==="number")O["access-control-max-age"]=String(E.maxAge)}else O["access-control-allow-methods"]="GET,POST,OPTIONS",O["access-control-allow-headers"]="content-type,x-idempotency-key,x-trace-id";return O}function P(E,O){let x=(E??"").replace(/\/+$/g,""),R=O.replace(/^\/+/g,"");return`${x}/${R}`.replace(/\/{2,}/g,"/")}function v(E,O,x){let R={basePath:x?.basePath??"",cors:x?.cors??!1,prettyJson:x?.prettyJson??!1,onError:x?.onError},t=E.list().map((n)=>({method:n.transport?.rest?.method??(n.meta.kind==="query"?"GET":"POST"),path:P(R.basePath,n.transport?.rest?.path??N(n.meta.key,n.meta.version)),name:n.meta.key,version:n.meta.version})),l=new Map;for(let n of t)l.set(`${n.method} ${n.path}`,n);let w=(n,f,S)=>{let C=R.prettyJson?JSON.stringify(f,null,R.prettyJson):JSON.stringify(f),m={"content-type":"application/json; charset=utf-8"};return new Response(C,{status:n,headers:S?{...m,...S}:m})};return async function(f){let S=new URL(f.url),C=`${f.method.toUpperCase()} ${S.pathname}`;if(R.cors&&f.method.toUpperCase()==="OPTIONS"){let i=L(R.cors===!0?{}:R.cors);return new Response(null,{status:204,headers:{...i,"content-length":"0"}})}let m=l.get(C);if(!m){let i={};if(R.cors)Object.assign(i,L(R.cors===!0?{}:R.cors));return w(404,{error:"NotFound",path:S.pathname},i)}try{let i={};if(m.method==="GET")if(S.searchParams.has("input")){let y=S.searchParams.get("input");i=y?JSON.parse(y):{}}else{let y={};for(let[U,G]of S.searchParams.entries())y[U]=G;i=y}else{let y=f.headers.get("content-type")||"";if(y.includes("application/json"))i=await f.json();else if(y.includes("application/x-www-form-urlencoded")){let U=await f.formData();i=Object.fromEntries(U.entries())}else if(!y)i={};else return w(415,{error:"UnsupportedMediaType",contentType:y})}let $=O(f),c=await E.execute(m.name,m.version,i,$),g={};if(R.cors)Object.assign(g,L(R.cors===!0?{}:R.cors));return w(200,c,g)}catch(i){if(R.onError){let c=R.onError(i),g={};if(R.cors)Object.assign(g,L(R.cors===!0?{}:R.cors));return w(c.status,c.body,g)}let $={};if(R.cors)Object.assign($,L(R.cors===!0?{}:R.cors));if(i?.issues)return w(400,{error:"ValidationError",issues:i.issues},$);if(typeof i?.message==="string"&&i.message.startsWith("PolicyDenied"))return w(403,{error:"PolicyDenied"},$);return w(500,{error:"InternalError"},$)}}}function B(E,O,x,R){let t=E.Router();for(let l of O.list()){let w=l.transport?.rest?.method??(l.meta.kind==="query"?"GET":"POST"),n=(R?.basePath??"")+(l.transport?.rest?.path??`/${l.meta.key.replace(/\./g,"/")}/v${l.meta.version}`);t[w.toLowerCase()](n,async(f,S)=>{let C=new URL(`${f.protocol}://${f.get("host")}${f.originalUrl}`),m=new Request(C.toString(),{method:w,headers:Object.fromEntries(Object.entries(f.headers).map(([g,y])=>[g,String(y)])),body:w==="POST"?JSON.stringify(f.body??{}):void 0}),$=await v(O,()=>x(f),R)(m);S.status($.status),$.headers.forEach((g,y)=>S.setHeader(y,g));let c=await $.text();S.send(c)})}if(R?.cors)t.options("*",(l,w)=>{let n=new Headers;new Response(null,{status:204}).headers.forEach((S,C)=>n.set(C,S)),w.status(204).send()});return t}export{B as expressRouter};
|
|
@@ -1,129 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { defaultRestPath } from "@contractspec/lib.contracts-spec/jsonschema";
|
|
3
|
-
function corsHeaders(opt) {
|
|
4
|
-
const h = {};
|
|
5
|
-
const origin = typeof opt === "object" ? opt.origin ?? "*" : "*";
|
|
6
|
-
h["access-control-allow-origin"] = origin;
|
|
7
|
-
h["vary"] = "Origin";
|
|
8
|
-
if (typeof opt === "object") {
|
|
9
|
-
if (opt.methods)
|
|
10
|
-
h["access-control-allow-methods"] = opt.methods.join(", ");
|
|
11
|
-
if (opt.headers)
|
|
12
|
-
h["access-control-allow-headers"] = opt.headers.join(", ");
|
|
13
|
-
if (opt.credentials)
|
|
14
|
-
h["access-control-allow-credentials"] = "true";
|
|
15
|
-
if (typeof opt.maxAge === "number") {
|
|
16
|
-
h["access-control-max-age"] = String(opt.maxAge);
|
|
17
|
-
}
|
|
18
|
-
} else {
|
|
19
|
-
h["access-control-allow-methods"] = "GET,POST,OPTIONS";
|
|
20
|
-
h["access-control-allow-headers"] = "content-type,x-idempotency-key,x-trace-id";
|
|
21
|
-
}
|
|
22
|
-
return h;
|
|
23
|
-
}
|
|
24
|
-
function joinPath(a, b) {
|
|
25
|
-
const left = (a ?? "").replace(/\/+$/g, "");
|
|
26
|
-
const right = b.replace(/^\/+/g, "");
|
|
27
|
-
return `${left}/${right}`.replace(/\/{2,}/g, "/");
|
|
28
|
-
}
|
|
29
|
-
function createFetchHandler(reg, ctxFactory, options) {
|
|
30
|
-
const opts = {
|
|
31
|
-
basePath: options?.basePath ?? "",
|
|
32
|
-
cors: options?.cors ?? false,
|
|
33
|
-
prettyJson: options?.prettyJson ?? false,
|
|
34
|
-
onError: options?.onError
|
|
35
|
-
};
|
|
36
|
-
const routes = reg.list().map((spec) => ({
|
|
37
|
-
method: spec.transport?.rest?.method ?? (spec.meta.kind === "query" ? "GET" : "POST"),
|
|
38
|
-
path: joinPath(opts.basePath, spec.transport?.rest?.path ?? defaultRestPath(spec.meta.key, spec.meta.version)),
|
|
39
|
-
name: spec.meta.key,
|
|
40
|
-
version: spec.meta.version
|
|
41
|
-
}));
|
|
42
|
-
const routeTable = new Map;
|
|
43
|
-
for (const r of routes)
|
|
44
|
-
routeTable.set(`${r.method} ${r.path}`, r);
|
|
45
|
-
const makeJson = (status, data, extraHeaders) => {
|
|
46
|
-
const body = opts.prettyJson ? JSON.stringify(data, null, opts.prettyJson) : JSON.stringify(data);
|
|
47
|
-
const base = {
|
|
48
|
-
"content-type": "application/json; charset=utf-8"
|
|
49
|
-
};
|
|
50
|
-
return new Response(body, {
|
|
51
|
-
status,
|
|
52
|
-
headers: extraHeaders ? { ...base, ...extraHeaders } : base
|
|
53
|
-
});
|
|
54
|
-
};
|
|
55
|
-
return async function handle(req) {
|
|
56
|
-
const url = new URL(req.url);
|
|
57
|
-
const key = `${req.method.toUpperCase()} ${url.pathname}`;
|
|
58
|
-
if (opts.cors && req.method.toUpperCase() === "OPTIONS") {
|
|
59
|
-
const h = corsHeaders(opts.cors === true ? {} : opts.cors);
|
|
60
|
-
return new Response(null, {
|
|
61
|
-
status: 204,
|
|
62
|
-
headers: { ...h, "content-length": "0" }
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
const route = routeTable.get(key);
|
|
66
|
-
if (!route) {
|
|
67
|
-
const headers = {};
|
|
68
|
-
if (opts.cors)
|
|
69
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
70
|
-
return makeJson(404, { error: "NotFound", path: url.pathname }, headers);
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
let input = {};
|
|
74
|
-
if (route.method === "GET") {
|
|
75
|
-
if (url.searchParams.has("input")) {
|
|
76
|
-
const raw = url.searchParams.get("input");
|
|
77
|
-
input = raw ? JSON.parse(raw) : {};
|
|
78
|
-
} else {
|
|
79
|
-
const obj = {};
|
|
80
|
-
for (const [k, v] of url.searchParams.entries())
|
|
81
|
-
obj[k] = v;
|
|
82
|
-
input = obj;
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
const contentType = req.headers.get("content-type") || "";
|
|
86
|
-
if (contentType.includes("application/json")) {
|
|
87
|
-
input = await req.json();
|
|
88
|
-
} else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
89
|
-
const form = await req.formData();
|
|
90
|
-
input = Object.fromEntries(form.entries());
|
|
91
|
-
} else if (!contentType) {
|
|
92
|
-
input = {};
|
|
93
|
-
} else {
|
|
94
|
-
return makeJson(415, { error: "UnsupportedMediaType", contentType });
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const ctx = ctxFactory(req);
|
|
98
|
-
const result = await reg.execute(route.name, route.version, input, ctx);
|
|
99
|
-
const headers = {};
|
|
100
|
-
if (opts.cors)
|
|
101
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
102
|
-
return makeJson(200, result, headers);
|
|
103
|
-
} catch (err) {
|
|
104
|
-
if (opts.onError) {
|
|
105
|
-
const mapped = opts.onError(err);
|
|
106
|
-
const headers2 = {};
|
|
107
|
-
if (opts.cors)
|
|
108
|
-
Object.assign(headers2, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
109
|
-
return makeJson(mapped.status, mapped.body, headers2);
|
|
110
|
-
}
|
|
111
|
-
const headers = {};
|
|
112
|
-
if (opts.cors)
|
|
113
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
114
|
-
if (err?.issues) {
|
|
115
|
-
return makeJson(400, {
|
|
116
|
-
error: "ValidationError",
|
|
117
|
-
issues: err.issues
|
|
118
|
-
}, headers);
|
|
119
|
-
}
|
|
120
|
-
if (typeof err?.message === "string" && err.message.startsWith("PolicyDenied")) {
|
|
121
|
-
return makeJson(403, { error: "PolicyDenied" }, headers);
|
|
122
|
-
}
|
|
123
|
-
return makeJson(500, { error: "InternalError" }, headers);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
export {
|
|
128
|
-
createFetchHandler
|
|
129
|
-
};
|
|
1
|
+
import{defaultRestPath as Z}from"@contractspec/lib.contracts-spec/jsonschema";function Q(B){let D={},I=typeof B==="object"?B.origin??"*":"*";if(D["access-control-allow-origin"]=I,D.vary="Origin",typeof B==="object"){if(B.methods)D["access-control-allow-methods"]=B.methods.join(", ");if(B.headers)D["access-control-allow-headers"]=B.headers.join(", ");if(B.credentials)D["access-control-allow-credentials"]="true";if(typeof B.maxAge==="number")D["access-control-max-age"]=String(B.maxAge)}else D["access-control-allow-methods"]="GET,POST,OPTIONS",D["access-control-allow-headers"]="content-type,x-idempotency-key,x-trace-id";return D}function _(B,D){let I=(B??"").replace(/\/+$/g,""),z=D.replace(/^\/+/g,"");return`${I}/${z}`.replace(/\/{2,}/g,"/")}function v(B,D,I){let z={basePath:I?.basePath??"",cors:I?.cors??!1,prettyJson:I?.prettyJson??!1,onError:I?.onError},X=B.list().map((C)=>({method:C.transport?.rest?.method??(C.meta.kind==="query"?"GET":"POST"),path:_(z.basePath,C.transport?.rest?.path??Z(C.meta.key,C.meta.version)),name:C.meta.key,version:C.meta.version})),W=new Map;for(let C of X)W.set(`${C.method} ${C.path}`,C);let L=(C,E,K)=>{let U=z.prettyJson?JSON.stringify(E,null,z.prettyJson):JSON.stringify(E),M={"content-type":"application/json; charset=utf-8"};return new Response(U,{status:C,headers:K?{...M,...K}:M})};return async function(E){let K=new URL(E.url),U=`${E.method.toUpperCase()} ${K.pathname}`;if(z.cors&&E.method.toUpperCase()==="OPTIONS"){let A=Q(z.cors===!0?{}:z.cors);return new Response(null,{status:204,headers:{...A,"content-length":"0"}})}let M=W.get(U);if(!M){let A={};if(z.cors)Object.assign(A,Q(z.cors===!0?{}:z.cors));return L(404,{error:"NotFound",path:K.pathname},A)}try{let A={};if(M.method==="GET")if(K.searchParams.has("input")){let G=K.searchParams.get("input");A=G?JSON.parse(G):{}}else{let G={};for(let[V,Y]of K.searchParams.entries())G[V]=Y;A=G}else{let G=E.headers.get("content-type")||"";if(G.includes("application/json"))A=await E.json();else if(G.includes("application/x-www-form-urlencoded")){let V=await E.formData();A=Object.fromEntries(V.entries())}else if(!G)A={};else return L(415,{error:"UnsupportedMediaType",contentType:G})}let N=D(E),S=await B.execute(M.name,M.version,A,N),O={};if(z.cors)Object.assign(O,Q(z.cors===!0?{}:z.cors));return L(200,S,O)}catch(A){if(z.onError){let S=z.onError(A),O={};if(z.cors)Object.assign(O,Q(z.cors===!0?{}:z.cors));return L(S.status,S.body,O)}let N={};if(z.cors)Object.assign(N,Q(z.cors===!0?{}:z.cors));if(A?.issues)return L(400,{error:"ValidationError",issues:A.issues},N);if(typeof A?.message==="string"&&A.message.startsWith("PolicyDenied"))return L(403,{error:"PolicyDenied"},N);return L(500,{error:"InternalError"},N)}}}export{v as createFetchHandler};
|
|
@@ -1,137 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { defaultRestPath } from "@contractspec/lib.contracts-spec/jsonschema";
|
|
3
|
-
function corsHeaders(opt) {
|
|
4
|
-
const h = {};
|
|
5
|
-
const origin = typeof opt === "object" ? opt.origin ?? "*" : "*";
|
|
6
|
-
h["access-control-allow-origin"] = origin;
|
|
7
|
-
h["vary"] = "Origin";
|
|
8
|
-
if (typeof opt === "object") {
|
|
9
|
-
if (opt.methods)
|
|
10
|
-
h["access-control-allow-methods"] = opt.methods.join(", ");
|
|
11
|
-
if (opt.headers)
|
|
12
|
-
h["access-control-allow-headers"] = opt.headers.join(", ");
|
|
13
|
-
if (opt.credentials)
|
|
14
|
-
h["access-control-allow-credentials"] = "true";
|
|
15
|
-
if (typeof opt.maxAge === "number") {
|
|
16
|
-
h["access-control-max-age"] = String(opt.maxAge);
|
|
17
|
-
}
|
|
18
|
-
} else {
|
|
19
|
-
h["access-control-allow-methods"] = "GET,POST,OPTIONS";
|
|
20
|
-
h["access-control-allow-headers"] = "content-type,x-idempotency-key,x-trace-id";
|
|
21
|
-
}
|
|
22
|
-
return h;
|
|
23
|
-
}
|
|
24
|
-
function joinPath(a, b) {
|
|
25
|
-
const left = (a ?? "").replace(/\/+$/g, "");
|
|
26
|
-
const right = b.replace(/^\/+/g, "");
|
|
27
|
-
return `${left}/${right}`.replace(/\/{2,}/g, "/");
|
|
28
|
-
}
|
|
29
|
-
function createFetchHandler(reg, ctxFactory, options) {
|
|
30
|
-
const opts = {
|
|
31
|
-
basePath: options?.basePath ?? "",
|
|
32
|
-
cors: options?.cors ?? false,
|
|
33
|
-
prettyJson: options?.prettyJson ?? false,
|
|
34
|
-
onError: options?.onError
|
|
35
|
-
};
|
|
36
|
-
const routes = reg.list().map((spec) => ({
|
|
37
|
-
method: spec.transport?.rest?.method ?? (spec.meta.kind === "query" ? "GET" : "POST"),
|
|
38
|
-
path: joinPath(opts.basePath, spec.transport?.rest?.path ?? defaultRestPath(spec.meta.key, spec.meta.version)),
|
|
39
|
-
name: spec.meta.key,
|
|
40
|
-
version: spec.meta.version
|
|
41
|
-
}));
|
|
42
|
-
const routeTable = new Map;
|
|
43
|
-
for (const r of routes)
|
|
44
|
-
routeTable.set(`${r.method} ${r.path}`, r);
|
|
45
|
-
const makeJson = (status, data, extraHeaders) => {
|
|
46
|
-
const body = opts.prettyJson ? JSON.stringify(data, null, opts.prettyJson) : JSON.stringify(data);
|
|
47
|
-
const base = {
|
|
48
|
-
"content-type": "application/json; charset=utf-8"
|
|
49
|
-
};
|
|
50
|
-
return new Response(body, {
|
|
51
|
-
status,
|
|
52
|
-
headers: extraHeaders ? { ...base, ...extraHeaders } : base
|
|
53
|
-
});
|
|
54
|
-
};
|
|
55
|
-
return async function handle(req) {
|
|
56
|
-
const url = new URL(req.url);
|
|
57
|
-
const key = `${req.method.toUpperCase()} ${url.pathname}`;
|
|
58
|
-
if (opts.cors && req.method.toUpperCase() === "OPTIONS") {
|
|
59
|
-
const h = corsHeaders(opts.cors === true ? {} : opts.cors);
|
|
60
|
-
return new Response(null, {
|
|
61
|
-
status: 204,
|
|
62
|
-
headers: { ...h, "content-length": "0" }
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
const route = routeTable.get(key);
|
|
66
|
-
if (!route) {
|
|
67
|
-
const headers = {};
|
|
68
|
-
if (opts.cors)
|
|
69
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
70
|
-
return makeJson(404, { error: "NotFound", path: url.pathname }, headers);
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
let input = {};
|
|
74
|
-
if (route.method === "GET") {
|
|
75
|
-
if (url.searchParams.has("input")) {
|
|
76
|
-
const raw = url.searchParams.get("input");
|
|
77
|
-
input = raw ? JSON.parse(raw) : {};
|
|
78
|
-
} else {
|
|
79
|
-
const obj = {};
|
|
80
|
-
for (const [k, v] of url.searchParams.entries())
|
|
81
|
-
obj[k] = v;
|
|
82
|
-
input = obj;
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
const contentType = req.headers.get("content-type") || "";
|
|
86
|
-
if (contentType.includes("application/json")) {
|
|
87
|
-
input = await req.json();
|
|
88
|
-
} else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
89
|
-
const form = await req.formData();
|
|
90
|
-
input = Object.fromEntries(form.entries());
|
|
91
|
-
} else if (!contentType) {
|
|
92
|
-
input = {};
|
|
93
|
-
} else {
|
|
94
|
-
return makeJson(415, { error: "UnsupportedMediaType", contentType });
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const ctx = ctxFactory(req);
|
|
98
|
-
const result = await reg.execute(route.name, route.version, input, ctx);
|
|
99
|
-
const headers = {};
|
|
100
|
-
if (opts.cors)
|
|
101
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
102
|
-
return makeJson(200, result, headers);
|
|
103
|
-
} catch (err) {
|
|
104
|
-
if (opts.onError) {
|
|
105
|
-
const mapped = opts.onError(err);
|
|
106
|
-
const headers2 = {};
|
|
107
|
-
if (opts.cors)
|
|
108
|
-
Object.assign(headers2, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
109
|
-
return makeJson(mapped.status, mapped.body, headers2);
|
|
110
|
-
}
|
|
111
|
-
const headers = {};
|
|
112
|
-
if (opts.cors)
|
|
113
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
114
|
-
if (err?.issues) {
|
|
115
|
-
return makeJson(400, {
|
|
116
|
-
error: "ValidationError",
|
|
117
|
-
issues: err.issues
|
|
118
|
-
}, headers);
|
|
119
|
-
}
|
|
120
|
-
if (typeof err?.message === "string" && err.message.startsWith("PolicyDenied")) {
|
|
121
|
-
return makeJson(403, { error: "PolicyDenied" }, headers);
|
|
122
|
-
}
|
|
123
|
-
return makeJson(500, { error: "InternalError" }, headers);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// src/rest-next-app.ts
|
|
129
|
-
function makeNextAppHandler(reg, ctxFactory, options) {
|
|
130
|
-
const handler = createFetchHandler(reg, ctxFactory, options);
|
|
131
|
-
return async function requestHandler(req) {
|
|
132
|
-
return handler(req);
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
export {
|
|
136
|
-
makeNextAppHandler
|
|
137
|
-
};
|
|
1
|
+
import{defaultRestPath as X}from"@contractspec/lib.contracts-spec/jsonschema";function I(O){let C={},A=typeof O==="object"?O.origin??"*":"*";if(C["access-control-allow-origin"]=A,C.vary="Origin",typeof O==="object"){if(O.methods)C["access-control-allow-methods"]=O.methods.join(", ");if(O.headers)C["access-control-allow-headers"]=O.headers.join(", ");if(O.credentials)C["access-control-allow-credentials"]="true";if(typeof O.maxAge==="number")C["access-control-max-age"]=String(O.maxAge)}else C["access-control-allow-methods"]="GET,POST,OPTIONS",C["access-control-allow-headers"]="content-type,x-idempotency-key,x-trace-id";return C}function Y(O,C){let A=(O??"").replace(/\/+$/g,""),R=C.replace(/^\/+/g,"");return`${A}/${R}`.replace(/\/{2,}/g,"/")}function V(O,C,A){let R={basePath:A?.basePath??"",cors:A?.cors??!1,prettyJson:A?.prettyJson??!1,onError:A?.onError},U=O.list().map((S)=>({method:S.transport?.rest?.method??(S.meta.kind==="query"?"GET":"POST"),path:Y(R.basePath,S.transport?.rest?.path??X(S.meta.key,S.meta.version)),name:S.meta.key,version:S.meta.version})),K=new Map;for(let S of U)K.set(`${S.method} ${S.path}`,S);let B=(S,N,z)=>{let M=R.prettyJson?JSON.stringify(N,null,R.prettyJson):JSON.stringify(N),D={"content-type":"application/json; charset=utf-8"};return new Response(M,{status:S,headers:z?{...D,...z}:D})};return async function(N){let z=new URL(N.url),M=`${N.method.toUpperCase()} ${z.pathname}`;if(R.cors&&N.method.toUpperCase()==="OPTIONS"){let f=I(R.cors===!0?{}:R.cors);return new Response(null,{status:204,headers:{...f,"content-length":"0"}})}let D=K.get(M);if(!D){let f={};if(R.cors)Object.assign(f,I(R.cors===!0?{}:R.cors));return B(404,{error:"NotFound",path:z.pathname},f)}try{let f={};if(D.method==="GET")if(z.searchParams.has("input")){let y=z.searchParams.get("input");f=y?JSON.parse(y):{}}else{let y={};for(let[Q,W]of z.searchParams.entries())y[Q]=W;f=y}else{let y=N.headers.get("content-type")||"";if(y.includes("application/json"))f=await N.json();else if(y.includes("application/x-www-form-urlencoded")){let Q=await N.formData();f=Object.fromEntries(Q.entries())}else if(!y)f={};else return B(415,{error:"UnsupportedMediaType",contentType:y})}let E=C(N),L=await O.execute(D.name,D.version,f,E),G={};if(R.cors)Object.assign(G,I(R.cors===!0?{}:R.cors));return B(200,L,G)}catch(f){if(R.onError){let L=R.onError(f),G={};if(R.cors)Object.assign(G,I(R.cors===!0?{}:R.cors));return B(L.status,L.body,G)}let E={};if(R.cors)Object.assign(E,I(R.cors===!0?{}:R.cors));if(f?.issues)return B(400,{error:"ValidationError",issues:f.issues},E);if(typeof f?.message==="string"&&f.message.startsWith("PolicyDenied"))return B(403,{error:"PolicyDenied"},E);return B(500,{error:"InternalError"},E)}}}function v(O,C,A){let R=V(O,C,A);return async function(K){return R(K)}}export{v as makeNextAppHandler};
|
|
@@ -1,148 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { defaultRestPath } from "@contractspec/lib.contracts-spec/jsonschema";
|
|
3
|
-
function corsHeaders(opt) {
|
|
4
|
-
const h = {};
|
|
5
|
-
const origin = typeof opt === "object" ? opt.origin ?? "*" : "*";
|
|
6
|
-
h["access-control-allow-origin"] = origin;
|
|
7
|
-
h["vary"] = "Origin";
|
|
8
|
-
if (typeof opt === "object") {
|
|
9
|
-
if (opt.methods)
|
|
10
|
-
h["access-control-allow-methods"] = opt.methods.join(", ");
|
|
11
|
-
if (opt.headers)
|
|
12
|
-
h["access-control-allow-headers"] = opt.headers.join(", ");
|
|
13
|
-
if (opt.credentials)
|
|
14
|
-
h["access-control-allow-credentials"] = "true";
|
|
15
|
-
if (typeof opt.maxAge === "number") {
|
|
16
|
-
h["access-control-max-age"] = String(opt.maxAge);
|
|
17
|
-
}
|
|
18
|
-
} else {
|
|
19
|
-
h["access-control-allow-methods"] = "GET,POST,OPTIONS";
|
|
20
|
-
h["access-control-allow-headers"] = "content-type,x-idempotency-key,x-trace-id";
|
|
21
|
-
}
|
|
22
|
-
return h;
|
|
23
|
-
}
|
|
24
|
-
function joinPath(a, b) {
|
|
25
|
-
const left = (a ?? "").replace(/\/+$/g, "");
|
|
26
|
-
const right = b.replace(/^\/+/g, "");
|
|
27
|
-
return `${left}/${right}`.replace(/\/{2,}/g, "/");
|
|
28
|
-
}
|
|
29
|
-
function createFetchHandler(reg, ctxFactory, options) {
|
|
30
|
-
const opts = {
|
|
31
|
-
basePath: options?.basePath ?? "",
|
|
32
|
-
cors: options?.cors ?? false,
|
|
33
|
-
prettyJson: options?.prettyJson ?? false,
|
|
34
|
-
onError: options?.onError
|
|
35
|
-
};
|
|
36
|
-
const routes = reg.list().map((spec) => ({
|
|
37
|
-
method: spec.transport?.rest?.method ?? (spec.meta.kind === "query" ? "GET" : "POST"),
|
|
38
|
-
path: joinPath(opts.basePath, spec.transport?.rest?.path ?? defaultRestPath(spec.meta.key, spec.meta.version)),
|
|
39
|
-
name: spec.meta.key,
|
|
40
|
-
version: spec.meta.version
|
|
41
|
-
}));
|
|
42
|
-
const routeTable = new Map;
|
|
43
|
-
for (const r of routes)
|
|
44
|
-
routeTable.set(`${r.method} ${r.path}`, r);
|
|
45
|
-
const makeJson = (status, data, extraHeaders) => {
|
|
46
|
-
const body = opts.prettyJson ? JSON.stringify(data, null, opts.prettyJson) : JSON.stringify(data);
|
|
47
|
-
const base = {
|
|
48
|
-
"content-type": "application/json; charset=utf-8"
|
|
49
|
-
};
|
|
50
|
-
return new Response(body, {
|
|
51
|
-
status,
|
|
52
|
-
headers: extraHeaders ? { ...base, ...extraHeaders } : base
|
|
53
|
-
});
|
|
54
|
-
};
|
|
55
|
-
return async function handle(req) {
|
|
56
|
-
const url = new URL(req.url);
|
|
57
|
-
const key = `${req.method.toUpperCase()} ${url.pathname}`;
|
|
58
|
-
if (opts.cors && req.method.toUpperCase() === "OPTIONS") {
|
|
59
|
-
const h = corsHeaders(opts.cors === true ? {} : opts.cors);
|
|
60
|
-
return new Response(null, {
|
|
61
|
-
status: 204,
|
|
62
|
-
headers: { ...h, "content-length": "0" }
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
const route = routeTable.get(key);
|
|
66
|
-
if (!route) {
|
|
67
|
-
const headers = {};
|
|
68
|
-
if (opts.cors)
|
|
69
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
70
|
-
return makeJson(404, { error: "NotFound", path: url.pathname }, headers);
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
let input = {};
|
|
74
|
-
if (route.method === "GET") {
|
|
75
|
-
if (url.searchParams.has("input")) {
|
|
76
|
-
const raw = url.searchParams.get("input");
|
|
77
|
-
input = raw ? JSON.parse(raw) : {};
|
|
78
|
-
} else {
|
|
79
|
-
const obj = {};
|
|
80
|
-
for (const [k, v] of url.searchParams.entries())
|
|
81
|
-
obj[k] = v;
|
|
82
|
-
input = obj;
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
const contentType = req.headers.get("content-type") || "";
|
|
86
|
-
if (contentType.includes("application/json")) {
|
|
87
|
-
input = await req.json();
|
|
88
|
-
} else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
89
|
-
const form = await req.formData();
|
|
90
|
-
input = Object.fromEntries(form.entries());
|
|
91
|
-
} else if (!contentType) {
|
|
92
|
-
input = {};
|
|
93
|
-
} else {
|
|
94
|
-
return makeJson(415, { error: "UnsupportedMediaType", contentType });
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const ctx = ctxFactory(req);
|
|
98
|
-
const result = await reg.execute(route.name, route.version, input, ctx);
|
|
99
|
-
const headers = {};
|
|
100
|
-
if (opts.cors)
|
|
101
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
102
|
-
return makeJson(200, result, headers);
|
|
103
|
-
} catch (err) {
|
|
104
|
-
if (opts.onError) {
|
|
105
|
-
const mapped = opts.onError(err);
|
|
106
|
-
const headers2 = {};
|
|
107
|
-
if (opts.cors)
|
|
108
|
-
Object.assign(headers2, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
109
|
-
return makeJson(mapped.status, mapped.body, headers2);
|
|
110
|
-
}
|
|
111
|
-
const headers = {};
|
|
112
|
-
if (opts.cors)
|
|
113
|
-
Object.assign(headers, corsHeaders(opts.cors === true ? {} : opts.cors));
|
|
114
|
-
if (err?.issues) {
|
|
115
|
-
return makeJson(400, {
|
|
116
|
-
error: "ValidationError",
|
|
117
|
-
issues: err.issues
|
|
118
|
-
}, headers);
|
|
119
|
-
}
|
|
120
|
-
if (typeof err?.message === "string" && err.message.startsWith("PolicyDenied")) {
|
|
121
|
-
return makeJson(403, { error: "PolicyDenied" }, headers);
|
|
122
|
-
}
|
|
123
|
-
return makeJson(500, { error: "InternalError" }, headers);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// src/rest-next-pages.ts
|
|
129
|
-
function makeNextPagesHandler(reg, ctxFactory, options) {
|
|
130
|
-
return async function handler(req, res) {
|
|
131
|
-
const url = `${req.headers["x-forwarded-proto"] ?? "http"}://${req.headers.host}${req.url}`;
|
|
132
|
-
const method = req.method?.toUpperCase() || "GET";
|
|
133
|
-
const request = new Request(url, {
|
|
134
|
-
method,
|
|
135
|
-
headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, String(v)])),
|
|
136
|
-
body: method === "POST" ? JSON.stringify(req.body ?? {}) : undefined
|
|
137
|
-
});
|
|
138
|
-
const perReqHandler = createFetchHandler(reg, () => ctxFactory(req), options);
|
|
139
|
-
const response = await perReqHandler(request);
|
|
140
|
-
res.status(response.status);
|
|
141
|
-
response.headers.forEach((v, k) => res.setHeader(k, v));
|
|
142
|
-
const text = await response.text();
|
|
143
|
-
res.send(text);
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
export {
|
|
147
|
-
makeNextPagesHandler
|
|
148
|
-
};
|
|
1
|
+
import{defaultRestPath as D}from"@contractspec/lib.contracts-spec/jsonschema";function U(f){let N={},x=typeof f==="object"?f.origin??"*":"*";if(N["access-control-allow-origin"]=x,N.vary="Origin",typeof f==="object"){if(f.methods)N["access-control-allow-methods"]=f.methods.join(", ");if(f.headers)N["access-control-allow-headers"]=f.headers.join(", ");if(f.credentials)N["access-control-allow-credentials"]="true";if(typeof f.maxAge==="number")N["access-control-max-age"]=String(f.maxAge)}else N["access-control-allow-methods"]="GET,POST,OPTIONS",N["access-control-allow-headers"]="content-type,x-idempotency-key,x-trace-id";return N}function I(f,N){let x=(f??"").replace(/\/+$/g,""),R=N.replace(/^\/+/g,"");return`${x}/${R}`.replace(/\/{2,}/g,"/")}function z(f,N,x){let R={basePath:x?.basePath??"",cors:x?.cors??!1,prettyJson:x?.prettyJson??!1,onError:x?.onError},y=f.list().map((O)=>({method:O.transport?.rest?.method??(O.meta.kind==="query"?"GET":"POST"),path:I(R.basePath,O.transport?.rest?.path??D(O.meta.key,O.meta.version)),name:O.meta.key,version:O.meta.version})),w=new Map;for(let O of y)w.set(`${O.method} ${O.path}`,O);let C=(O,n,E)=>{let m=R.prettyJson?JSON.stringify(n,null,R.prettyJson):JSON.stringify(n),$={"content-type":"application/json; charset=utf-8"};return new Response(m,{status:O,headers:E?{...$,...E}:$})};return async function(n){let E=new URL(n.url),m=`${n.method.toUpperCase()} ${E.pathname}`;if(R.cors&&n.method.toUpperCase()==="OPTIONS"){let i=U(R.cors===!0?{}:R.cors);return new Response(null,{status:204,headers:{...i,"content-length":"0"}})}let $=w.get(m);if(!$){let i={};if(R.cors)Object.assign(i,U(R.cors===!0?{}:R.cors));return C(404,{error:"NotFound",path:E.pathname},i)}try{let i={};if($.method==="GET")if(E.searchParams.has("input")){let S=E.searchParams.get("input");i=S?JSON.parse(S):{}}else{let S={};for(let[l,B]of E.searchParams.entries())S[l]=B;i=S}else{let S=n.headers.get("content-type")||"";if(S.includes("application/json"))i=await n.json();else if(S.includes("application/x-www-form-urlencoded")){let l=await n.formData();i=Object.fromEntries(l.entries())}else if(!S)i={};else return C(415,{error:"UnsupportedMediaType",contentType:S})}let A=N(n),g=await f.execute($.name,$.version,i,A),G={};if(R.cors)Object.assign(G,U(R.cors===!0?{}:R.cors));return C(200,g,G)}catch(i){if(R.onError){let g=R.onError(i),G={};if(R.cors)Object.assign(G,U(R.cors===!0?{}:R.cors));return C(g.status,g.body,G)}let A={};if(R.cors)Object.assign(A,U(R.cors===!0?{}:R.cors));if(i?.issues)return C(400,{error:"ValidationError",issues:i.issues},A);if(typeof i?.message==="string"&&i.message.startsWith("PolicyDenied"))return C(403,{error:"PolicyDenied"},A);return C(500,{error:"InternalError"},A)}}}function P(f,N,x){return async function(y,w){let C=`${y.headers["x-forwarded-proto"]??"http"}://${y.headers.host}${y.url}`,O=y.method?.toUpperCase()||"GET",n=new Request(C,{method:O,headers:Object.fromEntries(Object.entries(y.headers).map(([i,A])=>[i,String(A)])),body:O==="POST"?JSON.stringify(y.body??{}):void 0}),m=await z(f,()=>N(y),x)(n);w.status(m.status),m.headers.forEach((i,A)=>w.setHeader(A,i));let $=await m.text();w.send($)}}export{P as makeNextPagesHandler};
|
|
@@ -1,41 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
function parseReturns(returnsLike) {
|
|
4
|
-
if (!returnsLike)
|
|
5
|
-
return { isList: false, inner: "JSON" };
|
|
6
|
-
const trimmed = String(returnsLike).trim();
|
|
7
|
-
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
8
|
-
return { isList: true, inner: trimmed.slice(1, -1).trim() };
|
|
9
|
-
}
|
|
10
|
-
return { isList: false, inner: trimmed };
|
|
11
|
-
}
|
|
12
|
-
async function hydrateResourceIfNeeded(resources, result, opts) {
|
|
13
|
-
if (!resources || !opts.template)
|
|
14
|
-
return result;
|
|
15
|
-
const varName = opts.varName ?? "id";
|
|
16
|
-
const hydrateOne = async (item) => {
|
|
17
|
-
if (item && typeof item === "object" && varName in item) {
|
|
18
|
-
const key = String(item[varName]);
|
|
19
|
-
const uri = (opts.template ?? "").replace("{id}", key);
|
|
20
|
-
const match = resources.match(uri);
|
|
21
|
-
if (match) {
|
|
22
|
-
const resolved = await match.tmpl.resolve(match.params, {});
|
|
23
|
-
try {
|
|
24
|
-
return JSON.parse(String(resolved.data || "null"));
|
|
25
|
-
} catch {
|
|
26
|
-
return resolved.data;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return item;
|
|
31
|
-
};
|
|
32
|
-
if (opts.returns.isList && Array.isArray(result)) {
|
|
33
|
-
const hydrated = await Promise.all(result.map((x) => hydrateOne(x)));
|
|
34
|
-
return hydrated;
|
|
35
|
-
}
|
|
36
|
-
return await hydrateOne(result);
|
|
37
|
-
}
|
|
38
|
-
export {
|
|
39
|
-
parseReturns,
|
|
40
|
-
hydrateResourceIfNeeded
|
|
41
|
-
};
|
|
2
|
+
function d(t){if(!t)return{isList:!1,inner:"JSON"};let r=String(t).trim();if(r.startsWith("[")&&r.endsWith("]"))return{isList:!0,inner:r.slice(1,-1).trim()};return{isList:!1,inner:r}}async function l(t,r,e){if(!t||!e.template)return r;let a=e.varName??"id",c=async(n)=>{if(n&&typeof n==="object"&&a in n){let s=String(n[a]),u=(e.template??"").replace("{id}",s),i=t.match(u);if(i){let o=await i.tmpl.resolve(i.params,{});try{return JSON.parse(String(o.data||"null"))}catch{return o.data}}}return n};if(e.returns.isList&&Array.isArray(r))return await Promise.all(r.map((s)=>c(s)));return await c(r)}export{d as parseReturns,l as hydrateResourceIfNeeded};
|