@stremio-addon/sdk
Advanced tools
| import type { AddonInterface, Manifest } from "./types.js"; | ||
| export declare const basicManifest: Manifest; | ||
| export declare const configurableManifest: Manifest; | ||
| export declare const configurationRequiredManifest: Manifest; | ||
| export declare const bigBuckBunnyCatalog: { | ||
| metas: { | ||
| id: string; | ||
| name: string; | ||
| releaseInfo: string; | ||
| poster: string; | ||
| posterShape: "poster"; | ||
| type: "movie"; | ||
| }[]; | ||
| cacheMaxAge: number; | ||
| }; | ||
| export declare const bigBuckBunnyStream: { | ||
| streams: { | ||
| url: string; | ||
| }[]; | ||
| cacheMaxAge: number; | ||
| }; | ||
| export declare function makeAddon(manifest: Manifest, get?: AddonInterface["get"]): AddonInterface; | ||
| //# sourceMappingURL=__fixtures__.d.ts.map |
| {"version":3,"file":"__fixtures__.d.ts","sourceRoot":"","sources":["../src/__fixtures__.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3D,eAAO,MAAM,aAAa,EAAE,QAS3B,CAAC;AAGF,eAAO,MAAM,oBAAoB,EAAE,QAmBlC,CAAC;AAGF,eAAO,MAAM,6BAA6B,EAAE,QAkB3C,CAAC;AAGF,eAAO,MAAM,mBAAmB;;;;;;;;;;CAa/B,CAAC;AAGF,eAAO,MAAM,kBAAkB;;;;;CAO9B,CAAC;AAEF,wBAAgB,SAAS,CACvB,QAAQ,EAAE,QAAQ,EAClB,GAAG,GAAE,cAAc,CAAC,KAAK,CAAoB,GAC5C,cAAc,CAEhB"} |
| // Mirrors the basic example from https://github.com/Stremio/stremio-addon-sdk/blob/2728da3ee853207cd5ee200aabe15a08cc1d01d1/docs/api/responses/manifest.md | ||
| export const basicManifest = { | ||
| id: "org.stremio.example", | ||
| version: "0.0.1", | ||
| name: "Example Addon", | ||
| description: "Example Stremio Addon", | ||
| resources: ["catalog", "stream"], | ||
| types: ["movie", "series"], | ||
| catalogs: [{ type: "movie", id: "moviecatalog", name: "Movies" }], | ||
| idPrefixes: ["tt"], | ||
| }; | ||
| // Mirrors the configurable example from https://github.com/Stremio/stremio-addon-sdk/blob/2728da3ee853207cd5ee200aabe15a08cc1d01d1/docs/api/responses/manifest.md | ||
| export const configurableManifest = { | ||
| id: "com.example.configurable", | ||
| version: "1.0.0", | ||
| name: "Configurable Addon", | ||
| description: "Addon requiring user configuration", | ||
| resources: ["stream", "catalog"], | ||
| types: ["movie"], | ||
| catalogs: [{ type: "movie", id: "main", name: "Main" }], | ||
| behaviorHints: { configurable: true, configurationRequired: false }, | ||
| config: [ | ||
| { key: "apiKey", type: "password", title: "API Key", required: true }, | ||
| { | ||
| key: "quality", | ||
| type: "select", | ||
| title: "Quality", | ||
| options: ["720p", "1080p", "4K"], | ||
| default: "1080p", | ||
| }, | ||
| ], | ||
| }; | ||
| // Mirrors the configurationRequired example from https://github.com/Stremio/stremio-addon-sdk/blob/2728da3ee853207cd5ee200aabe15a08cc1d01d1/docs/api/responses/manifest.md | ||
| export const configurationRequiredManifest = { | ||
| id: "com.example.required", | ||
| version: "2.0.0", | ||
| name: "Premium Service", | ||
| description: "Requires configuration before use", | ||
| resources: ["stream"], | ||
| types: ["movie", "series"], | ||
| catalogs: [], | ||
| behaviorHints: { | ||
| configurable: true, | ||
| configurationRequired: true, | ||
| adult: false, | ||
| p2p: false, | ||
| }, | ||
| config: [ | ||
| { key: "username", type: "text", title: "Username", required: true }, | ||
| { key: "password", type: "password", title: "Password", required: true }, | ||
| ], | ||
| }; | ||
| // Catalog response from https://github.com/Stremio/stremio-addon-sdk/blob/2728da3ee853207cd5ee200aabe15a08cc1d01d1/docs/api/requests/defineCatalogHandler.md | ||
| export const bigBuckBunnyCatalog = { | ||
| metas: [ | ||
| { | ||
| id: "tt1254207", | ||
| name: "Big Buck Bunny", | ||
| releaseInfo: "2008", | ||
| poster: "https://image.tmdb.org/t/p/w600_and_h900_bestv2/uVEFQvFMMsg4e6yb03xOfVsDz4o.jpg", | ||
| posterShape: "poster", | ||
| type: "movie", | ||
| }, | ||
| ], | ||
| cacheMaxAge: 3600, | ||
| }; | ||
| // Stream response from https://github.com/Stremio/stremio-addon-sdk/blob/2728da3ee853207cd5ee200aabe15a08cc1d01d1/docs/api/requests/defineStreamHandler.md | ||
| export const bigBuckBunnyStream = { | ||
| streams: [ | ||
| { | ||
| url: "http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4", | ||
| }, | ||
| ], | ||
| cacheMaxAge: 3600, | ||
| }; | ||
| export function makeAddon(manifest, get = async () => ({})) { | ||
| return { manifest, get }; | ||
| } | ||
| //# sourceMappingURL=__fixtures__.js.map |
| {"version":3,"file":"__fixtures__.js","sourceRoot":"","sources":["../src/__fixtures__.ts"],"names":[],"mappings":"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"} |
| export {}; | ||
| //# sourceMappingURL=builder.test.d.ts.map |
| {"version":3,"file":"builder.test.d.ts","sourceRoot":"","sources":["../src/builder.test.ts"],"names":[],"mappings":""} |
| import { describe, it, expect } from "vitest"; | ||
| import { AddonBuilder } from "./builder.js"; | ||
| import { ValidationError } from "./validator.js"; | ||
| import { basicManifest, bigBuckBunnyCatalog, bigBuckBunnyStream, } from "./__fixtures__.js"; | ||
| const passthroughSchema = { | ||
| "~standard": { | ||
| version: 1, | ||
| vendor: "test", | ||
| validate: (value) => ({ value: value }), | ||
| }, | ||
| }; | ||
| const rejectingSchema = { | ||
| "~standard": { | ||
| version: 1, | ||
| vendor: "test", | ||
| validate: () => ({ | ||
| issues: [ | ||
| { message: "bad manifest" }, | ||
| ], | ||
| }), | ||
| }, | ||
| }; | ||
| describe("AddonBuilder", () => { | ||
| describe("construction", () => { | ||
| it("freezes the manifest", () => { | ||
| const builder = new AddonBuilder(basicManifest); | ||
| const { manifest } = builder.getInterface(); | ||
| expect(Object.isFrozen(manifest)).toBe(true); | ||
| expect(() => { | ||
| "use strict"; | ||
| manifest.name = "Mutated"; | ||
| }).toThrow(); | ||
| }); | ||
| it("accepts a manifest without schema", () => { | ||
| const builder = new AddonBuilder(basicManifest); | ||
| expect(builder.getInterface().manifest).toEqual(basicManifest); | ||
| }); | ||
| it("passes manifest through schema when provided", () => { | ||
| const builder = new AddonBuilder(basicManifest, passthroughSchema); | ||
| expect(builder.getInterface().manifest).toEqual(basicManifest); | ||
| }); | ||
| it("throws ValidationError when schema rejects", () => { | ||
| expect(() => new AddonBuilder(basicManifest, rejectingSchema)).toThrow(ValidationError); | ||
| }); | ||
| }); | ||
| describe("defineResourceHandler", () => { | ||
| it("returns this (chainable)", () => { | ||
| const builder = new AddonBuilder(basicManifest); | ||
| const ret = builder.defineStreamHandler(async () => ({ streams: [] })); | ||
| expect(ret).toBe(builder); | ||
| }); | ||
| it("throws when the same resource is defined twice", () => { | ||
| const builder = new AddonBuilder(basicManifest).defineStreamHandler(async () => ({ streams: [] })); | ||
| expect(() => builder.defineStreamHandler(async () => ({ streams: [] }))).toThrow('Handler for resource "stream" is already defined'); | ||
| }); | ||
| }); | ||
| describe("sugar methods route to the right resource", () => { | ||
| it("defineStreamHandler responds to get('stream', ...)", async () => { | ||
| const builder = new AddonBuilder(basicManifest).defineStreamHandler(async () => bigBuckBunnyStream); | ||
| const result = await builder | ||
| .getInterface() | ||
| .get("stream", "movie", "tt1254207"); | ||
| expect(result).toEqual(bigBuckBunnyStream); | ||
| }); | ||
| it("defineCatalogHandler responds to get('catalog', ...)", async () => { | ||
| const builder = new AddonBuilder(basicManifest).defineCatalogHandler(async () => bigBuckBunnyCatalog); | ||
| const result = await builder | ||
| .getInterface() | ||
| .get("catalog", "movie", "moviecatalog"); | ||
| expect(result).toEqual(bigBuckBunnyCatalog); | ||
| }); | ||
| it("defineMetaHandler responds to get('meta', ...)", async () => { | ||
| const meta = { meta: { id: "tt1254207", type: "movie", name: "BBB" } }; | ||
| const builder = new AddonBuilder(basicManifest).defineMetaHandler(async () => meta); | ||
| const result = await builder | ||
| .getInterface() | ||
| .get("meta", "movie", "tt1254207"); | ||
| expect(result).toEqual(meta); | ||
| }); | ||
| it("defineSubtitlesHandler responds to get('subtitles', ...)", async () => { | ||
| const subs = { subtitles: [] }; | ||
| const builder = new AddonBuilder(basicManifest).defineSubtitlesHandler(async () => subs); | ||
| const result = await builder | ||
| .getInterface() | ||
| .get("subtitles", "movie", "tt1254207"); | ||
| expect(result).toEqual(subs); | ||
| }); | ||
| }); | ||
| describe("getInterface().get", () => { | ||
| it("rejects when no handler is registered for the resource", async () => { | ||
| const builder = new AddonBuilder(basicManifest); | ||
| await expect(builder.getInterface().get("addon_catalog", "movie", "x")).rejects.toBe("No handler for addon_catalog"); | ||
| }); | ||
| it("passes default extra and config when omitted", async () => { | ||
| let captured; | ||
| const builder = new AddonBuilder(basicManifest).defineStreamHandler(async (args) => { | ||
| captured = args; | ||
| return { streams: [] }; | ||
| }); | ||
| await builder.getInterface().get("stream", "movie", "tt1254207"); | ||
| expect(captured).toEqual({ | ||
| type: "movie", | ||
| id: "tt1254207", | ||
| extra: {}, | ||
| config: {}, | ||
| }); | ||
| }); | ||
| it("passes through extra and config when provided", async () => { | ||
| let captured; | ||
| const builder = new AddonBuilder(basicManifest).defineStreamHandler(async (args) => { | ||
| captured = args; | ||
| return { streams: [] }; | ||
| }); | ||
| await builder | ||
| .getInterface() | ||
| .get("stream", "series", "tt0898266:9:17", { search: "foo" }, { apiKey: "x" }); | ||
| expect(captured).toEqual({ | ||
| type: "series", | ||
| id: "tt0898266:9:17", | ||
| extra: { search: "foo" }, | ||
| config: { apiKey: "x" }, | ||
| }); | ||
| }); | ||
| }); | ||
| }); | ||
| //# sourceMappingURL=builder.test.js.map |
| {"version":3,"file":"builder.test.js","sourceRoot":"","sources":["../src/builder.test.ts"],"names":[],"mappings":"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"} |
| export {}; | ||
| //# sourceMappingURL=router.test.d.ts.map |
| {"version":3,"file":"router.test.d.ts","sourceRoot":"","sources":["../src/router.test.ts"],"names":[],"mappings":""} |
| import { describe, it, expect, vi } from "vitest"; | ||
| import { createRouter } from "./router.js"; | ||
| import { basicManifest, bigBuckBunnyCatalog, bigBuckBunnyStream, configurableManifest, configurationRequiredManifest, makeAddon, } from "./__fixtures__.js"; | ||
| const BASE = "http://localhost"; | ||
| function spyAddon(manifest, response = {}) { | ||
| const calls = []; | ||
| const addon = makeAddon(manifest, async (resource, type, id, extra, config) => { | ||
| calls.push({ | ||
| resource, | ||
| type, | ||
| id, | ||
| extra: extra ?? {}, | ||
| config: config ?? {}, | ||
| }); | ||
| return response; | ||
| }); | ||
| return { addon, calls }; | ||
| } | ||
| async function readJson(res) { | ||
| return JSON.parse(await res.text()); | ||
| } | ||
| describe("createRouter", () => { | ||
| describe("manifest route", () => { | ||
| it("serves the manifest at /manifest.json", async () => { | ||
| const router = createRouter(makeAddon(basicManifest)); | ||
| const res = await router(new Request(`${BASE}/manifest.json`)); | ||
| expect(res).not.toBeNull(); | ||
| expect(res.status).toBe(200); | ||
| expect(res.headers.get("Content-Type")).toBe("application/json; charset=utf-8"); | ||
| expect(res.headers.get("Access-Control-Allow-Origin")).toBe("*"); | ||
| expect(await readJson(res)).toEqual(basicManifest); | ||
| }); | ||
| it("returns null for unmatched paths", async () => { | ||
| const router = createRouter(makeAddon(basicManifest)); | ||
| expect(await router(new Request(`${BASE}/random`))).toBeNull(); | ||
| expect(await router(new Request(`${BASE}/`))).toBeNull(); | ||
| expect(await router(new Request(`${BASE}/manifest`))).toBeNull(); | ||
| }); | ||
| }); | ||
| describe("resource routes (protocol URLs)", () => { | ||
| it("routes catalog feed: /catalog/movie/moviecatalog.json", async () => { | ||
| const { addon, calls } = spyAddon(basicManifest, bigBuckBunnyCatalog); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/catalog/movie/moviecatalog.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(await readJson(res)).toEqual(bigBuckBunnyCatalog); | ||
| expect(calls).toEqual([ | ||
| { | ||
| resource: "catalog", | ||
| type: "movie", | ||
| id: "moviecatalog", | ||
| extra: {}, | ||
| config: {}, | ||
| }, | ||
| ]); | ||
| }); | ||
| it("routes stream: /stream/movie/tt1254207.json", async () => { | ||
| const { addon, calls } = spyAddon(basicManifest, bigBuckBunnyStream); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(await readJson(res)).toEqual(bigBuckBunnyStream); | ||
| expect(calls[0]).toMatchObject({ | ||
| resource: "stream", | ||
| type: "movie", | ||
| id: "tt1254207", | ||
| }); | ||
| }); | ||
| it("preserves colons in id: /stream/series/tt0898266:9:17.json", async () => { | ||
| const seriesManifest = { | ||
| ...basicManifest, | ||
| resources: ["stream"], | ||
| catalogs: [], | ||
| }; | ||
| const { addon, calls } = spyAddon(seriesManifest, { streams: [] }); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/series/tt0898266:9:17.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(calls[0]).toMatchObject({ | ||
| resource: "stream", | ||
| type: "series", | ||
| id: "tt0898266:9:17", | ||
| }); | ||
| }); | ||
| it("routes meta: /meta/movie/tt1254207.json", async () => { | ||
| const metaManifest = { | ||
| ...basicManifest, | ||
| resources: ["meta"], | ||
| catalogs: [], | ||
| }; | ||
| const { addon, calls } = spyAddon(metaManifest, { | ||
| meta: { id: "tt1254207" }, | ||
| }); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/meta/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(calls[0].resource).toBe("meta"); | ||
| }); | ||
| it("routes subtitles: /subtitles/movie/tt1254207.json", async () => { | ||
| const subsManifest = { | ||
| ...basicManifest, | ||
| resources: ["subtitles"], | ||
| catalogs: [], | ||
| }; | ||
| const { addon, calls } = spyAddon(subsManifest, { subtitles: [] }); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/subtitles/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(calls[0].resource).toBe("subtitles"); | ||
| }); | ||
| it("decodes extra params from URL-encoded path segment", async () => { | ||
| const { addon, calls } = spyAddon(basicManifest, { metas: [] }); | ||
| const router = createRouter(addon); | ||
| await router(new Request(`${BASE}/catalog/movie/top/search=big%20buck%20bunny&skip=0.json`)); | ||
| expect(calls[0].extra).toEqual({ | ||
| search: "big buck bunny", | ||
| skip: "0", | ||
| }); | ||
| }); | ||
| it("parses single extra param: genre=Action", async () => { | ||
| const { addon, calls } = spyAddon(basicManifest, { metas: [] }); | ||
| const router = createRouter(addon); | ||
| await router(new Request(`${BASE}/catalog/movie/trending/genre=Action.json`)); | ||
| expect(calls[0].extra).toEqual({ genre: "Action" }); | ||
| }); | ||
| }); | ||
| describe("resource routes (errors)", () => { | ||
| it("returns 404 for resource not declared in manifest", async () => { | ||
| const router = createRouter(makeAddon(basicManifest)); | ||
| const res = await router(new Request(`${BASE}/subtitles/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(404); | ||
| expect(await readJson(res)).toEqual({ err: "resource not found" }); | ||
| }); | ||
| it("returns 500 when the handler rejects", async () => { | ||
| const addon = makeAddon(basicManifest, async () => { | ||
| throw new Error("boom"); | ||
| }); | ||
| const router = createRouter(addon); | ||
| const errSpy = vi.spyOn(console, "error").mockImplementation(() => { }); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(500); | ||
| expect(await readJson(res)).toEqual({ err: "handler error" }); | ||
| expect(errSpy).toHaveBeenCalled(); | ||
| errSpy.mockRestore(); | ||
| }); | ||
| it("returns 307 redirect when result.redirect is set", async () => { | ||
| const addon = makeAddon(basicManifest, async () => ({ | ||
| redirect: "https://example.com/elsewhere.json", | ||
| })); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(307); | ||
| expect(res.headers.get("Location")).toBe("https://example.com/elsewhere.json"); | ||
| }); | ||
| }); | ||
| describe("cache headers", () => { | ||
| it("sets Cache-Control from cacheMaxAge", async () => { | ||
| const addon = makeAddon(basicManifest, async () => ({ | ||
| streams: [], | ||
| cacheMaxAge: 3600, | ||
| })); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.headers.get("Cache-Control")).toBe("max-age=3600, public"); | ||
| }); | ||
| it("combines cacheMaxAge, staleRevalidate, and staleError", async () => { | ||
| const addon = makeAddon(basicManifest, async () => ({ | ||
| streams: [], | ||
| cacheMaxAge: 3600, | ||
| staleRevalidate: 1800, | ||
| staleError: 86400, | ||
| })); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.headers.get("Cache-Control")).toBe("max-age=3600, stale-while-revalidate=1800, stale-if-error=86400, public"); | ||
| }); | ||
| it("ignores non-integer cache values", async () => { | ||
| const addon = makeAddon(basicManifest, async () => ({ | ||
| streams: [], | ||
| cacheMaxAge: 3.5, | ||
| staleRevalidate: "1800", | ||
| })); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.headers.get("Cache-Control")).toBeNull(); | ||
| }); | ||
| it("omits Cache-Control when no cache fields present", async () => { | ||
| const addon = makeAddon(basicManifest, async () => ({ streams: [] })); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.headers.get("Cache-Control")).toBeNull(); | ||
| }); | ||
| }); | ||
| describe("config prefix (regression for #41/#42)", () => { | ||
| it("strips configurable flags when manifest served under config prefix", async () => { | ||
| const router = createRouter(makeAddon(configurationRequiredManifest)); | ||
| const res = await router(new Request(`${BASE}/eyJxIjoxfQ/manifest.json`)); | ||
| expect(res.status).toBe(200); | ||
| const body = await readJson(res); | ||
| expect(body.behaviorHints.configurable).toBeUndefined(); | ||
| expect(body.behaviorHints.configurationRequired).toBeUndefined(); | ||
| expect(body.behaviorHints.adult).toBe(false); | ||
| expect(body.behaviorHints.p2p).toBe(false); | ||
| }); | ||
| it("preserves configurable flags when manifest served without config prefix", async () => { | ||
| const router = createRouter(makeAddon(configurationRequiredManifest)); | ||
| const res = await router(new Request(`${BASE}/manifest.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(await readJson(res)).toEqual(configurationRequiredManifest); | ||
| }); | ||
| it("decodes URL-encoded JSON config and passes it to the handler", async () => { | ||
| const { addon, calls } = spyAddon(configurableManifest, { streams: [] }); | ||
| const router = createRouter(addon); | ||
| await router(new Request(`${BASE}/%7B%22apiKey%22%3A%22secret%22%7D/stream/movie/tt1254207.json`)); | ||
| expect(calls[0].config).toEqual({ apiKey: "secret" }); | ||
| }); | ||
| it("#41: configurable manifest still serves /manifest.json without prefix", async () => { | ||
| const router = createRouter(makeAddon(configurableManifest)); | ||
| const res = await router(new Request(`${BASE}/manifest.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(await readJson(res)).toEqual(configurableManifest); | ||
| }); | ||
| it("#41: configurable manifest still routes /stream/... without prefix", async () => { | ||
| const { addon, calls } = spyAddon(configurableManifest, { streams: [] }); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(calls[0]).toMatchObject({ | ||
| resource: "stream", | ||
| type: "movie", | ||
| id: "tt1254207", | ||
| config: {}, | ||
| }); | ||
| }); | ||
| it("#41: configurable manifest still routes /catalog/... without prefix", async () => { | ||
| const { addon, calls } = spyAddon(configurableManifest, { metas: [] }); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/catalog/movie/main.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(calls[0]).toMatchObject({ | ||
| resource: "catalog", | ||
| type: "movie", | ||
| id: "main", | ||
| config: {}, | ||
| }); | ||
| }); | ||
| it("config prefix activates from non-empty manifest.config alone", async () => { | ||
| const manifest = { | ||
| ...configurableManifest, | ||
| behaviorHints: undefined, | ||
| }; | ||
| const { addon, calls } = spyAddon(manifest, { streams: [] }); | ||
| const router = createRouter(addon); | ||
| await router(new Request(`${BASE}/%7B%22apiKey%22%3A%22x%22%7D/stream/movie/tt1254207.json`)); | ||
| expect(calls[0].config).toEqual({ apiKey: "x" }); | ||
| }); | ||
| it("non-configurable manifest does not activate prefix", async () => { | ||
| const router = createRouter(makeAddon(basicManifest)); | ||
| expect(await router(new Request(`${BASE}/anything/manifest.json`))).toBeNull(); | ||
| }); | ||
| it("non-configurable manifest returns base manifest verbatim", async () => { | ||
| const router = createRouter(makeAddon(basicManifest)); | ||
| const res = await router(new Request(`${BASE}/manifest.json`)); | ||
| expect(await readJson(res)).toEqual(basicManifest); | ||
| }); | ||
| }); | ||
| describe("config parsing", () => { | ||
| it("falls back to {} when config segment is not valid JSON", async () => { | ||
| const { addon, calls } = spyAddon(configurableManifest, { streams: [] }); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/not-valid-json/stream/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(calls[0].config).toEqual({}); | ||
| }); | ||
| }); | ||
| describe("catalog auto-registration", () => { | ||
| it("registers catalog handler when manifest.catalogs is non-empty even if resources omits it", async () => { | ||
| const manifest = { | ||
| ...basicManifest, | ||
| resources: ["stream"], | ||
| }; | ||
| const { addon, calls } = spyAddon(manifest, { metas: [] }); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/catalog/movie/moviecatalog.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(calls[0].resource).toBe("catalog"); | ||
| }); | ||
| }); | ||
| // The Fetch API requires absolute URLs on `new Request(...)`, so we construct a duck-typed Request to exercise the relative-URL branch of `getUrl`. | ||
| // This branch is hit in practice when the SDK is wrapped by Node/Express adapters (see @stremio-addon/compat). | ||
| describe("relative URL handling", () => { | ||
| function fakeRequest(url, host) { | ||
| return { | ||
| url, | ||
| headers: { get: (name) => (name === "host" ? host : null) }, | ||
| }; | ||
| } | ||
| it("uses the host header when url is relative", async () => { | ||
| const router = createRouter(makeAddon(basicManifest)); | ||
| const res = await router(fakeRequest("/manifest.json", "example.com:8080")); | ||
| expect(res.status).toBe(200); | ||
| expect(await readJson(res)).toEqual(basicManifest); | ||
| }); | ||
| it("falls back to localhost when host header is missing", async () => { | ||
| const router = createRouter(makeAddon(basicManifest)); | ||
| const res = await router(fakeRequest("/manifest.json", null)); | ||
| expect(res.status).toBe(200); | ||
| expect(await readJson(res)).toEqual(basicManifest); | ||
| }); | ||
| }); | ||
| describe("full-form resource objects in manifest", () => { | ||
| it("routes when resources contains a FullManifestResource", async () => { | ||
| const manifest = { | ||
| ...basicManifest, | ||
| resources: [ | ||
| { name: "stream", types: ["movie"], idPrefixes: ["tt"] }, | ||
| { name: "meta", types: ["movie", "series"] }, | ||
| ], | ||
| catalogs: [], | ||
| }; | ||
| const { addon, calls } = spyAddon(manifest, bigBuckBunnyStream); | ||
| const router = createRouter(addon); | ||
| const res = await router(new Request(`${BASE}/stream/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(200); | ||
| expect(calls[0].resource).toBe("stream"); | ||
| }); | ||
| it("404s for a resource not listed in the full-form resources array", async () => { | ||
| const manifest = { | ||
| ...basicManifest, | ||
| resources: [{ name: "stream", types: ["movie"] }], | ||
| catalogs: [], | ||
| }; | ||
| const router = createRouter(makeAddon(manifest)); | ||
| const res = await router(new Request(`${BASE}/subtitles/movie/tt1254207.json`)); | ||
| expect(res.status).toBe(404); | ||
| }); | ||
| }); | ||
| }); | ||
| //# sourceMappingURL=router.test.js.map |
| {"version":3,"file":"router.test.js","sourceRoot":"","sources":["../src/router.test.ts"],"names":[],"mappings":"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"} |
| export {}; | ||
| //# sourceMappingURL=validator.test.d.ts.map |
| {"version":3,"file":"validator.test.d.ts","sourceRoot":"","sources":["../src/validator.test.ts"],"names":[],"mappings":""} |
| import { describe, it, expect } from "vitest"; | ||
| import { validate, ValidationError } from "./validator.js"; | ||
| function makeSchema(validateFn) { | ||
| return { | ||
| "~standard": { | ||
| version: 1, | ||
| vendor: "test", | ||
| validate: validateFn, | ||
| }, | ||
| }; | ||
| } | ||
| describe("validate", () => { | ||
| it("returns the parsed value on success", () => { | ||
| const schema = makeSchema((value) => ({ | ||
| value: value, | ||
| })); | ||
| expect(validate(schema, { id: "abc" })).toEqual({ id: "abc" }); | ||
| }); | ||
| it("throws ValidationError when issues are present", () => { | ||
| const issues = [ | ||
| { message: "id must be a string", path: ["id"] }, | ||
| { message: "name is required" }, | ||
| ]; | ||
| const schema = makeSchema(() => ({ issues })); | ||
| expect(() => validate(schema, {})).toThrow(ValidationError); | ||
| try { | ||
| validate(schema, {}); | ||
| } | ||
| catch (err) { | ||
| expect(err).toBeInstanceOf(ValidationError); | ||
| expect(err.name).toBe("ValidationError"); | ||
| expect(err.message).toBe("id must be a string"); | ||
| expect(err.issues).toEqual(issues); | ||
| } | ||
| }); | ||
| it("throws TypeError when the schema returns a Promise", () => { | ||
| const schema = makeSchema(async (value) => ({ value: value })); | ||
| expect(() => validate(schema, { id: "abc" })).toThrow(TypeError); | ||
| expect(() => validate(schema, { id: "abc" })).toThrow("Schema validation must be synchronous"); | ||
| }); | ||
| }); | ||
| //# sourceMappingURL=validator.test.js.map |
| {"version":3,"file":"validator.test.js","sourceRoot":"","sources":["../src/validator.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE3D,SAAS,UAAU,CACjB,UAAwD;IAExD,OAAO;QACL,WAAW,EAAE;YACX,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,UAAU;SACrB;KACF,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAG,UAAU,CAAiB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACpD,KAAK,EAAE,KAAuB;SAC/B,CAAC,CAAC,CAAC;QAEJ,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,MAAM,GAAG;YACb,EAAE,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE;YAChD,EAAE,OAAO,EAAE,kBAAkB,EAAE;SACK,CAAC;QACvC,MAAM,MAAM,GAAG,UAAU,CAAiB,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAE9D,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAS,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAEnE,IAAI,CAAC;YACH,QAAQ,CAAC,MAAM,EAAE,EAAS,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;YAC5C,MAAM,CAAE,GAAuB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC9D,MAAM,CAAE,GAAuB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YACrE,MAAM,CAAE,GAAuB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,MAAM,GAAG,UAAU,CACvB,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAuB,EAAE,CAAQ,CAC7D,CAAC;QAEF,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CACnD,uCAAuC,CACxC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} |
+12
-3
@@ -5,4 +5,4 @@ import { match } from "path-to-regexp"; | ||
| const { pathname } = getUrl(request); | ||
| const routePrefix = getRoutePrefix(manifest); | ||
| const resourceHandlers = getResourceHandlers(manifest); | ||
| const routePrefix = getRoutePrefix(manifest, pathname, resourceHandlers); | ||
| const headers = { | ||
@@ -66,5 +66,14 @@ "Content-Type": "application/json; charset=utf-8", | ||
| } | ||
| function getRoutePrefix(manifest) { | ||
| function getRoutePrefix(manifest, pathname, resourceHandlers) { | ||
| const hasConfig = (manifest.config ?? []).length || manifest.behaviorHints?.configurable; | ||
| return hasConfig ? "{/:config}" : ""; | ||
| if (!hasConfig) | ||
| return ""; | ||
| // path-to-regexp v8's `{/:config}` matches greedily, so inspect the first | ||
| // path segment instead: if it's a known resource or `manifest.json`, the | ||
| // URL has no config prefix; otherwise treat it as the config segment. | ||
| const firstSegment = pathname.split("/")[1] ?? ""; | ||
| if (firstSegment === "manifest.json" || resourceHandlers.has(firstSegment)) { | ||
| return ""; | ||
| } | ||
| return "/:config"; | ||
| } | ||
@@ -71,0 +80,0 @@ function getResourceHandlers(manifest) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,EAA6B,MAAM,gBAAgB,CAAC;AAElE,MAAM,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAkB;IAC5D,OAAO,KAAK,UAAU,MAAM,CAAC,OAAgB;QAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG;YACd,cAAc,EAAE,iCAAiC;YACjD,6BAA6B,EAAE,GAAG;SACnC,CAAC;QAEF,wBAAwB;QACxB,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,UAAU,CACjD,GAAG,WAAW,gBAAgB,EAC9B,QAAQ,CACT,CAAC;QACF,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,iBAAiB,GAAG,gBAAgB,CACxC,QAAQ,EACR,aAAa,CAAC,MAAM,CAAC,MAAM,CAC5B,CAAC;YACF,OAAO,IAAI,QAAQ,CAAC,iBAAiB,EAAE;gBACrC,OAAO;aACR,CAAC,CAAC;QACL,CAAC;QAED,wBAAwB;QACxB,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,UAAU,CACjD,GAAG,WAAW,oCAAoC,EAClD,QAAQ,CACT,CAAC;QACF,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,EACJ,QAAQ,EACR,IAAI,EACJ,EAAE,EACF,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,SAAS,GAClB,GAAG,aAAa,CAAC,MAAM,CAAC;YAEzB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,oBAAoB,EAAE,CAAC,EAAE;oBACjE,MAAM,EAAE,GAAG;oBACX,OAAO;iBACR,CAAC,CAAC;YACL,CAAC;YAED,MAAM,MAAM,GAAG,WAAW,CAAgB,SAAS,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;YAEnC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,GAAG,CACtB,QAAiC,EACjC,IAAmB,EACnB,EAAE,EACF,KAAK,EACL,MAAM,CACP,CAAC;gBAEF,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACpB,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;wBACxB,MAAM,EAAE,GAAG;wBACX,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE;qBACvC,CAAC,CAAC;gBACL,CAAC;gBAED,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE9D,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;gBACzD,IAAI,kBAAkB,EAAE,CAAC;oBACvB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;gBACvD,CAAC;gBAED,OAAO,GAAG,CAAC;YACb,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACnB,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC,EAAE;oBAC5D,MAAM,EAAE,GAAG;oBACX,OAAO;iBACR,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,gDAAgD;QAChD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,GAAY;IAC1B,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAErC,OAAO,IAAI,GAAG,CAAC,UAAU,IAAI,IAAI,WAAW,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,cAAc,CAAC,QAAkB;IACxC,MAAM,SAAS,GACb,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC;IACzE,OAAO,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAkB;IAC7C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;IACD,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/B,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CACjD,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAW;IACxC,MAAM,YAAY,GAAG;QACnB,WAAW,EAAE,SAAS;QACtB,eAAe,EAAE,wBAAwB;QACzC,UAAU,EAAE,gBAAgB;KAC7B,CAAC;IACF,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;SAC3C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAiC,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QAChD,OAAO,QAAQ,GAAG,GAAG,GAAG,UAAU,CAAC;IACrC,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;SACtB,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACzD,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAkB,EAAE,MAA0B;IACtE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,iBAAiB,GAAG,WAAW,CAAC;IACpC,IACE,MAAM;QACN,QAAQ,CAAC,aAAa;QACtB,CAAC,QAAQ,CAAC,aAAa,CAAC,qBAAqB;YAC3C,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,EACtC,CAAC;QACD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC9C,kFAAkF;QAClF,OAAO,aAAa,CAAC,aAAa,CAAC,qBAAqB,CAAC;QACzD,4FAA4F;QAC5F,OAAO,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC;QAChD,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,SAAS,UAAU,CACjB,IAAmB,EACnB,QAAgB;IAEhB,MAAM,OAAO,GAAG,KAAK,CAAI,IAAI,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClC,qEAAqE;IACrE,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,EAAE,OAAO,CAAU,CAAC;IAClC,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,IAAI,CAAU,CAAC;AAChC,CAAC;AAED,SAAS,WAAW,CAA0B,KAAyB;IACrE,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,MAAW,CAAC;AACrB,CAAC;AAED,SAAS,UAAU,CAAC,KAAyB;IAC3C,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACrE,CAAC"} | ||
| {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"} |
+5
-3
| { | ||
| "name": "@stremio-addon/sdk", | ||
| "version": "0.3.3", | ||
| "version": "0.3.4", | ||
| "description": "Community Stremio Addon SDK standard schema definitions and helper functions", | ||
@@ -31,6 +31,8 @@ "type": "module", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1", | ||
| "test": "vitest run", | ||
| "test:watch": "vitest", | ||
| "build": "tsc", | ||
| "build:watch": "tsc --watch" | ||
| "build:watch": "tsc --watch", | ||
| "typecheck": "tsc --noEmit" | ||
| } | ||
| } |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
111267
96.44%39
69.57%1615
61.66%2
-33.33%