@@ -6,25 +6,17 @@ import { promisify } from 'node:util';
66
77const exec = promisify ( cp . exec ) ;
88
9- interface TurboDryRun {
10- packages : Array < string > ;
11- tasks : Array < Task > ;
12- }
13-
14- interface Task {
15- taskId : string ;
16- task : string ;
17- package : string ;
18- hash : string ;
19- command : string ;
20- outputs : Array < string > ;
21- logFile : string ;
22- directory : string ;
23- dependencies : Array < string > ;
24- dependents : Array < string > ;
9+ interface PackageJson {
10+ name : string ;
11+ version : string ;
12+ private ?: boolean ;
13+ dependencies ?: Record < string , string > ;
14+ devDependencies ?: Record < string , string > ;
15+ peerDependencies ?: Record < string , string > ;
2516}
2617
2718const rootDir = fileURLToPath ( new URL ( '../../' , import . meta. url ) ) ;
19+ const packagesDir = path . join ( rootDir , 'packages' ) ;
2820const outDir = fileURLToPath ( new URL ( '../public' , import . meta. url ) ) ;
2921
3022async function main ( ) {
@@ -33,53 +25,80 @@ async function main() {
3325 // Ensure output directory exists
3426 await fs . mkdir ( outDir , { recursive : true } ) ;
3527
36- const { stdout : turboStdout } = await exec ( 'turbo run build --dry-run=json' , {
37- cwd : new URL ( '../' , import . meta. url ) ,
38- } ) ;
28+ // Scan the packages directory for all packages
29+ const packageDirs = await fs . readdir ( packagesDir ) ;
30+ const packages : Array < {
31+ name : string ;
32+ dir : string ;
33+ packageJson : PackageJson ;
34+ } > = [ ] ;
3935
40- const turboJson : TurboDryRun = JSON . parse ( turboStdout ) ;
41-
42- for ( const task of turboJson . tasks ) {
43- const dir = path . join ( rootDir , task . directory ) ;
36+ for ( const packageDir of packageDirs ) {
37+ const dir = path . join ( packagesDir , packageDir ) ;
4438 const packageJsonPath = path . join ( dir , 'package.json' ) ;
45- const originalPackageJson = await fs . readFile ( packageJsonPath , 'utf8' ) ;
46- const originalPackageObj = JSON . parse ( originalPackageJson ) ;
39+
40+ try {
41+ const stat = await fs . stat ( packageJsonPath ) ;
42+ if ( ! stat . isFile ( ) ) continue ;
43+ } catch {
44+ continue ; // Skip directories without package.json
45+ }
46+
47+ const packageJsonContent = await fs . readFile ( packageJsonPath , 'utf8' ) ;
48+ const packageJson : PackageJson = JSON . parse ( packageJsonContent ) ;
4749
4850 // Skip private packages
49- if ( originalPackageObj . private ) continue ;
51+ if ( packageJson . private ) continue ;
5052
51- const packageObj = JSON . parse ( originalPackageJson ) ;
52- packageObj . version += `- ${ sha . trim ( ) } ` ;
53+ packages . push ( { name : packageJson . name , dir , packageJson } ) ;
54+ }
5355
54- // Update dependencies to use preview URLs
55- if ( task . dependencies . length > 0 ) {
56- for ( const dependency of task . dependencies ) {
57- const name = dependency . split ( '#' ) [ 0 ] ;
58- const escapedName = name . replace ( / ^ @ ( .+ ) \/ / , '$1-' ) ;
59- const tarballUrl = `https://${ process . env . VERCEL_URL } /${ escapedName } .tgz` ;
56+ // Create a set of all package names for dependency resolution
57+ const packageNames = new Set ( packages . map ( ( p ) => p . name ) ) ;
6058
61- if ( packageObj . dependencies && name in packageObj . dependencies ) {
62- packageObj . dependencies [ name ] = tarballUrl ;
63- }
64- if ( packageObj . devDependencies && name in packageObj . devDependencies ) {
65- packageObj . devDependencies [ name ] = tarballUrl ;
59+ for ( const { name, dir, packageJson } of packages ) {
60+ const packageJsonPath = path . join ( dir , 'package.json' ) ;
61+ const originalPackageJson = JSON . stringify ( packageJson , null , 2 ) ;
62+
63+ // Create modified package.json with preview version
64+ const modifiedPackageJson : PackageJson = JSON . parse ( originalPackageJson ) ;
65+ modifiedPackageJson . version += `-${ sha } ` ;
66+
67+ // Update workspace dependencies to use preview tarball URLs
68+ const updateDeps = ( deps : Record < string , string > | undefined ) => {
69+ if ( ! deps ) return ;
70+ for ( const depName of Object . keys ( deps ) ) {
71+ if ( packageNames . has ( depName ) ) {
72+ const escapedName = depName . replace ( / ^ @ ( .+ ) \/ / , '$1-' ) ;
73+ deps [ depName ] =
74+ `https://${ process . env . VERCEL_URL } /${ escapedName } .tgz` ;
6675 }
6776 }
68- }
77+ } ;
6978
70- // Write modified package.json
71- await fs . writeFile ( packageJsonPath , JSON . stringify ( packageObj , null , 2 ) ) ;
79+ updateDeps ( modifiedPackageJson . dependencies ) ;
80+ updateDeps ( modifiedPackageJson . devDependencies ) ;
81+ updateDeps ( modifiedPackageJson . peerDependencies ) ;
7282
73- // Pack the package
74- await exec ( `pnpm pack --out="${ outDir } /%s.tgz"` , {
75- cwd : dir ,
76- } ) ;
77-
78- // Restore original package.json
79- await fs . writeFile ( packageJsonPath , originalPackageJson ) ;
83+ // Write modified package.json
84+ await fs . writeFile (
85+ packageJsonPath ,
86+ JSON . stringify ( modifiedPackageJson , null , 2 )
87+ ) ;
88+
89+ try {
90+ // Pack the package
91+ await exec ( `pnpm pack --out="${ outDir } /%s.tgz"` , { cwd : dir } ) ;
92+ console . log ( `Packed ${ name } ` ) ;
93+ } finally {
94+ // Always restore original package.json
95+ await fs . writeFile ( packageJsonPath , originalPackageJson ) ;
96+ }
8097 }
8198
82- console . log ( `Successfully packed preview packages to ${ outDir } ` ) ;
99+ console . log (
100+ `\nSuccessfully packed ${ packages . length } preview packages to ${ outDir } `
101+ ) ;
83102}
84103
85104async function getSha ( ) : Promise < string > {
0 commit comments