@take-out/scripts 0.0.41 → 0.0.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@take-out/scripts",
3
- "version": "0.0.41",
3
+ "version": "0.0.43",
4
4
  "type": "module",
5
- "main": "./src/index.ts",
5
+ "main": "./src/run.ts",
6
6
  "sideEffects": false,
7
7
  "exports": {
8
8
  "./package.json": "./package.json",
@@ -24,7 +24,8 @@
24
24
  "access": "public"
25
25
  },
26
26
  "dependencies": {
27
- "@take-out/helpers": "0.0.41"
27
+ "@take-out/helpers": "0.0.43",
28
+ "glob": "^11.0.0"
28
29
  },
29
30
  "devDependencies": {
30
31
  "vxrn": "*"
@@ -20,11 +20,11 @@ if (!(await exists(`./node_modules/.bin/tko`))) {
20
20
  }
21
21
  }
22
22
 
23
- // check if critical packages are built - both helpers and takeout are needed for tko to work
23
+ // check if critical packages are built - both helpers and cli are needed for tko to work
24
24
  if (hasPackages) {
25
25
  const needsBuild =
26
26
  !(await exists(`./packages/helpers/dist`)) ||
27
- !(await exists(`./packages/takeout/dist/esm`))
27
+ !(await exists(`./packages/cli/dist/esm`))
28
28
 
29
29
  if (needsBuild) {
30
30
  // build helpers first as other packages depend on it
@@ -69,7 +69,7 @@ function symlinkBins() {
69
69
  // workaround for https://github.com/oven-sh/bun/issues/19782
70
70
  // bun doesn't create symlinks for workspace packages properly
71
71
  const packagesWithCLI = [
72
- { name: 'takeout', cliFile: 'cli.mjs', alias: 'tko' },
72
+ { name: 'cli', cliFile: 'cli.mjs', alias: 'tko' },
73
73
  { name: 'postgres', cliFile: 'cli.cjs' },
74
74
  ]
75
75
 
@@ -127,60 +127,62 @@ function doesPackageMatchPattern(packageName: string, pattern: string): boolean
127
127
  return packageName === pattern
128
128
  }
129
129
 
130
- async function fetchPackageVersionFromTag(
131
- packageName: string,
132
- tag: string
133
- ): Promise<string | null> {
134
- try {
135
- console.info(`⏳ Lookup ${packageName}@${tag}...`)
136
- // Use --json to ensure parseable output, even if it's just a string.
137
- const result = await $`npm view ${packageName}@${tag} version --json`.text()
138
- const versionData = JSON.parse(result.trim())
139
-
140
- let version: string | undefined
141
- if (Array.isArray(versionData)) {
142
- if (versionData.length === 0) {
143
- console.warn(`❓ No specific versions found for ${packageName}@${tag}.`)
144
- return null
145
- }
146
- // If multiple versions, prefer the last one, as it's often the latest/highest precedent for a tag.
147
- version = versionData[versionData.length - 1]
148
- if (versionData.length > 1) {
149
- console.info(
150
- `ℹ️ Multiple versions found for ${packageName}@${tag}: [${versionData.join(', ')}]. Using: ${version}`
151
- )
152
- }
153
- } else if (typeof versionData === 'string') {
154
- version = versionData
130
+ async function updatePackagesInWorkspace(
131
+ packagesToUpdate: string[],
132
+ cwd: string,
133
+ workspaceName: string
134
+ ) {
135
+ if (packagesToUpdate.length === 0) {
136
+ return
137
+ }
138
+
139
+ $.cwd(cwd)
140
+
141
+ if (globalTag) {
142
+ // check which packages actually have the tag
143
+ const packagesWithTag = (
144
+ await Promise.all(
145
+ packagesToUpdate.map(async (pkg) => {
146
+ try {
147
+ await $`npm view ${pkg}@${globalTag} version --json`.quiet()
148
+ return pkg
149
+ } catch {
150
+ return null
151
+ }
152
+ })
153
+ )
154
+ ).filter((pkg): pkg is string => pkg !== null)
155
+
156
+ if (packagesWithTag.length === 0) {
157
+ return
155
158
  }
156
159
 
157
- if (typeof version === 'string' && version.trim() !== '') {
158
- console.info(`✅ Found ${packageName}@${tag}: ${version}`)
159
- return version
160
+ console.info(` 📦 ${workspaceName}: updating ${packagesWithTag.length} package(s)`)
161
+
162
+ const packageNamesWithTags = packagesWithTag.map((pkg) => `${pkg}@${globalTag}`)
163
+
164
+ try {
165
+ await $`bun add ${packageNamesWithTags} --ignore-scripts`.quiet()
166
+ } catch (error: any) {
167
+ const errorMessage = error.message?.split('\n')[0]
168
+ console.warn(` ⚠️ ${workspaceName}: ${errorMessage}`)
160
169
  }
170
+ } else {
171
+ console.info(` 📦 ${workspaceName}: updating ${packagesToUpdate.length} package(s)`)
161
172
 
162
- console.warn(
163
- `❓ Unexpected or empty version format for ${packageName}@${tag}: ${JSON.stringify(versionData)}`
164
- )
165
- return null
166
- } catch (error: any) {
167
- // Trim error message to avoid overly verbose logs from npm
168
- const errorMessage = error.message?.split('\n')[0]
169
- console.warn(
170
- `⚠️ Could not fetch version for ${packageName}@${tag}. Error: ${errorMessage}`
171
- )
172
- return null
173
+ try {
174
+ await $`bun update ${packagesToUpdate} --latest --ignore-scripts`.quiet()
175
+ } catch (error: any) {
176
+ const errorMessage = error.message?.split('\n')[0]
177
+ console.warn(` ⚠️ ${workspaceName}: ${errorMessage}`)
178
+ }
173
179
  }
174
180
  }
175
181
 
176
- async function updatePackages(packagesToUpdate: string[], cwd: string) {
177
- if (packagesToUpdate.length === 0) {
178
- console.info('No packages to update after resolving versions.')
179
- return
180
- }
181
-
182
- $.cwd(cwd)
183
-
182
+ async function updatePackages(
183
+ packagesByWorkspace: Map<string, { dir: string; packages: string[] }>,
184
+ rootDir: string
185
+ ) {
184
186
  try {
185
187
  rmSync(`node_modules/vite`, {
186
188
  recursive: true,
@@ -191,63 +193,48 @@ async function updatePackages(packagesToUpdate: string[], cwd: string) {
191
193
  }
192
194
 
193
195
  if (globalTag) {
194
- // check which packages actually have the tag
195
196
  console.info(`🔍 Checking which packages have tag '${globalTag}'...\n`)
196
- const packagesWithTag: string[] = []
197
-
198
- for (const pkg of packagesToUpdate) {
199
- try {
200
- await $`npm view ${pkg}@${globalTag} version --json`.quiet()
201
- packagesWithTag.push(pkg)
202
- console.info(` ✓ ${pkg}@${globalTag} exists`)
203
- } catch {
204
- console.info(` ⊘ ${pkg}@${globalTag} not found, skipping`)
205
- }
197
+ const allPackages = new Set<string>()
198
+ for (const { packages } of packagesByWorkspace.values()) {
199
+ packages.forEach((pkg) => allPackages.add(pkg))
206
200
  }
207
201
 
208
- if (packagesWithTag.length === 0) {
202
+ const packagesWithTag = new Set<string>()
203
+ await Promise.all(
204
+ [...allPackages].map(async (pkg) => {
205
+ try {
206
+ await $`npm view ${pkg}@${globalTag} version --json`.quiet()
207
+ console.info(` ✓ ${pkg}@${globalTag} exists`)
208
+ packagesWithTag.add(pkg)
209
+ } catch {
210
+ console.info(` ⊘ ${pkg}@${globalTag} not found, skipping`)
211
+ }
212
+ })
213
+ )
214
+
215
+ if (packagesWithTag.size === 0) {
209
216
  console.info(`\n⚠️ No packages found with tag '${globalTag}'`)
210
217
  return
211
218
  }
212
219
 
213
- console.info(`
214
- 📦 Updating ${packagesWithTag.length} package(s) with tag '${globalTag}' using --ignore-scripts...
215
- `)
220
+ console.info(`\n📦 Updating packages across workspaces...`)
216
221
 
217
- const packageNamesWithTags = packagesWithTag.map((pkg) => `${pkg}@${globalTag}`)
218
- const addCommand = `bun add ${packageNamesWithTags.join(' ')} --ignore-scripts`
219
- console.info(`\n🪄 Running: ${addCommand}\n`)
220
-
221
- try {
222
- await $`bun add ${packageNamesWithTags} --ignore-scripts`
223
- console.info(
224
- `✅ Successfully updated all packages with tag '${globalTag}' (scripts ignored)`
225
- )
226
- } catch (error: any) {
227
- const errorMessage = error.message?.split('\n')[0]
228
- console.warn(`⚠️ Failed to update packages. Error: ${errorMessage}`)
222
+ for (const [name, { dir, packages }] of packagesByWorkspace) {
223
+ const validPackages = packages.filter((pkg) => packagesWithTag.has(pkg))
224
+ await updatePackagesInWorkspace(validPackages, dir, name)
229
225
  }
230
226
  } else {
231
- // Bulk update when not using tags
232
- console.info(`
233
- 📦 Bulk updating ${packagesToUpdate.length} package(s) using --latest --ignore-scripts...
234
- `)
235
-
236
- const updateCommand = `bun update ${packagesToUpdate.join(' ')} --latest --ignore-scripts`
237
- console.info(`\n🪄 Running: ${updateCommand}\n`)
227
+ console.info(`\n📦 Updating packages across workspaces...`)
238
228
 
239
- try {
240
- await $`bun update ${packagesToUpdate} --latest --ignore-scripts`
241
- console.info(`✅ Successfully updated all packages (scripts ignored)`)
242
- } catch (error: any) {
243
- const errorMessage = error.message?.split('\n')[0]
244
- console.warn(`⚠️ Failed to update packages. Error: ${errorMessage}`)
229
+ for (const [name, { dir, packages }] of packagesByWorkspace) {
230
+ await updatePackagesInWorkspace(packages, dir, name)
245
231
  }
246
232
  }
247
233
 
248
234
  console.info(
249
235
  "\n⚙️ Running a final 'bun install' to process all changes and run lifecycle scripts..."
250
236
  )
237
+ $.cwd(rootDir)
251
238
  try {
252
239
  await $`bun install`
253
240
  console.info("✅ Final 'bun install' completed successfully.")
@@ -260,15 +247,20 @@ async function updatePackages(packagesToUpdate: string[], cwd: string) {
260
247
  }
261
248
  }
262
249
 
250
+ function getWorkspaceName(packageJsonPath: string, rootDir: string): string {
251
+ const dir = packageJsonPath.replace('/package.json', '')
252
+ if (dir === rootDir) return 'root'
253
+ return dir.replace(rootDir + '/', '')
254
+ }
255
+
263
256
  async function main() {
264
257
  const rootDir = process.cwd()
265
258
  const packageJsonFiles = findPackageJsonFiles(rootDir)
266
259
  console.info(`Found ${packageJsonFiles.length} package.json files`)
267
260
 
268
- // Get workspace package names to exclude from updates
261
+ // get workspace package names to exclude from updates
269
262
  const workspacePackageNames = new Set<string>()
270
263
  for (const packageJsonPath of packageJsonFiles) {
271
- // skip the root package.json when collecting workspace names
272
264
  if (packageJsonPath === join(rootDir, 'package.json')) continue
273
265
 
274
266
  try {
@@ -286,50 +278,49 @@ async function main() {
286
278
  `Found ${workspacePackageNames.size} workspace packages to exclude from updates`
287
279
  )
288
280
 
289
- const allDependencies = new Set<string>()
281
+ // build map of packages to update per workspace
282
+ const packagesByWorkspace = new Map<string, { dir: string; packages: string[] }>()
283
+ const allMatchingDeps = new Set<string>()
290
284
 
291
285
  for (const packageJsonPath of packageJsonFiles) {
292
286
  const deps = extractDependencies(packageJsonPath)
293
- deps.forEach((dep) => allDependencies.add(dep))
294
- }
287
+ const matchingDeps: string[] = []
295
288
 
296
- console.info(`Found ${allDependencies.size} total dependencies`)
289
+ for (const dep of deps) {
290
+ // skip workspace packages
291
+ if (workspacePackageNames.has(dep)) continue
297
292
 
298
- const matchingDependencies: string[] = []
299
- for (const dep of allDependencies) {
300
- // skip workspace packages - they should never be updated through bun update
301
- if (workspacePackageNames.has(dep)) {
302
- console.info(`⏩ Skipping workspace package: ${dep}`)
303
- continue
293
+ for (const pattern of packagePatterns) {
294
+ if (doesPackageMatchPattern(dep, pattern)) {
295
+ matchingDeps.push(dep)
296
+ allMatchingDeps.add(dep)
297
+ break
298
+ }
299
+ }
304
300
  }
305
301
 
306
- for (const pattern of packagePatterns) {
307
- // packagePatterns from arg parsing
308
- if (doesPackageMatchPattern(dep, pattern)) {
309
- matchingDependencies.push(dep)
310
- break
311
- }
302
+ if (matchingDeps.length > 0) {
303
+ const dir = packageJsonPath.replace('/package.json', '')
304
+ const name = getWorkspaceName(packageJsonPath, rootDir)
305
+ packagesByWorkspace.set(name, { dir, packages: matchingDeps })
312
306
  }
313
307
  }
314
308
 
315
309
  console.info(
316
- `Found ${matchingDependencies.length} dependencies matching patterns: ${packagePatterns.join(', ')}`
310
+ `Found ${allMatchingDeps.size} dependencies matching patterns: ${packagePatterns.join(', ')}`
317
311
  )
312
+ console.info(`Found matches in ${packagesByWorkspace.size} workspace(s)`)
318
313
 
319
- if (matchingDependencies.length === 0) {
314
+ if (allMatchingDeps.size === 0) {
320
315
  console.info('No matching packages found to update.')
321
316
  return
322
317
  }
323
318
 
324
- const packagesForBunUpdate: string[] = [...matchingDependencies]
325
-
326
319
  if (globalTag) {
327
- console.info(
328
- `🏷️ Using tag '${globalTag}' for ${packagesForBunUpdate.length} package(s)`
329
- )
320
+ console.info(`🏷️ Using tag '${globalTag}'`)
330
321
  }
331
322
 
332
- await updatePackages(packagesForBunUpdate, rootDir)
323
+ await updatePackages(packagesByWorkspace, rootDir)
333
324
 
334
325
  console.info('\n🎉 Dependency update complete!')
335
326
  }