| ... | ... | @@ -40,6 +40,7 @@ const WorkspaceConfig = Schema.Struct({ |
| 40 | 40 | catalog: Schema.optional(Schema.Record(Schema.String, Schema.String)), |
| 41 | 41 | overrides: Schema.optional(Schema.Record(Schema.String, Schema.String)), |
| 42 | 42 | patchedDependencies: Schema.optional(Schema.Record(Schema.String, Schema.String)), |
| 43 | allowBuilds: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)), |
| 43 | 44 | }); |
| 44 | 45 | type WorkspaceConfig = typeof WorkspaceConfig.Type; |
| 45 | 46 | |
| ... | ... | @@ -49,7 +50,14 @@ const StageWorkspaceConfig = Schema.Struct({ |
| 49 | 50 | cpu: Schema.Array(Schema.String), |
| 50 | 51 | libc: Schema.optional(Schema.Array(Schema.String)), |
| 51 | 52 | }), |
| 53 | // pnpm 11 only reads these from pnpm-workspace.yaml (not package.json#pnpm). |
| 54 | // Without allowBuilds the staged `vp install --prod` fails with |
| 55 | // ERR_PNPM_IGNORED_BUILDS for packages that have lifecycle scripts. |
| 56 | allowBuilds: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)), |
| 57 | patchedDependencies: Schema.optional(Schema.Record(Schema.String, Schema.String)), |
| 58 | overrides: Schema.optional(Schema.Record(Schema.String, Schema.String)), |
| 52 | 59 | }); |
| 60 | type StageWorkspaceConfig = typeof StageWorkspaceConfig.Type; |
| 53 | 61 | |
| 54 | 62 | const RepoRoot = Effect.service(Path.Path).pipe( |
| 55 | 63 | Effect.flatMap((path) => path.fromFileUrl(new URL("..", import.meta.url))), |
| ... | ... | @@ -563,10 +571,6 @@ interface StagePackageJson { |
| 563 | 571 | readonly devDependencies: { |
| 564 | 572 | readonly electron: string; |
| 565 | 573 | }; |
| 566 | | readonly overrides: Record<string, unknown>; |
| 567 | | readonly pnpm?: { |
| 568 | | readonly patchedDependencies?: Record<string, string>; |
| 569 | | }; |
| 570 | 574 | } |
| 571 | 575 | |
| 572 | 576 | export const STAGE_INSTALL_ARGS = ["install", "--prod"] as const; |
| ... | ... | @@ -876,10 +880,14 @@ const stageClerkPasskeyNativeBinaries = Effect.fn("stageClerkPasskeyNativeBinari |
| 876 | 880 | } |
| 877 | 881 | }); |
| 878 | 882 | |
| 879 | | export function createStageWorkspaceConfig( |
| 880 | | platform: typeof BuildPlatform.Type, |
| 881 | | arch: typeof BuildArch.Type, |
| 882 | | ): typeof StageWorkspaceConfig.Type { |
| 883 | export function createStageWorkspaceConfig(input: { |
| 884 | readonly platform: typeof BuildPlatform.Type; |
| 885 | readonly arch: typeof BuildArch.Type; |
| 886 | readonly allowBuilds?: Record<string, boolean>; |
| 887 | readonly patchedDependencies?: Record<string, string>; |
| 888 | readonly overrides?: Record<string, string>; |
| 889 | }): StageWorkspaceConfig { |
| 890 | const { platform, arch, allowBuilds, patchedDependencies, overrides } = input; |
| 883 | 891 | const hostOs = platform === "mac" ? "darwin" : platform === "win" ? "win32" : "linux"; |
| 884 | 892 | const hostCpu = arch === "universal" ? ["arm64", "x64"] : [arch]; |
| 885 | 893 | // Windows artifacts also bundle the same-architecture WSL Linux backend, which loads |
| ... | ... | @@ -887,36 +895,37 @@ export function createStageWorkspaceConfig( |
| 887 | 895 | // Pull the Linux (glibc) variants in addition to the host platform's so |
| 888 | 896 | // they ship in the asar; without them the WSL backend crash-loops on require |
| 889 | 897 | // ("Cannot find module '@yuuang/ffi-rs-linux-x64-gnu'"). |
| 890 | | if (platform === "win") { |
| 891 | | return { |
| 892 | | supportedArchitectures: { |
| 893 | | os: Array.from(new Set([hostOs, "linux"])), |
| 894 | | cpu: hostCpu, |
| 895 | | libc: ["glibc"], |
| 896 | | }, |
| 897 | | }; |
| 898 | | } |
| 898 | const supportedArchitectures = |
| 899 | platform === "win" |
| 900 | ? { |
| 901 | os: Array.from(new Set([hostOs, "linux"])), |
| 902 | cpu: hostCpu, |
| 903 | libc: ["glibc"], |
| 904 | } |
| 905 | : { |
| 906 | os: [hostOs], |
| 907 | cpu: hostCpu, |
| 908 | }; |
| 909 | |
| 899 | 910 | return { |
| 900 | | supportedArchitectures: { |
| 901 | | os: [hostOs], |
| 902 | | cpu: hostCpu, |
| 903 | | }, |
| 911 | supportedArchitectures, |
| 912 | ...(allowBuilds && Object.keys(allowBuilds).length > 0 ? { allowBuilds } : {}), |
| 913 | ...(patchedDependencies && Object.keys(patchedDependencies).length > 0 |
| 914 | ? { patchedDependencies } |
| 915 | : {}), |
| 916 | ...(overrides && Object.keys(overrides).length > 0 ? { overrides } : {}), |
| 904 | 917 | }; |
| 905 | 918 | } |
| 906 | 919 | |
| 907 | | export function createStagePnpmConfig( |
| 920 | export function createStagePatchedDependencies( |
| 908 | 921 | patchedDependencies: Record<string, string>, |
| 909 | 922 | dependencies: Record<string, unknown>, |
| 910 | | ): StagePackageJson["pnpm"] | undefined { |
| 911 | | const stagePatchedDependencies = Object.fromEntries( |
| 923 | ): Record<string, string> { |
| 924 | return Object.fromEntries( |
| 912 | 925 | Object.entries(patchedDependencies).filter(([patchKey]) => |
| 913 | 926 | Object.hasOwn(dependencies, getPatchedDependencyPackageName(patchKey)), |
| 914 | 927 | ), |
| 915 | 928 | ); |
| 916 | | |
| 917 | | return Object.keys(stagePatchedDependencies).length > 0 |
| 918 | | ? { patchedDependencies: stagePatchedDependencies } |
| 919 | | : undefined; |
| 920 | 929 | } |
| 921 | 930 | |
| 922 | 931 | function getPatchedDependencyPackageName(patchKey: string): string { |
| ... | ... | @@ -1540,6 +1549,7 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* ( |
| 1540 | 1549 | const workspaceCatalog = workspaceConfig.catalog ?? {}; |
| 1541 | 1550 | const workspaceOverrides = workspaceConfig.overrides ?? {}; |
| 1542 | 1551 | const workspacePatchedDependencies = workspaceConfig.patchedDependencies ?? {}; |
| 1552 | const workspaceAllowBuilds = workspaceConfig.allowBuilds ?? {}; |
| 1543 | 1553 | |
| 1544 | 1554 | const platformConfig = PLATFORM_CONFIG[options.platform]; |
| 1545 | 1555 | if (!platformConfig) { |
| ... | ... | @@ -1709,7 +1719,10 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* ( |
| 1709 | 1719 | ) |
| 1710 | 1720 | : {}), |
| 1711 | 1721 | }; |
| 1712 | | const stagePnpmConfig = createStagePnpmConfig(workspacePatchedDependencies, stageDependencies); |
| 1722 | const stagePatchedDependencies = createStagePatchedDependencies( |
| 1723 | workspacePatchedDependencies, |
| 1724 | stageDependencies, |
| 1725 | ); |
| 1713 | 1726 | const stagePackageJson: StagePackageJson = { |
| 1714 | 1727 | name: "t3code", |
| 1715 | 1728 | version: appVersion, |
| ... | ... | @@ -1738,20 +1751,24 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* ( |
| 1738 | 1751 | devDependencies: { |
| 1739 | 1752 | electron: electronVersion, |
| 1740 | 1753 | }, |
| 1741 | | overrides: resolvedOverrides, |
| 1742 | | ...(stagePnpmConfig ? { pnpm: stagePnpmConfig } : {}), |
| 1743 | 1754 | }; |
| 1744 | 1755 | |
| 1745 | 1756 | const stagePackageJsonString = yield* encodeJsonString(stagePackageJson); |
| 1746 | 1757 | yield* fs.writeFileString(path.join(stageAppDir, "package.json"), `${stagePackageJsonString}\n`); |
| 1747 | | const stageWorkspaceConfig = createStageWorkspaceConfig(options.platform, options.arch); |
| 1758 | const stageWorkspaceConfig = createStageWorkspaceConfig({ |
| 1759 | platform: options.platform, |
| 1760 | arch: options.arch, |
| 1761 | allowBuilds: workspaceAllowBuilds, |
| 1762 | patchedDependencies: stagePatchedDependencies, |
| 1763 | overrides: resolvedOverrides, |
| 1764 | }); |
| 1748 | 1765 | const stageWorkspaceConfigString = yield* encodeStageWorkspaceConfig(stageWorkspaceConfig); |
| 1749 | 1766 | yield* fs.writeFileString( |
| 1750 | 1767 | path.join(stageAppDir, "pnpm-workspace.yaml"), |
| 1751 | 1768 | stageWorkspaceConfigString, |
| 1752 | 1769 | ); |
| 1753 | 1770 | |
| 1754 | | if (Object.keys(workspacePatchedDependencies).length > 0) { |
| 1771 | if (Object.keys(stagePatchedDependencies).length > 0) { |
| 1755 | 1772 | yield* fs.copy(path.join(repoRoot, "patches"), path.join(stageAppDir, "patches")); |
| 1756 | 1773 | } |
| 1757 | 1774 | |