@hyperspan/framework 1.0.11 → 1.0.13
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/package.json +1 -1
- package/src/client/js.test.ts +27 -0
- package/src/client/js.ts +31 -15
- package/src/server.ts +14 -8
- package/src/types.ts +1 -1
package/package.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import { extractExports } from './js';
|
|
3
|
+
|
|
4
|
+
describe('extractExports', () => {
|
|
5
|
+
test('extracts aliased export from bundled JS content', () => {
|
|
6
|
+
const contents = 'function d(n,t){if(t)n.classList.remove("hidden");else n.classList.add("hidden")}function p(){let n=document.querySelector("[data-google-spreadsheet-id]"),t=document.querySelector("[data-google-sheet-select]"),a=document.querySelector("[data-google-sheet-message]");if(console.log("googleSheetsPickerClient",n,t),!n||!t)return;let l=(e)=>{if(!a)return;a.textContent=e||"",d(a,Boolean(e))},h=(e)=>{t.innerHTML="",e.forEach((s)=>{let o=document.createElement("option");o.value=s,o.textContent=s,t.appendChild(o)})},r=(e)=>{d(t,e),t.disabled=!e,t.required=e},c=async()=>{let e=n.value.trim();if(l(null),!e){r(!1);return}try{let s=await fetch(`/api/google-sheets/${encodeURIComponent(e)}`),o=await s.json();if(!s.ok||o.error)throw Error(o.error||"Unable to load sheet names.");let i=(o.sheets||[]).map((u)=>u.title).filter(Boolean);if(i.length===0){l("No sheets found in that spreadsheet."),r(!1);return}h(i),t.value=i[0],r(!0)}catch(s){l(s instanceof Error?s.message:"Unable to load sheet names."),r(!1)}};n.addEventListener("input",c),n.addEventListener("change",c)}export{p as mountGoogleSheetsPicker};';
|
|
7
|
+
|
|
8
|
+
const result = extractExports(contents);
|
|
9
|
+
|
|
10
|
+
expect(result).toEqual({
|
|
11
|
+
exports: '{mountGoogleSheetsPicker}',
|
|
12
|
+
fnArgs: '{mountGoogleSheetsPicker}',
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('returns empty exports when none found', () => {
|
|
17
|
+
const contents = 'function noop(){return 1}const value=2;';
|
|
18
|
+
|
|
19
|
+
const result = extractExports(contents);
|
|
20
|
+
|
|
21
|
+
expect(result).toEqual({
|
|
22
|
+
exports: '* as _module',
|
|
23
|
+
fnArgs: '_module',
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
package/src/client/js.ts
CHANGED
|
@@ -47,21 +47,7 @@ export async function buildClientJS(modulePathResolved: string): Promise<HS.Clie
|
|
|
47
47
|
|
|
48
48
|
// Get the contents of the file to extract the exports
|
|
49
49
|
const contents = await result.outputs[0].text();
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
let exports = '{}';
|
|
53
|
-
if (exportLine) {
|
|
54
|
-
const exportName = exportLine[1];
|
|
55
|
-
exports =
|
|
56
|
-
'{' +
|
|
57
|
-
exportName
|
|
58
|
-
.split(',')
|
|
59
|
-
.map((name) => name.trim().split(' as '))
|
|
60
|
-
.map(([name, alias]) => `${alias === 'default' ? 'default as ' + name : alias}`)
|
|
61
|
-
.join(', ') +
|
|
62
|
-
'}';
|
|
63
|
-
}
|
|
64
|
-
const fnArgs = exports.replace(/(\w+)\s*as\s*(\w+)/g, '$1: $2');
|
|
50
|
+
const { exports, fnArgs } = extractExports(contents);
|
|
65
51
|
|
|
66
52
|
CLIENT_JS_CACHE.set(assetHash, { esmName, exports, fnArgs, publicPath });
|
|
67
53
|
})();
|
|
@@ -102,6 +88,36 @@ export async function buildClientJS(modulePathResolved: string): Promise<HS.Clie
|
|
|
102
88
|
}
|
|
103
89
|
}
|
|
104
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Extract the exports from a client JS module
|
|
93
|
+
*/
|
|
94
|
+
export function extractExports(contents: string): { exports: string, fnArgs: string } {
|
|
95
|
+
const exportLine = EXPORT_REGEX.exec(contents);
|
|
96
|
+
let exports = '{}';
|
|
97
|
+
let fnArgs = '{}';
|
|
98
|
+
|
|
99
|
+
if (exportLine) {
|
|
100
|
+
const exportName = exportLine[1];
|
|
101
|
+
exports =
|
|
102
|
+
'{' +
|
|
103
|
+
exportName
|
|
104
|
+
.split(',')
|
|
105
|
+
.map((name) => name.trim().split(' as '))
|
|
106
|
+
.map(([name, alias]) => `${alias === 'default' ? 'default as ' + name : alias}`)
|
|
107
|
+
.join(', ') +
|
|
108
|
+
'}';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
fnArgs = exports.replace(/(\w+)\s*as\s*(\w+)/g, '$1: $2').trim();
|
|
112
|
+
|
|
113
|
+
if (exports === '{}' && fnArgs === '{}') {
|
|
114
|
+
exports = '* as _module'
|
|
115
|
+
fnArgs = '_module'
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return { exports, fnArgs };
|
|
119
|
+
}
|
|
120
|
+
|
|
105
121
|
/**
|
|
106
122
|
* Convert a function to a string (results in loss of context!)
|
|
107
123
|
* Handles named, async, and arrow functions
|
package/src/server.ts
CHANGED
|
@@ -202,9 +202,11 @@ export function createRoute(config: Partial<HS.RouteConfig> = {}): HS.Route {
|
|
|
202
202
|
/**
|
|
203
203
|
* Add a middleware function to this route (for all HTTP methods) (non-destructive)
|
|
204
204
|
*/
|
|
205
|
-
use(middleware: HS.MiddlewareFunction, opts:
|
|
206
|
-
if (opts
|
|
207
|
-
|
|
205
|
+
use(middleware: HS.MiddlewareFunction, opts: HS.MiddlewareMethodOptions = {}) {
|
|
206
|
+
if (opts?.methods) {
|
|
207
|
+
opts.methods.forEach(method => {
|
|
208
|
+
api._middleware[method].push(middleware);
|
|
209
|
+
});
|
|
208
210
|
} else {
|
|
209
211
|
api._middleware['*'].push(middleware);
|
|
210
212
|
}
|
|
@@ -214,9 +216,11 @@ export function createRoute(config: Partial<HS.RouteConfig> = {}): HS.Route {
|
|
|
214
216
|
* Set the complete middleware stack for this route (for all HTTP methods) (destructive)
|
|
215
217
|
* NOTE: This will override the middleware stack for this route
|
|
216
218
|
*/
|
|
217
|
-
middleware(middleware: Array<HS.MiddlewareFunction>, opts:
|
|
218
|
-
if (opts
|
|
219
|
-
|
|
219
|
+
middleware(middleware: Array<HS.MiddlewareFunction>, opts: HS.MiddlewareMethodOptions = {}) {
|
|
220
|
+
if (opts?.methods) {
|
|
221
|
+
opts.methods.forEach(method => {
|
|
222
|
+
api._middleware[method] = middleware;
|
|
223
|
+
});
|
|
220
224
|
} else {
|
|
221
225
|
api._middleware['*'] = middleware;
|
|
222
226
|
}
|
|
@@ -326,8 +330,10 @@ export async function createServer(config: HS.Config = {} as HS.Config): Promise
|
|
|
326
330
|
_routes: _routes,
|
|
327
331
|
_middleware: { GET: [], POST: [], PUT: [], PATCH: [], DELETE: [], HEAD: [], OPTIONS: [], '*': [] },
|
|
328
332
|
use(middleware: HS.MiddlewareFunction, opts?: HS.MiddlewareMethodOptions) {
|
|
329
|
-
if (opts?.
|
|
330
|
-
|
|
333
|
+
if (opts?.methods) {
|
|
334
|
+
opts.methods.forEach(method => {
|
|
335
|
+
api._middleware[method].push(middleware);
|
|
336
|
+
});
|
|
331
337
|
} else {
|
|
332
338
|
api._middleware['*'].push(middleware);
|
|
333
339
|
}
|
package/src/types.ts
CHANGED
|
@@ -135,7 +135,7 @@ export namespace Hyperspan {
|
|
|
135
135
|
) => Promise<Response> | Response;
|
|
136
136
|
export type MiddlewareMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | '*';
|
|
137
137
|
export type MiddlewareMethodOptions = {
|
|
138
|
-
|
|
138
|
+
methods?: Hyperspan.MiddlewareMethod[];
|
|
139
139
|
};
|
|
140
140
|
|
|
141
141
|
export interface Route {
|