edge.libx.js 0.0.1

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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/bin/cli.sh +7 -0
  4. package/bin/set-secrets.ts +70 -0
  5. package/bin/test.ts +18 -0
  6. package/build/Main.d.ts +1 -0
  7. package/build/Main.js +6 -0
  8. package/build/Main.js.map +1 -0
  9. package/build/helpers/EdgeNetwork.d.ts +13 -0
  10. package/build/helpers/EdgeNetwork.js +100 -0
  11. package/build/helpers/EdgeNetwork.js.map +1 -0
  12. package/build/helpers/Exceptions.d.ts +37 -0
  13. package/build/helpers/Exceptions.js +100 -0
  14. package/build/helpers/Exceptions.js.map +1 -0
  15. package/build/helpers/getExpress.d.ts +4 -0
  16. package/build/helpers/getExpress.js +25 -0
  17. package/build/helpers/getExpress.js.map +1 -0
  18. package/build/helpers/index.d.ts +12 -0
  19. package/build/helpers/index.js +70 -0
  20. package/build/helpers/index.js.map +1 -0
  21. package/build/helpers/jwt.d.ts +57 -0
  22. package/build/helpers/jwt.js +227 -0
  23. package/build/helpers/jwt.js.map +1 -0
  24. package/build/helpers/localServer.d.ts +1 -0
  25. package/build/helpers/localServer.js +54 -0
  26. package/build/helpers/localServer.js.map +1 -0
  27. package/build/helpers/require.d.ts +1 -0
  28. package/build/helpers/require.js +219 -0
  29. package/build/helpers/require.js.map +1 -0
  30. package/build/modules/@module.d.ts +6 -0
  31. package/build/modules/@module.js +16 -0
  32. package/build/modules/@module.js.map +1 -0
  33. package/build/modules/RouterWrapper.d.ts +21 -0
  34. package/build/modules/RouterWrapper.js +62 -0
  35. package/build/modules/RouterWrapper.js.map +1 -0
  36. package/build/modules/cors.d.ts +15 -0
  37. package/build/modules/cors.js +117 -0
  38. package/build/modules/cors.js.map +1 -0
  39. package/jest.config.js +26 -0
  40. package/package.json +65 -0
  41. package/src/Main.ts +1 -0
  42. package/src/helpers/EdgeNetwork.ts +113 -0
  43. package/src/helpers/Exceptions.ts +102 -0
  44. package/src/helpers/getExpress.ts +25 -0
  45. package/src/helpers/index.ts +61 -0
  46. package/src/helpers/jwt.ts +287 -0
  47. package/src/helpers/localServer.ts +75 -0
  48. package/src/helpers/require.ts +331 -0
  49. package/src/modules/@module.ts +13 -0
  50. package/src/modules/RouterWrapper.ts +68 -0
  51. package/src/modules/cors.ts +153 -0
@@ -0,0 +1,13 @@
1
+ import { libx } from 'libx.js/build/bundles/essentials.js';
2
+
3
+ export class Module {
4
+ public constructor(public options?: Partial<ModuleOptions>) {
5
+ this.options = { ...new ModuleOptions(), ...options };
6
+ libx.log.v('Module:ctor');
7
+ }
8
+
9
+ }
10
+
11
+ export class ModuleOptions {
12
+
13
+ }
@@ -0,0 +1,68 @@
1
+ import { libx } from 'libx.js/build/bundles/essentials.js';
2
+ import { Route, Router, RouterType, error, json, cors, withParams, IRequest, text, ResponseHandler } from 'itty-router';
3
+ import { createServerAdapter } from '@whatwg-node/server';
4
+
5
+ type BaseRouterInitializer = (string) => { base: string; router: RouterType<IRequest, any[]> };
6
+
7
+ export class RouterWrapper<TCtx = any> {
8
+ private static cors = cors({ origin: ['*'], allowMethods: ['POST'] });
9
+ private static preflight = this.cors.preflight;
10
+ private static corsify = this.cors.corsify;
11
+
12
+ public constructor(public base: string, public router: RouterType<Request, [], any>) {
13
+
14
+ }
15
+
16
+ private static tryCors(response, request): Response {
17
+ try {
18
+ return this.corsify(response, request);
19
+ } catch (err) {
20
+ libx.log.w('tryCors: failed to perform CORS', err);
21
+ }
22
+ }
23
+
24
+ public static getNew(base: string) {
25
+ const router = Router({
26
+ base,
27
+ before: [this.preflight],
28
+ catch: this.errorHandler,
29
+ finally: [this.tryCors],
30
+ });
31
+ router.all('*', withParams);
32
+ // router.finally.push(this.corsify);
33
+
34
+ // router.all('*', () => error(404));
35
+
36
+ return new RouterWrapper(base, router);
37
+ }
38
+
39
+
40
+ public static errorHandler(error) {
41
+ const isObject = libx.isObject(error);
42
+ const errMessage = error?.message ?? error;
43
+ const msg = 'Error: ' + (!isObject ? (errMessage ?? 'Server Error') : JSON.stringify(error));
44
+ const status = parseInt(error?.status ?? error?.statusCode ?? error?.code ?? error?.error?.code) || 500;
45
+ console.error('Server error: ', error, status);
46
+ return new Response(msg, { status })
47
+ }
48
+
49
+ public registerRoute(newBase: string, baseRouterInitializer: BaseRouterInitializer) {
50
+ const route = baseRouterInitializer(`${this.base}${newBase}`);
51
+ this.router.all(newBase + '/*', route.router.fetch);
52
+ return this.router;
53
+ };
54
+
55
+ public fetchHandler(request: IRequest, ctx: TCtx) {
56
+ // return this.router.fetch(request, ctx).then(json).then(RouterWrapper.corsify).catch(this.errorHandler);
57
+ return this.router.fetch(request, ctx).then(json).catch(RouterWrapper.errorHandler);
58
+ }
59
+
60
+ public catchNotFound() {
61
+ this.router.all('*', () => error(404));
62
+ }
63
+
64
+ public createServerAdapter() {
65
+ const ittyServer = createServerAdapter(this.fetchHandler.bind(this));
66
+ return ittyServer;
67
+ }
68
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Multi purpose CORS lib.
3
+ * Note: Based on the `cors` package in npm but using only
4
+ * web APIs. Feel free to use it in your own projects.
5
+ */
6
+
7
+ type StaticOrigin = boolean | string | RegExp | (boolean | string | RegExp)[]
8
+
9
+ type OriginFn = (
10
+ origin: string | undefined,
11
+ req: Request
12
+ ) => StaticOrigin | Promise<StaticOrigin>
13
+
14
+ interface CorsOptions {
15
+ origin?: StaticOrigin | OriginFn
16
+ methods?: string | string[]
17
+ allowedHeaders?: string | string[]
18
+ exposedHeaders?: string | string[]
19
+ credentials?: boolean
20
+ maxAge?: number
21
+ preflightContinue?: boolean
22
+ optionsSuccessStatus?: number
23
+ }
24
+
25
+ const defaultOptions: CorsOptions = {
26
+ origin: '*',
27
+ methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
28
+ preflightContinue: false,
29
+ optionsSuccessStatus: 204,
30
+ }
31
+
32
+ function isOriginAllowed(origin: string, allowed: StaticOrigin): boolean {
33
+ return Array.isArray(allowed)
34
+ ? allowed.some((o) => isOriginAllowed(origin, o))
35
+ : typeof allowed === 'string'
36
+ ? origin === allowed
37
+ : allowed instanceof RegExp
38
+ ? allowed.test(origin)
39
+ : !!allowed
40
+ }
41
+
42
+ function getOriginHeaders(reqOrigin: string | undefined, origin: StaticOrigin) {
43
+ const headers = new Headers()
44
+
45
+ if (origin === '*') {
46
+ // Allow any origin
47
+ headers.set('Access-Control-Allow-Origin', '*')
48
+ } else if (typeof origin === 'string') {
49
+ // Fixed origin
50
+ headers.set('Access-Control-Allow-Origin', origin)
51
+ headers.append('Vary', 'Origin')
52
+ } else {
53
+ const allowed = isOriginAllowed(reqOrigin ?? '', origin)
54
+
55
+ if (allowed && reqOrigin) {
56
+ headers.set('Access-Control-Allow-Origin', reqOrigin)
57
+ }
58
+ headers.append('Vary', 'Origin')
59
+ }
60
+
61
+ return headers
62
+ }
63
+
64
+ // originHeadersFromReq
65
+
66
+ async function originHeadersFromReq(
67
+ req: Request,
68
+ origin: StaticOrigin | OriginFn
69
+ ) {
70
+ const reqOrigin = req.headers.get('Origin') || undefined
71
+ const value =
72
+ typeof origin === 'function' ? await origin(reqOrigin, req) : origin
73
+
74
+ if (!value) return
75
+ return getOriginHeaders(reqOrigin, value)
76
+ }
77
+
78
+ function getAllowedHeaders(req: Request, allowed?: string | string[]) {
79
+ const headers = new Headers()
80
+
81
+ if (!allowed) {
82
+ allowed = req.headers.get('Access-Control-Request-Headers')!
83
+ headers.append('Vary', 'Access-Control-Request-Headers')
84
+ } else if (Array.isArray(allowed)) {
85
+ // If the allowed headers is an array, turn it into a string
86
+ allowed = allowed.join(',')
87
+ }
88
+ if (allowed) {
89
+ headers.set('Access-Control-Allow-Headers', allowed)
90
+ }
91
+
92
+ return headers
93
+ }
94
+
95
+ export default async function cors(
96
+ req: Request,
97
+ res: Response,
98
+ options?: CorsOptions
99
+ ) {
100
+ const opts = { ...defaultOptions, ...options }
101
+ const { headers } = res
102
+ const originHeaders = await originHeadersFromReq(req, opts.origin ?? false)
103
+ const mergeHeaders = (v: string, k: string) => {
104
+ if (k === 'Vary') headers.append(k, v)
105
+ else headers.set(k, v)
106
+ }
107
+
108
+ // If there's no origin we won't touch the response
109
+ if (!originHeaders) return res
110
+
111
+ originHeaders.forEach(mergeHeaders)
112
+
113
+ if (opts.credentials) {
114
+ headers.set('Access-Control-Allow-Credentials', 'true')
115
+ }
116
+
117
+ const exposed = Array.isArray(opts.exposedHeaders)
118
+ ? opts.exposedHeaders.join(',')
119
+ : opts.exposedHeaders
120
+
121
+ if (exposed) {
122
+ headers.set('Access-Control-Expose-Headers', exposed)
123
+ }
124
+ debugger
125
+ // Handle the preflight request
126
+ if (req.method === 'OPTIONS') {
127
+ if (opts.methods) {
128
+ const methods = Array.isArray(opts.methods)
129
+ ? opts.methods.join(',')
130
+ : opts.methods
131
+
132
+ headers.set('Access-Control-Allow-Methods', methods)
133
+ }
134
+
135
+ getAllowedHeaders(req, opts.allowedHeaders).forEach(mergeHeaders)
136
+
137
+ if (typeof opts.maxAge === 'number') {
138
+ headers.set('Access-Control-Max-Age', String(opts.maxAge))
139
+ }
140
+
141
+ if (opts.preflightContinue) return res
142
+
143
+ headers.set('Content-Length', '0')
144
+ return new Response(null, { status: opts.optionsSuccessStatus, headers })
145
+ }
146
+
147
+ // If we got here, it's a normal request
148
+ return res
149
+ }
150
+
151
+ export function initCors(options?: CorsOptions) {
152
+ return (req: Request, res: Response) => cors(req, res, options)
153
+ }