Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@podium/client

Package Overview
Dependencies
Maintainers
0
Versions
196
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@podium/client - npm Package Compare versions

Comparing version 5.1.10 to 5.2.0-next.1

18

CHANGELOG.md

@@ -1,8 +0,22 @@

## [5.1.10](https://github.com/podium-lib/client/compare/v5.1.9...v5.1.10) (2024-09-06)
# [5.2.0-next.1](https://github.com/podium-lib/client/compare/v5.1.10-next.2...v5.2.0-next.1) (2024-09-10)
### Features
* read assets from podlets using 103 early hints ([64e4b27](https://github.com/podium-lib/client/commit/64e4b27773b87c220bcab1028ecdda82be2aa9fc))
## [5.1.10-next.2](https://github.com/podium-lib/client/compare/v5.1.10-next.1...v5.1.10-next.2) (2024-08-26)
### Bug Fixes
* **deps:** update dependency @podium/utils to v5.2.0 ([f7d4675](https://github.com/podium-lib/client/commit/f7d4675e6e2b9f2fba26cbd164d3e7a73b9c132e))
* use AbortController instead of AbortSignal to avoid unhandled exception ([#412](https://github.com/podium-lib/client/issues/412)) ([87f5ffe](https://github.com/podium-lib/client/commit/87f5ffe553aa49189658a9be0e19d1323878a55a))
## [5.1.10-next.1](https://github.com/podium-lib/client/compare/v5.1.9...v5.1.10-next.1) (2024-08-22)
### Bug Fixes
* use AbortSignal to ensure timeouts are respected ([08899d9](https://github.com/podium-lib/client/commit/08899d974246037cb1893a5b6d06bd6df58815e2))
## [5.1.9](https://github.com/podium-lib/client/compare/v5.1.8...v5.1.9) (2024-08-19)

@@ -9,0 +23,0 @@

@@ -70,2 +70,4 @@ import { PassThrough } from 'stream';

#uri;
#js;
#css;

@@ -124,2 +126,4 @@ /**

_fallback: '',
_js: [],
_css: [],
};

@@ -151,2 +155,20 @@

get js() {
// return the internal js value or, fallback to the manifest for backwards compatibility
return this.#js || this.#manifest.js;
}
set js(value) {
this.#js = value;
}
get css() {
// return the internal css value or, fallback to the manifest for backwards compatibility
return this.#css || this.#manifest.css;
}
set css(value) {
this.#css = value;
}
get rejectUnauthorized() {

@@ -314,2 +336,6 @@ return this.#rejectUnauthorized;

this.push(this.#manifest._fallback);
// @ts-expect-error Internal property
this.js = this.#manifest._js;
// @ts-expect-error Internal property
this.css = this.#manifest._css;
this.push(null);

@@ -316,0 +342,0 @@ this.#isFallback = true;

31

lib/http.js

@@ -1,2 +0,2 @@

import { request } from 'undici';
import { request as undiciRequest } from 'undici';

@@ -10,8 +10,12 @@ /**

* @property {number} [timeout]
* @property {number} [bodyTimeout]
* @property {object} [query]
* @property {import('http').IncomingHttpHeaders} [headers]
* @property {(info: { statusCode: number; headers: Record<string, string | string[]>; }) => void} [onInfo]
*/
export default class HTTP {
constructor(requestFn = undiciRequest) {
this.requestFn = requestFn;
}
/**

@@ -23,8 +27,21 @@ * @param {string} url

async request(url, options) {
const { statusCode, headers, body } = await request(
new URL(url),
options,
);
return { statusCode, headers, body };
const abortController = new AbortController();
const timeoutId = setTimeout(() => {
abortController.abort();
}, options.timeout || 1000);
try {
const { statusCode, headers, body } = await this.requestFn(
new URL(url),
{
...options,
signal: abortController.signal,
},
);
return { statusCode, headers, body };
} finally {
clearTimeout(timeoutId);
}
}
}

@@ -12,2 +12,4 @@ import { pipeline } from 'stream';

import HTTP from './http.js';
import { parseLinkHeaders, filterAssets } from './utils.js';
import { AssetJs, AssetCss } from '@podium/utils';

@@ -137,9 +139,29 @@ const currentDirectory = dirname(fileURLToPath(import.meta.url));

let hintsReceived = false;
/** @type {import('./http.js').PodiumHttpClientRequestOptions} */
const reqOptions = {
rejectUnauthorized: outgoing.rejectUnauthorized,
bodyTimeout: outgoing.timeout,
timeout: outgoing.timeout,
method: 'GET',
query: outgoing.reqOptions.query,
headers,
onInfo({ statusCode, headers }) {
if (statusCode === 103 && !hintsReceived) {
const parsedAssetObjects = parseLinkHeaders(headers.link);
const scriptObjects = parsedAssetObjects.filter(
(asset) => asset instanceof AssetJs,
);
const styleObjects = parsedAssetObjects.filter(
(asset) => asset instanceof AssetCss,
);
// set the content js asset objects
outgoing.js = filterAssets('content', scriptObjects);
// set the content css asset objects
outgoing.css = filterAssets('content', styleObjects);
hintsReceived = true;
}
},
};

@@ -272,2 +294,3 @@

// @ts-ignore
pipeline([body, outgoing], (err) => {

@@ -311,4 +334,4 @@ if (err) {

new Response({
js: utils.filterAssets('fallback', outgoing.manifest.js),
css: utils.filterAssets('fallback', outgoing.manifest.css),
js: utils.filterAssets('fallback', outgoing.js),
css: utils.filterAssets('fallback', outgoing.css),
}),

@@ -315,0 +338,0 @@ );

@@ -7,2 +7,4 @@ import abslog from 'abslog';

import HTTP from './http.js';
import { parseLinkHeaders, filterAssets } from './utils.js';
import { AssetJs, AssetCss } from '@podium/utils';

@@ -98,2 +100,4 @@ const currentDirectory = dirname(fileURLToPath(import.meta.url));

let hintsReceived = false;
/** @type {import('./http.js').PodiumHttpClientRequestOptions} */

@@ -105,2 +109,28 @@ const reqOptions = {

headers,
onInfo({ statusCode, headers }) {
if (statusCode === 103 && !hintsReceived) {
const parsedAssetObjects = parseLinkHeaders(headers.link);
const scriptObjects = parsedAssetObjects.filter(
(asset) => asset instanceof AssetJs,
);
const styleObjects = parsedAssetObjects.filter(
(asset) => asset instanceof AssetCss,
);
// set the content js asset fallback objects
// @ts-expect-error internal property
outgoing.manifest._js = filterAssets(
'fallback',
scriptObjects,
);
// set the fallback css asset fallback objects
// @ts-expect-error internal property
outgoing.manifest._css = filterAssets(
'fallback',
styleObjects,
);
hintsReceived = true;
}
},
};

@@ -107,0 +137,0 @@

@@ -162,3 +162,3 @@ import Metrics from '@metrics/client';

const { manifest, headers, redirect, isFallback } =
const { headers, redirect, isFallback } =
await this.#resolver.resolve(outgoing);

@@ -181,7 +181,7 @@

isFallback ? 'fallback' : 'content',
manifest.css,
outgoing.css,
),
js: utils.filterAssets(
isFallback ? 'fallback' : 'content',
manifest.js,
outgoing.js,
),

@@ -188,0 +188,0 @@ redirect,

@@ -0,1 +1,3 @@

import { AssetJs, AssetCss } from '@podium/utils';
/**

@@ -74,1 +76,43 @@ * Checks if a header object has a header.

};
// parse link headers in AssetCss and AssetJs objects
export const parseLinkHeaders = (headers) => {
const links = [];
if (!headers) return links;
headers.split(',').forEach((link) => {
const parts = link.split(';');
const [href, ...rest] = parts;
const value = href.replace(/<|>|"/g, '').trim();
const asset = { value };
for (const key of rest) {
const [keyName, keyValue] = key.split('=');
asset[keyName.trim()] = keyValue.trim();
}
if (asset['asset-type'] === 'script') {
links.push(new AssetJs(asset));
}
if (asset['asset-type'] === 'style') {
links.push(new AssetCss(asset));
}
});
return links;
};
export const toPreloadAssetObjects = (assetObjects) => {
return assetObjects.map((assetObject) => {
return new AssetCss({
type:
assetObject instanceof AssetJs
? 'application/javascript'
: 'text/css',
crossorigin: !!assetObject.crossorigin,
rel: 'preload',
as: assetObject instanceof AssetJs ? 'script' : 'style',
media: assetObject.media || '',
value: assetObject.value.trim(),
});
});
};
{
"name": "@podium/client",
"version": "5.1.10",
"version": "5.2.0-next.1",
"type": "module",

@@ -51,9 +51,9 @@ "license": "MIT",

"devDependencies": {
"@podium/test-utils": "2.5.2",
"@podium/test-utils": "3.1.0-next.3",
"@semantic-release/changelog": "6.0.3",
"@semantic-release/git": "10.0.1",
"@semantic-release/github": "10.1.7",
"@semantic-release/github": "10.0.6",
"@semantic-release/npm": "12.0.1",
"@semantic-release/release-notes-generator": "13.0.0",
"@sinonjs/fake-timers": "11.3.1",
"@sinonjs/fake-timers": "11.2.2",
"@types/readable-stream": "4.0.15",

@@ -66,6 +66,6 @@ "benchmark": "2.1.4",

"get-stream": "9.0.1",
"globals": "15.9.0",
"globals": "15.8.0",
"http-proxy": "1.18.1",
"is-stream": "4.0.1",
"npm-run-all2": "5.0.2",
"npm-run-all2": "5.0.0",
"prettier": "3.3.2",

@@ -72,0 +72,0 @@ "semantic-release": "23.1.1",

@@ -49,2 +49,6 @@ /**

constructor(options?: PodiumClientHttpOutgoingOptions, reqOptions?: PodiumClientResourceOptions, incoming?: import('@podium/utils').HttpIncoming);
set js(value: any);
get js(): any;
set css(value: any);
get css(): any;
get rejectUnauthorized(): boolean;

@@ -51,0 +55,0 @@ get reqOptions(): {

@@ -8,7 +8,9 @@ /**

* @property {number} [timeout]
* @property {number} [bodyTimeout]
* @property {object} [query]
* @property {import('http').IncomingHttpHeaders} [headers]
* @property {(info: { statusCode: number; headers: Record<string, string | string[]>; }) => void} [onInfo]
*/
export default class HTTP {
constructor(requestFn?: typeof undiciRequest);
requestFn: typeof undiciRequest;
/**

@@ -27,5 +29,9 @@ * @param {string} url

timeout?: number;
bodyTimeout?: number;
query?: object;
headers?: import('http').IncomingHttpHeaders;
onInfo?: (info: {
statusCode: number;
headers: Record<string, string | string[]>;
}) => void;
};
import { request as undiciRequest } from 'undici';
export function isHeaderDefined(headers: object, header: string): boolean;
export function hasManifestChange(item: object): boolean;
export function validateIncoming(incoming?: object): boolean;
export function filterAssets<T extends import("@podium/utils").AssetJs | import("@podium/utils").AssetCss>(scope: "content" | "fallback" | "all", assets: T[]): T[];
export function filterAssets<T extends AssetJs | AssetCss>(scope: "content" | "fallback" | "all", assets: T[]): T[];
export function parseLinkHeaders(headers: any): any[];
export function toPreloadAssetObjects(assetObjects: any): any;
import { AssetJs } from '@podium/utils';
import { AssetCss } from '@podium/utils';
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc