@ms-cloudpack/app-server 0.20.8 → 0.20.10
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/lib/createPageSessionContext.d.ts.map +1 -1
- package/lib/createPageSessionContext.js +1 -0
- package/lib/createPageSessionContext.js.map +1 -1
- package/lib/renderRoute/injectScripts.d.ts +1 -1
- package/lib/renderRoute/injectScripts.d.ts.map +1 -1
- package/lib/renderRoute/injectScripts.js +6 -3
- package/lib/renderRoute/injectScripts.js.map +1 -1
- package/package.json +11 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPageSessionContext.d.ts","sourceRoot":"","sources":["../src/createPageSessionContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,UAAU,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC,EAC7E,WAAW,EAAE,MAAM,GAClB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"createPageSessionContext.d.ts","sourceRoot":"","sources":["../src/createPageSessionContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,UAAU,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC,EAC7E,WAAW,EAAE,MAAM,GAClB,kBAAkB,CAYpB"}
|
|
@@ -11,6 +11,7 @@ export function createPageSessionContext(session, requestPath) {
|
|
|
11
11
|
pageLoadTimePerformanceEntry: session.config.telemetry?.pageLoadTimePerformanceEntry,
|
|
12
12
|
define: session.config.define,
|
|
13
13
|
hostApiServerUrls: session.urls.hostApiServer,
|
|
14
|
+
showOverlay: session.config.server?.showOverlay,
|
|
14
15
|
};
|
|
15
16
|
}
|
|
16
17
|
//# sourceMappingURL=createPageSessionContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPageSessionContext.js","sourceRoot":"","sources":["../src/createPageSessionContext.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA6E,EAC7E,WAAmB;IAEnB,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,eAAe,EAAE,OAAO,CAAC,QAAQ;QACjC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE;QACpC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE;QAChD,WAAW;QACX,4BAA4B,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,4BAA4B;QACpF,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;QAC7B,iBAAiB,EAAE,OAAO,CAAC,IAAI,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"createPageSessionContext.js","sourceRoot":"","sources":["../src/createPageSessionContext.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA6E,EAC7E,WAAmB;IAEnB,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,eAAe,EAAE,OAAO,CAAC,QAAQ;QACjC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE;QACpC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE;QAChD,WAAW;QACX,4BAA4B,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,4BAA4B;QACpF,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;QAC7B,iBAAiB,EAAE,OAAO,CAAC,IAAI,CAAC,aAAa;QAC7C,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW;KAChD,CAAC;AACJ,CAAC","sourcesContent":["import type { Session } from '@ms-cloudpack/common-types';\nimport type { PageSessionContext } from '@ms-cloudpack/common-types-browser';\n\n/**\n * Create a page session context that needs to be on the page for Cloudpack to work properly.\n */\nexport function createPageSessionContext(\n session: Pick<Session, 'id' | 'sequence' | 'projectName' | 'urls' | 'config'>,\n requestPath: string,\n): PageSessionContext {\n return {\n sessionId: session.id,\n currentSequence: session.sequence,\n apiUrl: session.urls.apiServer ?? '',\n bundleServerUrl: session.urls.bundleServer ?? '',\n requestPath,\n pageLoadTimePerformanceEntry: session.config.telemetry?.pageLoadTimePerformanceEntry,\n define: session.config.define,\n hostApiServerUrls: session.urls.hostApiServer,\n showOverlay: session.config.server?.showOverlay,\n };\n}\n"]}
|
|
@@ -9,5 +9,5 @@ export declare const happyDomSettings: IOptionalBrowserSettings;
|
|
|
9
9
|
*
|
|
10
10
|
* Note that this just logs an error rather than returning an error response if something fails, for now.
|
|
11
11
|
*/
|
|
12
|
-
export declare function injectScripts(options: RenderRouteOptions, result: ExpandedRenderFunctionResult, context: PartialContext<'session', 'importMap'>): Promise<void>;
|
|
12
|
+
export declare function injectScripts(options: RenderRouteOptions, result: ExpandedRenderFunctionResult, context: PartialContext<'session', 'config' | 'importMap'>): Promise<void>;
|
|
13
13
|
//# sourceMappingURL=injectScripts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injectScripts.d.ts","sourceRoot":"","sources":["../../src/renderRoute/injectScripts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAyB,KAAK,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAEjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,kDAAkD;AAClD,eAAO,MAAM,gBAAgB,EAAE,wBAK9B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,4BAA4B,EACpC,OAAO,EAAE,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"injectScripts.d.ts","sourceRoot":"","sources":["../../src/renderRoute/injectScripts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAyB,KAAK,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAEjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,kDAAkD;AAClD,eAAO,MAAM,gBAAgB,EAAE,wBAK9B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,4BAA4B,EACpC,OAAO,EAAE,cAAc,CAAC,SAAS,EAAE,QAAQ,GAAG,WAAW,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CAiEf"}
|
|
@@ -14,7 +14,7 @@ export const happyDomSettings = {
|
|
|
14
14
|
*/
|
|
15
15
|
export async function injectScripts(options, result, context) {
|
|
16
16
|
const { route, overlayScript, entryScripts, inlineScripts, baseUrl } = options;
|
|
17
|
-
const { importMap } = context.session;
|
|
17
|
+
const { config, importMap } = context.session;
|
|
18
18
|
if (typeof result.content !== 'string') {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
@@ -51,8 +51,11 @@ export async function injectScripts(options, result, context) {
|
|
|
51
51
|
addScript({ document, content: inlineScript });
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
//
|
|
55
|
-
|
|
54
|
+
// Skip injecting the overlay script if it's disabled (the overlay itself also has logic to
|
|
55
|
+
// hide if 'never', but it's better not to load the script)
|
|
56
|
+
if (overlayScript && config.server?.showOverlay !== 'never') {
|
|
57
|
+
addScript({ document, url: overlayScript });
|
|
58
|
+
}
|
|
56
59
|
if (entryScripts) {
|
|
57
60
|
for (const entryScript of entryScripts) {
|
|
58
61
|
addScript({ document, url: entryScript });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injectScripts.js","sourceRoot":"","sources":["../../src/renderRoute/injectScripts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAgD,MAAM,WAAW,CAAC;AACjF,OAAO,cAAc,MAAM,iDAAiD,CAAC;AAI7E,kDAAkD;AAClD,MAAM,CAAC,MAAM,gBAAgB,GAA6B;IACxD,4BAA4B,EAAE,IAAI;IAClC,2BAA2B,EAAE,IAAI;IACjC,qBAAqB,EAAE,IAAI;IAC3B,wBAAwB,EAAE,IAAI;CAC/B,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAA2B,EAC3B,MAAoC,EACpC,
|
|
1
|
+
{"version":3,"file":"injectScripts.js","sourceRoot":"","sources":["../../src/renderRoute/injectScripts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExpandedRenderFunctionResult } from '@ms-cloudpack/common-types';\nimport { Window, type Document, type IOptionalBrowserSettings } from 'happy-dom';\nimport HTMLSerializer from 'happy-dom/lib/html-serializer/HTMLSerializer.js';\nimport type { RenderRouteOptions } from '../types/RenderRouteOptions.js';\nimport type { PartialContext } from '@ms-cloudpack/api-server';\n\n/** `happy-dom` settings to disable scripts etc */\nexport const happyDomSettings: IOptionalBrowserSettings = {\n disableJavaScriptFileLoading: true,\n disableJavaScriptEvaluation: true,\n disableCSSFileLoading: true,\n disableIframePageLoading: true,\n};\n\n/**\n * Modify the HTML response by injecting the import map, inline scripts, and entry/overlay scripts.\n *\n * Note that this just logs an error rather than returning an error response if something fails, for now.\n */\nexport async function injectScripts(\n options: RenderRouteOptions,\n result: ExpandedRenderFunctionResult,\n context: PartialContext<'session', 'config' | 'importMap'>,\n): Promise<void> {\n const { route, overlayScript, entryScripts, inlineScripts, baseUrl } = options;\n const { config, importMap } = context.session;\n\n if (typeof result.content !== 'string') {\n return;\n }\n\n const window = new Window({\n url: baseUrl,\n settings: {\n disableJavaScriptFileLoading: true,\n disableJavaScriptEvaluation: true,\n disableCSSFileLoading: true,\n disableIframePageLoading: true,\n },\n });\n try {\n // TODO: happy-dom is overkill for what we're doing here--a full browser-like environment isn't\n // needed to just parse and modify the HTML. If it becomes a perf concern (less likely since\n // HTML page rendering is probably just done once per page load), we could switch to\n // a pure parser like parse5 or htmlparser2.\n window.document.write(result.content);\n } catch (e) {\n // Trying to write a test for the above, it seemed very permissive, but catch just in case\n console.error(\n `Error parsing html response for rendering route \"${JSON.stringify(route.match)}\":\\n${(e as Error).stack || e}`,\n );\n await window.happyDOM.close();\n return;\n }\n\n try {\n const document = window.document;\n\n if (entryScripts || overlayScript) {\n // Inject the import map at the top of the head, in case other scripts use it\n addScript({ document, type: 'importmap', prepend: true, content: JSON.stringify(importMap, null, 2) });\n }\n\n if (inlineScripts) {\n for (const inlineScript of inlineScripts) {\n addScript({ document, content: inlineScript });\n }\n }\n\n // Skip injecting the overlay script if it's disabled (the overlay itself also has logic to\n // hide if 'never', but it's better not to load the script)\n if (overlayScript && config.server?.showOverlay !== 'never') {\n addScript({ document, url: overlayScript });\n }\n\n if (entryScripts) {\n for (const entryScript of entryScripts) {\n addScript({ document, url: entryScript });\n }\n }\n\n const serializer = new HTMLSerializer();\n result.content = serializer.serializeToString(document);\n } catch (e) {\n console.error(`Error injecting scripts for route \"${JSON.stringify(route.match)}\":\\n${(e as Error).stack || e}`);\n } finally {\n await window.happyDOM.close();\n }\n}\n\n/**\n * Helper function to add a script to the document.\n * No-op if neither `url` nor `content` is provided.\n */\nfunction addScript(params: {\n document: Document;\n type?: string;\n prepend?: boolean;\n url?: string;\n content?: string;\n}): void {\n const { document, type = 'module', prepend, url, content } = params;\n if (!url && !content) {\n return;\n }\n\n const script = document.createElement('script');\n script.type = type;\n if (url) {\n script.src = url;\n } else if (content) {\n script.innerHTML = content;\n }\n\n if (prepend) {\n document.head.prepend(script);\n } else {\n document.head.appendChild(script);\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ms-cloudpack/app-server",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.10",
|
|
4
4
|
"description": "An implementation of the App server for Cloudpack.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,23 +14,23 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@ms-cloudpack/api-server": "^0.64.
|
|
18
|
-
"@ms-cloudpack/bundle-server": "^0.8.
|
|
19
|
-
"@ms-cloudpack/common-types": "^0.27.
|
|
20
|
-
"@ms-cloudpack/create-express-app": "^1.10.
|
|
17
|
+
"@ms-cloudpack/api-server": "^0.64.18",
|
|
18
|
+
"@ms-cloudpack/bundle-server": "^0.8.10",
|
|
19
|
+
"@ms-cloudpack/common-types": "^0.27.5",
|
|
20
|
+
"@ms-cloudpack/create-express-app": "^1.10.49",
|
|
21
21
|
"@ms-cloudpack/environment": "^0.1.1",
|
|
22
|
-
"@ms-cloudpack/import-map": "^0.10.
|
|
23
|
-
"@ms-cloudpack/inline-scripts": "^0.2.
|
|
22
|
+
"@ms-cloudpack/import-map": "^0.10.43",
|
|
23
|
+
"@ms-cloudpack/inline-scripts": "^0.2.32",
|
|
24
24
|
"@ms-cloudpack/path-string-parsing": "^1.2.7",
|
|
25
|
-
"@ms-cloudpack/path-utilities": "^3.1.
|
|
26
|
-
"@ms-cloudpack/task-reporter": "^0.17.
|
|
25
|
+
"@ms-cloudpack/path-utilities": "^3.1.20",
|
|
26
|
+
"@ms-cloudpack/task-reporter": "^0.17.3",
|
|
27
27
|
"@ms-cloudpack/worker-pool": "^0.4.1",
|
|
28
28
|
"happy-dom": "^18.0.0",
|
|
29
29
|
"http-proxy-middleware": "^2.0.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@ms-cloudpack/common-types-browser": "^0.6.
|
|
33
|
-
"@ms-cloudpack/config": "^0.38.
|
|
32
|
+
"@ms-cloudpack/common-types-browser": "^0.6.3",
|
|
33
|
+
"@ms-cloudpack/config": "^0.38.2",
|
|
34
34
|
"@ms-cloudpack/eslint-plugin-internal": "^0.0.1",
|
|
35
35
|
"@ms-cloudpack/scripts": "^0.0.1",
|
|
36
36
|
"@ms-cloudpack/test-utilities": "^0.5.0"
|