Skip to content

Commit

Permalink
Merge branch 'main' into windows-ci
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford authored Jul 14, 2024
2 parents d2bce03 + 2e373b2 commit 78e12b7
Show file tree
Hide file tree
Showing 15 changed files with 2,194 additions and 3,326 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
node: [18.x, 20.x]
node: [16.x, 18.x, 20.x, 22.x]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
Expand Down
12 changes: 4 additions & 8 deletions docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@ If no modules are given, all "imports" in the initial map are relinked.
* `--cache` _<mode>_ Cache mode for fetches (online, offline, no-cache) (default: online)
* `--root` _<url>_ URL to treat as server root, i.e. rebase import maps against
* `--preload` _[mode]_ Add module preloads to HTML output (default: static, dynamic)
* `--integrity` Add module preloads with integrity attributes to HTML output (default: false)
* `--integrity` Add module integrity attributes to the import map (default: false)
* `--compact` Output a compact import map (default: false)
* `--freeze` Freeze input map dependencies, i.e. do not modify them (default: false)
* `--stdout` Output the import map to stdout (default: false)
* `--silent` Silence all output (default: false)
* `-h, --help` Display this message
Expand Down Expand Up @@ -88,9 +87,8 @@ If no packages are provided, all "imports" in the initial map are reinstalled.
* `--cache` _<mode>_ Cache mode for fetches (online, offline, no-cache) (default: online)
* `--root` _<url>_ URL to treat as server root, i.e. rebase import maps against
* `--preload` _[mode]_ Add module preloads to HTML output (default: static, dynamic)
* `--integrity` Add module preloads with integrity attributes to HTML output (default: false)
* `--integrity` Add module integrity attributes to the import map (default: false)
* `--compact` Output a compact import map (default: false)
* `--freeze` Freeze input map dependencies, i.e. do not modify them (default: false)
* `--stdout` Output the import map to stdout (default: false)
* `--silent` Silence all output (default: false)
* `-h, --help` Display this message
Expand Down Expand Up @@ -139,9 +137,8 @@ Uninstalls packages from an import map. The given packages must be valid package
* `--cache` _<mode>_ Cache mode for fetches (online, offline, no-cache) (default: online)
* `--root` _<url>_ URL to treat as server root, i.e. rebase import maps against
* `--preload` _[mode]_ Add module preloads to HTML output (default: static, dynamic)
* `--integrity` Add module preloads with integrity attributes to HTML output (default: false)
* `--integrity` Add module integrity attributes to the import map (default: false)
* `--compact` Output a compact import map (default: false)
* `--freeze` Freeze input map dependencies, i.e. do not modify them (default: false)
* `--stdout` Output the import map to stdout (default: false)
* `--silent` Silence all output (default: false)
* `-h, --help` Display this message
Expand Down Expand Up @@ -172,9 +169,8 @@ Updates packages in an import map to the latest versions that are compatible wit
* `--cache` _<mode>_ Cache mode for fetches (online, offline, no-cache) (default: online)
* `--root` _<url>_ URL to treat as server root, i.e. rebase import maps against
* `--preload` _[mode]_ Add module preloads to HTML output (default: static, dynamic)
* `--integrity` Add module preloads with integrity attributes to HTML output (default: false)
* `--integrity` Add module integrity attributes to the import map (default: false)
* `--compact` Output a compact import map (default: false)
* `--freeze` Freeze input map dependencies, i.e. do not modify them (default: false)
* `--stdout` Output the import map to stdout (default: false)
* `--silent` Silence all output (default: false)
* `-h, --help` Display this message
Expand Down
5,341 changes: 2,069 additions & 3,272 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "jspm",
"type": "module",
"version": "3.1.0",
"version": "3.2.0",
"description": "Import Map Package Manager",
"license": "Apache-2.0",
"bin": {
Expand All @@ -12,22 +12,22 @@
"jspm.js"
],
"dependencies": {
"@jspm/generator": "^1.1.10",
"@jspm/generator": "^2.1.2",
"cac": "^6.7.14",
"ora": "^6.3.0",
"picocolors": "^1.0.0",
"rollup": "^3.29.2"
},
"devDependencies": {
"@antfu/eslint-config": "^0.34.2",
"@babel/core": "^7.21.4",
"@babel/core": "^7.24.7",
"@types/node": "^18.15.11",
"esbuild": "^0.16.17",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"prettier": "^2.8.7",
"tinyspy": "^1.1.1",
"tsx": "^3.12.6",
"tsx": "^4.16.2",
"typescript": "^4.9.5"
}
}
3 changes: 2 additions & 1 deletion src/build/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from "node:path";
import process from "node:process";
import { pathToFileURL } from "node:url";
import { type RollupOptions, rollup } from "rollup";

import { JspmError, exists } from "../utils";
Expand Down Expand Up @@ -40,7 +41,7 @@ export default async function build(entry: string, options: Flags) {
`Build config file does not exist: ${buildConfigPath}`
);
}
const rollupConfig = await import(buildConfigPath)
const rollupConfig = await import(pathToFileURL(buildConfigPath).href)
.then((mod) => mod.default)
.catch((err) => {
throw new JspmError(`Failed to load build config: ${err}`);
Expand Down
34 changes: 16 additions & 18 deletions src/build/rollup-importmap-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ const isValidUrl = (url: string) => {

export const RollupImportmapPlugin = async (flags: Flags): Promise<Plugin> => {
/*
Install without a freeze might bump the versions.
We would like to maintian 1:1 on what users defined in importmap.
We need to load the importmap from local into the generator.
And then run a re-install. So, the generator uses the importmap
to resolve any dependencies.
*/
const generator = await getGenerator({ ...flags, freeze: true });
await generator.install();
const generator = await getGenerator({ ...flags });
await generator.reinstall();

return {
name: "rollup-importmap-plugin",
Expand All @@ -43,25 +44,22 @@ export const RollupImportmapPlugin = async (flags: Flags): Promise<Plugin> => {
}
},
load: async (id: string) => {
let url: URL;
try {
const url = new URL(id);
if (url.protocol === "file:") {
const filePath =
path.extname(url.pathname) === ""
? `${url.pathname}.js`
: url.pathname;

return await fs.readFile(pathToFileURL(filePath), "utf-8");
}
url = new URL(id);
} catch (e) {
throw new JspmError(`Unsupported URL ${id} \n ${e.message}`);
}

if (url.protocol === "https:") {
switch (url.protocol) {
case 'file:':
return await fs.readFile(new URL(id), "utf-8");
case 'https:': {
const response = await fetch(id);
return await response.text();
}
} catch (err) {
throw new JspmError(
`\n Unsupported protocol ${id} \n ${err.message} \n`
);
default:
throw new JspmError(`Unsupported protocol ${url.protocol}`);
}
},
};
Expand Down
13 changes: 3 additions & 10 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const preloadOpt: opt = [
];
const integrityOpt: opt = [
"--integrity",
"Add module preloads with integrity attributes to HTML output",
"Add module integrity attributes to the import map",
{ default: false },
];
const cacheOpt: opt = [
Expand All @@ -85,11 +85,6 @@ const rootOpt: opt = [
"URL to treat as server root, i.e. rebase import maps against",
{},
];
const freezeOpt: opt = [
"--freeze",
"Freeze input map dependencies, i.e. do not modify them",
{ default: false },
];
const silentOpt: opt = ["--silent", "Silence all output", { default: false }];
const buildConfigOpt: opt = [
"--config <file>",
Expand Down Expand Up @@ -134,7 +129,6 @@ cli
.option(...preloadOpt)
.option(...integrityOpt)
.option(...compactOpt)
.option(...freezeOpt)
.option(...stdoutOpt)
.example(
(name) => `Link a remote package in importmap.json
Expand Down Expand Up @@ -181,7 +175,6 @@ cli
.option(...preloadOpt)
.option(...integrityOpt)
.option(...compactOpt)
.option(...freezeOpt)
.option(...stdoutOpt)
.example(
(name) => `Install a package
Expand Down Expand Up @@ -236,7 +229,6 @@ cli
.option(...preloadOpt)
.option(...integrityOpt)
.option(...compactOpt)
.option(...freezeOpt)
.option(...stdoutOpt)
.example(
(name) => `
Expand Down Expand Up @@ -265,7 +257,6 @@ cli
.option(...preloadOpt)
.option(...integrityOpt)
.option(...compactOpt)
.option(...freezeOpt)
.option(...stdoutOpt)
.example(
(name) => `
Expand Down Expand Up @@ -293,6 +284,8 @@ Clears the global module fetch cache, for situations where the contents of a dep

cli
.command("build [entry]", "Build the module using importmap")
.option(...resolutionOpt)
.option(...mapOpt)
.option(...buildConfigOpt)
.option(...buildOutputOpt)
.action(wrapCommand(build));
Expand Down
2 changes: 1 addition & 1 deletion src/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ async function handleLocalFile(
generator: Generator
) {
const source = await fs.readFile(resolvedModule.target, { encoding: "utf8" });
const { default: babel } = await import("@babel/core");
const babel = await import("@babel/core");

try {
babel.parse(source);
Expand Down
1 change: 0 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export interface Flags extends BuildFlags {
preload?: boolean | string;
integrity?: boolean;
compact?: boolean;
freeze?: boolean;
silent?: boolean;
cache?: string;
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export async function getGenerator(
defaultProvider: getProvider(flags),
resolutions: getResolutions(flags),
cache: getCacheMode(flags),
freeze: flags.freeze,
integrity: flags.integrity,
commonJS: true, // TODO: only for --local flag
});
}
Expand Down
File renamed without changes.
73 changes: 73 additions & 0 deletions test/integrity.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import assert from "assert";
import {
type Scenario,
mapDirectory,
mapFile,
runScenarios,
} from "./scenarios";

const importMap = await mapFile("test/fixtures/importmap.json");

const scenarios: Scenario[] = [
// The inline improtmap should be linked and the integrity attribute should be added
{
files: importMap,
commands: ["jspm link react -o index.html --integrity"],
validationFn: async (files: Map<string, string>) => {
const html = files.get("index.html");

assert(html.includes("integrity"));
},
},
// The importmap generated should have integrity attribute
{
files: importMap,
commands: ["jspm link --integrity"],
validationFn: async (files: Map<string, string>) => {
const map = JSON.parse(files.get("importmap.json"));
assert(map.integrity);
},
},
// Scenario should detect the provider and add integrity attribute
{
files: await mapFile("test/fixtures/unpkg.importmap.json"),
commands: [
"jspm link -m unpkg.importmap.json -o importmap.json --integrity",
],
validationFn: async (files: Map<string, string>) => {
const map = JSON.parse(files.get("importmap.json"));
assert(map.integrity);
},
},
// Scenario should detect the provider and add integrity attribute
{
files: await mapDirectory("test/fixtures/scenario_provider_swap"),
commands: ["jspm install --provider nodemodules --integrity"],
validationFn: async (files) => {
const map = JSON.parse(files.get("importmap.json"));
assert(map.integrity);
},
},
// Scenario installs package from denoland along with integrity attribute
{
files: new Map(),
commands: ["jspm install denoland:zod --integrity"],
validationFn: async (files) => {
const map = JSON.parse(files.get("importmap.json"));
assert(map.imports.zod.includes("deno.land"));
assert(map.integrity);
},
},
// Scenario installs package from skypack along with integrity attribute
{
files: new Map(),
commands: ["jspm install lit --provider skypack --integrity"],
validationFn: async (files) => {
const map = JSON.parse(files.get("importmap.json"));
assert(map.imports.lit.includes("cdn.skypack.dev"));
assert(map.integrity);
},
},
];

runScenarios(scenarios);
4 changes: 2 additions & 2 deletions test/ownname.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ const scenarios: Scenario[] = [
commands: ["jspm install app"],
validationFn: async (files: Map<string, string>) => {
// Installing the own-name package "app" should result in the version of
// es-module-lexer in the import map being upgraded to 1.3.1, since it's a
// es-module-lexer in the import map being upgraded to 1.5.4, since it's a
// transitive dependency of "./app.js".
const map = JSON.parse(files.get("importmap.json"));
assert(
map?.imports?.["es-module-lexer"]?.includes("es-module-lexer@1.3.1")
map?.imports?.["es-module-lexer"]?.includes("es-module-lexer@1.5.4")
);
},
},
Expand Down
16 changes: 14 additions & 2 deletions test/providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,23 @@ const scenarios: Scenario[] = [
// Scenarios that check we can use each available provider:
const files = await mapDirectory("test/fixtures/scenario_providers");
for (const provider of availableProviders) {
if (provider === "esm.sh") {
/*
Disabling esm.sh provider for now. There is a bug for installing lit.
https://github.com/jspm/generator/issues/335
*/
continue;
}

let spec = "lit";
let name = "lit";
if (provider.includes("deno")) {
spec = "denoland:oak/body.ts"; // deno doesn't support npm packages
name = "oak/body.ts";
// oak is using jsr. We need to add support for jsr registry and imort protocol
// https://github.com/jspm/generator/issues/366
// spec = "denoland:oak/body.ts"; // deno doesn't support npm packages
// name = "oak/body.ts";
spec = "denoland:zod";
name = "zod";
}
if (provider === "node") {
spec = "@jspm/core/nodelibs/fs"; // node provider is only for polyfills
Expand Down
9 changes: 4 additions & 5 deletions test/scenarios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export async function mapDirectory(dir: string): Promise<Files> {
} else {
const subFiles = await mapDirectory(filePath);
for (const [subFile, subData] of subFiles) {
files.set(path.join(file, subFile).replace(/\\/g, '/'), subData);
files.set(path.join(file, subFile).replace(/\\/g, "/"), subData);
}
}
}
Expand Down Expand Up @@ -103,10 +103,9 @@ async function deleteTmpPkg(dir: string) {
try {
await fs.rm(dir, { recursive: true });
return;
}
catch (err) {
if (err.code === 'EBUSY')
await new Promise(resolve => setTimeout(resolve, 10));
} catch (err) {
if (err.code === "EBUSY")
await new Promise((resolve) => setTimeout(resolve, 10));
}
}
} else {
Expand Down

0 comments on commit 78e12b7

Please sign in to comment.