@kasko/fe-webapp-utils-lib
Advanced tools
Comparing version 2.1.0 to 2.3.0
# Changelog | ||
## [v2.3.0](https://github.com/kasko/fe-webapp-utils-lib/compare/v2.2.0...v2.3.0) (2023-08-29) | ||
## Feature | ||
- Adds `SnippetConfig` interface; | ||
- Adds generic `/snippet` endpoint; | ||
- Allow `.csv` file to be entry for `requireTypescript` function; | ||
## Bugfix | ||
- Allow global `touchpointId` config; | ||
## [v2.1.0](https://github.com/kasko/fe-webapp-utils-lib/compare/v2.0.0...v2.1.0) (2023-08-28) | ||
@@ -4,0 +13,0 @@ ## Feature |
@@ -115,3 +115,3 @@ "use strict"; | ||
async function requireTypescript(entry, cacheName) { | ||
const tpTmp = (0, import_node_path.join)((0, import_node_path.resolve)("."), `.tmp/${cacheName}.js`); | ||
const tpTmp = (0, import_node_path.join)((0, import_node_path.resolve)("."), `.tmp/${cacheName}.mjs`); | ||
await (0, import_esbuild.build)({ | ||
@@ -134,7 +134,6 @@ entryPoints: [entry], | ||
minify: true, | ||
format: "cjs", | ||
format: "esm", | ||
platform: "node" | ||
}); | ||
delete require.cache[require.resolve(tpTmp)]; | ||
return require(tpTmp); | ||
return import(tpTmp + "?" + (/* @__PURE__ */ new Date()).getTime()); | ||
} | ||
@@ -141,0 +140,0 @@ async function buildResponse(entryJSON, responseJSON, id, language) { |
/// <reference types="node" /> | ||
export { mockApi, type MockedAPIMiddleware } from './server/mock-api'; | ||
export { type SnippetConfig } from './interfaces/snippet'; | ||
export interface WebappConfig { | ||
@@ -10,5 +11,7 @@ outbase: string; | ||
publicKey: string; | ||
touchpointId?: string; | ||
plugins: Record<string, string>; | ||
entries: Record<string, { | ||
index: string; | ||
snippet: string; | ||
extra?: string[]; | ||
@@ -18,3 +21,3 @@ }>; | ||
} | ||
export declare function webappSetup({ outbase, host: apiHost, publicKey, language, dataSvcUrl, kaskoJsUrl, entries, plugins, port, }: WebappConfig): Promise<{ | ||
export declare function webappSetup({ outbase, host: apiHost, publicKey, touchpointId, language, dataSvcUrl, kaskoJsUrl, entries, plugins, port, }: WebappConfig): Promise<{ | ||
entryPointsExtra: string[]; | ||
@@ -21,0 +24,0 @@ serverMiddleware: (buildContext: import("esbuild").ServeResult, loadMockApi: (req: import("http").IncomingMessage, res: import("http").ServerResponse<import("http").IncomingMessage> & { |
@@ -242,3 +242,3 @@ "use strict"; | ||
async function requireTypescript(entry, cacheName) { | ||
const tpTmp = (0, import_node_path.join)((0, import_node_path.resolve)("."), `.tmp/${cacheName}.js`); | ||
const tpTmp = (0, import_node_path.join)((0, import_node_path.resolve)("."), `.tmp/${cacheName}.mjs`); | ||
await (0, import_esbuild.build)({ | ||
@@ -261,7 +261,6 @@ entryPoints: [entry], | ||
minify: true, | ||
format: "cjs", | ||
format: "esm", | ||
platform: "node" | ||
}); | ||
delete require.cache[require.resolve(tpTmp)]; | ||
return require(tpTmp); | ||
return import(tpTmp + "?" + (/* @__PURE__ */ new Date()).getTime()); | ||
} | ||
@@ -903,2 +902,14 @@ | ||
} | ||
function resolveUncommonFilePath(path, common) { | ||
const splitCommonPath = common.split("/").filter(Boolean); | ||
const normalFilePath = path.split("/").filter(Boolean).join("/"); | ||
for (const depth in splitCommonPath) { | ||
const normalCommonPath = splitCommonPath.slice(0, -depth || splitCommonPath.length).join("/"); | ||
const resolvedPath = normalFilePath.replace(new RegExp("^" + normalCommonPath), ""); | ||
if (normalFilePath !== resolvedPath) { | ||
return (0, import_node_path3.join)("/", ...new Array(parseInt(depth, 10)).fill("_.._"), resolvedPath); | ||
} | ||
} | ||
return path; | ||
} | ||
async function serverMiddleware({ | ||
@@ -936,2 +947,18 @@ outbase, | ||
const indexHtmlFile = loadHtmlFile("./www/index.html", { | ||
"webapp.plugins.head": head, | ||
"webapp.plugins.body": body, | ||
"webapp.touchpoint.extra": entries.common?.extra?.map((extraFile) => { | ||
if (extraFile.endsWith(".css")) { | ||
return { | ||
type: "link", | ||
props: { | ||
rel: "stylesheet", | ||
class: "kasko-stylesheet", | ||
property: "stylesheet", | ||
href: resolveUncommonFilePath(extraFile, baseDir) | ||
} | ||
}; | ||
} | ||
return null; | ||
}).filter(Boolean) || [], | ||
"index.list.js": [ | ||
@@ -951,2 +978,22 @@ { | ||
[`GET /${process.env.WEBAPP_PUBLIC_KEY}/:touchpoint`]: (req, res, params) => { | ||
if (process.env.WEBAPP_TOUCHPOINT_ID && params.touchpoint === process.env.WEBAPP_TOUCHPOINT_ID) { | ||
const [hostname2, port3] = req.headers.host?.split(":") || []; | ||
req.pipe( | ||
(0, import_node_http.request)( | ||
{ | ||
hostname: hostname2, | ||
port: port3, | ||
path: "", | ||
method: req.method, | ||
headers: req.headers | ||
}, | ||
(proxyRes) => { | ||
res.writeHead(proxyRes.statusCode || 200, proxyRes.headers); | ||
proxyRes.pipe(res, { end: true }); | ||
} | ||
), | ||
{ end: true } | ||
); | ||
return; | ||
} | ||
const [hostname, port2] = req.headers.host?.split(":") || []; | ||
@@ -970,2 +1017,29 @@ req.pipe( | ||
}, | ||
"GET /snippet": async (_req, res) => { | ||
if (!entries.common) { | ||
return false; | ||
} | ||
const snippet = await requireTypescript(entries.common.snippet, "snippet"); | ||
const mergedSnippet = { | ||
key: process.env.WEBAPP_PUBLIC_KEY, | ||
language: process.env.WEBAPP_LANGUAGE, | ||
touchpoint: process.env.WEBAPP_TOUCHPOINT_ID, | ||
container: "kasko-widget-container", | ||
mode: "fullscreen", | ||
...snippet.default | ||
}; | ||
const webappHtmlFile = loadHtmlFile("./www/snippet.html", { | ||
"webapp.snippet.js": [ | ||
{ | ||
type: "script", | ||
children: `Kasko.Setup({base_url: \`http://\${location.host}\`,${JSON.stringify( | ||
mergedSnippet | ||
).replace(/^{|}$/g, "")}});` | ||
} | ||
], | ||
...customInject || {} | ||
}); | ||
res.writeHead(200, { "Content-Type": "text/html" }); | ||
res.end(webappHtmlFile); | ||
}, | ||
"GET /:touchpoint": (_req, res, params) => { | ||
@@ -1156,2 +1230,3 @@ const touchpoint = entries[params.touchpoint]; | ||
publicKey, | ||
touchpointId, | ||
language, | ||
@@ -1172,3 +1247,3 @@ dataSvcUrl, | ||
bugsnagEnabled: false, | ||
touchpointId: location.pathname.split('/').filter(Boolean).pop(), | ||
touchpointId: ${touchpointId ? JSON.stringify(touchpointId) : `location.pathname.split('/').filter(Boolean).pop()`}, | ||
publicKey: ${JSON.stringify(publicKey)}, | ||
@@ -1175,0 +1250,0 @@ language: new URLSearchParams(location.search).get('language') || ${JSON.stringify(language)} || 'en', |
{ | ||
"name": "@kasko/fe-webapp-utils-lib", | ||
"version": "2.1.0", | ||
"version": "2.3.0", | ||
"main": "./dist/index.js", | ||
@@ -5,0 +5,0 @@ "types": "./dist/index.d.ts", |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
810773
40
22415
43