From 0ca4964bc6e4c8e84018bd75ad8eb11bf9dacfd6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 01:03:43 +0000 Subject: [PATCH 1/5] Initial plan From 9cfc088c7a16e196fc978c56808af96efea2144b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 01:05:51 +0000 Subject: [PATCH 2/5] Add npm build test to CI workflow Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com> --- .github/workflows/test.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a86bac4..47742c8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,3 +21,13 @@ jobs: test_target: "*.test.ts" jsr_dependencies: "@std/assert @std/async @cross/runtime" npm_dependencies: "sinon" + npm_build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Deno + uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + - name: Build npm package + run: deno task build:dist From cb8869f123c171ad0ee1793d48fe3c8dee0c0884 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 01:06:50 +0000 Subject: [PATCH 3/5] Add permissions and fix setup-deno version for consistency Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com> --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 47742c8..0f00184 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,10 +23,12 @@ jobs: npm_dependencies: "sinon" npm_build: runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@v4 - name: Setup Deno - uses: denoland/setup-deno@v2 + uses: denoland/setup-deno@v1 with: deno-version: v2.x - name: Build npm package From e42a035d73d3764da55b0ce6b074dcfa4da6baa5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 01:16:51 +0000 Subject: [PATCH 4/5] Fix npm build by adding @cross/runtime to externals and removing CJS build Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com> --- build/build.ts | 41 ++++++++----------------------------- build/package.template.json | 15 ++------------ 2 files changed, 10 insertions(+), 46 deletions(-) diff --git a/build/build.ts b/build/build.ts index 1b8ce59..2dc6480 100644 --- a/build/build.ts +++ b/build/build.ts @@ -1,6 +1,5 @@ import esbuild from "esbuild"; -import { dtsPlugin } from "esbuild-plugin-d.ts"; -import { cp, readFile, writeFile } from "@cross/fs"; +import { readFile, writeFile } from "@cross/fs"; import { dirname, fromFileUrl, resolve } from "@std/path"; /** @@ -68,50 +67,26 @@ if (command === "clean") { /* Handle argument `build`: Transpile and generate typings */ } else if (command === "build") { + // Build the ESM JavaScript bundle await build({ entryPoints: [resolve(relativeProjectRoot, "mod.ts")], bundle: true, minify: true, sourcemap: false, + outdir: resolvedDistPath, + platform: "node", + format: "esm", // Mark runtime-specific modules as external - they won't be bundled // node:test is a Node.js built-in, bun:test is a Bun built-in - external: ["bun:test", "node:test"], + // @cross/runtime is a JSR dependency that must be externalized + external: ["bun:test", "node:test", "@cross/runtime"], // Use banner to add a comment banner: { js: `// @cross/test - Cross-runtime testing for Deno, Bun, and Node.js // This build is for Node.js. For Deno, use JSR: jsr:@cross/test `, }, - }, [ - { - outdir: resolvedDistPath, - platform: "node", - format: "cjs", - outExtension: { ".js": ".cjs" }, - }, - { - outdir: resolvedDistPath, - platform: "node", - format: "esm", - plugins: [dtsPlugin({ - experimentalBundling: true, - tsconfig: { - compilerOptions: { - declaration: true, - emitDeclarationOnly: true, - allowImportingTsExtensions: true, - lib: ["es6", "dom"], - }, - }, - })], - }, - ]); - - // Just re-use the .d.ts for commonjs, as .d.cts - await cp( - resolve(resolvedDistPath, "mod.d.ts"), - resolve(resolvedDistPath, "mod.d.cts"), - ); + }); /* Handle argument `package`: Generate package.json based on a base config and values from deno.json */ } else if (command === "package") { diff --git a/build/package.template.json b/build/package.template.json index 6f1086f..4d00c66 100644 --- a/build/package.template.json +++ b/build/package.template.json @@ -26,21 +26,10 @@ "framework" ], "type": "module", - "main": "./dist/mod.cjs", - "module": "./dist/mod.js", - "types": "./dist/mod.d.ts", + "main": "./dist/mod.js", "exports": { "./package.json": "./package.json", - ".": { - "import": { - "types": "./dist/mod.d.ts", - "default": "./dist/mod.js" - }, - "require": { - "types": "./dist/mod.d.cts", - "default": "./dist/mod.cjs" - } - } + ".": "./dist/mod.js" }, "license": "MIT" } From 41563b6a3cf2473ef3959188b34d5d38eb289d8f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 23:28:36 +0000 Subject: [PATCH 5/5] Bundle @cross/runtime, add npm.ts entry point, and add smoke test to CI Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com> --- .github/workflows/test.yml | 6 ++++++ build/build.ts | 31 ++++++++++++++++++++++++++++--- build/package.template.json | 4 ++-- deno.json | 2 +- npm.ts | 30 ++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 npm.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0f00184..a5488b3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,3 +33,9 @@ jobs: deno-version: v2.x - name: Build npm package run: deno task build:dist + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + - name: Smoke test Node artifact + run: node -e "import('./dist/npm.js')" diff --git a/build/build.ts b/build/build.ts index 2dc6480..75f5c87 100644 --- a/build/build.ts +++ b/build/build.ts @@ -67,9 +67,34 @@ if (command === "clean") { /* Handle argument `build`: Transpile and generate typings */ } else if (command === "build") { + // Plugin to bundle JSR packages like @cross/runtime by resolving them via Deno's cache + const jsrResolverPlugin: esbuild.Plugin = { + name: "jsr-resolver", + setup(pluginBuild) { + pluginBuild.onResolve({ filter: /^@cross\/runtime$/ }, async (_args) => { + const cmd = new Deno.Command("deno", { + args: ["info", "--json", "jsr:@cross/runtime"], + cwd: relativeProjectRoot, + stdout: "piped", + stderr: "piped", + }); + const { stdout, success } = await cmd.output(); + if (!success) return null; + const info = JSON.parse(new TextDecoder().decode(stdout)); + const mod = info.modules?.find((m: { specifier: string; local?: string }) => m.local && m.specifier?.endsWith("mod.ts")); + if (mod?.local) return { path: mod.local, namespace: "jsr-ts" }; + return null; + }); + pluginBuild.onLoad({ filter: /.*/, namespace: "jsr-ts" }, async (args) => { + const contents = await Deno.readTextFile(args.path); + return { contents, loader: "ts" }; + }); + }, + }; + // Build the ESM JavaScript bundle await build({ - entryPoints: [resolve(relativeProjectRoot, "mod.ts")], + entryPoints: [resolve(relativeProjectRoot, "npm.ts")], bundle: true, minify: true, sourcemap: false, @@ -78,8 +103,8 @@ if (command === "clean") { format: "esm", // Mark runtime-specific modules as external - they won't be bundled // node:test is a Node.js built-in, bun:test is a Bun built-in - // @cross/runtime is a JSR dependency that must be externalized - external: ["bun:test", "node:test", "@cross/runtime"], + external: ["bun:test", "node:test"], + plugins: [jsrResolverPlugin], // Use banner to add a comment banner: { js: `// @cross/test - Cross-runtime testing for Deno, Bun, and Node.js diff --git a/build/package.template.json b/build/package.template.json index 4d00c66..8a5b4e7 100644 --- a/build/package.template.json +++ b/build/package.template.json @@ -26,10 +26,10 @@ "framework" ], "type": "module", - "main": "./dist/mod.js", + "main": "./dist/npm.js", "exports": { "./package.json": "./package.json", - ".": "./dist/mod.js" + ".": "./dist/npm.js" }, "license": "MIT" } diff --git a/deno.json b/deno.json index 2a197b6..c0304ff 100644 --- a/deno.json +++ b/deno.json @@ -24,6 +24,6 @@ "sinon": "npm:sinon@~19.0.2" }, "publish": { - "exclude": [".github", "*.test.ts", "build", "dist"] + "exclude": [".github", "*.test.ts", "build", "dist", "npm.ts"] } } diff --git a/npm.ts b/npm.ts new file mode 100644 index 0000000..c96ef61 --- /dev/null +++ b/npm.ts @@ -0,0 +1,30 @@ +// Entry point for the npm (Node.js) build - uses the Node.js shim directly. +// For cross-runtime usage via JSR, use jsr:@cross/test instead. +import type { BrowserTestResult, TestSubject, WrappedTestOptions } from "./mod.ts"; +import { wrappedTest } from "./shims/node.ts"; + +export type { BrowserTestResult, ContextStepFunction, SimpleStepFunction, StepFunction, StepOptions, StepSubject, TestContext, TestSubject, WrappedTest, WrappedTestOptions } from "./mod.ts"; + +/** + * Defines and executes a single test (Node.js). + * @param name - The name of the test. + * @param testFn - The function containing the test logic. + * @param options? - Options for the test. + */ +export async function test(name: string, testFn: TestSubject, options: WrappedTestOptions = {}) { + await wrappedTest(name, testFn, options); +} + +/** + * Not applicable in Node.js - always returns undefined. + */ +export function getTestResults(): BrowserTestResult[] | undefined { + return undefined; +} + +/** + * Not applicable in Node.js - no-op. + */ +export function printTestSummary(): void { + // no-op +}