diff --git a/src/generator.ts b/src/generator.ts index 40b971d..1bfd44c 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -40,7 +40,7 @@ import { Replacer } from "./common/str.js"; import { analyzeHtml } from "./html/analyze.js"; import { InstallTarget, type InstallMode } from "./install/installer.js"; import { LockResolutions } from "./install/lock.js"; -import { getDefaultProviderStrings, type Provider } from "./providers/index.js"; +import { configureProviders, getDefaultProviderStrings, type Provider } from "./providers/index.js"; import * as nodemodules from "./providers/nodemodules.js"; import { Resolver } from "./trace/resolver.js"; import { getMaybeWrapperUrl } from "./common/wrapper.js"; @@ -315,6 +315,24 @@ export interface GeneratorOptions { * Defaults to 3. */ fetchRetries?: number; + + /** + * Provider configuration options + * + * @example + * ```js + * const generator = new Generator({ + * mapUrl: import.meta.url, + * defaultProvider: "jspm.io", + * providerConfig: { + * "jspm.io": { + * cdnUrl: `https://jspm-mirror.com/` + * } + * } + */ + providerConfig?: { + [providerName: string]: any; + }; } export interface ModuleAnalysis { @@ -408,6 +426,7 @@ export class Generator { typeScript = false, integrity = false, fetchRetries, + providerConfig = {}, }: GeneratorOptions = {}) { // Initialise the debug logger: const { log, logStream } = createLogger(); @@ -524,6 +543,8 @@ export class Generator { // Set the fetch retry count if (typeof fetchRetries === 'number') setRetryCount(fetchRetries); + + configureProviders(providerConfig, resolver.providers); } /** diff --git a/src/providers/index.ts b/src/providers/index.ts index b4556a1..7ea8943 100644 --- a/src/providers/index.ts +++ b/src/providers/index.ts @@ -50,6 +50,8 @@ export interface Provider { ): Promise; supportedLayers?: string[]; + + configure?(config: any): void; } export const defaultProviders: Record = { @@ -68,6 +70,15 @@ export function getProvider(name: string, providers: Record) { throw new JspmError(`No provider named "${name}" has been defined.`); } +// Apply provider configurations +export function configureProviders(providerConfig: Record, providers: Record) { + for (const [providerName, provider] of Object.entries(providers)) { + if (provider.configure) { + provider.configure(providerConfig[providerName] || {}); + } + } +} + export function getDefaultProviderStrings() { let res = []; for (const [name, provider] of Object.entries(defaultProviders)) { diff --git a/src/providers/jspm.ts b/src/providers/jspm.ts index 0e95ec0..58353ab 100644 --- a/src/providers/jspm.ts +++ b/src/providers/jspm.ts @@ -9,7 +9,7 @@ import { SemverRange } from "sver"; // @ts-ignore import { fetch } from "#fetch"; -const cdnUrl = "https://ga.jspm.io/"; +let cdnUrl = "https://ga.jspm.io/"; const systemCdnUrl = "https://ga.system.jspm.io/"; const apiUrl = "https://api.jspm.io/"; @@ -25,6 +25,10 @@ export async function pkgToUrl( return `${layer === "system" ? systemCdnUrl : cdnUrl}${pkgToStr(pkg)}/`; } +export function configure(config: any) { + cdnUrl = config.cdnUrl || "https://ga.jspm.io/"; +} + const exactPkgRegEx = /^(([a-z]+):)?((?:@[^/\\%@]+\/)?[^./\\%@][^/\\%@]*)@([^\/]+)(\/.*)?$/; diff --git a/test/providers/config.test.js b/test/providers/config.test.js new file mode 100644 index 0000000..5abab1b --- /dev/null +++ b/test/providers/config.test.js @@ -0,0 +1,26 @@ +import { Generator } from "@jspm/generator"; +import assert from "assert"; + +// this private origin shouldn't really be shared publicly +const name = [111, 97, 107, 116, 105, 113].map(x => String.fromCharCode(x)).reverse().join(''); + +// Test with custom CDN URL +{ + const generator = new Generator({ + mapUrl: import.meta.url, + defaultProvider: "jspm.io", + providerConfig: { + "jspm.io": { + cdnUrl: `https://${name}.com/` + } + } + }); + + await generator.install("react@17.0.1"); + const json = generator.getMap(); + + assert.strictEqual( + json.imports.react, + `https://${name}.com/npm:react@17.0.1/dev.index.js` + ); +}