each-package
Advanced tools
@@ -37,3 +37,3 @@ "use strict"; | ||
| return (0, _workerts.default)(command, args, options, function(err, results) { | ||
| err ? reject(err) : resolve(results); | ||
| return err ? reject(err) : resolve(results); | ||
| }); | ||
@@ -40,0 +40,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/index.ts"],"sourcesContent":["import type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\nimport worker from './worker.ts';\n\nexport * from './types.ts';\n\nexport default function eachPackage(command: string, args: string[]): Promise<EachResult[]>;\nexport default function eachPackage(command: string, args: string[], options: EachOptions): Promise<EachResult[]>;\n\nexport default function eachPackage(command: string, args: string[], callback: EachCallback): void;\nexport default function eachPackage(command: string, args: string[], options: EachOptions, callback: EachCallback): void;\n\nexport default function eachPackage(command: string, args: string[], options?: EachOptions | EachCallback, callback?: EachCallback): void | Promise<EachResult[]> {\n callback = typeof options === 'function' ? options : callback;\n options = typeof options === 'function' ? {} : ((options || {}) as EachOptions);\n\n if (typeof callback === 'function') return worker(command, args, options, callback);\n return new Promise((resolve, reject) =>\n worker(command, args, options, (err?: EachError, results?: EachResult[]): void => {\n err ? reject(err) : resolve(results);\n })\n );\n}\n"],"names":["eachPackage","command","args","options","callback","worker","Promise","resolve","reject","err","results"],"mappings":";;;;+BAWA;;;eAAwBA;;;+DAVL;qBAEL;;;;;;;;;;;;;;;;;;;AAQC,SAASA,YAAYC,OAAe,EAAEC,IAAc,EAAEC,OAAoC,EAAEC,QAAuB;IAChIA,WAAW,OAAOD,YAAY,aAAaA,UAAUC;IACrDD,UAAU,OAAOA,YAAY,aAAa,CAAC,IAAMA,WAAW,CAAC;IAE7D,IAAI,OAAOC,aAAa,YAAY,OAAOC,IAAAA,iBAAM,EAACJ,SAASC,MAAMC,SAASC;IAC1E,OAAO,IAAIE,QAAQ,SAACC,SAASC;eAC3BH,IAAAA,iBAAM,EAACJ,SAASC,MAAMC,SAAS,SAACM,KAAiBC;YAC/CD,MAAMD,OAAOC,OAAOF,QAAQG;QAC9B;;AAEJ"} | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/index.ts"],"sourcesContent":["import type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\nimport worker from './worker.ts';\n\nexport * from './types.ts';\n\nexport default function eachPackage(command: string, args: string[]): Promise<EachResult[]>;\nexport default function eachPackage(command: string, args: string[], options: EachOptions): Promise<EachResult[]>;\n\nexport default function eachPackage(command: string, args: string[], callback: EachCallback): void;\nexport default function eachPackage(command: string, args: string[], options: EachOptions, callback: EachCallback): void;\n\nexport default function eachPackage(command: string, args: string[], options?: EachOptions | EachCallback, callback?: EachCallback): void | Promise<EachResult[]> {\n callback = typeof options === 'function' ? options : callback;\n options = typeof options === 'function' ? {} : ((options || {}) as EachOptions);\n\n if (typeof callback === 'function') return worker(command, args, options, callback);\n return new Promise((resolve, reject) => worker(command, args, options, (err?: EachError, results?: EachResult[]): void => (err ? reject(err) : resolve(results))));\n}\n"],"names":["eachPackage","command","args","options","callback","worker","Promise","resolve","reject","err","results"],"mappings":";;;;+BAWA;;;eAAwBA;;;+DAVL;qBAEL;;;;;;;;;;;;;;;;;;;AAQC,SAASA,YAAYC,OAAe,EAAEC,IAAc,EAAEC,OAAoC,EAAEC,QAAuB;IAChIA,WAAW,OAAOD,YAAY,aAAaA,UAAUC;IACrDD,UAAU,OAAOA,YAAY,aAAa,CAAC,IAAMA,WAAW,CAAC;IAE7D,IAAI,OAAOC,aAAa,YAAY,OAAOC,IAAAA,iBAAM,EAACJ,SAASC,MAAMC,SAASC;IAC1E,OAAO,IAAIE,QAAQ,SAACC,SAASC;eAAWH,IAAAA,iBAAM,EAACJ,SAASC,MAAMC,SAAS,SAACM,KAAiBC;mBAAkCD,MAAMD,OAAOC,OAAOF,QAAQG;;;AACzJ"} |
@@ -11,3 +11,3 @@ import { type Entry } from 'fs-iterator'; | ||
| import type { EachOptions } from '../types.js'; | ||
| export type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => void; | ||
| export type Callback = (err: Error | null, entries?: PackageEntry[], graph?: DependencyGraph<PackageEntry>) => void; | ||
| export default function packageLayers(options: EachOptions, callback: Callback): void; |
@@ -11,3 +11,3 @@ import { type Entry } from 'fs-iterator'; | ||
| import type { EachOptions } from '../types.js'; | ||
| export type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => void; | ||
| export type Callback = (err: Error | null, entries?: PackageEntry[], graph?: DependencyGraph<PackageEntry>) => void; | ||
| export default function packageLayers(options: EachOptions, callback: Callback): void; |
@@ -13,3 +13,2 @@ "use strict"; | ||
| var _fsiterator = /*#__PURE__*/ _interop_require_default(require("fs-iterator")); | ||
| var _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
| var _removebombuffer = /*#__PURE__*/ _interop_require_default(require("remove-bom-buffer")); | ||
@@ -102,10 +101,3 @@ var _testmatch = /*#__PURE__*/ _interop_require_default(require("test-match")); | ||
| // full graph at one layer, sorted by relative path | ||
| if (!options.topological) { | ||
| var sorted = entries.sort(function(a, b) { | ||
| return _path.default.dirname(a.path).localeCompare(_path.default.dirname(b.path)); | ||
| }); | ||
| return callback(null, [ | ||
| sorted | ||
| ]); | ||
| } | ||
| if (!options.topological) return callback(null, entries); | ||
| // Build nodes map | ||
@@ -136,14 +128,10 @@ var nodes = {}; | ||
| var _graph_sort = graph.sort(), cycles = _graph_sort.cycles, duplicates = _graph_sort.duplicates; | ||
| if (cycles && cycles.length) { | ||
| cycles.forEach(function(c) { | ||
| console.log("Skipping cycle: ".concat(c.join(' -> '))); | ||
| }); | ||
| } | ||
| if (duplicates && duplicates.length) { | ||
| duplicates.forEach(function(d) { | ||
| console.log("Skipping duplicates: ".concat(JSON.stringify(d.values.map(function(x) { | ||
| return x.path; | ||
| })))); | ||
| }); | ||
| } | ||
| if (cycles && cycles.length) cycles.forEach(function(c) { | ||
| return console.log("Skipping cycle: ".concat(c.join(' -> '))); | ||
| }); | ||
| if (duplicates && duplicates.length) duplicates.forEach(function(d) { | ||
| return console.log("Skipping duplicates: ".concat(JSON.stringify(d.values.map(function(x) { | ||
| return x.path; | ||
| })))); | ||
| }); | ||
| // Remove cyclic packages from the graph | ||
@@ -170,3 +158,3 @@ if (cycles && cycles.length) { | ||
| } | ||
| return callback(null, { | ||
| return callback(null, entries, { | ||
| nodes: nodes, | ||
@@ -173,0 +161,0 @@ dependencies: dependencies |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/lib/packageLayers.ts"],"sourcesContent":["import fs from 'fs';\nimport Iterator, { type Entry } from 'fs-iterator';\nimport path from 'path';\nimport removeBOM from 'remove-bom-buffer';\nimport match from 'test-match';\nimport Graph, { type DependencyGraph } from 'topological-sort-group';\n\nexport interface PackageEntry extends Entry {\n package: { name: string; dependencies: object; optionalDependencies: object };\n}\n\nimport type { EachOptions } from '../types.ts';\n\nexport type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => void;\n\nconst defaultIgnores = 'node_modules,.git';\n\nexport default function packageLayers(options: EachOptions, callback: Callback): void {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n\n const cwd = options.cwd || process.cwd();\n\n const ignores = options.ignore ? options.ignore : defaultIgnores;\n const matcher = match({ exclude: ignores });\n\n const iterator = new Iterator(cwd as string, {\n filter: function filter(entry) {\n if (entry.stats.isDirectory() || entry.realStats?.isDirectory()) return entry.basename[0] !== '.' && matcher(entry.basename);\n if (entry.stats.isFile()) {\n // Only include package.json files\n if (entry.basename !== 'package.json') return false;\n // Exclude root package.json unless --root flag is set\n if (!options.root && entry.path === 'package.json') return false;\n return true;\n }\n return false;\n },\n depth,\n lstat: true,\n });\n const entries: PackageEntry[] = [];\n iterator.forEach(\n (entry: PackageEntry, cb): void => {\n if (!entry.stats.isFile()) {\n cb();\n return;\n }\n fs.readFile(entry.fullPath, 'utf8', (err, contents) => {\n if (err) return cb(err);\n try {\n const pkg = JSON.parse(removeBOM(contents));\n if (pkg.private && !options.private) return cb();\n if (pkg.name === undefined) return cb(); // skip packages without names\n entry.package = pkg;\n entries.push(entry);\n cb();\n } catch (_err) {\n console.log(`Failed to parse JSON for ${entry.path}`);\n cb();\n }\n });\n },\n { concurrency: Infinity, callbacks: true },\n (err) => {\n if (err) return callback(err);\n\n // full graph at one layer, sorted by relative path\n if (!options.topological) {\n const sorted = entries.sort((a, b) => path.dirname(a.path).localeCompare(path.dirname(b.path))) as PackageEntry[];\n return callback(null, [sorted]);\n }\n\n // Build nodes map\n const nodes: Record<string, PackageEntry> = {};\n const dependencies: Record<string, string[]> = {};\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n nodes[entry.package.name] = entry;\n dependencies[entry.package.name] = [];\n }\n\n // Build dependencies from package.json dependencies and optionalDependencies\n for (let j = 0; j < entries.length; j++) {\n const e = entries[j];\n const deps = { ...(e.package.dependencies || {}), ...(e.package.optionalDependencies || {}) };\n for (const name in deps) {\n if (nodes[name]) {\n // This package depends on another package in the graph\n dependencies[e.package.name].push(name);\n }\n }\n }\n\n // Use Graph for cycle detection\n const graph = Graph.from<PackageEntry>({ nodes, dependencies });\n const { cycles, duplicates } = graph.sort();\n\n if (cycles && cycles.length) {\n cycles.forEach((c) => {\n console.log(`Skipping cycle: ${c.join(' -> ')}`);\n });\n }\n if (duplicates && duplicates.length) {\n duplicates.forEach((d) => {\n console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x) => x.path))}`);\n });\n }\n\n // Remove cyclic packages from the graph\n if (cycles && cycles.length) {\n const cyclicPackages: Record<string, boolean> = {};\n for (let ci = 0; ci < cycles.length; ci++) {\n const c = cycles[ci];\n for (let cj = 0; cj < c.length; cj++) {\n cyclicPackages[String(c[cj])] = true;\n }\n }\n for (const cyclicName in cyclicPackages) {\n delete nodes[cyclicName];\n delete dependencies[cyclicName];\n }\n // Remove references to cyclic packages from dependencies\n for (const key in dependencies) {\n const depList = dependencies[key];\n for (let di = depList.length - 1; di >= 0; di--) {\n if (cyclicPackages[depList[di]]) depList.splice(di, 1);\n }\n }\n }\n\n return callback(null, { nodes, dependencies });\n }\n );\n}\n"],"names":["packageLayers","defaultIgnores","options","callback","depth","Infinity","cwd","process","ignores","ignore","matcher","match","exclude","iterator","Iterator","filter","entry","stats","isDirectory","realStats","basename","isFile","root","path","lstat","entries","forEach","cb","fs","readFile","fullPath","err","contents","pkg","JSON","parse","removeBOM","private","name","undefined","package","push","_err","console","log","concurrency","callbacks","topological","sorted","sort","a","b","dirname","localeCompare","nodes","dependencies","i","length","j","e","deps","optionalDependencies","graph","Graph","from","cycles","duplicates","c","join","d","stringify","values","map","x","cyclicPackages","ci","cj","String","cyclicName","key","depList","di","splice"],"mappings":"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"} | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/lib/packageLayers.ts"],"sourcesContent":["import fs from 'fs';\nimport Iterator, { type Entry } from 'fs-iterator';\nimport removeBOM from 'remove-bom-buffer';\nimport match from 'test-match';\nimport Graph, { type DependencyGraph } from 'topological-sort-group';\n\nexport interface PackageEntry extends Entry {\n package: { name: string; dependencies: object; optionalDependencies: object };\n}\n\nimport type { EachOptions } from '../types.ts';\n\nexport type Callback = (err: Error | null, entries?: PackageEntry[], graph?: DependencyGraph<PackageEntry>) => void;\n\nconst defaultIgnores = 'node_modules,.git';\n\nexport default function packageLayers(options: EachOptions, callback: Callback): void {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n\n const cwd = options.cwd || process.cwd();\n\n const ignores = options.ignore ? options.ignore : defaultIgnores;\n const matcher = match({ exclude: ignores });\n\n const iterator = new Iterator(cwd as string, {\n filter: function filter(entry) {\n if (entry.stats.isDirectory() || entry.realStats?.isDirectory()) return entry.basename[0] !== '.' && matcher(entry.basename);\n if (entry.stats.isFile()) {\n // Only include package.json files\n if (entry.basename !== 'package.json') return false;\n // Exclude root package.json unless --root flag is set\n if (!options.root && entry.path === 'package.json') return false;\n return true;\n }\n return false;\n },\n depth,\n lstat: true,\n });\n const entries: PackageEntry[] = [];\n iterator.forEach(\n (entry: PackageEntry, cb): void => {\n if (!entry.stats.isFile()) {\n cb();\n return;\n }\n fs.readFile(entry.fullPath, 'utf8', (err, contents) => {\n if (err) return cb(err);\n try {\n const pkg = JSON.parse(removeBOM(contents));\n if (pkg.private && !options.private) return cb();\n if (pkg.name === undefined) return cb(); // skip packages without names\n entry.package = pkg;\n entries.push(entry);\n cb();\n } catch (_err) {\n console.log(`Failed to parse JSON for ${entry.path}`);\n cb();\n }\n });\n },\n { concurrency: Infinity, callbacks: true },\n (err) => {\n if (err) return callback(err);\n\n // full graph at one layer, sorted by relative path\n if (!options.topological) return callback(null, entries);\n\n // Build nodes map\n const nodes: Record<string, PackageEntry> = {};\n const dependencies: Record<string, string[]> = {};\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n nodes[entry.package.name] = entry;\n dependencies[entry.package.name] = [];\n }\n\n // Build dependencies from package.json dependencies and optionalDependencies\n for (let j = 0; j < entries.length; j++) {\n const e = entries[j];\n const deps = { ...(e.package.dependencies || {}), ...(e.package.optionalDependencies || {}) };\n for (const name in deps) {\n if (nodes[name]) {\n // This package depends on another package in the graph\n dependencies[e.package.name].push(name);\n }\n }\n }\n\n // Use Graph for cycle detection\n const graph = Graph.from<PackageEntry>({ nodes, dependencies });\n const { cycles, duplicates } = graph.sort();\n\n if (cycles && cycles.length) cycles.forEach((c) => console.log(`Skipping cycle: ${c.join(' -> ')}`));\n if (duplicates && duplicates.length) duplicates.forEach((d) => console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x) => x.path))}`));\n\n // Remove cyclic packages from the graph\n if (cycles && cycles.length) {\n const cyclicPackages: Record<string, boolean> = {};\n for (let ci = 0; ci < cycles.length; ci++) {\n const c = cycles[ci];\n for (let cj = 0; cj < c.length; cj++) {\n cyclicPackages[String(c[cj])] = true;\n }\n }\n for (const cyclicName in cyclicPackages) {\n delete nodes[cyclicName];\n delete dependencies[cyclicName];\n }\n // Remove references to cyclic packages from dependencies\n for (const key in dependencies) {\n const depList = dependencies[key];\n for (let di = depList.length - 1; di >= 0; di--) {\n if (cyclicPackages[depList[di]]) depList.splice(di, 1);\n }\n }\n }\n\n return callback(null, entries, { nodes, dependencies });\n }\n );\n}\n"],"names":["packageLayers","defaultIgnores","options","callback","depth","Infinity","cwd","process","ignores","ignore","matcher","match","exclude","iterator","Iterator","filter","entry","stats","isDirectory","realStats","basename","isFile","root","path","lstat","entries","forEach","cb","fs","readFile","fullPath","err","contents","pkg","JSON","parse","removeBOM","private","name","undefined","package","push","_err","console","log","concurrency","callbacks","topological","nodes","dependencies","i","length","j","e","deps","optionalDependencies","graph","Graph","from","sort","cycles","duplicates","c","join","d","stringify","values","map","x","cyclicPackages","ci","cj","String","cyclicName","key","depList","di","splice"],"mappings":"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"} |
+29
-68
@@ -78,4 +78,5 @@ "use strict"; | ||
| var concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency; | ||
| (0, _packageLayersts.default)(options, function(err, result) { | ||
| (0, _packageLayersts.default)(options, function(err, entries, graph) { | ||
| if (err) return callback(err); | ||
| if (entries.length === 0) return callback(null, []); | ||
| // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI) | ||
@@ -86,71 +87,18 @@ var interactive = !!options.interactive; | ||
| }); | ||
| var session = _spawnterm.createSession && !options.streaming && interactive ? (0, _spawnterm.createSession)({ | ||
| header: "".concat(process.cwd(), "> ").concat(command, " ").concat(quotedArgs.join(' ')), | ||
| var header = "".concat(process.cwd(), "> ").concat(command, " ").concat(quotedArgs.join(' ')); | ||
| var session = entries.length >= 2 && process.stdout.isTTY && _spawnterm.createSession && !options.streaming && interactive ? (0, _spawnterm.createSession)({ | ||
| header: header, | ||
| showStatusBar: true, | ||
| interactive: interactive | ||
| }) : null; | ||
| // Show command header when not using terminal session (unless silent) | ||
| if (!session && !options.silent) { | ||
| console.log("$ ".concat(command, " ").concat(quotedArgs.join(' '))); | ||
| } | ||
| if (!session && !options.silent) console.log(header); | ||
| var results = []; | ||
| var finalize = function(err) { | ||
| if (err) err.results = results; | ||
| if (session) { | ||
| session.waitAndClose(function() { | ||
| err ? callback(err) : callback(null, results); | ||
| }); | ||
| } else { | ||
| err ? callback(err) : callback(null, results); | ||
| } | ||
| if (session) session.waitAndClose(function() { | ||
| return err ? callback(err) : callback(null, results); | ||
| }); | ||
| else err ? callback(err) : callback(null, results); | ||
| }; | ||
| // Non-topological mode: layers is PackageEntry[][] | ||
| if (Array.isArray(result)) { | ||
| var layers = result; | ||
| var processLayers = function(layers, done) { | ||
| if (layers.length === 0) { | ||
| done(); | ||
| return; | ||
| } | ||
| var layerEntries = layers.shift(); | ||
| var queue = new _queuecb.default(concurrency); | ||
| layerEntries.forEach(function(entry) { | ||
| queue.defer(function(cb) { | ||
| var spawnOptions = _object_spread_props(_object_spread({}, options), { | ||
| cwd: _path.default.dirname(entry.fullPath) | ||
| }); | ||
| var prefix = _path.default.dirname(entry.path); | ||
| var next = function(err, res) { | ||
| if (err && err.message.indexOf('ExperimentalWarning') >= 0) { | ||
| res = err; | ||
| err = null; | ||
| } | ||
| results.push({ | ||
| path: prefix, | ||
| command: command, | ||
| args: args, | ||
| error: err, | ||
| result: res | ||
| }); | ||
| cb(); | ||
| }; | ||
| if (session) session.spawn(command, args, spawnOptions, { | ||
| group: prefix, | ||
| expanded: options.expanded | ||
| }, next); | ||
| else (0, _spawnstreaming.default)(command, args, spawnOptions, { | ||
| prefix: prefix | ||
| }, next); | ||
| }); | ||
| }); | ||
| queue.await(function(err) { | ||
| return err ? done(err) : processLayers(layers, done); | ||
| }); | ||
| }; | ||
| processLayers(layers, finalize); | ||
| return; | ||
| } | ||
| // Topological mode: use topological-scheduler | ||
| var graph = result; | ||
| (0, _topologicalscheduler.default)(graph, function(entry, _id, cb) { | ||
| var spawnEntry = function(entry, cb) { | ||
| var spawnOptions = _object_spread_props(_object_spread({}, options), { | ||
@@ -172,3 +120,3 @@ cwd: _path.default.dirname(entry.fullPath) | ||
| }); | ||
| cb(err, res); | ||
| cb(); | ||
| }; | ||
@@ -180,12 +128,25 @@ if (session) session.spawn(command, args, spawnOptions, { | ||
| else (0, _spawnstreaming.default)(command, args, spawnOptions, { | ||
| prefix: prefix | ||
| prefix: process.stdout.isTTY ? prefix : undefined | ||
| }, next); | ||
| }; | ||
| // Topological mode: use topological-scheduler | ||
| if (options.topological) (0, _topologicalscheduler.default)(graph, function(entry, _id, cb) { | ||
| return spawnEntry(entry, cb); | ||
| }, { | ||
| concurrency: concurrency, | ||
| failDependents: options.failDependents | ||
| }, function(err) { | ||
| finalize(err); | ||
| }); | ||
| }, finalize); | ||
| else { | ||
| var sorted = entries.sort(function(a, b) { | ||
| return _path.default.dirname(a.path).localeCompare(_path.default.dirname(b.path)); | ||
| }); | ||
| var queue = new _queuecb.default(concurrency); | ||
| sorted.forEach(function(entry) { | ||
| return queue.defer(spawnEntry.bind(null, entry)); | ||
| }); | ||
| queue.await(finalize); | ||
| return; | ||
| } | ||
| }); | ||
| } | ||
| /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/worker.ts"],"sourcesContent":["import type { SpawnResult } from 'cross-spawn-cb';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport { createSession } from 'spawn-term';\nimport schedule, { type DependencyGraph } from 'topological-scheduler';\nimport packageLayers, { type PackageEntry } from './lib/packageLayers.ts';\n\nimport type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\n\nexport default function worker(command: string, args: string[], options: EachOptions, callback: EachCallback): void {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency;\n\n packageLayers(options, (err, result) => {\n if (err) return callback(err);\n\n // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI)\n const interactive = !!options.interactive;\n const quotedArgs = args.map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg));\n const session = createSession && !options.streaming && interactive ? createSession({ header: `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n // Show command header when not using terminal session (unless silent)\n if (!session && !options.silent) {\n console.log(`$ ${command} ${quotedArgs.join(' ')}`);\n }\n\n const results: EachResult[] = [];\n\n const finalize = (err?: Error): void => {\n if (err) (err as EachError).results = results;\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n };\n\n // Non-topological mode: layers is PackageEntry[][]\n if (Array.isArray(result)) {\n const layers = result as PackageEntry[][];\n const processLayers = (layers: PackageEntry[][], done: (err?: Error) => void): void => {\n if (layers.length === 0) {\n done();\n return;\n }\n const layerEntries = layers.shift();\n\n const queue = new Queue(concurrency);\n layerEntries.forEach((entry) => {\n queue.defer((cb: () => void) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): void => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb();\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n });\n });\n\n queue.await((err: Error) => (err ? done(err) : processLayers(layers, done)));\n };\n\n processLayers(layers, finalize);\n return;\n }\n\n // Topological mode: use topological-scheduler\n const graph = result as DependencyGraph<PackageEntry>;\n\n schedule(\n graph,\n (entry, _id, cb) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): void => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb(err, res);\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n },\n { concurrency, failDependents: options.failDependents },\n (err) => {\n finalize(err);\n }\n );\n });\n}\n"],"names":["worker","command","args","options","callback","depth","Infinity","concurrency","packageLayers","err","result","interactive","quotedArgs","map","arg","test","session","createSession","streaming","header","process","cwd","join","showStatusBar","silent","console","log","results","finalize","waitAndClose","Array","isArray","layers","processLayers","done","length","layerEntries","shift","queue","Queue","forEach","entry","defer","cb","spawnOptions","path","dirname","fullPath","prefix","next","res","message","indexOf","push","error","spawn","group","expanded","spawnStreaming","await","graph","schedule","_id","failDependents"],"mappings":"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"} | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/worker.ts"],"sourcesContent":["import type { SpawnResult } from 'cross-spawn-cb';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport { createSession } from 'spawn-term';\nimport schedule from 'topological-scheduler';\nimport packageLayers, { type PackageEntry } from './lib/packageLayers.ts';\n\nimport type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\n\nexport default function worker(command: string, args: string[], options: EachOptions, callback: EachCallback): void {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency;\n\n packageLayers(options, (err, entries, graph) => {\n if (err) return callback(err);\n if (entries.length === 0) return callback(null, []);\n\n // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI)\n const interactive = !!options.interactive;\n const quotedArgs = args.map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg));\n\n const header = `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`;\n const session = entries.length >= 2 && process.stdout.isTTY && createSession && !options.streaming && interactive ? createSession({ header, showStatusBar: true, interactive }) : null;\n if (!session && !options.silent) console.log(header);\n\n const results: EachResult[] = [];\n\n const finalize = (err?: Error): void => {\n if (err) (err as EachError).results = results;\n if (session) session.waitAndClose(() => (err ? callback(err) : callback(null, results)));\n else err ? callback(err) : callback(null, results);\n };\n\n const spawnEntry = (entry: PackageEntry, cb) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): void => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb();\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix: process.stdout.isTTY ? prefix : undefined }, next);\n };\n\n // Topological mode: use topological-scheduler\n if (options.topological) schedule(graph, (entry, _id, cb) => spawnEntry(entry, cb), { concurrency, failDependents: options.failDependents }, finalize);\n // Non-topological mode: layers is PackageEntry[]\n else {\n const sorted = entries.sort((a, b) => path.dirname(a.path).localeCompare(path.dirname(b.path))) as PackageEntry[];\n const queue = new Queue(concurrency);\n sorted.forEach((entry) => queue.defer(spawnEntry.bind(null, entry)));\n queue.await(finalize);\n return;\n }\n });\n}\n"],"names":["worker","command","args","options","callback","depth","Infinity","concurrency","packageLayers","err","entries","graph","length","interactive","quotedArgs","map","arg","test","header","process","cwd","join","session","stdout","isTTY","createSession","streaming","showStatusBar","silent","console","log","results","finalize","waitAndClose","spawnEntry","entry","cb","spawnOptions","path","dirname","fullPath","prefix","next","res","message","indexOf","push","error","result","spawn","group","expanded","spawnStreaming","undefined","topological","schedule","_id","failDependents","sorted","sort","a","b","localeCompare","queue","Queue","forEach","defer","bind","await"],"mappings":"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"} |
@@ -7,5 +7,3 @@ import worker from './worker.js'; | ||
| if (typeof callback === 'function') return worker(command, args, options, callback); | ||
| return new Promise((resolve, reject)=>worker(command, args, options, (err, results)=>{ | ||
| err ? reject(err) : resolve(results); | ||
| })); | ||
| return new Promise((resolve, reject)=>worker(command, args, options, (err, results)=>err ? reject(err) : resolve(results))); | ||
| } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/index.ts"],"sourcesContent":["import type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\nimport worker from './worker.ts';\n\nexport * from './types.ts';\n\nexport default function eachPackage(command: string, args: string[]): Promise<EachResult[]>;\nexport default function eachPackage(command: string, args: string[], options: EachOptions): Promise<EachResult[]>;\n\nexport default function eachPackage(command: string, args: string[], callback: EachCallback): void;\nexport default function eachPackage(command: string, args: string[], options: EachOptions, callback: EachCallback): void;\n\nexport default function eachPackage(command: string, args: string[], options?: EachOptions | EachCallback, callback?: EachCallback): void | Promise<EachResult[]> {\n callback = typeof options === 'function' ? options : callback;\n options = typeof options === 'function' ? {} : ((options || {}) as EachOptions);\n\n if (typeof callback === 'function') return worker(command, args, options, callback);\n return new Promise((resolve, reject) =>\n worker(command, args, options, (err?: EachError, results?: EachResult[]): void => {\n err ? reject(err) : resolve(results);\n })\n );\n}\n"],"names":["worker","eachPackage","command","args","options","callback","Promise","resolve","reject","err","results"],"mappings":"AACA,OAAOA,YAAY,cAAc;AAEjC,cAAc,aAAa;AAQ3B,eAAe,SAASC,YAAYC,OAAe,EAAEC,IAAc,EAAEC,OAAoC,EAAEC,QAAuB;IAChIA,WAAW,OAAOD,YAAY,aAAaA,UAAUC;IACrDD,UAAU,OAAOA,YAAY,aAAa,CAAC,IAAMA,WAAW,CAAC;IAE7D,IAAI,OAAOC,aAAa,YAAY,OAAOL,OAAOE,SAASC,MAAMC,SAASC;IAC1E,OAAO,IAAIC,QAAQ,CAACC,SAASC,SAC3BR,OAAOE,SAASC,MAAMC,SAAS,CAACK,KAAiBC;YAC/CD,MAAMD,OAAOC,OAAOF,QAAQG;QAC9B;AAEJ"} | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/index.ts"],"sourcesContent":["import type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\nimport worker from './worker.ts';\n\nexport * from './types.ts';\n\nexport default function eachPackage(command: string, args: string[]): Promise<EachResult[]>;\nexport default function eachPackage(command: string, args: string[], options: EachOptions): Promise<EachResult[]>;\n\nexport default function eachPackage(command: string, args: string[], callback: EachCallback): void;\nexport default function eachPackage(command: string, args: string[], options: EachOptions, callback: EachCallback): void;\n\nexport default function eachPackage(command: string, args: string[], options?: EachOptions | EachCallback, callback?: EachCallback): void | Promise<EachResult[]> {\n callback = typeof options === 'function' ? options : callback;\n options = typeof options === 'function' ? {} : ((options || {}) as EachOptions);\n\n if (typeof callback === 'function') return worker(command, args, options, callback);\n return new Promise((resolve, reject) => worker(command, args, options, (err?: EachError, results?: EachResult[]): void => (err ? reject(err) : resolve(results))));\n}\n"],"names":["worker","eachPackage","command","args","options","callback","Promise","resolve","reject","err","results"],"mappings":"AACA,OAAOA,YAAY,cAAc;AAEjC,cAAc,aAAa;AAQ3B,eAAe,SAASC,YAAYC,OAAe,EAAEC,IAAc,EAAEC,OAAoC,EAAEC,QAAuB;IAChIA,WAAW,OAAOD,YAAY,aAAaA,UAAUC;IACrDD,UAAU,OAAOA,YAAY,aAAa,CAAC,IAAMA,WAAW,CAAC;IAE7D,IAAI,OAAOC,aAAa,YAAY,OAAOL,OAAOE,SAASC,MAAMC,SAASC;IAC1E,OAAO,IAAIC,QAAQ,CAACC,SAASC,SAAWR,OAAOE,SAASC,MAAMC,SAAS,CAACK,KAAiBC,UAAkCD,MAAMD,OAAOC,OAAOF,QAAQG;AACzJ"} |
@@ -11,3 +11,3 @@ import { type Entry } from 'fs-iterator'; | ||
| import type { EachOptions } from '../types.js'; | ||
| export type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => void; | ||
| export type Callback = (err: Error | null, entries?: PackageEntry[], graph?: DependencyGraph<PackageEntry>) => void; | ||
| export default function packageLayers(options: EachOptions, callback: Callback): void; |
| import fs from 'fs'; | ||
| import Iterator from 'fs-iterator'; | ||
| import path from 'path'; | ||
| import removeBOM from 'remove-bom-buffer'; | ||
@@ -58,8 +57,3 @@ import match from 'test-match'; | ||
| // full graph at one layer, sorted by relative path | ||
| if (!options.topological) { | ||
| const sorted = entries.sort((a, b)=>path.dirname(a.path).localeCompare(path.dirname(b.path))); | ||
| return callback(null, [ | ||
| sorted | ||
| ]); | ||
| } | ||
| if (!options.topological) return callback(null, entries); | ||
| // Build nodes map | ||
@@ -93,12 +87,4 @@ const nodes = {}; | ||
| const { cycles, duplicates } = graph.sort(); | ||
| if (cycles && cycles.length) { | ||
| cycles.forEach((c)=>{ | ||
| console.log(`Skipping cycle: ${c.join(' -> ')}`); | ||
| }); | ||
| } | ||
| if (duplicates && duplicates.length) { | ||
| duplicates.forEach((d)=>{ | ||
| console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x)=>x.path))}`); | ||
| }); | ||
| } | ||
| if (cycles && cycles.length) cycles.forEach((c)=>console.log(`Skipping cycle: ${c.join(' -> ')}`)); | ||
| if (duplicates && duplicates.length) duplicates.forEach((d)=>console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x)=>x.path))}`)); | ||
| // Remove cyclic packages from the graph | ||
@@ -125,3 +111,3 @@ if (cycles && cycles.length) { | ||
| } | ||
| return callback(null, { | ||
| return callback(null, entries, { | ||
| nodes, | ||
@@ -128,0 +114,0 @@ dependencies |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/lib/packageLayers.ts"],"sourcesContent":["import fs from 'fs';\nimport Iterator, { type Entry } from 'fs-iterator';\nimport path from 'path';\nimport removeBOM from 'remove-bom-buffer';\nimport match from 'test-match';\nimport Graph, { type DependencyGraph } from 'topological-sort-group';\n\nexport interface PackageEntry extends Entry {\n package: { name: string; dependencies: object; optionalDependencies: object };\n}\n\nimport type { EachOptions } from '../types.ts';\n\nexport type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => void;\n\nconst defaultIgnores = 'node_modules,.git';\n\nexport default function packageLayers(options: EachOptions, callback: Callback): void {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n\n const cwd = options.cwd || process.cwd();\n\n const ignores = options.ignore ? options.ignore : defaultIgnores;\n const matcher = match({ exclude: ignores });\n\n const iterator = new Iterator(cwd as string, {\n filter: function filter(entry) {\n if (entry.stats.isDirectory() || entry.realStats?.isDirectory()) return entry.basename[0] !== '.' && matcher(entry.basename);\n if (entry.stats.isFile()) {\n // Only include package.json files\n if (entry.basename !== 'package.json') return false;\n // Exclude root package.json unless --root flag is set\n if (!options.root && entry.path === 'package.json') return false;\n return true;\n }\n return false;\n },\n depth,\n lstat: true,\n });\n const entries: PackageEntry[] = [];\n iterator.forEach(\n (entry: PackageEntry, cb): void => {\n if (!entry.stats.isFile()) {\n cb();\n return;\n }\n fs.readFile(entry.fullPath, 'utf8', (err, contents) => {\n if (err) return cb(err);\n try {\n const pkg = JSON.parse(removeBOM(contents));\n if (pkg.private && !options.private) return cb();\n if (pkg.name === undefined) return cb(); // skip packages without names\n entry.package = pkg;\n entries.push(entry);\n cb();\n } catch (_err) {\n console.log(`Failed to parse JSON for ${entry.path}`);\n cb();\n }\n });\n },\n { concurrency: Infinity, callbacks: true },\n (err) => {\n if (err) return callback(err);\n\n // full graph at one layer, sorted by relative path\n if (!options.topological) {\n const sorted = entries.sort((a, b) => path.dirname(a.path).localeCompare(path.dirname(b.path))) as PackageEntry[];\n return callback(null, [sorted]);\n }\n\n // Build nodes map\n const nodes: Record<string, PackageEntry> = {};\n const dependencies: Record<string, string[]> = {};\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n nodes[entry.package.name] = entry;\n dependencies[entry.package.name] = [];\n }\n\n // Build dependencies from package.json dependencies and optionalDependencies\n for (let j = 0; j < entries.length; j++) {\n const e = entries[j];\n const deps = { ...(e.package.dependencies || {}), ...(e.package.optionalDependencies || {}) };\n for (const name in deps) {\n if (nodes[name]) {\n // This package depends on another package in the graph\n dependencies[e.package.name].push(name);\n }\n }\n }\n\n // Use Graph for cycle detection\n const graph = Graph.from<PackageEntry>({ nodes, dependencies });\n const { cycles, duplicates } = graph.sort();\n\n if (cycles && cycles.length) {\n cycles.forEach((c) => {\n console.log(`Skipping cycle: ${c.join(' -> ')}`);\n });\n }\n if (duplicates && duplicates.length) {\n duplicates.forEach((d) => {\n console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x) => x.path))}`);\n });\n }\n\n // Remove cyclic packages from the graph\n if (cycles && cycles.length) {\n const cyclicPackages: Record<string, boolean> = {};\n for (let ci = 0; ci < cycles.length; ci++) {\n const c = cycles[ci];\n for (let cj = 0; cj < c.length; cj++) {\n cyclicPackages[String(c[cj])] = true;\n }\n }\n for (const cyclicName in cyclicPackages) {\n delete nodes[cyclicName];\n delete dependencies[cyclicName];\n }\n // Remove references to cyclic packages from dependencies\n for (const key in dependencies) {\n const depList = dependencies[key];\n for (let di = depList.length - 1; di >= 0; di--) {\n if (cyclicPackages[depList[di]]) depList.splice(di, 1);\n }\n }\n }\n\n return callback(null, { nodes, dependencies });\n }\n );\n}\n"],"names":["fs","Iterator","path","removeBOM","match","Graph","defaultIgnores","packageLayers","options","callback","depth","Infinity","cwd","process","ignores","ignore","matcher","exclude","iterator","filter","entry","stats","isDirectory","realStats","basename","isFile","root","lstat","entries","forEach","cb","readFile","fullPath","err","contents","pkg","JSON","parse","private","name","undefined","package","push","_err","console","log","concurrency","callbacks","topological","sorted","sort","a","b","dirname","localeCompare","nodes","dependencies","i","length","j","e","deps","optionalDependencies","graph","from","cycles","duplicates","c","join","d","stringify","values","map","x","cyclicPackages","ci","cj","String","cyclicName","key","depList","di","splice"],"mappings":"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"} | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/lib/packageLayers.ts"],"sourcesContent":["import fs from 'fs';\nimport Iterator, { type Entry } from 'fs-iterator';\nimport removeBOM from 'remove-bom-buffer';\nimport match from 'test-match';\nimport Graph, { type DependencyGraph } from 'topological-sort-group';\n\nexport interface PackageEntry extends Entry {\n package: { name: string; dependencies: object; optionalDependencies: object };\n}\n\nimport type { EachOptions } from '../types.ts';\n\nexport type Callback = (err: Error | null, entries?: PackageEntry[], graph?: DependencyGraph<PackageEntry>) => void;\n\nconst defaultIgnores = 'node_modules,.git';\n\nexport default function packageLayers(options: EachOptions, callback: Callback): void {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n\n const cwd = options.cwd || process.cwd();\n\n const ignores = options.ignore ? options.ignore : defaultIgnores;\n const matcher = match({ exclude: ignores });\n\n const iterator = new Iterator(cwd as string, {\n filter: function filter(entry) {\n if (entry.stats.isDirectory() || entry.realStats?.isDirectory()) return entry.basename[0] !== '.' && matcher(entry.basename);\n if (entry.stats.isFile()) {\n // Only include package.json files\n if (entry.basename !== 'package.json') return false;\n // Exclude root package.json unless --root flag is set\n if (!options.root && entry.path === 'package.json') return false;\n return true;\n }\n return false;\n },\n depth,\n lstat: true,\n });\n const entries: PackageEntry[] = [];\n iterator.forEach(\n (entry: PackageEntry, cb): void => {\n if (!entry.stats.isFile()) {\n cb();\n return;\n }\n fs.readFile(entry.fullPath, 'utf8', (err, contents) => {\n if (err) return cb(err);\n try {\n const pkg = JSON.parse(removeBOM(contents));\n if (pkg.private && !options.private) return cb();\n if (pkg.name === undefined) return cb(); // skip packages without names\n entry.package = pkg;\n entries.push(entry);\n cb();\n } catch (_err) {\n console.log(`Failed to parse JSON for ${entry.path}`);\n cb();\n }\n });\n },\n { concurrency: Infinity, callbacks: true },\n (err) => {\n if (err) return callback(err);\n\n // full graph at one layer, sorted by relative path\n if (!options.topological) return callback(null, entries);\n\n // Build nodes map\n const nodes: Record<string, PackageEntry> = {};\n const dependencies: Record<string, string[]> = {};\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n nodes[entry.package.name] = entry;\n dependencies[entry.package.name] = [];\n }\n\n // Build dependencies from package.json dependencies and optionalDependencies\n for (let j = 0; j < entries.length; j++) {\n const e = entries[j];\n const deps = { ...(e.package.dependencies || {}), ...(e.package.optionalDependencies || {}) };\n for (const name in deps) {\n if (nodes[name]) {\n // This package depends on another package in the graph\n dependencies[e.package.name].push(name);\n }\n }\n }\n\n // Use Graph for cycle detection\n const graph = Graph.from<PackageEntry>({ nodes, dependencies });\n const { cycles, duplicates } = graph.sort();\n\n if (cycles && cycles.length) cycles.forEach((c) => console.log(`Skipping cycle: ${c.join(' -> ')}`));\n if (duplicates && duplicates.length) duplicates.forEach((d) => console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x) => x.path))}`));\n\n // Remove cyclic packages from the graph\n if (cycles && cycles.length) {\n const cyclicPackages: Record<string, boolean> = {};\n for (let ci = 0; ci < cycles.length; ci++) {\n const c = cycles[ci];\n for (let cj = 0; cj < c.length; cj++) {\n cyclicPackages[String(c[cj])] = true;\n }\n }\n for (const cyclicName in cyclicPackages) {\n delete nodes[cyclicName];\n delete dependencies[cyclicName];\n }\n // Remove references to cyclic packages from dependencies\n for (const key in dependencies) {\n const depList = dependencies[key];\n for (let di = depList.length - 1; di >= 0; di--) {\n if (cyclicPackages[depList[di]]) depList.splice(di, 1);\n }\n }\n }\n\n return callback(null, entries, { nodes, dependencies });\n }\n );\n}\n"],"names":["fs","Iterator","removeBOM","match","Graph","defaultIgnores","packageLayers","options","callback","depth","Infinity","cwd","process","ignores","ignore","matcher","exclude","iterator","filter","entry","stats","isDirectory","realStats","basename","isFile","root","path","lstat","entries","forEach","cb","readFile","fullPath","err","contents","pkg","JSON","parse","private","name","undefined","package","push","_err","console","log","concurrency","callbacks","topological","nodes","dependencies","i","length","j","e","deps","optionalDependencies","graph","from","cycles","duplicates","sort","c","join","d","stringify","values","map","x","cyclicPackages","ci","cj","String","cyclicName","key","depList","di","splice"],"mappings":"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"} |
+22
-68
@@ -11,75 +11,22 @@ import path from 'path'; | ||
| const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency; | ||
| packageLayers(options, (err, result)=>{ | ||
| packageLayers(options, (err, entries, graph)=>{ | ||
| if (err) return callback(err); | ||
| if (entries.length === 0) return callback(null, []); | ||
| // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI) | ||
| const interactive = !!options.interactive; | ||
| const quotedArgs = args.map((arg)=>/\s/.test(arg) ? `"${arg}"` : arg); | ||
| const session = createSession && !options.streaming && interactive ? createSession({ | ||
| header: `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`, | ||
| const header = `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`; | ||
| const session = entries.length >= 2 && process.stdout.isTTY && createSession && !options.streaming && interactive ? createSession({ | ||
| header, | ||
| showStatusBar: true, | ||
| interactive | ||
| }) : null; | ||
| // Show command header when not using terminal session (unless silent) | ||
| if (!session && !options.silent) { | ||
| console.log(`$ ${command} ${quotedArgs.join(' ')}`); | ||
| } | ||
| if (!session && !options.silent) console.log(header); | ||
| const results = []; | ||
| const finalize = (err)=>{ | ||
| if (err) err.results = results; | ||
| if (session) { | ||
| session.waitAndClose(()=>{ | ||
| err ? callback(err) : callback(null, results); | ||
| }); | ||
| } else { | ||
| err ? callback(err) : callback(null, results); | ||
| } | ||
| if (session) session.waitAndClose(()=>err ? callback(err) : callback(null, results)); | ||
| else err ? callback(err) : callback(null, results); | ||
| }; | ||
| // Non-topological mode: layers is PackageEntry[][] | ||
| if (Array.isArray(result)) { | ||
| const layers = result; | ||
| const processLayers = (layers, done)=>{ | ||
| if (layers.length === 0) { | ||
| done(); | ||
| return; | ||
| } | ||
| const layerEntries = layers.shift(); | ||
| const queue = new Queue(concurrency); | ||
| layerEntries.forEach((entry)=>{ | ||
| queue.defer((cb)=>{ | ||
| const spawnOptions = { | ||
| ...options, | ||
| cwd: path.dirname(entry.fullPath) | ||
| }; | ||
| const prefix = path.dirname(entry.path); | ||
| const next = (err, res)=>{ | ||
| if (err && err.message.indexOf('ExperimentalWarning') >= 0) { | ||
| res = err; | ||
| err = null; | ||
| } | ||
| results.push({ | ||
| path: prefix, | ||
| command, | ||
| args, | ||
| error: err, | ||
| result: res | ||
| }); | ||
| cb(); | ||
| }; | ||
| if (session) session.spawn(command, args, spawnOptions, { | ||
| group: prefix, | ||
| expanded: options.expanded | ||
| }, next); | ||
| else spawnStreaming(command, args, spawnOptions, { | ||
| prefix | ||
| }, next); | ||
| }); | ||
| }); | ||
| queue.await((err)=>err ? done(err) : processLayers(layers, done)); | ||
| }; | ||
| processLayers(layers, finalize); | ||
| return; | ||
| } | ||
| // Topological mode: use topological-scheduler | ||
| const graph = result; | ||
| schedule(graph, (entry, _id, cb)=>{ | ||
| const spawnEntry = (entry, cb)=>{ | ||
| const spawnOptions = { | ||
@@ -102,3 +49,3 @@ ...options, | ||
| }); | ||
| cb(err, res); | ||
| cb(); | ||
| }; | ||
@@ -110,11 +57,18 @@ if (session) session.spawn(command, args, spawnOptions, { | ||
| else spawnStreaming(command, args, spawnOptions, { | ||
| prefix | ||
| prefix: process.stdout.isTTY ? prefix : undefined | ||
| }, next); | ||
| }, { | ||
| }; | ||
| // Topological mode: use topological-scheduler | ||
| if (options.topological) schedule(graph, (entry, _id, cb)=>spawnEntry(entry, cb), { | ||
| concurrency, | ||
| failDependents: options.failDependents | ||
| }, (err)=>{ | ||
| finalize(err); | ||
| }); | ||
| }, finalize); | ||
| else { | ||
| const sorted = entries.sort((a, b)=>path.dirname(a.path).localeCompare(path.dirname(b.path))); | ||
| const queue = new Queue(concurrency); | ||
| sorted.forEach((entry)=>queue.defer(spawnEntry.bind(null, entry))); | ||
| queue.await(finalize); | ||
| return; | ||
| } | ||
| }); | ||
| } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/worker.ts"],"sourcesContent":["import type { SpawnResult } from 'cross-spawn-cb';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport { createSession } from 'spawn-term';\nimport schedule, { type DependencyGraph } from 'topological-scheduler';\nimport packageLayers, { type PackageEntry } from './lib/packageLayers.ts';\n\nimport type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\n\nexport default function worker(command: string, args: string[], options: EachOptions, callback: EachCallback): void {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency;\n\n packageLayers(options, (err, result) => {\n if (err) return callback(err);\n\n // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI)\n const interactive = !!options.interactive;\n const quotedArgs = args.map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg));\n const session = createSession && !options.streaming && interactive ? createSession({ header: `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n // Show command header when not using terminal session (unless silent)\n if (!session && !options.silent) {\n console.log(`$ ${command} ${quotedArgs.join(' ')}`);\n }\n\n const results: EachResult[] = [];\n\n const finalize = (err?: Error): void => {\n if (err) (err as EachError).results = results;\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n };\n\n // Non-topological mode: layers is PackageEntry[][]\n if (Array.isArray(result)) {\n const layers = result as PackageEntry[][];\n const processLayers = (layers: PackageEntry[][], done: (err?: Error) => void): void => {\n if (layers.length === 0) {\n done();\n return;\n }\n const layerEntries = layers.shift();\n\n const queue = new Queue(concurrency);\n layerEntries.forEach((entry) => {\n queue.defer((cb: () => void) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): void => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb();\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n });\n });\n\n queue.await((err: Error) => (err ? done(err) : processLayers(layers, done)));\n };\n\n processLayers(layers, finalize);\n return;\n }\n\n // Topological mode: use topological-scheduler\n const graph = result as DependencyGraph<PackageEntry>;\n\n schedule(\n graph,\n (entry, _id, cb) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): void => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb(err, res);\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n },\n { concurrency, failDependents: options.failDependents },\n (err) => {\n finalize(err);\n }\n );\n });\n}\n"],"names":["path","Queue","spawnStreaming","createSession","schedule","packageLayers","worker","command","args","options","callback","depth","Infinity","concurrency","err","result","interactive","quotedArgs","map","arg","test","session","streaming","header","process","cwd","join","showStatusBar","silent","console","log","results","finalize","waitAndClose","Array","isArray","layers","processLayers","done","length","layerEntries","shift","queue","forEach","entry","defer","cb","spawnOptions","dirname","fullPath","prefix","next","res","message","indexOf","push","error","spawn","group","expanded","await","graph","_id","failDependents"],"mappings":"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"} | ||
| {"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/worker.ts"],"sourcesContent":["import type { SpawnResult } from 'cross-spawn-cb';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport { createSession } from 'spawn-term';\nimport schedule from 'topological-scheduler';\nimport packageLayers, { type PackageEntry } from './lib/packageLayers.ts';\n\nimport type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\n\nexport default function worker(command: string, args: string[], options: EachOptions, callback: EachCallback): void {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency;\n\n packageLayers(options, (err, entries, graph) => {\n if (err) return callback(err);\n if (entries.length === 0) return callback(null, []);\n\n // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI)\n const interactive = !!options.interactive;\n const quotedArgs = args.map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg));\n\n const header = `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`;\n const session = entries.length >= 2 && process.stdout.isTTY && createSession && !options.streaming && interactive ? createSession({ header, showStatusBar: true, interactive }) : null;\n if (!session && !options.silent) console.log(header);\n\n const results: EachResult[] = [];\n\n const finalize = (err?: Error): void => {\n if (err) (err as EachError).results = results;\n if (session) session.waitAndClose(() => (err ? callback(err) : callback(null, results)));\n else err ? callback(err) : callback(null, results);\n };\n\n const spawnEntry = (entry: PackageEntry, cb) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): void => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb();\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix: process.stdout.isTTY ? prefix : undefined }, next);\n };\n\n // Topological mode: use topological-scheduler\n if (options.topological) schedule(graph, (entry, _id, cb) => spawnEntry(entry, cb), { concurrency, failDependents: options.failDependents }, finalize);\n // Non-topological mode: layers is PackageEntry[]\n else {\n const sorted = entries.sort((a, b) => path.dirname(a.path).localeCompare(path.dirname(b.path))) as PackageEntry[];\n const queue = new Queue(concurrency);\n sorted.forEach((entry) => queue.defer(spawnEntry.bind(null, entry)));\n queue.await(finalize);\n return;\n }\n });\n}\n"],"names":["path","Queue","spawnStreaming","createSession","schedule","packageLayers","worker","command","args","options","callback","depth","Infinity","concurrency","err","entries","graph","length","interactive","quotedArgs","map","arg","test","header","process","cwd","join","session","stdout","isTTY","streaming","showStatusBar","silent","console","log","results","finalize","waitAndClose","spawnEntry","entry","cb","spawnOptions","dirname","fullPath","prefix","next","res","message","indexOf","push","error","result","spawn","group","expanded","undefined","topological","_id","failDependents","sorted","sort","a","b","localeCompare","queue","forEach","defer","bind","await"],"mappings":"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"} |
+1
-1
| { | ||
| "name": "each-package", | ||
| "version": "1.5.0", | ||
| "version": "1.5.1", | ||
| "description": "Run commands in each package folder starting with cwd skipping node_modules folders", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
90782
-8.32%876
-11.43%