1 |
|
2 |
|
3 |
|
4 |
|
5 | class DenoStdInternalError extends Error {
|
6 | constructor(message){
|
7 | super(message);
|
8 | this.name = "DenoStdInternalError";
|
9 | }
|
10 | }
|
11 | function assert(expr, msg = "") {
|
12 | if (!expr) {
|
13 | throw new DenoStdInternalError(msg);
|
14 | }
|
15 | }
|
16 | const { hasOwn } = Object;
|
17 | function get(obj, key) {
|
18 | if (hasOwn(obj, key)) {
|
19 | return obj[key];
|
20 | }
|
21 | }
|
22 | function getForce(obj, key) {
|
23 | const v = get(obj, key);
|
24 | assert(v != null);
|
25 | return v;
|
26 | }
|
27 | function isNumber(x) {
|
28 | if (typeof x === "number") return true;
|
29 | if (/^0x[0-9a-f]+$/i.test(String(x))) return true;
|
30 | return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(String(x));
|
31 | }
|
32 | function hasKey(obj, keys) {
|
33 | let o = obj;
|
34 | keys.slice(0, -1).forEach((key)=>{
|
35 | o = get(o, key) ?? {};
|
36 | });
|
37 | const key1 = keys[keys.length - 1];
|
38 | return key1 in o;
|
39 | }
|
40 | function parse(args, { "--": doubleDash = false , alias: alias3 = {} , boolean: __boolean = false , default: defaults = {} , stopEarly =false , string =[] , unknown =(i)=>i
|
41 | } = {}) {
|
42 | const flags = {
|
43 | bools: {},
|
44 | strings: {},
|
45 | unknownFn: unknown,
|
46 | allBools: false
|
47 | };
|
48 | if (__boolean !== undefined) {
|
49 | if (typeof __boolean === "boolean") {
|
50 | flags.allBools = !!__boolean;
|
51 | } else {
|
52 | const booleanArgs = typeof __boolean === "string" ? [
|
53 | __boolean
|
54 | ] : __boolean;
|
55 | for (const key of booleanArgs.filter(Boolean)){
|
56 | flags.bools[key] = true;
|
57 | }
|
58 | }
|
59 | }
|
60 | const aliases = {};
|
61 | if (alias3 !== undefined) {
|
62 | for(const key in alias3){
|
63 | const val = getForce(alias3, key);
|
64 | if (typeof val === "string") {
|
65 | aliases[key] = [
|
66 | val
|
67 | ];
|
68 | } else {
|
69 | aliases[key] = val;
|
70 | }
|
71 | for (const alias1 of getForce(aliases, key)){
|
72 | aliases[alias1] = [
|
73 | key
|
74 | ].concat(aliases[key].filter((y)=>alias1 !== y
|
75 | ));
|
76 | }
|
77 | }
|
78 | }
|
79 | if (string !== undefined) {
|
80 | const stringArgs = typeof string === "string" ? [
|
81 | string
|
82 | ] : string;
|
83 | for (const key of stringArgs.filter(Boolean)){
|
84 | flags.strings[key] = true;
|
85 | const alias = get(aliases, key);
|
86 | if (alias) {
|
87 | for (const al of alias){
|
88 | flags.strings[al] = true;
|
89 | }
|
90 | }
|
91 | }
|
92 | }
|
93 | const argv = {
|
94 | _: []
|
95 | };
|
96 | function argDefined(key, arg) {
|
97 | return flags.allBools && /^--[^=]+$/.test(arg) || get(flags.bools, key) || !!get(flags.strings, key) || !!get(aliases, key);
|
98 | }
|
99 | function setKey(obj, keys, value) {
|
100 | let o = obj;
|
101 | keys.slice(0, -1).forEach(function(key) {
|
102 | if (get(o, key) === undefined) {
|
103 | o[key] = {};
|
104 | }
|
105 | o = get(o, key);
|
106 | });
|
107 | const key4 = keys[keys.length - 1];
|
108 | if (get(o, key4) === undefined || get(flags.bools, key4) || typeof get(o, key4) === "boolean") {
|
109 | o[key4] = value;
|
110 | } else if (Array.isArray(get(o, key4))) {
|
111 | o[key4].push(value);
|
112 | } else {
|
113 | o[key4] = [
|
114 | get(o, key4),
|
115 | value
|
116 | ];
|
117 | }
|
118 | }
|
119 | function setArg(key, val, arg = undefined) {
|
120 | if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
121 | if (flags.unknownFn(arg, key, val) === false) return;
|
122 | }
|
123 | const value = !get(flags.strings, key) && isNumber(val) ? Number(val) : val;
|
124 | setKey(argv, key.split("."), value);
|
125 | const alias = get(aliases, key);
|
126 | if (alias) {
|
127 | for (const x of alias){
|
128 | setKey(argv, x.split("."), value);
|
129 | }
|
130 | }
|
131 | }
|
132 | function aliasIsBoolean(key) {
|
133 | return getForce(aliases, key).some((x)=>typeof get(flags.bools, x) === "boolean"
|
134 | );
|
135 | }
|
136 | for (const key3 of Object.keys(flags.bools)){
|
137 | setArg(key3, defaults[key3] === undefined ? false : defaults[key3]);
|
138 | }
|
139 | let notFlags = [];
|
140 | if (args.includes("--")) {
|
141 | notFlags = args.slice(args.indexOf("--") + 1);
|
142 | args = args.slice(0, args.indexOf("--"));
|
143 | }
|
144 | for(let i = 0; i < args.length; i++){
|
145 | const arg = args[i];
|
146 | if (/^--.+=/.test(arg)) {
|
147 | const m = arg.match(/^--([^=]+)=(.*)$/s);
|
148 | assert(m != null);
|
149 | const [, key, value] = m;
|
150 | if (flags.bools[key]) {
|
151 | const booleanValue = value !== "false";
|
152 | setArg(key, booleanValue, arg);
|
153 | } else {
|
154 | setArg(key, value, arg);
|
155 | }
|
156 | } else if (/^--no-.+/.test(arg)) {
|
157 | const m = arg.match(/^--no-(.+)/);
|
158 | assert(m != null);
|
159 | setArg(m[1], false, arg);
|
160 | } else if (/^--.+/.test(arg)) {
|
161 | const m = arg.match(/^--(.+)/);
|
162 | assert(m != null);
|
163 | const [, key] = m;
|
164 | const next = args[i + 1];
|
165 | if (next !== undefined && !/^-/.test(next) && !get(flags.bools, key) && !flags.allBools && (get(aliases, key) ? !aliasIsBoolean(key) : true)) {
|
166 | setArg(key, next, arg);
|
167 | i++;
|
168 | } else if (/^(true|false)$/.test(next)) {
|
169 | setArg(key, next === "true", arg);
|
170 | i++;
|
171 | } else {
|
172 | setArg(key, get(flags.strings, key) ? "" : true, arg);
|
173 | }
|
174 | } else if (/^-[^-]+/.test(arg)) {
|
175 | const letters = arg.slice(1, -1).split("");
|
176 | let broken = false;
|
177 | for(let j = 0; j < letters.length; j++){
|
178 | const next = arg.slice(j + 2);
|
179 | if (next === "-") {
|
180 | setArg(letters[j], next, arg);
|
181 | continue;
|
182 | }
|
183 | if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
|
184 | setArg(letters[j], next.split(/=(.+)/)[1], arg);
|
185 | broken = true;
|
186 | break;
|
187 | }
|
188 | if (/[A-Za-z]/.test(letters[j]) && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
|
189 | setArg(letters[j], next, arg);
|
190 | broken = true;
|
191 | break;
|
192 | }
|
193 | if (letters[j + 1] && letters[j + 1].match(/\W/)) {
|
194 | setArg(letters[j], arg.slice(j + 2), arg);
|
195 | broken = true;
|
196 | break;
|
197 | } else {
|
198 | setArg(letters[j], get(flags.strings, letters[j]) ? "" : true, arg);
|
199 | }
|
200 | }
|
201 | const [key] = arg.slice(-1);
|
202 | if (!broken && key !== "-") {
|
203 | if (args[i + 1] && !/^(-|--)[^-]/.test(args[i + 1]) && !get(flags.bools, key) && (get(aliases, key) ? !aliasIsBoolean(key) : true)) {
|
204 | setArg(key, args[i + 1], arg);
|
205 | i++;
|
206 | } else if (args[i + 1] && /^(true|false)$/.test(args[i + 1])) {
|
207 | setArg(key, args[i + 1] === "true", arg);
|
208 | i++;
|
209 | } else {
|
210 | setArg(key, get(flags.strings, key) ? "" : true, arg);
|
211 | }
|
212 | }
|
213 | } else {
|
214 | if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
215 | argv._.push(flags.strings["_"] ?? !isNumber(arg) ? arg : Number(arg));
|
216 | }
|
217 | if (stopEarly) {
|
218 | argv._.push(...args.slice(i + 1));
|
219 | break;
|
220 | }
|
221 | }
|
222 | }
|
223 | for (const key2 of Object.keys(defaults)){
|
224 | if (!hasKey(argv, key2.split("."))) {
|
225 | setKey(argv, key2.split("."), defaults[key2]);
|
226 | if (aliases[key2]) {
|
227 | for (const x of aliases[key2]){
|
228 | setKey(argv, x.split("."), defaults[key2]);
|
229 | }
|
230 | }
|
231 | }
|
232 | }
|
233 | if (doubleDash) {
|
234 | argv["--"] = [];
|
235 | for (const key of notFlags){
|
236 | argv["--"].push(key);
|
237 | }
|
238 | } else {
|
239 | for (const key of notFlags){
|
240 | argv._.push(key);
|
241 | }
|
242 | }
|
243 | return argv;
|
244 | }
|
245 | const importMeta = {
|
246 | url: "file:///home/runner/work/deno-fetch-event-adapter/deno-fetch-event-adapter/listen.ts",
|
247 | main: import.meta.main
|
248 | };
|
249 | class AdaptedFetchEvent extends Event {
|
250 | #event;
|
251 | #request;
|
252 | constructor(event, hostname){
|
253 | super('fetch');
|
254 | if (typeof event === 'string' || typeof hostname === 'object') throw Error('Overload not implemented');
|
255 | this.#event = event;
|
256 | const headers = new Headers([
|
257 | ...this.#event.request.headers,
|
258 | ...hostname ? [
|
259 | [
|
260 | 'x-forwarded-for',
|
261 | hostname
|
262 | ]
|
263 | ] : [],
|
264 | ]);
|
265 | this.#request = new Proxy(this.#event.request, {
|
266 | get (target, prop) {
|
267 | return prop === 'headers' ? headers : Reflect.get(target, prop);
|
268 | }
|
269 | });
|
270 | }
|
271 | get request() {
|
272 | return this.#request;
|
273 | }
|
274 | respondWith(r) {
|
275 | this.#event.respondWith(r);
|
276 | }
|
277 | waitUntil(_f) {}
|
278 | get clientId() {
|
279 | return '';
|
280 | }
|
281 | get preloadResponse() {
|
282 | return Promise.resolve();
|
283 | }
|
284 | get replacesClientId() {
|
285 | return '';
|
286 | }
|
287 | get resultingClientId() {
|
288 | return '';
|
289 | }
|
290 | }
|
291 | Object.defineProperty(self, 'FetchEvent', {
|
292 | configurable: false,
|
293 | enumerable: false,
|
294 | writable: false,
|
295 | value: AdaptedFetchEvent
|
296 | });
|
297 | const NAME = 'Deno Fetch Event Adapter';
|
298 | (async ()=>{
|
299 | let server;
|
300 | if (!self.location) {
|
301 | throw new Error(`${NAME}: When using Deno Fetch Event Adapter, a --location is required.`);
|
302 | }
|
303 | if (self.location.protocol === 'https:' || self.location.port === '433') {
|
304 | const { cert: certFile , key: keyFile } = parse(Deno.args, {
|
305 | alias: {
|
306 | cert: [
|
307 | 'c',
|
308 | 'cert-file'
|
309 | ],
|
310 | key: [
|
311 | 'k',
|
312 | 'key-file'
|
313 | ]
|
314 | }
|
315 | });
|
316 | if (!certFile || !keyFile) {
|
317 | throw new Error(`${NAME}: When using HTTPS or port 443, a --cert and --key are required.`);
|
318 | }
|
319 | server = Deno.listenTls({
|
320 | hostname: self.location.hostname,
|
321 | port: Number(self.location.port || 443),
|
322 | certFile,
|
323 | keyFile
|
324 | });
|
325 | } else {
|
326 | server = Deno.listen({
|
327 | hostname: self.location.hostname,
|
328 | port: Number(self.location.port || 80)
|
329 | });
|
330 | }
|
331 | for await (const conn of server){
|
332 | (async ()=>{
|
333 | try {
|
334 | for await (const event of Deno.serveHttp(conn)){
|
335 | const { hostname } = conn.remoteAddr;
|
336 | self.dispatchEvent(new AdaptedFetchEvent(event, hostname));
|
337 | }
|
338 | } catch (error) {
|
339 | self.dispatchEvent(new ErrorEvent('error', {
|
340 | message: error?.message,
|
341 | filename: importMeta.url,
|
342 | error
|
343 | }));
|
344 | }
|
345 | })();
|
346 | }
|
347 | })();
|
348 |
|