@glasstrace/sdk 0.12.5 → 0.13.0

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.
@@ -0,0 +1,242 @@
1
+ import {
2
+ NEXT_CONFIG_NAMES
3
+ } from "./chunk-DXRZKKSO.js";
4
+
5
+ // src/cli/monorepo.ts
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+ function resolveProjectRoot(cwd) {
9
+ if (hasNextConfig(cwd)) {
10
+ return { projectRoot: cwd, isMonorepo: false };
11
+ }
12
+ if (hasNextDependency(cwd)) {
13
+ return { projectRoot: cwd, isMonorepo: false };
14
+ }
15
+ if (isMonorepoRoot(cwd)) {
16
+ const apps = findNextJsApps(cwd);
17
+ if (apps.length === 0) {
18
+ throw new Error(
19
+ "This is a monorepo but no Next.js apps were found in workspace packages."
20
+ );
21
+ }
22
+ if (apps.length === 1) {
23
+ const appDir = apps[0];
24
+ const relativePath = path.relative(cwd, appDir);
25
+ return {
26
+ projectRoot: appDir,
27
+ isMonorepo: true,
28
+ appRelativePath: relativePath
29
+ };
30
+ }
31
+ const appList = apps.map((app) => ` - ${path.relative(cwd, app)}`).join("\n");
32
+ throw new Error(
33
+ `Found multiple Next.js apps:
34
+ ${appList}
35
+ Run init from the specific app directory you want to instrument.`
36
+ );
37
+ }
38
+ throw new Error(
39
+ "No Next.js project found in the current directory.\nRun this command from your Next.js app directory, or from a monorepo root."
40
+ );
41
+ }
42
+ function hasNextConfig(dir) {
43
+ return NEXT_CONFIG_NAMES.some(
44
+ (name) => fs.existsSync(path.join(dir, name))
45
+ );
46
+ }
47
+ function hasNextDependency(dir) {
48
+ const packageJsonPath = path.join(dir, "package.json");
49
+ if (!fs.existsSync(packageJsonPath)) return false;
50
+ try {
51
+ const content = fs.readFileSync(packageJsonPath, "utf-8");
52
+ const pkg = JSON.parse(content);
53
+ const deps = pkg["dependencies"];
54
+ const devDeps = pkg["devDependencies"];
55
+ if (typeof deps === "object" && deps !== null && "next" in deps) return true;
56
+ if (typeof devDeps === "object" && devDeps !== null && "next" in devDeps) return true;
57
+ } catch {
58
+ }
59
+ return false;
60
+ }
61
+ function isMonorepoRoot(dir) {
62
+ if (fs.existsSync(path.join(dir, "pnpm-workspace.yaml"))) return true;
63
+ if (fs.existsSync(path.join(dir, "turbo.json"))) return true;
64
+ if (fs.existsSync(path.join(dir, "lerna.json"))) return true;
65
+ const packageJsonPath = path.join(dir, "package.json");
66
+ if (fs.existsSync(packageJsonPath)) {
67
+ try {
68
+ const content = fs.readFileSync(packageJsonPath, "utf-8");
69
+ const pkg = JSON.parse(content);
70
+ if (pkg["workspaces"] !== void 0) return true;
71
+ } catch {
72
+ }
73
+ }
74
+ return false;
75
+ }
76
+ function findNextJsApps(monorepoRoot) {
77
+ const { includeGlobs, negationPatterns } = collectWorkspaceGlobs(monorepoRoot);
78
+ if (includeGlobs.length === 0) {
79
+ throw new Error(
80
+ 'Monorepo detected but no workspace configuration found.\nAdd a "workspaces" field to package.json or create pnpm-workspace.yaml.'
81
+ );
82
+ }
83
+ const workspaceDirs = expandGlobs(monorepoRoot, includeGlobs);
84
+ const excludedDirs = expandGlobs(monorepoRoot, negationPatterns);
85
+ const excludedSet = new Set(excludedDirs);
86
+ const seen = /* @__PURE__ */ new Set();
87
+ const nextApps = [];
88
+ for (const dir of workspaceDirs) {
89
+ if (seen.has(dir)) continue;
90
+ seen.add(dir);
91
+ if (excludedSet.has(dir)) continue;
92
+ if (hasNextConfig(dir) || hasNextDependency(dir)) {
93
+ nextApps.push(dir);
94
+ }
95
+ }
96
+ return nextApps.sort();
97
+ }
98
+ function collectWorkspaceGlobs(root) {
99
+ const globs = [];
100
+ const negations = [];
101
+ const pnpmPath = path.join(root, "pnpm-workspace.yaml");
102
+ if (fs.existsSync(pnpmPath)) {
103
+ const content = fs.readFileSync(pnpmPath, "utf-8");
104
+ const parsed = parsePnpmWorkspaceYaml(content);
105
+ globs.push(...parsed.includeGlobs);
106
+ negations.push(...parsed.negationPatterns);
107
+ }
108
+ const packageJsonPath = path.join(root, "package.json");
109
+ if (fs.existsSync(packageJsonPath)) {
110
+ try {
111
+ const content = fs.readFileSync(packageJsonPath, "utf-8");
112
+ const pkg = JSON.parse(content);
113
+ globs.push(...parsePackageJsonWorkspaces(pkg));
114
+ } catch {
115
+ }
116
+ }
117
+ const lernaPath = path.join(root, "lerna.json");
118
+ if (fs.existsSync(lernaPath)) {
119
+ try {
120
+ const content = fs.readFileSync(lernaPath, "utf-8");
121
+ const lerna = JSON.parse(content);
122
+ const packages = lerna["packages"];
123
+ if (Array.isArray(packages)) {
124
+ for (const pkg of packages) {
125
+ if (typeof pkg === "string") {
126
+ globs.push(pkg);
127
+ }
128
+ }
129
+ }
130
+ } catch {
131
+ }
132
+ }
133
+ return {
134
+ includeGlobs: [...new Set(globs)],
135
+ negationPatterns: [...new Set(negations)]
136
+ };
137
+ }
138
+ function parsePnpmWorkspaceYaml(content) {
139
+ const lines = content.split("\n");
140
+ const includeGlobs = [];
141
+ const negationPatterns = [];
142
+ let inPackages = false;
143
+ for (const rawLine of lines) {
144
+ const trimmed = rawLine.trim();
145
+ if (/^packages\s*:/.test(trimmed)) {
146
+ inPackages = true;
147
+ continue;
148
+ }
149
+ if (inPackages && trimmed.length > 0 && !trimmed.startsWith("-") && !rawLine.startsWith(" ") && !rawLine.startsWith(" ")) {
150
+ inPackages = false;
151
+ continue;
152
+ }
153
+ if (!inPackages) continue;
154
+ const itemMatch = /^\s*-\s+(.+)$/.exec(rawLine);
155
+ if (!itemMatch) continue;
156
+ const value = itemMatch[1].trim().replace(/^["']|["']$/g, "");
157
+ if (value.length === 0) continue;
158
+ if (value.startsWith("!")) {
159
+ negationPatterns.push(value.slice(1));
160
+ continue;
161
+ }
162
+ includeGlobs.push(value);
163
+ }
164
+ return { includeGlobs, negationPatterns };
165
+ }
166
+ function parsePackageJsonWorkspaces(pkg) {
167
+ const workspaces = pkg["workspaces"];
168
+ if (workspaces === void 0 || workspaces === null) return [];
169
+ if (Array.isArray(workspaces)) {
170
+ return workspaces.filter((w) => typeof w === "string");
171
+ }
172
+ if (typeof workspaces === "object") {
173
+ const obj = workspaces;
174
+ const packages = obj["packages"];
175
+ if (Array.isArray(packages)) {
176
+ return packages.filter((p) => typeof p === "string");
177
+ }
178
+ }
179
+ return [];
180
+ }
181
+ function expandGlobs(root, globs) {
182
+ const dirs = [];
183
+ for (const glob of globs) {
184
+ const cleanGlob = glob.replace(/\/+$/, "");
185
+ if (cleanGlob.includes("**")) {
186
+ const prefix = cleanGlob.split("**")[0].replace(/\/+$/, "");
187
+ const baseDir = path.join(root, prefix);
188
+ if (fs.existsSync(baseDir)) {
189
+ dirs.push(...walkDirectories(baseDir));
190
+ }
191
+ } else if (cleanGlob.includes("*")) {
192
+ const parts = cleanGlob.split("*");
193
+ const baseDir = path.join(root, parts[0].replace(/\/+$/, ""));
194
+ const suffix = parts.slice(1).join("*");
195
+ if (!fs.existsSync(baseDir)) continue;
196
+ let entries;
197
+ try {
198
+ entries = fs.readdirSync(baseDir, { withFileTypes: true });
199
+ } catch {
200
+ continue;
201
+ }
202
+ for (const entry of entries) {
203
+ if (!entry.isDirectory()) continue;
204
+ if (suffix && !entry.name.endsWith(suffix)) continue;
205
+ dirs.push(path.join(baseDir, entry.name));
206
+ }
207
+ } else {
208
+ const targetDir = path.join(root, cleanGlob);
209
+ if (fs.existsSync(targetDir) && fs.statSync(targetDir).isDirectory()) {
210
+ dirs.push(targetDir);
211
+ }
212
+ }
213
+ }
214
+ return dirs;
215
+ }
216
+ function walkDirectories(baseDir) {
217
+ const result = [];
218
+ let entries;
219
+ try {
220
+ entries = fs.readdirSync(baseDir, { withFileTypes: true });
221
+ } catch {
222
+ return result;
223
+ }
224
+ for (const entry of entries) {
225
+ if (!entry.isDirectory()) continue;
226
+ if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
227
+ const fullPath = path.join(baseDir, entry.name);
228
+ if (fs.existsSync(path.join(fullPath, "package.json"))) {
229
+ result.push(fullPath);
230
+ }
231
+ result.push(...walkDirectories(fullPath));
232
+ }
233
+ return result;
234
+ }
235
+
236
+ export {
237
+ resolveProjectRoot,
238
+ isMonorepoRoot,
239
+ findNextJsApps,
240
+ parsePnpmWorkspaceYaml
241
+ };
242
+ //# sourceMappingURL=chunk-RFSCWIVN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/monorepo.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { NEXT_CONFIG_NAMES } from \"./constants.js\";\n\n/** Result of classifying the project root directory. */\nexport interface ProjectClassification {\n /** The directory to scaffold into (may differ from cwd for monorepos). */\n projectRoot: string;\n /** Whether this was auto-resolved from a monorepo root. */\n isMonorepo: boolean;\n /** If monorepo, the relative path from cwd to the resolved app. */\n appRelativePath?: string;\n}\n\n/**\n * Classifies the current directory and resolves the target project root.\n *\n * Classification logic:\n * 1. If the directory contains a Next.js config file, it is a Next.js app\n * directory. Returns it directly.\n * 1b. If no config file exists but package.json lists \"next\" as a dependency,\n * it is still a Next.js app (config files are optional since Next.js 12).\n * 2. If the directory contains monorepo markers (pnpm-workspace.yaml,\n * turbo.json, lerna.json, or a workspaces field in package.json),\n * scans workspace packages for Next.js apps.\n * 3. Otherwise, fails with a user-facing error.\n *\n * @param cwd - The current working directory\n * @returns The resolved project classification\n * @throws Error with a user-facing message if the location is invalid\n */\nexport function resolveProjectRoot(cwd: string): ProjectClassification {\n // Step 1: Check if cwd is a Next.js app directory (config file)\n if (hasNextConfig(cwd)) {\n return { projectRoot: cwd, isMonorepo: false };\n }\n\n // Step 1b: Check if cwd has \"next\" as a dependency (config is optional)\n if (hasNextDependency(cwd)) {\n return { projectRoot: cwd, isMonorepo: false };\n }\n\n // Step 2: Check for monorepo markers\n if (isMonorepoRoot(cwd)) {\n // findNextJsApps throws if no workspace globs are found (e.g., turbo.json\n // exists but no pnpm-workspace.yaml or workspaces in package.json)\n const apps = findNextJsApps(cwd);\n\n if (apps.length === 0) {\n throw new Error(\n \"This is a monorepo but no Next.js apps were found in workspace packages.\",\n );\n }\n\n if (apps.length === 1) {\n const appDir = apps[0];\n const relativePath = path.relative(cwd, appDir);\n return {\n projectRoot: appDir,\n isMonorepo: true,\n appRelativePath: relativePath,\n };\n }\n\n // Multiple apps found — cannot auto-resolve\n const appList = apps\n .map((app) => ` - ${path.relative(cwd, app)}`)\n .join(\"\\n\");\n throw new Error(\n `Found multiple Next.js apps:\\n${appList}\\nRun init from the specific app directory you want to instrument.`,\n );\n }\n\n // Step 3: Neither Next.js app nor monorepo\n throw new Error(\n \"No Next.js project found in the current directory.\\n\" +\n \"Run this command from your Next.js app directory, or from a monorepo root.\",\n );\n}\n\n/**\n * Checks whether the given directory contains a Next.js config file.\n */\nfunction hasNextConfig(dir: string): boolean {\n return NEXT_CONFIG_NAMES.some((name) =>\n fs.existsSync(path.join(dir, name)),\n );\n}\n\n/**\n * Checks whether the given directory's package.json lists \"next\" as a\n * dependency or devDependency. This handles the case where a Next.js app\n * has no explicit config file (config files are optional since Next.js 12).\n */\nfunction hasNextDependency(dir: string): boolean {\n const packageJsonPath = path.join(dir, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n\n try {\n const content = fs.readFileSync(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as Record<string, unknown>;\n const deps = pkg[\"dependencies\"];\n const devDeps = pkg[\"devDependencies\"];\n\n if (typeof deps === \"object\" && deps !== null && \"next\" in deps) return true;\n if (typeof devDeps === \"object\" && devDeps !== null && \"next\" in devDeps) return true;\n } catch {\n // Invalid JSON — not a Next.js indicator\n }\n\n return false;\n}\n\n/**\n * Detects monorepo markers in the given directory.\n *\n * Checks for:\n * - pnpm-workspace.yaml\n * - turbo.json\n * - lerna.json\n * - \"workspaces\" field in package.json\n */\nexport function isMonorepoRoot(dir: string): boolean {\n // Check for standalone monorepo marker files\n if (fs.existsSync(path.join(dir, \"pnpm-workspace.yaml\"))) return true;\n if (fs.existsSync(path.join(dir, \"turbo.json\"))) return true;\n if (fs.existsSync(path.join(dir, \"lerna.json\"))) return true;\n\n // Check for \"workspaces\" field in package.json\n const packageJsonPath = path.join(dir, \"package.json\");\n if (fs.existsSync(packageJsonPath)) {\n try {\n const content = fs.readFileSync(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as Record<string, unknown>;\n if (pkg[\"workspaces\"] !== undefined) return true;\n } catch {\n // Invalid JSON — not a monorepo indicator\n }\n }\n\n return false;\n}\n\n/**\n * Finds Next.js apps in workspace packages.\n *\n * Parses workspace globs from:\n * - pnpm-workspace.yaml (packages array)\n * - package.json workspaces field (string[] or { packages: string[] })\n * - lerna.json packages field (string[])\n *\n * Expands the workspace globs using filesystem traversal and returns\n * absolute paths of directories that contain a Next.js config file or\n * have \"next\" as a dependency in package.json.\n *\n * @param monorepoRoot - Absolute path to the monorepo root directory\n * @returns Sorted array of absolute paths to Next.js app directories\n */\nexport function findNextJsApps(monorepoRoot: string): string[] {\n const { includeGlobs, negationPatterns } = collectWorkspaceGlobs(monorepoRoot);\n\n if (includeGlobs.length === 0) {\n throw new Error(\n \"Monorepo detected but no workspace configuration found.\\n\" +\n 'Add a \"workspaces\" field to package.json or create pnpm-workspace.yaml.',\n );\n }\n\n const workspaceDirs = expandGlobs(monorepoRoot, includeGlobs);\n\n // Apply negation patterns: filter out directories matching any exclusion\n const excludedDirs = expandGlobs(monorepoRoot, negationPatterns);\n const excludedSet = new Set(excludedDirs);\n\n // Deduplicate and filter for Next.js apps\n const seen = new Set<string>();\n const nextApps: string[] = [];\n\n for (const dir of workspaceDirs) {\n if (seen.has(dir)) continue;\n seen.add(dir);\n if (excludedSet.has(dir)) continue;\n if (hasNextConfig(dir) || hasNextDependency(dir)) {\n nextApps.push(dir);\n }\n }\n\n return nextApps.sort();\n}\n\n/** Workspace globs split into include and negation patterns. */\nexport interface WorkspaceGlobs {\n includeGlobs: string[];\n negationPatterns: string[];\n}\n\n/**\n * Collects workspace globs from all supported monorepo config sources.\n * Returns deduplicated include globs and negation patterns separately.\n */\nfunction collectWorkspaceGlobs(root: string): WorkspaceGlobs {\n const globs: string[] = [];\n const negations: string[] = [];\n\n // 1. pnpm-workspace.yaml\n const pnpmPath = path.join(root, \"pnpm-workspace.yaml\");\n if (fs.existsSync(pnpmPath)) {\n const content = fs.readFileSync(pnpmPath, \"utf-8\");\n const parsed = parsePnpmWorkspaceYaml(content);\n globs.push(...parsed.includeGlobs);\n negations.push(...parsed.negationPatterns);\n }\n\n // 2. package.json workspaces\n const packageJsonPath = path.join(root, \"package.json\");\n if (fs.existsSync(packageJsonPath)) {\n try {\n const content = fs.readFileSync(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as Record<string, unknown>;\n globs.push(...parsePackageJsonWorkspaces(pkg));\n } catch {\n // Invalid JSON — skip\n }\n }\n\n // 3. lerna.json packages\n const lernaPath = path.join(root, \"lerna.json\");\n if (fs.existsSync(lernaPath)) {\n try {\n const content = fs.readFileSync(lernaPath, \"utf-8\");\n const lerna = JSON.parse(content) as Record<string, unknown>;\n const packages = lerna[\"packages\"];\n if (Array.isArray(packages)) {\n for (const pkg of packages) {\n if (typeof pkg === \"string\") {\n globs.push(pkg);\n }\n }\n }\n } catch {\n // Invalid JSON — skip\n }\n }\n\n // Deduplicate\n return {\n includeGlobs: [...new Set(globs)],\n negationPatterns: [...new Set(negations)],\n };\n}\n\n/**\n * Parses pnpm-workspace.yaml to extract workspace package globs.\n *\n * The format is simple enough to parse with string processing:\n * ```yaml\n * packages:\n * - \"apps/*\"\n * - packages/*\n * - '!packages/internal'\n * ```\n *\n * Handles both quoted and unquoted values. Negation patterns (lines\n * starting with !) are returned separately so callers can apply them\n * as exclusions after expanding include globs.\n *\n * @internal Exported for unit testing only.\n */\nexport function parsePnpmWorkspaceYaml(content: string): WorkspaceGlobs {\n const lines = content.split(\"\\n\");\n const includeGlobs: string[] = [];\n const negationPatterns: string[] = [];\n let inPackages = false;\n\n for (const rawLine of lines) {\n const trimmed = rawLine.trim();\n\n // Detect the `packages:` key\n if (/^packages\\s*:/.test(trimmed)) {\n inPackages = true;\n continue;\n }\n\n // Stop when we hit another top-level key (no leading whitespace before key)\n if (inPackages && trimmed.length > 0 && !trimmed.startsWith(\"-\") && !rawLine.startsWith(\" \") && !rawLine.startsWith(\"\\t\")) {\n inPackages = false;\n continue;\n }\n\n if (!inPackages) continue;\n\n // Parse list items: ` - \"glob\"` or ` - glob` or ` - 'glob'`\n const itemMatch = /^\\s*-\\s+(.+)$/.exec(rawLine);\n if (!itemMatch) continue;\n\n // Strip surrounding quotes (single or double)\n const value = itemMatch[1].trim().replace(/^[\"']|[\"']$/g, \"\");\n\n // Skip empty values\n if (value.length === 0) continue;\n\n // Collect negation patterns separately (strip the leading !)\n if (value.startsWith(\"!\")) {\n negationPatterns.push(value.slice(1));\n continue;\n }\n\n includeGlobs.push(value);\n }\n\n return { includeGlobs, negationPatterns };\n}\n\n/**\n * Extracts workspace globs from a parsed package.json object.\n *\n * Handles both forms:\n * - `\"workspaces\": [\"packages/*\", \"apps/*\"]`\n * - `\"workspaces\": { \"packages\": [\"packages/*\", \"apps/*\"] }`\n */\nfunction parsePackageJsonWorkspaces(pkg: Record<string, unknown>): string[] {\n const workspaces = pkg[\"workspaces\"];\n if (workspaces === undefined || workspaces === null) return [];\n\n // Array form: string[]\n if (Array.isArray(workspaces)) {\n return workspaces.filter((w): w is string => typeof w === \"string\");\n }\n\n // Object form: { packages: string[] }\n if (typeof workspaces === \"object\") {\n const obj = workspaces as Record<string, unknown>;\n const packages = obj[\"packages\"];\n if (Array.isArray(packages)) {\n return packages.filter((p): p is string => typeof p === \"string\");\n }\n }\n\n return [];\n}\n\n/**\n * Expands workspace globs into actual directory paths.\n *\n * Supports:\n * - `packages/*` — matches one level of directories under packages/\n * - `apps/*` — matches one level of directories under apps/\n * - `packages/foo` — matches a specific directory (literal path)\n * - `packages/**` — recursively walks for directories with package.json\n *\n * @param root - The monorepo root directory\n * @param globs - Workspace glob patterns to expand\n * @returns Array of absolute paths to matched directories\n */\nfunction expandGlobs(root: string, globs: string[]): string[] {\n const dirs: string[] = [];\n\n for (const glob of globs) {\n // Remove trailing slash if present\n const cleanGlob = glob.replace(/\\/+$/, \"\");\n\n if (cleanGlob.includes(\"**\")) {\n // Recursive glob — walk the directory tree\n const prefix = cleanGlob.split(\"**\")[0].replace(/\\/+$/, \"\");\n const baseDir = path.join(root, prefix);\n if (fs.existsSync(baseDir)) {\n dirs.push(...walkDirectories(baseDir));\n }\n } else if (cleanGlob.includes(\"*\")) {\n // Single-level wildcard — expand one directory level\n const parts = cleanGlob.split(\"*\");\n // For \"packages/*\", parts = [\"packages/\", \"\"]\n const baseDir = path.join(root, parts[0].replace(/\\/+$/, \"\"));\n const suffix = parts.slice(1).join(\"*\"); // Anything after the wildcard\n\n if (!fs.existsSync(baseDir)) continue;\n\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(baseDir, { withFileTypes: true });\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n // If there is a suffix pattern, the entry name must end with it\n if (suffix && !entry.name.endsWith(suffix)) continue;\n dirs.push(path.join(baseDir, entry.name));\n }\n } else {\n // Literal path — no wildcards\n const targetDir = path.join(root, cleanGlob);\n if (fs.existsSync(targetDir) && fs.statSync(targetDir).isDirectory()) {\n dirs.push(targetDir);\n }\n }\n }\n\n return dirs;\n}\n\n/**\n * Recursively walks a directory tree and returns all subdirectories\n * that contain a package.json (indicating they are workspace packages).\n * Skips node_modules and hidden directories.\n */\nfunction walkDirectories(baseDir: string): string[] {\n const result: string[] = [];\n\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(baseDir, { withFileTypes: true });\n } catch {\n return result;\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n // Skip node_modules and hidden directories\n if (entry.name === \"node_modules\" || entry.name.startsWith(\".\")) continue;\n\n const fullPath = path.join(baseDir, entry.name);\n\n // A workspace package should have a package.json\n if (fs.existsSync(path.join(fullPath, \"package.json\"))) {\n result.push(fullPath);\n }\n\n // Continue recursing for nested workspaces\n result.push(...walkDirectories(fullPath));\n }\n\n return result;\n}\n"],"mappings":"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","names":[]}