diff --git a/_packages/tsgo-darwin-arm64/CHANGELOG.md b/_packages/tsgo-darwin-arm64/CHANGELOG.md index dbf3f23a..d043b398 100644 --- a/_packages/tsgo-darwin-arm64/CHANGELOG.md +++ b/_packages/tsgo-darwin-arm64/CHANGELOG.md @@ -1,5 +1,9 @@ # @effect/tsgo-darwin-arm64 +## 0.36.4 + +## 0.36.3 + ## 0.36.2 ## 0.36.1 diff --git a/_packages/tsgo-darwin-arm64/package.json b/_packages/tsgo-darwin-arm64/package.json index be057fbf..2394146b 100644 --- a/_packages/tsgo-darwin-arm64/package.json +++ b/_packages/tsgo-darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@effect/tsgo-darwin-arm64", - "version": "0.36.2", + "version": "0.36.4", "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.", "license": "MIT", "repository": { diff --git a/_packages/tsgo-darwin-x64/CHANGELOG.md b/_packages/tsgo-darwin-x64/CHANGELOG.md index 1da13cb6..760cca23 100644 --- a/_packages/tsgo-darwin-x64/CHANGELOG.md +++ b/_packages/tsgo-darwin-x64/CHANGELOG.md @@ -1,5 +1,9 @@ # @effect/tsgo-darwin-x64 +## 0.36.4 + +## 0.36.3 + ## 0.36.2 ## 0.36.1 diff --git a/_packages/tsgo-darwin-x64/package.json b/_packages/tsgo-darwin-x64/package.json index d691f4d1..a5b6c9e1 100644 --- a/_packages/tsgo-darwin-x64/package.json +++ b/_packages/tsgo-darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@effect/tsgo-darwin-x64", - "version": "0.36.2", + "version": "0.36.4", "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.", "license": "MIT", "repository": { diff --git a/_packages/tsgo-linux-arm/CHANGELOG.md b/_packages/tsgo-linux-arm/CHANGELOG.md index 945a7d64..7f21b730 100644 --- a/_packages/tsgo-linux-arm/CHANGELOG.md +++ b/_packages/tsgo-linux-arm/CHANGELOG.md @@ -1,5 +1,9 @@ # @effect/tsgo-linux-arm +## 0.36.4 + +## 0.36.3 + ## 0.36.2 ## 0.36.1 diff --git a/_packages/tsgo-linux-arm/package.json b/_packages/tsgo-linux-arm/package.json index d0618feb..977f9886 100644 --- a/_packages/tsgo-linux-arm/package.json +++ b/_packages/tsgo-linux-arm/package.json @@ -1,6 +1,6 @@ { "name": "@effect/tsgo-linux-arm", - "version": "0.36.2", + "version": "0.36.4", "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.", "license": "MIT", "repository": { diff --git a/_packages/tsgo-linux-arm64/CHANGELOG.md b/_packages/tsgo-linux-arm64/CHANGELOG.md index cc5093b8..ad7b51ff 100644 --- a/_packages/tsgo-linux-arm64/CHANGELOG.md +++ b/_packages/tsgo-linux-arm64/CHANGELOG.md @@ -1,5 +1,9 @@ # @effect/tsgo-linux-arm64 +## 0.36.4 + +## 0.36.3 + ## 0.36.2 ## 0.36.1 diff --git a/_packages/tsgo-linux-arm64/package.json b/_packages/tsgo-linux-arm64/package.json index 0e4cf9df..38ddca9c 100644 --- a/_packages/tsgo-linux-arm64/package.json +++ b/_packages/tsgo-linux-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@effect/tsgo-linux-arm64", - "version": "0.36.2", + "version": "0.36.4", "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.", "license": "MIT", "repository": { diff --git a/_packages/tsgo-linux-x64/CHANGELOG.md b/_packages/tsgo-linux-x64/CHANGELOG.md index b31027ba..276d50d0 100644 --- a/_packages/tsgo-linux-x64/CHANGELOG.md +++ b/_packages/tsgo-linux-x64/CHANGELOG.md @@ -1,5 +1,9 @@ # @effect/tsgo-linux-x64 +## 0.36.4 + +## 0.36.3 + ## 0.36.2 ## 0.36.1 diff --git a/_packages/tsgo-linux-x64/package.json b/_packages/tsgo-linux-x64/package.json index 4d1cfe8f..478b0eb7 100644 --- a/_packages/tsgo-linux-x64/package.json +++ b/_packages/tsgo-linux-x64/package.json @@ -1,6 +1,6 @@ { "name": "@effect/tsgo-linux-x64", - "version": "0.36.2", + "version": "0.36.4", "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.", "license": "MIT", "repository": { diff --git a/_packages/tsgo-win32-arm64/CHANGELOG.md b/_packages/tsgo-win32-arm64/CHANGELOG.md index 29cf1f58..9db3546e 100644 --- a/_packages/tsgo-win32-arm64/CHANGELOG.md +++ b/_packages/tsgo-win32-arm64/CHANGELOG.md @@ -1,5 +1,9 @@ # @effect/tsgo-win32-arm64 +## 0.36.4 + +## 0.36.3 + ## 0.36.2 ## 0.36.1 diff --git a/_packages/tsgo-win32-arm64/package.json b/_packages/tsgo-win32-arm64/package.json index 8bb16cf0..3f112fe1 100644 --- a/_packages/tsgo-win32-arm64/package.json +++ b/_packages/tsgo-win32-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@effect/tsgo-win32-arm64", - "version": "0.36.2", + "version": "0.36.4", "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.", "license": "MIT", "repository": { diff --git a/_packages/tsgo-win32-x64/CHANGELOG.md b/_packages/tsgo-win32-x64/CHANGELOG.md index 101e89b7..90d54829 100644 --- a/_packages/tsgo-win32-x64/CHANGELOG.md +++ b/_packages/tsgo-win32-x64/CHANGELOG.md @@ -1,5 +1,9 @@ # @effect/tsgo-win32-x64 +## 0.36.4 + +## 0.36.3 + ## 0.36.2 ## 0.36.1 diff --git a/_packages/tsgo-win32-x64/package.json b/_packages/tsgo-win32-x64/package.json index 7ff0bfaa..83f2ebaf 100644 --- a/_packages/tsgo-win32-x64/package.json +++ b/_packages/tsgo-win32-x64/package.json @@ -1,6 +1,6 @@ { "name": "@effect/tsgo-win32-x64", - "version": "0.36.2", + "version": "0.36.4", "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.", "license": "MIT", "repository": { diff --git a/_packages/tsgo/CHANGELOG.md b/_packages/tsgo/CHANGELOG.md index f2d74841..71487b0b 100644 --- a/_packages/tsgo/CHANGELOG.md +++ b/_packages/tsgo/CHANGELOG.md @@ -1,5 +1,18 @@ # @effect/tsgo +## 0.36.4 + +### Patch Changes + +- 7a616ec: Allow declaration emit with `noEmitOnError` when all diagnostics are ignored Effect diagnostics. + +## 0.36.3 + +### Patch Changes + +- 73f7f28: Refresh patched binaries when an updated `@effect/tsgo` package provides a different replacement artifact. +- 9190801: Update Effect v4 dependencies and embedded test fixtures to `4.0.0-beta.107`. + ## 0.36.2 ### Patch Changes diff --git a/_packages/tsgo/package.json b/_packages/tsgo/package.json index 2c8833f4..74ed4bec 100644 --- a/_packages/tsgo/package.json +++ b/_packages/tsgo/package.json @@ -1,6 +1,6 @@ { "name": "@effect/tsgo", - "version": "0.36.2", + "version": "0.36.4", "type": "module", "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.", "license": "MIT", @@ -58,12 +58,12 @@ "@effect/tsgo-darwin-arm64": "workspace:*" }, "devDependencies": { - "@effect/platform-node": "^4.0.0-beta.104", - "@effect/platform-node-shared": "^4.0.0-beta.104", + "@effect/platform-node": "^4.0.0-beta.107", + "@effect/platform-node-shared": "^4.0.0-beta.107", "@types/node": "^24.3.0", "tsdown": "^0.20.1", "typescript": "^5.9.2", - "effect": "^4.0.0-beta.104", + "effect": "^4.0.0-beta.107", "vitest": "^3.2.1" } } diff --git a/_packages/tsgo/src/patcher/discovery.ts b/_packages/tsgo/src/patcher/discovery.ts index 5ca2db98..f7239b18 100644 --- a/_packages/tsgo/src/patcher/discovery.ts +++ b/_packages/tsgo/src/patcher/discovery.ts @@ -3,6 +3,7 @@ import * as Data from "effect/Data" import * as Effect from "effect/Effect" import * as FileSystem from "effect/FileSystem" import * as Path from "effect/Path" +import { hashFile } from "./fileHash.js" import type { Component, DiscoveredBinary } from "./types.js" export const defaultTypescriptPackageNames = ["typescript", "@typescript/native"] as const @@ -19,6 +20,8 @@ interface PackageMetadata { readonly main?: string } +type DiscoveredBinaryLocation = Omit + const isNativeTypescriptVersion = (version: string) => { const match = /\d+/.exec(version.trim()) return match !== null && Number(match[0]) >= 7 @@ -82,7 +85,7 @@ export const experimentalOxlintTarget = (platform: NodeJS.Platform, arch: string const discoverTypeScript: ( cwdRequire: NodeJS.Require, preferredPackage?: string -) => Effect.Effect = ( +) => Effect.Effect = ( cwdRequire, preferredPackage ) => Effect.gen(function*() { @@ -102,14 +105,14 @@ const discoverTypeScript: ( packageName: platformPackageName, packageVersion: platformPackage.version, binaryPath: path.join(path.dirname(platformPackage.packageJsonPath), "lib", binaryName) - } satisfies DiscoveredBinary] + } satisfies DiscoveredBinaryLocation] } return [] }) const discoverOxlint: ( cwdRequire: NodeJS.Require -) => Effect.Effect = (cwdRequire) => +) => Effect.Effect = (cwdRequire) => Effect.gen(function*() { const path = yield* Path.Path const oxlint = yield* optionally(readPackage(cwdRequire, "oxlint")) @@ -121,7 +124,7 @@ const discoverOxlint: ( ? error : new DiscoveryError({ reason: "Unable to determine the Oxlint platform target." }) }) - const discovered: Array = [] + const discovered: Array = [] if (oxlint !== undefined) { const binding = yield* readPackage(nodeModule.createRequire(oxlint.packageJsonPath), target.oxlintPackage) if (binding.main === undefined) { @@ -157,7 +160,7 @@ const discoverOxlint: ( const discoverVitePlusOxlint: ( cwdRequire: NodeJS.Require -) => Effect.Effect = (cwdRequire) => +) => Effect.Effect = (cwdRequire) => Effect.gen(function*() { const vitePlus = yield* optionally(readPackage(cwdRequire, "vite-plus")) if (vitePlus === undefined) return [] @@ -170,9 +173,13 @@ export const discoverBinaries = (cwd: string, preferredTypescriptPackage?: strin const typescript = yield* discoverTypeScript(cwdRequire, preferredTypescriptPackage) const oxlint = yield* discoverOxlint(cwdRequire) const vitePlusOxlint = yield* discoverVitePlusOxlint(cwdRequire) - return [...new Map( + const discovered = [...new Map( [...typescript, ...oxlint, ...vitePlusOxlint].map((binary) => [binary.binaryPath, binary]) ).values()] + return yield* Effect.forEach(discovered, (binary) => hashFile(binary.binaryPath).pipe( + Effect.map((fileHash) => ({ ...binary, fileHash })), + Effect.mapError(() => new DiscoveryError({ reason: `Unable to read discovered binary ${binary.binaryPath}.` })) + )) }) export const selectComponents = ( diff --git a/_packages/tsgo/src/patcher/fileHash.ts b/_packages/tsgo/src/patcher/fileHash.ts new file mode 100644 index 00000000..4918df89 --- /dev/null +++ b/_packages/tsgo/src/patcher/fileHash.ts @@ -0,0 +1,17 @@ +import * as Crypto from "effect/Crypto" +import * as Effect from "effect/Effect" +import * as Encoding from "effect/Encoding" +import * as FileSystem from "effect/FileSystem" + +const textEncoder = new TextEncoder() + +export const hashBytes = (contents: string | Uint8Array) => Effect.gen(function*() { + const crypto = yield* Crypto.Crypto + const digest = yield* crypto.digest("SHA-256", typeof contents === "string" ? textEncoder.encode(contents) : contents) + return Encoding.encodeHex(digest) +}) + +export const hashFile = (filePath: string) => Effect.gen(function*() { + const fs = yield* FileSystem.FileSystem + return yield* hashBytes(yield* fs.readFile(filePath)) +}) diff --git a/_packages/tsgo/src/patcher/index.ts b/_packages/tsgo/src/patcher/index.ts index ad327671..ef97a372 100644 --- a/_packages/tsgo/src/patcher/index.ts +++ b/_packages/tsgo/src/patcher/index.ts @@ -1,5 +1,6 @@ import { randomUUID } from "node:crypto" import * as nodeModule from "node:module" +import * as Crypto from "effect/Crypto" import * as Data from "effect/Data" import * as Effect from "effect/Effect" import * as FileSystem from "effect/FileSystem" @@ -7,6 +8,7 @@ import * as Path from "effect/Path" import * as Scope from "effect/Scope" import metadataJson from "../metadata.json" with { type: "json" } import { discoverBinaries, requireComponents, selectComponents } from "./discovery.js" +import { hashBytes, hashFile } from "./fileHash.js" import type { Component, DiscoveredBinary, @@ -40,6 +42,7 @@ const exists = (fs: FileSystem.FileSystem, filePath: string) => fs.exists(filePa export interface ResolvedReplacement { readonly path: string + readonly fileHash: string } export type ReplacementResolver = ( @@ -47,7 +50,7 @@ export type ReplacementResolver = ( ) => Effect.Effect< ResolvedReplacement, PatcherError | ReplacementUnavailableError, - FileSystem.FileSystem | Path.Path | Scope.Scope + Crypto.Crypto | FileSystem.FileSystem | Path.Path | Scope.Scope > const toKebabCase = (value: string): string => { @@ -96,9 +99,11 @@ export const renderOxlintDeclarations = (source: string): string => { const resolveOxlintDeclarations = (target: DiscoveredBinary) => Effect.gen(function*() { const fs = yield* FileSystem.FileSystem const path = yield* Path.Path - const source = yield* fs.readFileString(target.binaryPath).pipe( + const backupPath = `${target.binaryPath}.original` + const sourcePath = (yield* exists(fs, backupPath)) ? backupPath : target.binaryPath + const source = yield* fs.readFileString(sourcePath).pipe( Effect.mapError((error) => new PatcherError({ - reason: `Unable to read Oxlint declarations at ${target.binaryPath}: ${error.message}` + reason: `Unable to read Oxlint declarations at ${sourcePath}: ${error.message}` })) ) const replacement = yield* Effect.try({ @@ -117,7 +122,12 @@ const resolveOxlintDeclarations = (target: DiscoveredBinary) => Effect.gen(funct reason: `Unable to write generated Oxlint declarations at ${replacementPath}: ${error.message}` })) ) - return { path: replacementPath } + const fileHash = yield* hashBytes(replacement).pipe( + Effect.mapError((error) => new PatcherError({ + reason: `Unable to hash generated Oxlint declarations: ${error.message}` + })) + ) + return { path: replacementPath, fileHash } }) const resolvePlatformPackage = (target: DiscoveredBinary) => Effect.gen(function*() { @@ -152,7 +162,12 @@ export const resolveReplacement: ReplacementResolver = (target) => Effect.gen(fu reason: `Missing packaged artifact ${replacementPath}.` }) } - return { path: replacementPath } + const fileHash = yield* hashFile(replacementPath).pipe( + Effect.mapError((error) => new PatcherError({ + reason: `Unable to hash packaged artifact ${replacementPath}: ${error.message}` + })) + ) + return { path: replacementPath, fileHash } }) export interface PreparePatchOptions { @@ -169,8 +184,13 @@ export const preparePatch = ( const fs = yield* FileSystem.FileSystem const resolver = options.resolveReplacement ?? resolveReplacement const operations: Array = [] + const cleanup: Array = [] const skipped: Array = [] - const available: Array<{ readonly target: DiscoveredBinary; readonly replacementPath: string }> = [] + const available: Array<{ + readonly target: DiscoveredBinary + readonly replacementPath: string + readonly backupExists: boolean + }> = [] for (const target of targets) { const backupPath = `${target.binaryPath}.original` @@ -179,14 +199,6 @@ export const preparePatch = ( if (!targetExists) { return yield* new PatcherError({ reason: `Installed binary does not exist: ${target.binaryPath}` }) } - if (backupExists) { - skipped.push({ - target, - reason: "already-patched", - message: `${target.component} skipped because backup already exists at ${backupPath}.` - }) - continue - } const replacement = yield* resolver(target).pipe( Effect.catchTag("ReplacementUnavailableError", (error) => { if (!options.skipMissing) return Effect.fail(error) @@ -195,12 +207,26 @@ export const preparePatch = ( }) ) if (replacement === undefined) continue - available.push({ target, replacementPath: replacement.path }) + if (backupExists && target.fileHash === replacement.fileHash) { + skipped.push({ + target, + reason: "already-patched", + message: `${target.component} skipped because its hash matches the replacement.` + }) + continue + } + available.push({ target, replacementPath: replacement.path, backupExists }) } - for (const { replacementPath, target } of available) { + for (const { backupExists, replacementPath, target } of available) { const backupPath = `${target.binaryPath}.original` - operations.push({ _tag: "Rename", sourcePath: target.binaryPath, destinationPath: backupPath }) + if (backupExists) { + const quarantinePath = `${target.binaryPath}.${randomUUID()}.patched` + operations.push({ _tag: "Rename", sourcePath: target.binaryPath, destinationPath: quarantinePath }) + cleanup.push({ _tag: "Remove", path: quarantinePath }) + } else { + operations.push({ _tag: "Rename", sourcePath: target.binaryPath, destinationPath: backupPath }) + } operations.push({ _tag: "Copy", sourcePath: replacementPath, @@ -211,7 +237,7 @@ export const preparePatch = ( } } - return { operations, cleanup: [], skipped } satisfies PreparedPatch + return { operations, cleanup, skipped } satisfies PreparedPatch }) export const prepareUnpatch = (targets: ReadonlyArray) => Effect.gen(function*() { diff --git a/_packages/tsgo/src/patcher/types.ts b/_packages/tsgo/src/patcher/types.ts index d98e03a4..b4d510f2 100644 --- a/_packages/tsgo/src/patcher/types.ts +++ b/_packages/tsgo/src/patcher/types.ts @@ -5,6 +5,7 @@ export interface DiscoveredBinary { readonly packageName: string readonly packageVersion: string readonly binaryPath: string + readonly fileHash: string } export type FileSystemOperation = RenameOperation | CopyOperation | ChmodOperation | RemoveOperation diff --git a/_packages/tsgo/test/experimental-oxlint.test.ts b/_packages/tsgo/test/experimental-oxlint.test.ts index 6483f45c..2d2dd95a 100644 --- a/_packages/tsgo/test/experimental-oxlint.test.ts +++ b/_packages/tsgo/test/experimental-oxlint.test.ts @@ -1,13 +1,16 @@ import * as NodeServices from "@effect/platform-node/NodeServices" import * as Effect from "effect/Effect" +import { createHash } from "node:crypto" import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises" import { tmpdir } from "node:os" -import { join } from "node:path" +import { dirname, join } from "node:path" import { afterEach, describe, expect, it } from "vitest" import { discoverBinaries, experimentalOxlintTarget } from "../src/patcher/index.js" const temporaryDirectories: Array = [] +const hash = (value: string) => createHash("sha256").update(value).digest("hex") + const makeTemporaryDirectory = async () => { const directory = await mkdtemp(join(tmpdir(), "effect-tsgo-oxlint-")) temporaryDirectories.push(directory) @@ -21,6 +24,11 @@ const writePackage = async (directory: string, packageName: string, packageJson: return packageDirectory } +const writeBinary = async (filePath: string, contents: string) => { + await mkdir(dirname(filePath), { recursive: true }) + await writeFile(filePath, contents) +} + afterEach(async () => { await Promise.all(temporaryDirectories.splice(0).map((directory) => rm(directory, { recursive: true, force: true }))) }) @@ -53,6 +61,11 @@ describe("experimental Oxlint discovery", () => { main: "oxlint.node" }) const tsgolintDirectory = await writePackage(directory, platform.tsgolintPackage, { version: "2.0.1" }) + await Promise.all([ + writeBinary(join(bindingDirectory, "oxlint.node"), "oxlint"), + writeBinary(join(oxlintDirectory, "dist", "index.d.ts"), "declarations"), + writeBinary(join(tsgolintDirectory, platform.tsgolintExecutable), "tsgolint") + ]) const discovered = await Effect.runPromise( discoverBinaries(directory).pipe(Effect.provide(NodeServices.layer)) @@ -62,19 +75,22 @@ describe("experimental Oxlint discovery", () => { component: "oxlint", packageName: platform.oxlintPackage, packageVersion: "1.0.1", - binaryPath: join(bindingDirectory, "oxlint.node") + binaryPath: join(bindingDirectory, "oxlint.node"), + fileHash: hash("oxlint") }, { component: "oxlint-dts", packageName: "oxlint", packageVersion: "1.0.0", - binaryPath: join(oxlintDirectory, "dist", "index.d.ts") + binaryPath: join(oxlintDirectory, "dist", "index.d.ts"), + fileHash: hash("declarations") }, { component: "oxlint-tsgolint", packageName: platform.tsgolintPackage, packageVersion: "2.0.1", - binaryPath: join(tsgolintDirectory, platform.tsgolintExecutable) + binaryPath: join(tsgolintDirectory, platform.tsgolintExecutable), + fileHash: hash("tsgolint") } ]) }) @@ -84,6 +100,8 @@ describe("experimental Oxlint discovery", () => { await writePackage(directory, "typescript", { version: "7.0.0" }) const platformPackage = `@typescript/typescript-${process.platform}-${process.arch}` const platformDirectory = await writePackage(directory, platformPackage, { version: "7.0.1" }) + const binaryPath = join(platformDirectory, "lib", process.platform === "win32" ? "tsc.exe" : "tsc") + await writeBinary(binaryPath, "typescript") const discovered = await Effect.runPromise( discoverBinaries(directory).pipe(Effect.provide(NodeServices.layer)) @@ -92,7 +110,8 @@ describe("experimental Oxlint discovery", () => { component: "typescript", packageName: platformPackage, packageVersion: "7.0.1", - binaryPath: join(platformDirectory, "lib", process.platform === "win32" ? "tsc.exe" : "tsc") + binaryPath, + fileHash: hash("typescript") }) }) @@ -111,6 +130,11 @@ describe("experimental Oxlint discovery", () => { platform.tsgolintPackage, { version: "2.0.1" } ) + await Promise.all([ + writeBinary(join(bindingDirectory, "oxlint.node"), "oxlint"), + writeBinary(join(oxlintDirectory, "dist", "index.d.ts"), "declarations"), + writeBinary(join(tsgolintDirectory, platform.tsgolintExecutable), "tsgolint") + ]) const discovered = await Effect.runPromise( discoverBinaries(directory).pipe(Effect.provide(NodeServices.layer)) @@ -120,19 +144,22 @@ describe("experimental Oxlint discovery", () => { component: "oxlint", packageName: platform.oxlintPackage, packageVersion: "1.0.1", - binaryPath: join(bindingDirectory, "oxlint.node") + binaryPath: join(bindingDirectory, "oxlint.node"), + fileHash: hash("oxlint") }, { component: "oxlint-dts", packageName: "oxlint", packageVersion: "1.0.0", - binaryPath: join(oxlintDirectory, "dist", "index.d.ts") + binaryPath: join(oxlintDirectory, "dist", "index.d.ts"), + fileHash: hash("declarations") }, { component: "oxlint-tsgolint", packageName: platform.tsgolintPackage, packageVersion: "2.0.1", - binaryPath: join(tsgolintDirectory, platform.tsgolintExecutable) + binaryPath: join(tsgolintDirectory, platform.tsgolintExecutable), + fileHash: hash("tsgolint") } ]) }) diff --git a/_packages/tsgo/test/patcher.test.ts b/_packages/tsgo/test/patcher.test.ts index e4fc7ecc..0a94c29a 100644 --- a/_packages/tsgo/test/patcher.test.ts +++ b/_packages/tsgo/test/patcher.test.ts @@ -1,8 +1,10 @@ import * as NodeServices from "@effect/platform-node/NodeServices" +import * as Crypto from "effect/Crypto" import * as Effect from "effect/Effect" import * as FileSystem from "effect/FileSystem" import * as Path from "effect/Path" import * as Scope from "effect/Scope" +import { createHash } from "node:crypto" import { access, mkdir, mkdtemp, readFile, readdir, rm, writeFile } from "node:fs/promises" import { tmpdir } from "node:os" import { join } from "node:path" @@ -20,13 +22,15 @@ import { const temporaryDirectories: Array = [] +const hash = (value: string) => createHash("sha256").update(value).digest("hex") + const makeTemporaryDirectory = async () => { const directory = await mkdtemp(join(tmpdir(), "effect-tsgo-patcher-")) temporaryDirectories.push(directory) return directory } -const run = (effect: Effect.Effect) => +const run = (effect: Effect.Effect) => Effect.runPromise(Effect.scoped(effect).pipe(Effect.provide(NodeServices.layer))) afterEach(async () => { @@ -47,14 +51,27 @@ describe("patcher", () => { writeFile(secondReplacement, "second-effect") ]) const targets: ReadonlyArray = [ - { component: "oxlint-dts", packageName: "oxlint", packageVersion: "1", binaryPath: first }, - { component: "oxlint-tsgolint", packageName: "oxlint-tsgolint", packageVersion: "2", binaryPath: second } + { + component: "oxlint-dts", + packageName: "oxlint", + packageVersion: "1", + binaryPath: first, + fileHash: hash("first") + }, + { + component: "oxlint-tsgolint", + packageName: "oxlint-tsgolint", + packageVersion: "2", + binaryPath: second, + fileHash: hash("second") + } ] const plan = await run(preparePatch(targets, { skipMissing: false, resolveReplacement: (target) => Effect.succeed({ - path: target.component === "oxlint-dts" ? firstReplacement : secondReplacement + path: target.component === "oxlint-dts" ? firstReplacement : secondReplacement, + fileHash: hash(target.component === "oxlint-dts" ? "first-effect" : "second-effect") }) })) expect(plan.operations).toEqual([ @@ -69,19 +86,21 @@ describe("patcher", () => { it("generates an Oxlint declaration replacement in the temporary directory", async () => { const directory = await makeTemporaryDirectory() const declarationPath = join(directory, "index.d.ts") - await writeFile(declarationPath, [ + const declarations = [ 'type LintPluginOptionsSchema = "eslint" | "typescript";', "type RuleNoConfig = unknown;", "interface DummyRuleMap {", ' "eslint/no-unused-vars"?: RuleNoConfig;', "}", "" - ].join("\n")) + ].join("\n") + await writeFile(declarationPath, declarations) const target: DiscoveredBinary = { component: "oxlint-dts", packageName: "oxlint", packageVersion: "1.0.0", - binaryPath: declarationPath + binaryPath: declarationPath, + fileHash: hash(await readFile(declarationPath, "utf8")) } const replacement = await run(Effect.gen(function*() { @@ -96,6 +115,15 @@ describe("patcher", () => { expect(replacement.source).toContain('"effecttsgo/floating-effect"?: RuleNoConfig;') expect(replacement.source).toContain('"eslint/no-unused-vars"?: RuleNoConfig;') await expect(access(replacement.path)).rejects.toThrow() + + await writeFile(`${declarationPath}.original`, declarations) + await writeFile(declarationPath, replacement.source) + const refreshed = await run(Effect.gen(function*() { + const fs = yield* FileSystem.FileSystem + const resolved = yield* resolveReplacement(target) + return yield* fs.readFileString(resolved.path) + })) + expect(refreshed).toBe(replacement.source) }) it("rejects declarations whose expected anchors changed", () => { @@ -120,7 +148,7 @@ describe("patcher", () => { await expect(access(`${target}.original`)).rejects.toThrow() }) - it("treats the persisted original backup as already patched", async () => { + it("refreshes a stale patch while preserving the original backup", async () => { const directory = await makeTemporaryDirectory() const targetPath = join(directory, "binary") const replacementPath = join(directory, "replacement") @@ -131,18 +159,45 @@ describe("patcher", () => { component: "oxlint-tsgolint", packageName: "oxlint-tsgolint", packageVersion: "1", - binaryPath: targetPath + binaryPath: targetPath, + fileHash: hash("patched") + } + const plan = await run(preparePatch([target], { + skipMissing: false, + resolveReplacement: () => Effect.succeed({ path: replacementPath, fileHash: hash("replacement") }) + })) + expect(plan.operations.map(({ _tag }) => _tag)).toEqual(["Rename", "Copy", "Chmod"]) + expect(plan.cleanup).toHaveLength(1) + expect(plan.skipped).toEqual([]) + await run(applyPlan(plan)) + expect(await readFile(targetPath, "utf8")).toBe("replacement") + expect(await readFile(`${targetPath}.original`, "utf8")).toBe("original") + expect((await readdir(directory)).filter((name) => name.endsWith(".patched"))).toEqual([]) + }) + + it("skips a patch whose target already matches the replacement", async () => { + const directory = await makeTemporaryDirectory() + const targetPath = join(directory, "binary") + const replacementPath = join(directory, "replacement") + await writeFile(targetPath, "replacement") + await writeFile(`${targetPath}.original`, "original") + await writeFile(replacementPath, "replacement") + const target: DiscoveredBinary = { + component: "oxlint-tsgolint", + packageName: "oxlint-tsgolint", + packageVersion: "1", + binaryPath: targetPath, + fileHash: hash("replacement") } const plan = await run(preparePatch([target], { skipMissing: false, - resolveReplacement: () => Effect.succeed({ path: replacementPath }) + resolveReplacement: () => Effect.succeed({ path: replacementPath, fileHash: hash("replacement") }) })) expect(plan.operations).toEqual([]) expect(plan.skipped[0]?.reason).toBe("already-patched") expect(plan.skipped[0]?.message).toBe( - `oxlint-tsgolint skipped because backup already exists at ${targetPath}.original.` + `oxlint-tsgolint skipped because its hash matches the replacement.` ) - await expect(access(`${targetPath}.original.1`)).rejects.toThrow() }) it("rolls back prior reversible operations when mutation fails", async () => { @@ -170,7 +225,8 @@ describe("patcher", () => { component: "typescript", packageName: "typescript", packageVersion: "7.0.0", - binaryPath: targetPath + binaryPath: targetPath, + fileHash: hash("patched") } await writeFile(targetPath, "patched") await writeFile(`${targetPath}.original`, "original") @@ -190,7 +246,8 @@ describe("patcher", () => { component: "oxlint", packageName: "oxlint", packageVersion: "missing", - binaryPath: targetPath + binaryPath: targetPath, + fileHash: hash("original") } const unavailable = () => Effect.fail(new ReplacementUnavailableError({ target, reason: "not packaged" })) const plan = await run(preparePatch([target], { diff --git a/_packages/tsgo/upstream.json b/_packages/tsgo/upstream.json index 33629f44..6e80d066 100644 --- a/_packages/tsgo/upstream.json +++ b/_packages/tsgo/upstream.json @@ -3,10 +3,10 @@ "tags": { "typescript": { "latest": "7.0.2", - "next": "7.1.0-dev.20260808.1" + "next": "7.1.0-dev.20260810.1" }, "oxlint": { - "latest": "1.77.0" + "latest": "1.78.0" }, "oxlint-tsgolint": { "latest": "7.0.2001" @@ -17,7 +17,7 @@ "7.0.2": { "gitHead": "2bd066d87f5bafd315be9f40889d0a60b9e58e0b" }, - "7.1.0-dev.20260808.1": { + "7.1.0-dev.20260810.1": { "gitHead": "24fabe95acba758c05fcb349bf427a3a0c8ad676" } }, @@ -33,8 +33,8 @@ "1.76.0": { "gitHead": "65fe65d8429e1d1bdf86c517ff08bd119ee87660" }, - "1.77.0": { - "gitHead": "9a423f2f485b79c2353c49442c0c7f60f900261d" + "1.78.0": { + "gitHead": "c42d6397eab5b2d5bb2bd6746c57bc2a9cad21bd" } } }, diff --git a/_patches/typescript-go/009-execute-tsc-emit.patch b/_patches/typescript-go/009-execute-tsc-emit.patch index fc7df1a2..913f69ab 100644 --- a/_patches/typescript-go/009-execute-tsc-emit.patch +++ b/_patches/typescript-go/009-execute-tsc-emit.patch @@ -67,3 +67,33 @@ index 3a1e3de69..8cb7c24c0 100644 result.Status = ExitStatusDiagnosticsPresent_OutputsGenerated } return result, statistics +diff --git a/internal/compiler/program.go b/internal/compiler/program.go +--- a/internal/compiler/program.go ++++ b/internal/compiler/program.go +@@ -30,6 +30,16 @@ import ( + "github.com/microsoft/typescript-go/internal/tracing" + "github.com/microsoft/typescript-go/internal/tsoptions" + "github.com/microsoft/typescript-go/internal/tspath" + ) + ++// FilterDiagnosticsForNoEmitOnErrorCallback is invoked before diagnostics ++// suppress emit when noEmitOnError is enabled. ++var FilterDiagnosticsForNoEmitOnErrorCallback func(*core.CompilerOptions, []*ast.Diagnostic) []*ast.Diagnostic ++ ++// RegisterFilterDiagnosticsForNoEmitOnErrorCallback registers a callback to ++// filter diagnostics used by noEmitOnError. ++func RegisterFilterDiagnosticsForNoEmitOnErrorCallback(cb func(*core.CompilerOptions, []*ast.Diagnostic) []*ast.Diagnostic) { ++ FilterDiagnosticsForNoEmitOnErrorCallback = cb ++} ++ + type ProgramOptions struct { +@@ -1743,6 +1753,9 @@ func HandleNoEmitOnError(ctx context.Context, program ProgramLike, file *ast.Sou + program.GetBindDiagnostics, + program.GetSemanticDiagnostics, + ) ++ if FilterDiagnosticsForNoEmitOnErrorCallback != nil { ++ diagnostics = FilterDiagnosticsForNoEmitOnErrorCallback(program.Options(), diagnostics) ++ } + if len(diagnostics) == 0 { + return nil // No diagnostics, so we can proceed with emitting + } diff --git a/_tools/oxlint-configuration-base-schema.json b/_tools/oxlint-configuration-base-schema.json index 022feed3..a37652d8 100644 --- a/_tools/oxlint-configuration-base-schema.json +++ b/_tools/oxlint-configuration-base-schema.json @@ -672,6 +672,21 @@ }, "additionalProperties": false }, + "AnchorHasContentConfig": { + "type": "object", + "properties": { + "components": { + "description": "Additional custom component names to treat as anchor elements.", + "default": [], + "type": "array", + "items": { + "type": "string" + }, + "markdownDescription": "Additional custom component names to treat as anchor elements." + } + }, + "additionalProperties": false + }, "AnchorIsValidAspect": { "type": "string", "enum": [ @@ -2034,6 +2049,15 @@ }, "additionalProperties": false }, + "DescriptionFormatConfig": { + "type": "object", + "properties": { + "descriptionFormat": { + "type": "string" + } + }, + "additionalProperties": false + }, "Destructure": { "oneOf": [ { @@ -2091,13 +2115,7 @@ "$ref": "#/definitions/RequireDescription" }, { - "type": "object", - "properties": { - "descriptionFormat": { - "type": "string" - } - }, - "additionalProperties": false + "$ref": "#/definitions/DescriptionFormatConfig" } ] }, @@ -3563,6 +3581,26 @@ "jsdoc/implements-on-classes": { "$ref": "#/definitions/RuleNoConfig" }, + "jsdoc/no-blank-blocks": { + "anyOf": [ + { + "$ref": "#/definitions/RuleNoConfig" + }, + { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "$ref": "#/definitions/NoBlankBlocks" + } + ], + "maxItems": 2, + "minItems": 2 + } + ] + }, "jsdoc/no-defaults": { "anyOf": [ { @@ -3757,7 +3795,24 @@ ] }, "jsx-a11y/anchor-has-content": { - "$ref": "#/definitions/RuleNoConfig" + "anyOf": [ + { + "$ref": "#/definitions/RuleNoConfig" + }, + { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "$ref": "#/definitions/AnchorHasContentConfig" + } + ], + "maxItems": 2, + "minItems": 2 + } + ] }, "jsx-a11y/anchor-is-valid": { "anyOf": [ @@ -5850,6 +5905,26 @@ } ] }, + "one-var": { + "anyOf": [ + { + "$ref": "#/definitions/RuleNoConfig" + }, + { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "$ref": "#/definitions/OneVar" + } + ], + "maxItems": 2, + "minItems": 2 + } + ] + }, "operator-assignment": { "anyOf": [ { @@ -13715,6 +13790,18 @@ }, "additionalProperties": false }, + "NoBlankBlocks": { + "type": "object", + "properties": { + "enableFixer": { + "description": "Whether to automatically remove blank JSDoc blocks.", + "default": false, + "type": "boolean", + "markdownDescription": "Whether to automatically remove blank JSDoc blocks." + } + }, + "additionalProperties": false + }, "NoCallbackInPromiseConfig": { "type": "object", "properties": { @@ -16584,6 +16671,153 @@ } ] }, + "OneVar": { + "description": "Enforces consistent grouping of variable declarations.", + "allOf": [ + { + "$ref": "#/definitions/OneVarConfig" + } + ], + "markdownDescription": "Enforces consistent grouping of variable declarations." + }, + "OneVarConfig": { + "description": "Configuration accepted by the `one-var` rule.", + "anyOf": [ + { + "description": "Applies one grouping mode to every declaration kind and initialization state.", + "allOf": [ + { + "$ref": "#/definitions/OneVarMode" + } + ], + "markdownDescription": "Applies one grouping mode to every declaration kind and initialization state." + }, + { + "description": "Configures grouping by declaration kind or initialization state.", + "allOf": [ + { + "$ref": "#/definitions/OneVarOptions" + } + ], + "markdownDescription": "Configures grouping by declaration kind or initialization state." + } + ], + "markdownDescription": "Configuration accepted by the `one-var` rule." + }, + "OneVarMode": { + "description": "Controls how variable declarators are grouped into declarations.", + "oneOf": [ + { + "description": "Requires one declaration per variable kind in each applicable scope.", + "type": "string", + "enum": [ + "always" + ], + "markdownDescription": "Requires one declaration per variable kind in each applicable scope." + }, + { + "description": "Requires each declarator to have its own declaration statement.", + "type": "string", + "enum": [ + "never" + ], + "markdownDescription": "Requires each declarator to have its own declaration statement." + }, + { + "description": "Requires adjacent declarations of the same kind to be combined.", + "type": "string", + "enum": [ + "consecutive" + ], + "markdownDescription": "Requires adjacent declarations of the same kind to be combined." + } + ], + "markdownDescription": "Controls how variable declarators are grouped into declarations." + }, + "OneVarOptions": { + "description": "Options for configuring declaration grouping by kind or initialization state.\n\n`initialized` and `uninitialized` take precedence over the per-kind option for the\ncorresponding declarators.", + "type": "object", + "properties": { + "awaitUsing": { + "description": "Controls grouping for `await using` declarations.", + "default": null, + "allOf": [ + { + "$ref": "#/definitions/OneVarMode" + } + ], + "markdownDescription": "Controls grouping for `await using` declarations." + }, + "const": { + "description": "Controls grouping for `const` declarations.", + "default": null, + "allOf": [ + { + "$ref": "#/definitions/OneVarMode" + } + ], + "markdownDescription": "Controls grouping for `const` declarations." + }, + "initialized": { + "description": "Controls grouping for initialized declarators, overriding per-kind options.", + "default": null, + "allOf": [ + { + "$ref": "#/definitions/OneVarMode" + } + ], + "markdownDescription": "Controls grouping for initialized declarators, overriding per-kind options." + }, + "let": { + "description": "Controls grouping for `let` declarations.", + "default": null, + "allOf": [ + { + "$ref": "#/definitions/OneVarMode" + } + ], + "markdownDescription": "Controls grouping for `let` declarations." + }, + "separateRequires": { + "description": "Keeps direct `require(...)` initializers separate from other initialized declarations.", + "default": false, + "type": "boolean", + "markdownDescription": "Keeps direct `require(...)` initializers separate from other initialized declarations." + }, + "uninitialized": { + "description": "Controls grouping for uninitialized declarators, overriding per-kind options.", + "default": null, + "allOf": [ + { + "$ref": "#/definitions/OneVarMode" + } + ], + "markdownDescription": "Controls grouping for uninitialized declarators, overriding per-kind options." + }, + "using": { + "description": "Controls grouping for `using` declarations.", + "default": null, + "allOf": [ + { + "$ref": "#/definitions/OneVarMode" + } + ], + "markdownDescription": "Controls grouping for `using` declarations." + }, + "var": { + "description": "Controls grouping for `var` declarations.", + "default": null, + "allOf": [ + { + "$ref": "#/definitions/OneVarMode" + } + ], + "markdownDescription": "Controls grouping for `var` declarations." + } + }, + "additionalProperties": false, + "markdownDescription": "Options for configuring declaration grouping by kind or initialization state.\n\n`initialized` and `uninitialized` take precedence over the per-kind option for the\ncorresponding declarators." + }, "OnlyExportComponentsConfig": { "type": "object", "properties": { diff --git a/_tools/repoctl/package.json b/_tools/repoctl/package.json index e051219c..e8b20e0d 100644 --- a/_tools/repoctl/package.json +++ b/_tools/repoctl/package.json @@ -11,8 +11,8 @@ "test": "node --test test/*.test.ts" }, "dependencies": { - "@effect/platform-node": "^4.0.0-beta.104", - "effect": "^4.0.0-beta.104", + "@effect/platform-node": "^4.0.0-beta.107", + "effect": "^4.0.0-beta.107", "semver": "^7.7.2" }, "devDependencies": { diff --git a/etscore/version_generated.go b/etscore/version_generated.go index 31bde5d8..9d4ed496 100644 --- a/etscore/version_generated.go +++ b/etscore/version_generated.go @@ -2,4 +2,4 @@ package etscore -const EffectVersion = "0.36.2" +const EffectVersion = "0.36.4" diff --git a/etsexecutehooks/doc.go b/etsexecutehooks/doc.go index 57eacfa0..6e4ed1f2 100644 --- a/etsexecutehooks/doc.go +++ b/etsexecutehooks/doc.go @@ -1,11 +1,11 @@ -// Package etsexecutehooks provides exit-code filtering for Effect diagnostics. -// -// This package registers a FilterDiagnosticsForExitCodeCallback that filters out -// Effect diagnostics from exit-code determination based on the -// IgnoreEffectSuggestionsInTscExitCode and IgnoreEffectWarningsInTscExitCode -// configuration options. -// -// Import this package with a blank import in the main entry point: -// -// import _ "github.com/effect-ts/tsgo/etsexecutehooks" -package etsexecutehooks +// Package etsexecutehooks provides command-line filtering for Effect diagnostics. +// +// This package registers a FilterDiagnosticsForExitCodeCallback that filters out +// Effect diagnostics from exit-code and noEmitOnError determination based on the +// IgnoreEffectSuggestionsInTscExitCode and IgnoreEffectWarningsInTscExitCode +// configuration options. +// +// Import this package with a blank import in the main entry point: +// +// import _ "github.com/effect-ts/tsgo/etsexecutehooks" +package etsexecutehooks diff --git a/etsexecutehooks/init.go b/etsexecutehooks/init.go index a98320ba..f3b663a9 100644 --- a/etsexecutehooks/init.go +++ b/etsexecutehooks/init.go @@ -4,6 +4,7 @@ import ( "github.com/effect-ts/tsgo/etscore" "github.com/effect-ts/tsgo/internal/rule" "github.com/microsoft/typescript-go/shim/ast" + "github.com/microsoft/typescript-go/shim/compiler" "github.com/microsoft/typescript-go/shim/core" "github.com/microsoft/typescript-go/shim/diagnostics" "github.com/microsoft/typescript-go/shim/execute/tsc" @@ -11,6 +12,7 @@ import ( func init() { tsc.RegisterFilterDiagnosticsForExitCodeCallback(filterDiagnosticsForExitCode) + compiler.RegisterFilterDiagnosticsForNoEmitOnErrorCallback(filterDiagnosticsForExitCode) } // filterDiagnosticsForExitCode is the callback registered with the tsc package. diff --git a/etsexecutehooks/init_test.go b/etsexecutehooks/init_test.go index f41a2c70..2d44e877 100644 --- a/etsexecutehooks/init_test.go +++ b/etsexecutehooks/init_test.go @@ -1,14 +1,48 @@ package etsexecutehooks import ( + "context" "testing" "github.com/effect-ts/tsgo/etscore" "github.com/microsoft/typescript-go/shim/ast" + "github.com/microsoft/typescript-go/shim/compiler" "github.com/microsoft/typescript-go/shim/core" "github.com/microsoft/typescript-go/shim/diagnostics" + "github.com/microsoft/typescript-go/shim/tspath" ) +type noEmitProgram struct { + opts *core.CompilerOptions + diagnostics []*ast.Diagnostic +} + +func (p *noEmitProgram) Options() *core.CompilerOptions { return p.opts } +func (p *noEmitProgram) GetSourceFile(string) *ast.SourceFile { return nil } +func (p *noEmitProgram) GetSourceFiles() []*ast.SourceFile { return nil } +func (p *noEmitProgram) GetConfigFileParsingDiagnostics() []*ast.Diagnostic { return p.diagnostics } +func (p *noEmitProgram) GetSyntacticDiagnostics(context.Context, *ast.SourceFile) []*ast.Diagnostic { + return nil +} +func (p *noEmitProgram) GetBindDiagnostics(context.Context, *ast.SourceFile) []*ast.Diagnostic { + return nil +} +func (p *noEmitProgram) GetProgramDiagnostics() []*ast.Diagnostic { return nil } +func (p *noEmitProgram) GetGlobalDiagnostics(context.Context) []*ast.Diagnostic { return nil } +func (p *noEmitProgram) GetSemanticDiagnostics(context.Context, *ast.SourceFile) []*ast.Diagnostic { + return nil +} +func (p *noEmitProgram) GetDeclarationDiagnostics(context.Context, *ast.SourceFile) []*ast.Diagnostic { + return nil +} +func (p *noEmitProgram) GetSuggestionDiagnostics(context.Context, *ast.SourceFile) []*ast.Diagnostic { + return nil +} +func (p *noEmitProgram) Emit(context.Context, compiler.EmitOptions) *compiler.EmitResult { return nil } +func (p *noEmitProgram) CommonSourceDirectory() string { return "" } +func (p *noEmitProgram) IsSourceFileDefaultLibrary(tspath.Path) bool { return false } +func (p *noEmitProgram) Program() *compiler.Program { return nil } + // makeDiag creates a minimal diagnostic with the given code and category. func makeDiag(code int32, category diagnostics.Category) *ast.Diagnostic { return ast.NewDiagnosticFromSerialized( @@ -112,6 +146,29 @@ func TestFilterDiagnosticsForExitCode_IgnoreWarnings(t *testing.T) { } } +func TestNoEmitOnError_IgnoresConfiguredEffectWarnings(t *testing.T) { + t.Parallel() + opts := &core.CompilerOptions{ + NoEmitOnError: core.BoolToTristate(true), + Effect: &etscore.EffectPluginOptions{ + IgnoreEffectWarningsInTscExitCode: true, + }, + } + program := &noEmitProgram{ + opts: opts, + diagnostics: []*ast.Diagnostic{makeDiag(377011, diagnostics.CategoryWarning)}, + } + + if result := compiler.HandleNoEmitOnError(context.Background(), program, nil); result != nil { + t.Fatal("expected ignored Effect warning not to suppress emit") + } + + program.diagnostics = []*ast.Diagnostic{makeDiag(1002, diagnostics.CategoryError)} + if result := compiler.HandleNoEmitOnError(context.Background(), program, nil); result == nil || !result.EmitSkipped { + t.Fatal("expected TypeScript error to suppress emit") + } +} + func TestFilterDiagnosticsForExitCode_ErrorsNotFilteredByDefault(t *testing.T) { t.Parallel() // With suggestion+warning ignore set but error ignore NOT set, errors are kept diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1755ea6c..bc02b93f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,17 +18,17 @@ importers: _packages/tsgo: devDependencies: '@effect/platform-node': - specifier: ^4.0.0-beta.104 - version: 4.0.0-beta.104(effect@4.0.0-beta.104)(ioredis@5.9.2) + specifier: ^4.0.0-beta.107 + version: 4.0.0-beta.107(effect@4.0.0-beta.107)(ioredis@5.9.2) '@effect/platform-node-shared': - specifier: ^4.0.0-beta.104 - version: 4.0.0-beta.104(effect@4.0.0-beta.104) + specifier: ^4.0.0-beta.107 + version: 4.0.0-beta.107(effect@4.0.0-beta.107) '@types/node': specifier: ^24.3.0 version: 24.10.13 effect: - specifier: ^4.0.0-beta.104 - version: 4.0.0-beta.104 + specifier: ^4.0.0-beta.107 + version: 4.0.0-beta.107 tsdown: specifier: ^0.20.1 version: 0.20.3(typescript@5.9.3) @@ -78,11 +78,11 @@ importers: _tools/repoctl: dependencies: '@effect/platform-node': - specifier: ^4.0.0-beta.104 - version: 4.0.0-beta.104(effect@4.0.0-beta.104)(ioredis@5.9.2) + specifier: ^4.0.0-beta.107 + version: 4.0.0-beta.107(effect@4.0.0-beta.107)(ioredis@5.9.2) effect: - specifier: ^4.0.0-beta.104 - version: 4.0.0-beta.104 + specifier: ^4.0.0-beta.107 + version: 4.0.0-beta.107 semver: specifier: ^7.7.2 version: 7.8.5 @@ -145,8 +145,8 @@ importers: testdata/tests/effect-v4: dependencies: '@effect/vitest': - specifier: 4.0.0-beta.104 - version: 4.0.0-beta.104(effect@4.0.0-beta.104)(vitest@4.1.10(@types/node@22.19.15)(vite@7.3.1(@types/node@22.19.15)(yaml@2.9.0))) + specifier: 4.0.0-beta.107 + version: 4.0.0-beta.107(effect@4.0.0-beta.107)(vitest@4.1.10(@types/node@22.19.15)(vite@7.3.1(@types/node@22.19.15)(yaml@2.9.0))) '@standard-schema/spec': specifier: ^1.1.0 version: 1.1.0 @@ -157,8 +157,8 @@ importers: specifier: 4.1.10 version: 4.1.10 effect: - specifier: 4.0.0-beta.104 - version: 4.0.0-beta.104 + specifier: 4.0.0-beta.107 + version: 4.0.0-beta.107 fast-check: specifier: ^4.4.0 version: 4.5.3 @@ -178,8 +178,8 @@ importers: specifier: ^22.0.0 version: 22.19.15 effect: - specifier: 4.0.0-beta.104 - version: 4.0.0-beta.104 + specifier: 4.0.0-beta.107 + version: 4.0.0-beta.107 fast-check: specifier: ^4.4.0 version: 4.5.3 @@ -196,8 +196,8 @@ importers: specifier: ^22.0.0 version: 22.19.15 effect: - specifier: 4.0.0-beta.104 - version: 4.0.0-beta.104 + specifier: 4.0.0-beta.107 + version: 4.0.0-beta.107 fast-check: specifier: ^4.4.0 version: 4.5.3 @@ -208,8 +208,8 @@ importers: testdata/tests/oxlint: dependencies: effect: - specifier: 4.0.0-beta.104 - version: 4.0.0-beta.104 + specifier: 4.0.0-beta.107 + version: 4.0.0-beta.107 packages: @@ -303,18 +303,18 @@ packages: resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} engines: {node: '>= 20.12.0'} - '@effect/platform-node-shared@4.0.0-beta.104': - resolution: {integrity: sha512-wZQWlreuCfR+Ip6E93h2Wo56lFdBTflzSErFKxvrAW06/ORa7yZMD4oq4Ow5aU5+AlQgomQSEeBKM7uao4ZewQ==} + '@effect/platform-node-shared@4.0.0-beta.107': + resolution: {integrity: sha512-y6BqcRi86BfTJv+tvDrob4ozYVHxxlHYcn/zIQqZjXI9CvKnkgD6ng+38G1o45c4f2ucU+6HRI9POCmFdMoVGA==} engines: {node: '>=18.0.0'} peerDependencies: - effect: ^4.0.0-beta.104 + effect: ^4.0.0-beta.107 - '@effect/platform-node@4.0.0-beta.104': - resolution: {integrity: sha512-edqD0sRzL3Qow26TnD+RuHNVolFB7c1M/xWGzW0TRc7PzXpRWQawM1haMXOrB8W1UXpg8T8jF5MU56vFhPGJyw==} + '@effect/platform-node@4.0.0-beta.107': + resolution: {integrity: sha512-k+6YNbV4Ck0L6YXtlgkvEnuP5tlxWD8EeWOrpn46PDqbGEwt4ONpRltTwm3tn2cyBXD0i+2P11cUH/6sdFagTA==} engines: {node: '>=18.0.0'} peerDependencies: - effect: ^4.0.0-beta.104 - ioredis: ^5.7.0 + effect: ^4.0.0-beta.107 + ioredis: '>=5.7.0 <6.0.0' '@effect/vitest@0.27.0': resolution: {integrity: sha512-8bM7n9xlMUYw9GqPIVgXFwFm2jf27m/R7psI64PGpwU5+26iwyxp9eAXEsfT5S6lqztYfpQQ1Ubp5o6HfNYzJQ==} @@ -322,11 +322,11 @@ packages: effect: ^3.19.0 vitest: ^3.2.0 - '@effect/vitest@4.0.0-beta.104': - resolution: {integrity: sha512-09AvNl3tJNR7hOEnxE8TqSlBTeqfrWu/s4mIjlv1q6c/r6izkH/qhUrByP87ebbEtCMPJDHHXNcKFs3kEbugbQ==} + '@effect/vitest@4.0.0-beta.107': + resolution: {integrity: sha512-n4/qsx4DnT4dEI/wNgMivxyUeJoeiU1TCSz0WnoHWk/dny40Oxjip2P9IXGQDgPb9fsYVnerF0QRA6nPUuExQA==} peerDependencies: - effect: ^4.0.0-beta.104 - vitest: ^4.1.0 + effect: ^4.0.0-beta.107 + vitest: '>=4.1.0 <5.0.0' '@emnapi/core@1.8.1': resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} @@ -952,8 +952,8 @@ packages: effect@3.19.19: resolution: {integrity: sha512-Yc8U/SVXo2dHnaP7zNBlAo83h/nzSJpi7vph6Hzyl4ulgMBIgPmz3UzOjb9sBgpFE00gC0iETR244sfXDNLHRg==} - effect@4.0.0-beta.104: - resolution: {integrity: sha512-YSSaaMc8gBoHnabYXlgHpKVctsj4ezTSoojdd8SA3NWHoZ7LMPiUDhCnP1ZSOfQ7ly6P6XLhAw216NfLEHfg2A==} + effect@4.0.0-beta.107: + resolution: {integrity: sha512-OoBAv8eF+yanc+C6xhgEUnWeXUSHA6ynnscYqpkAY9GSnzZWystsIjBowVqCkLpHGlnRtdIqYT3wHwpOY6JDnQ==} empathic@2.0.0: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} @@ -1582,19 +1582,19 @@ snapshots: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@effect/platform-node-shared@4.0.0-beta.104(effect@4.0.0-beta.104)': + '@effect/platform-node-shared@4.0.0-beta.107(effect@4.0.0-beta.107)': dependencies: '@types/ws': 8.18.1 - effect: 4.0.0-beta.104 + effect: 4.0.0-beta.107 ws: 8.21.1 transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform-node@4.0.0-beta.104(effect@4.0.0-beta.104)(ioredis@5.9.2)': + '@effect/platform-node@4.0.0-beta.107(effect@4.0.0-beta.107)(ioredis@5.9.2)': dependencies: - '@effect/platform-node-shared': 4.0.0-beta.104(effect@4.0.0-beta.104) - effect: 4.0.0-beta.104 + '@effect/platform-node-shared': 4.0.0-beta.107(effect@4.0.0-beta.107) + effect: 4.0.0-beta.107 ioredis: 5.9.2 mime: 4.1.0 undici: 8.9.0 @@ -1607,9 +1607,9 @@ snapshots: effect: 3.19.19 vitest: 3.2.4(@types/node@22.19.15)(yaml@2.9.0) - '@effect/vitest@4.0.0-beta.104(effect@4.0.0-beta.104)(vitest@4.1.10(@types/node@22.19.15)(vite@7.3.1(@types/node@22.19.15)(yaml@2.9.0)))': + '@effect/vitest@4.0.0-beta.107(effect@4.0.0-beta.107)(vitest@4.1.10(@types/node@22.19.15)(vite@7.3.1(@types/node@22.19.15)(yaml@2.9.0)))': dependencies: - effect: 4.0.0-beta.104 + effect: 4.0.0-beta.107 vitest: 4.1.10(@types/node@22.19.15)(vite@7.3.1(@types/node@22.19.15)(yaml@2.9.0)) '@emnapi/core@1.8.1': @@ -2063,7 +2063,7 @@ snapshots: '@standard-schema/spec': 1.1.0 fast-check: 3.23.2 - effect@4.0.0-beta.104: + effect@4.0.0-beta.107: dependencies: '@standard-schema/spec': 1.1.0 fast-check: 4.9.0 diff --git a/shim/compiler/shim.go b/shim/compiler/shim.go index f6f3079d..bf8c3a71 100644 --- a/shim/compiler/shim.go +++ b/shim/compiler/shim.go @@ -26,6 +26,7 @@ const EmitOnlyJs = compiler.EmitOnlyJs type EmitOptions = compiler.EmitOptions type EmitResult = compiler.EmitResult type FileIncludeReason = compiler.FileIncludeReason +var FilterDiagnosticsForNoEmitOnErrorCallback = compiler.FilterDiagnosticsForNoEmitOnErrorCallback //go:linkname FilterNoEmitSemanticDiagnostics github.com/microsoft/typescript-go/internal/compiler.FilterNoEmitSemanticDiagnostics func FilterNoEmitSemanticDiagnostics(diagnostics []*ast.Diagnostic, options *core.CompilerOptions) []*ast.Diagnostic //go:linkname GetDiagnosticsOfAnyProgram github.com/microsoft/typescript-go/internal/compiler.GetDiagnosticsOfAnyProgram @@ -42,6 +43,8 @@ func NewProgram(opts compiler.ProgramOptions) *compiler.Program type Program = compiler.Program type ProgramLike = compiler.ProgramLike type ProgramOptions = compiler.ProgramOptions +//go:linkname RegisterFilterDiagnosticsForNoEmitOnErrorCallback github.com/microsoft/typescript-go/internal/compiler.RegisterFilterDiagnosticsForNoEmitOnErrorCallback +func RegisterFilterDiagnosticsForNoEmitOnErrorCallback(cb func(*core.CompilerOptions, []*ast.Diagnostic) []*ast.Diagnostic) //go:linkname SortAndDeduplicateDiagnostics github.com/microsoft/typescript-go/internal/compiler.SortAndDeduplicateDiagnostics func SortAndDeduplicateDiagnostics(diagnostics []*ast.Diagnostic) []*ast.Diagnostic type SourceFileMayBeEmittedHost = compiler.SourceFileMayBeEmittedHost diff --git a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.errors.txt b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.errors.txt index b4be7406..73f7eb97 100644 --- a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.errors.txt +++ b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.errors.txt @@ -4,7 +4,10 @@ Effect version: 4.0.0 ==== /.src/schemaMutableKey_ts2322.ts (0 errors) ==== - import { Schema, Struct as Struct_, SchemaAST } from "effect" + import { Schema, Struct as Struct_, SchemaAST } from "effect" + declare module "effect/SchemaAST" { + export function optionalKey(ast: A): A + } interface optionalKeyLambda extends Struct_.Lambda { diff --git a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.flows.schemaMutableKey_ts2322.mermaid b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.flows.schemaMutableKey_ts2322.mermaid index 41694078..aa7cdf89 100644 --- a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.flows.schemaMutableKey_ts2322.mermaid +++ b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.flows.schemaMutableKey_ts2322.mermaid @@ -1,15 +1,16 @@ flowchart TB - 0[/"type:
node: Struct_.Lambda"/] - 1[["type: #40;schema: Top#41; =#gt; optionalKey#lt;Top#gt;
node: #40;schema#41; =#gt; Schema.make#40;SchemaAST.optionalKey#40;schema.ast#41;, #123; schema #125;#41;"]] - 2[/"type: optionalKey#lt;Top#gt;
node: Schema.make#40;SchemaAST.optionalKey#40;schema.ast#41;, #123; schema #125;#41;"/] - 3[/"type: AST
node: schema.ast"/] - 4["type: AST
callee: SchemaAST.optionalKey
args: #91;#93;"] - 5[/"type: #lt;A extends AST#gt;#40;ast: A#41; =#gt; A
node: SchemaAST.optionalKey"/] - 6["type: optionalKeyLambda
callee: Struct_.lambda
args: #91;#93;"] - 7[/"type: #lt;L extends #40;a: any#41; =#gt; any#gt;#40;f: #40;a: Parameters#lt;L#gt;#91;0#93;#41; =#gt; ReturnType#lt;L#gt;#41; =#gt; L
node: Struct_.lambda"/] - 3 -->|"kind: pipe"| 4 - 5 -->|"kind: transformCallee"| 4 - 4 -->|"kind: usedBy"| 2 - 2 -->|"kind: potentialReturn"| 1 - 1 -->|"kind: pipe"| 6 - 7 -->|"kind: transformCallee"| 6 \ No newline at end of file + 0[["type: #lt;A extends SchemaAST.AST#gt;#40;ast: A#41; =#gt; A
node: export function optionalKey#lt;A extends SchemaAST.AST#gt;#40;ast: A#41;: A"]] + 1[/"type:
node: Struct_.Lambda"/] + 2[["type: #40;schema: Top#41; =#gt; optionalKey#lt;Top#gt;
node: #40;schema#41; =#gt; Schema.make#40;SchemaAST.optionalKey#40;schema.ast#41;, #123; schema #125;#41;"]] + 3[/"type: optionalKey#lt;Top#gt;
node: Schema.make#40;SchemaAST.optionalKey#40;schema.ast#41;, #123; schema #125;#41;"/] + 4[/"type: AST
node: schema.ast"/] + 5["type: AST
callee: SchemaAST.optionalKey
args: #91;#93;"] + 6[/"type: #lt;A extends SchemaAST.AST#gt;#40;ast: A#41; =#gt; A
node: SchemaAST.optionalKey"/] + 7["type: optionalKeyLambda
callee: Struct_.lambda
args: #91;#93;"] + 8[/"type: #lt;L extends #40;a: any#41; =#gt; any#gt;#40;f: #40;a: Parameters#lt;L#gt;#91;0#93;#41; =#gt; ReturnType#lt;L#gt;#41; =#gt; L
node: Struct_.lambda"/] + 4 -->|"kind: pipe"| 5 + 6 -->|"kind: transformCallee"| 5 + 5 -->|"kind: usedBy"| 3 + 3 -->|"kind: potentialReturn"| 2 + 2 -->|"kind: pipe"| 7 + 8 -->|"kind: transformCallee"| 7 \ No newline at end of file diff --git a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.pipings.txt b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.pipings.txt index 1882a4e1..4971c764 100644 --- a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.pipings.txt +++ b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322.pipings.txt @@ -1,7 +1,7 @@ ==== /.src/schemaMutableKey_ts2322.ts (2 flows) ==== === Piping Flow === -Location: 30:27 - 30:133 +Location: 33:27 - 33:133 Node: Struct_.lambda((schema) => Schema.make(SchemaAST.optionalKey(schema.ast), { schema })) Node Kind: KindCallExpression @@ -15,7 +15,7 @@ Transformations (1): outType: optionalKeyLambda === Piping Flow === -Location: 30:86 - 30:119 +Location: 33:86 - 33:119 Node: SchemaAST.optionalKey(schema.ast) Node Kind: KindCallExpression diff --git a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.errors.txt b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.errors.txt index 2ff778af..b80aae37 100644 --- a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.errors.txt +++ b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.errors.txt @@ -15,7 +15,10 @@ Effect version: 4.0.0 ==== /.src/schemaMutableKey_ts2322_pluginDisabled.ts (0 errors) ==== - import { Schema, Struct as Struct_, SchemaAST } from "effect" + import { Schema, Struct as Struct_, SchemaAST } from "effect" + declare module "effect/SchemaAST" { + export function optionalKey
(ast: A): A + } interface optionalKeyLambda extends Struct_.Lambda { diff --git a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.flows.schemaMutableKey_ts2322_pluginDisabled.mermaid b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.flows.schemaMutableKey_ts2322_pluginDisabled.mermaid index 41694078..aa7cdf89 100644 --- a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.flows.schemaMutableKey_ts2322_pluginDisabled.mermaid +++ b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.flows.schemaMutableKey_ts2322_pluginDisabled.mermaid @@ -1,15 +1,16 @@ flowchart TB - 0[/"type:
node: Struct_.Lambda"/] - 1[["type: #40;schema: Top#41; =#gt; optionalKey#lt;Top#gt;
node: #40;schema#41; =#gt; Schema.make#40;SchemaAST.optionalKey#40;schema.ast#41;, #123; schema #125;#41;"]] - 2[/"type: optionalKey#lt;Top#gt;
node: Schema.make#40;SchemaAST.optionalKey#40;schema.ast#41;, #123; schema #125;#41;"/] - 3[/"type: AST
node: schema.ast"/] - 4["type: AST
callee: SchemaAST.optionalKey
args: #91;#93;"] - 5[/"type: #lt;A extends AST#gt;#40;ast: A#41; =#gt; A
node: SchemaAST.optionalKey"/] - 6["type: optionalKeyLambda
callee: Struct_.lambda
args: #91;#93;"] - 7[/"type: #lt;L extends #40;a: any#41; =#gt; any#gt;#40;f: #40;a: Parameters#lt;L#gt;#91;0#93;#41; =#gt; ReturnType#lt;L#gt;#41; =#gt; L
node: Struct_.lambda"/] - 3 -->|"kind: pipe"| 4 - 5 -->|"kind: transformCallee"| 4 - 4 -->|"kind: usedBy"| 2 - 2 -->|"kind: potentialReturn"| 1 - 1 -->|"kind: pipe"| 6 - 7 -->|"kind: transformCallee"| 6 \ No newline at end of file + 0[["type: #lt;A extends SchemaAST.AST#gt;#40;ast: A#41; =#gt; A
node: export function optionalKey#lt;A extends SchemaAST.AST#gt;#40;ast: A#41;: A"]] + 1[/"type:
node: Struct_.Lambda"/] + 2[["type: #40;schema: Top#41; =#gt; optionalKey#lt;Top#gt;
node: #40;schema#41; =#gt; Schema.make#40;SchemaAST.optionalKey#40;schema.ast#41;, #123; schema #125;#41;"]] + 3[/"type: optionalKey#lt;Top#gt;
node: Schema.make#40;SchemaAST.optionalKey#40;schema.ast#41;, #123; schema #125;#41;"/] + 4[/"type: AST
node: schema.ast"/] + 5["type: AST
callee: SchemaAST.optionalKey
args: #91;#93;"] + 6[/"type: #lt;A extends SchemaAST.AST#gt;#40;ast: A#41; =#gt; A
node: SchemaAST.optionalKey"/] + 7["type: optionalKeyLambda
callee: Struct_.lambda
args: #91;#93;"] + 8[/"type: #lt;L extends #40;a: any#41; =#gt; any#gt;#40;f: #40;a: Parameters#lt;L#gt;#91;0#93;#41; =#gt; ReturnType#lt;L#gt;#41; =#gt; L
node: Struct_.lambda"/] + 4 -->|"kind: pipe"| 5 + 6 -->|"kind: transformCallee"| 5 + 5 -->|"kind: usedBy"| 3 + 3 -->|"kind: potentialReturn"| 2 + 2 -->|"kind: pipe"| 7 + 8 -->|"kind: transformCallee"| 7 \ No newline at end of file diff --git a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.pipings.txt b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.pipings.txt index 32521831..336f52b8 100644 --- a/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.pipings.txt +++ b/testdata/baselines/reference/effect-v4/schemaMutableKey_ts2322_pluginDisabled.pipings.txt @@ -1,7 +1,7 @@ ==== /.src/schemaMutableKey_ts2322_pluginDisabled.ts (2 flows) ==== === Piping Flow === -Location: 30:27 - 30:133 +Location: 33:27 - 33:133 Node: Struct_.lambda((schema) => Schema.make(SchemaAST.optionalKey(schema.ast), { schema })) Node Kind: KindCallExpression @@ -15,7 +15,7 @@ Transformations (1): outType: optionalKeyLambda === Piping Flow === -Location: 30:86 - 30:119 +Location: 33:86 - 33:119 Node: SchemaAST.optionalKey(schema.ast) Node Kind: KindCallExpression diff --git a/testdata/tests/effect-v4-document-symbols/package.json b/testdata/tests/effect-v4-document-symbols/package.json index 88a5ad70..71d47e69 100644 --- a/testdata/tests/effect-v4-document-symbols/package.json +++ b/testdata/tests/effect-v4-document-symbols/package.json @@ -2,7 +2,7 @@ "name": "effect-v4-document-symbols-tests", "private": true, "dependencies": { - "effect": "4.0.0-beta.104", + "effect": "4.0.0-beta.107", "@standard-schema/spec": "^1.1.0", "fast-check": "^4.4.0", "pure-rand": "^7.0.0", diff --git a/testdata/tests/effect-v4-refactors/package.json b/testdata/tests/effect-v4-refactors/package.json index a34f99cc..8a783a0e 100644 --- a/testdata/tests/effect-v4-refactors/package.json +++ b/testdata/tests/effect-v4-refactors/package.json @@ -2,7 +2,7 @@ "name": "effect-v4-refactors-tests", "private": true, "dependencies": { - "effect": "4.0.0-beta.104", + "effect": "4.0.0-beta.107", "@standard-schema/spec": "^1.1.0", "fast-check": "^4.4.0", "pure-rand": "^7.0.0", diff --git a/testdata/tests/effect-v4/package.json b/testdata/tests/effect-v4/package.json index f8cf2875..e4c47383 100644 --- a/testdata/tests/effect-v4/package.json +++ b/testdata/tests/effect-v4/package.json @@ -2,11 +2,11 @@ "name": "effect-v4-tests", "private": true, "dependencies": { - "@effect/vitest": "4.0.0-beta.104", + "@effect/vitest": "4.0.0-beta.107", "@standard-schema/spec": "^1.1.0", "@types/node": "^22.0.0", "@vitest/runner": "4.1.10", - "effect": "4.0.0-beta.104", + "effect": "4.0.0-beta.107", "fast-check": "^4.4.0", "pure-rand": "^7.0.0", "vitest": "4.1.10" diff --git a/testdata/tests/effect-v4/schemaMutableKey_ts2322.ts b/testdata/tests/effect-v4/schemaMutableKey_ts2322.ts index 22f713e4..6d40a4fb 100644 --- a/testdata/tests/effect-v4/schemaMutableKey_ts2322.ts +++ b/testdata/tests/effect-v4/schemaMutableKey_ts2322.ts @@ -1,4 +1,7 @@ -import { Schema, Struct as Struct_, SchemaAST } from "effect" +import { Schema, Struct as Struct_, SchemaAST } from "effect" +declare module "effect/SchemaAST" { + export function optionalKey
(ast: A): A +} interface optionalKeyLambda extends Struct_.Lambda { diff --git a/testdata/tests/effect-v4/schemaMutableKey_ts2322_pluginDisabled.ts b/testdata/tests/effect-v4/schemaMutableKey_ts2322_pluginDisabled.ts index 54e76534..bff487e2 100644 --- a/testdata/tests/effect-v4/schemaMutableKey_ts2322_pluginDisabled.ts +++ b/testdata/tests/effect-v4/schemaMutableKey_ts2322_pluginDisabled.ts @@ -9,7 +9,10 @@ } // @filename: schemaMutableKey_ts2322_pluginDisabled.ts -import { Schema, Struct as Struct_, SchemaAST } from "effect" +import { Schema, Struct as Struct_, SchemaAST } from "effect" +declare module "effect/SchemaAST" { + export function optionalKey(ast: A): A +} interface optionalKeyLambda extends Struct_.Lambda { diff --git a/testdata/tests/oxlint/package.json b/testdata/tests/oxlint/package.json index 699c606d..7cfaa681 100644 --- a/testdata/tests/oxlint/package.json +++ b/testdata/tests/oxlint/package.json @@ -2,6 +2,6 @@ "name": "oxlint-profile-tests", "private": true, "dependencies": { - "effect": "4.0.0-beta.104" + "effect": "4.0.0-beta.107" } }