@nexical/cli 0.11.0 → 0.11.2
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/.github/workflows/deploy.yml +1 -1
- package/.husky/pre-commit +1 -0
- package/.prettierignore +8 -0
- package/.prettierrc +7 -0
- package/GEMINI.md +36 -30
- package/README.md +85 -56
- package/dist/chunk-AC4B3HPJ.js +93 -0
- package/dist/chunk-AC4B3HPJ.js.map +1 -0
- package/dist/{chunk-JYASTIIW.js → chunk-PJIOCW2A.js} +1 -1
- package/dist/chunk-PJIOCW2A.js.map +1 -0
- package/dist/{chunk-WKERTCM6.js → chunk-Q7YLW5HJ.js} +5 -2
- package/dist/chunk-Q7YLW5HJ.js.map +1 -0
- package/dist/index.js +41 -12
- package/dist/index.js.map +1 -1
- package/dist/src/commands/init.d.ts +4 -1
- package/dist/src/commands/init.js +8 -4
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/module/add.d.ts +3 -1
- package/dist/src/commands/module/add.js +24 -13
- package/dist/src/commands/module/add.js.map +1 -1
- package/dist/src/commands/module/list.js +9 -5
- package/dist/src/commands/module/list.js.map +1 -1
- package/dist/src/commands/module/remove.d.ts +3 -1
- package/dist/src/commands/module/remove.js +13 -7
- package/dist/src/commands/module/remove.js.map +1 -1
- package/dist/src/commands/module/update.d.ts +3 -1
- package/dist/src/commands/module/update.js +7 -5
- package/dist/src/commands/module/update.js.map +1 -1
- package/dist/src/commands/run.d.ts +4 -1
- package/dist/src/commands/run.js +10 -2
- package/dist/src/commands/run.js.map +1 -1
- package/dist/src/commands/setup.js +9 -4
- package/dist/src/commands/setup.js.map +1 -1
- package/dist/src/utils/discovery.js +1 -1
- package/dist/src/utils/git.js +1 -1
- package/dist/src/utils/url-resolver.js +1 -1
- package/eslint.config.mjs +67 -0
- package/index.ts +34 -20
- package/package.json +56 -32
- package/src/commands/init.ts +79 -76
- package/src/commands/module/add.ts +158 -148
- package/src/commands/module/list.ts +61 -50
- package/src/commands/module/remove.ts +59 -54
- package/src/commands/module/update.ts +44 -42
- package/src/commands/run.ts +89 -81
- package/src/commands/setup.ts +70 -60
- package/src/utils/discovery.ts +98 -113
- package/src/utils/git.ts +35 -28
- package/src/utils/url-resolver.ts +50 -45
- package/test/e2e/lifecycle.e2e.test.ts +139 -131
- package/test/integration/commands/init.integration.test.ts +64 -64
- package/test/integration/commands/module.integration.test.ts +122 -122
- package/test/integration/commands/run.integration.test.ts +70 -63
- package/test/integration/utils/command-loading.integration.test.ts +40 -53
- package/test/unit/commands/init.test.ts +163 -128
- package/test/unit/commands/module/add.test.ts +312 -245
- package/test/unit/commands/module/list.test.ts +108 -91
- package/test/unit/commands/module/remove.test.ts +74 -67
- package/test/unit/commands/module/update.test.ts +74 -70
- package/test/unit/commands/run.test.ts +253 -201
- package/test/unit/commands/setup.test.ts +138 -128
- package/test/unit/utils/command-discovery.test.ts +138 -125
- package/test/unit/utils/git.test.ts +135 -117
- package/test/unit/utils/integration-helpers.test.ts +59 -49
- package/test/unit/utils/url-resolver.test.ts +46 -34
- package/test/utils/integration-helpers.ts +36 -29
- package/tsconfig.json +15 -25
- package/tsup.config.ts +14 -14
- package/vitest.config.ts +10 -10
- package/vitest.e2e.config.ts +6 -6
- package/vitest.integration.config.ts +17 -17
- package/dist/chunk-JYASTIIW.js.map +0 -1
- package/dist/chunk-OKXOCNXP.js +0 -105
- package/dist/chunk-OKXOCNXP.js.map +0 -1
- package/dist/chunk-WKERTCM6.js.map +0 -1
package/tsconfig.json
CHANGED
|
@@ -1,26 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"src/commands/**/*",
|
|
18
|
-
"src/utils/**/*",
|
|
19
|
-
"test/**/*",
|
|
20
|
-
"index.ts"
|
|
21
|
-
],
|
|
22
|
-
"exclude": [
|
|
23
|
-
"node_modules",
|
|
24
|
-
"dist"
|
|
25
|
-
]
|
|
26
|
-
}
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"lib": ["ESNext"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"outDir": "./dist"
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/commands/**/*", "src/utils/**/*", "test/**/*", "index.ts"],
|
|
15
|
+
"exclude": ["node_modules", "dist"]
|
|
16
|
+
}
|
package/tsup.config.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import type { Options } from 'tsup';
|
|
2
2
|
|
|
3
3
|
export default <Options>{
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
entry: ['index.ts', 'src/**/*.ts'],
|
|
5
|
+
format: ['esm'],
|
|
6
|
+
target: 'node18',
|
|
7
|
+
clean: true,
|
|
8
|
+
bundle: true,
|
|
9
|
+
sourcemap: true,
|
|
10
|
+
dts: true,
|
|
11
|
+
minify: false,
|
|
12
|
+
splitting: true,
|
|
13
|
+
outDir: 'dist',
|
|
14
|
+
shims: true, // Enable shims (including __require shim for legacy deps)
|
|
15
|
+
banner: {
|
|
16
|
+
js: 'import { createRequire } from "module"; const require = createRequire(import.meta.url);',
|
|
17
|
+
},
|
|
18
18
|
};
|
package/vitest.config.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { defineConfig } from 'vitest/config';
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
},
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
include: ['test/unit/**/*.test.ts'],
|
|
8
|
+
coverage: {
|
|
9
|
+
provider: 'v8',
|
|
10
|
+
reporter: ['text', 'json', 'html'],
|
|
11
|
+
include: ['src/**/*.ts'],
|
|
12
|
+
exclude: ['index.ts', '**/*.d.ts'],
|
|
14
13
|
},
|
|
14
|
+
},
|
|
15
15
|
});
|
package/vitest.e2e.config.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { defineConfig } from 'vitest/config';
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
include: ['test/e2e/**/*.test.ts'],
|
|
8
|
+
testTimeout: 60000,
|
|
9
|
+
},
|
|
10
10
|
});
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { defineConfig } from 'vitest/config';
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
},
|
|
16
|
-
coverage: {
|
|
17
|
-
provider: 'v8',
|
|
18
|
-
reporter: ['text', 'json', 'html'],
|
|
19
|
-
include: ['src/**/*.ts'],
|
|
20
|
-
},
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
include: ['test/integration/**/*.test.ts'],
|
|
8
|
+
// Increase timeout for integration tests as they do real IO
|
|
9
|
+
testTimeout: 60000,
|
|
10
|
+
fileParallelism: false,
|
|
11
|
+
server: {
|
|
12
|
+
deps: {
|
|
13
|
+
inline: ['@nexical/cli-core'],
|
|
14
|
+
},
|
|
21
15
|
},
|
|
16
|
+
coverage: {
|
|
17
|
+
provider: 'v8',
|
|
18
|
+
reporter: ['text', 'json', 'html'],
|
|
19
|
+
include: ['src/**/*.ts'],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
22
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/url-resolver.ts"],"sourcesContent":["/**\n * Resolves a git URL from various shorthand formats.\n * \n * Supported formats:\n * - gh@org/repo -> https://github.com/org/repo.git\n * - gh@org/repo//path -> https://github.com/org/repo.git//path\n * - https://github.com/org/repo -> https://github.com/org/repo.git\n * - https://github.com/org/repo.git -> https://github.com/org/repo.git\n * \n * @param url The URL string to resolve\n * @returns The fully qualified git URL with .git extension\n */\nexport function resolveGitUrl(url: string): string {\n if (!url) {\n throw new Error('URL cannot be empty');\n }\n\n let resolved = url;\n\n // Handle gh@ syntax\n if (resolved.startsWith('gh@')) {\n resolved = resolved.replace(/^gh@/, 'https://github.com/');\n }\n\n // Handle subpaths (split by //)\n // We must be careful not to split the protocol (e.g. https://)\n const protocolMatch = resolved.match(/^[a-z0-9]+:\\/\\//i);\n let splitIndex = -1;\n\n if (protocolMatch) {\n splitIndex = resolved.indexOf('//', protocolMatch[0].length);\n } else {\n splitIndex = resolved.indexOf('//');\n }\n\n let repoUrl = resolved;\n let subPath = '';\n\n if (splitIndex !== -1) {\n repoUrl = resolved.substring(0, splitIndex);\n subPath = resolved.substring(splitIndex + 2);\n }\n\n // Ensure .git extension, but ONLY for remote URLs (not local paths)\n const isLocal = repoUrl.startsWith('/') || repoUrl.startsWith('./') || repoUrl.startsWith('../') || repoUrl.startsWith('file:') || repoUrl.startsWith('~');\n\n if (!isLocal && !repoUrl.endsWith('.git')) {\n repoUrl += '.git';\n }\n\n // Reconstruction\n if (subPath) {\n return `${repoUrl}//${subPath}`;\n }\n\n return repoUrl;\n}\n"],"mappings":";;;;;;AAAA;AAYO,SAAS,cAAc,KAAqB;AAC/C,MAAI,CAAC,KAAK;AACN,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACzC;AAEA,MAAI,WAAW;AAGf,MAAI,SAAS,WAAW,KAAK,GAAG;AAC5B,eAAW,SAAS,QAAQ,QAAQ,qBAAqB;AAAA,EAC7D;AAIA,QAAM,gBAAgB,SAAS,MAAM,kBAAkB;AACvD,MAAI,aAAa;AAEjB,MAAI,eAAe;AACf,iBAAa,SAAS,QAAQ,MAAM,cAAc,CAAC,EAAE,MAAM;AAAA,EAC/D,OAAO;AACH,iBAAa,SAAS,QAAQ,IAAI;AAAA,EACtC;AAEA,MAAI,UAAU;AACd,MAAI,UAAU;AAEd,MAAI,eAAe,IAAI;AACnB,cAAU,SAAS,UAAU,GAAG,UAAU;AAC1C,cAAU,SAAS,UAAU,aAAa,CAAC;AAAA,EAC/C;AAGA,QAAM,UAAU,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,IAAI,KAAK,QAAQ,WAAW,KAAK,KAAK,QAAQ,WAAW,OAAO,KAAK,QAAQ,WAAW,GAAG;AAEzJ,MAAI,CAAC,WAAW,CAAC,QAAQ,SAAS,MAAM,GAAG;AACvC,eAAW;AAAA,EACf;AAGA,MAAI,SAAS;AACT,WAAO,GAAG,OAAO,KAAK,OAAO;AAAA,EACjC;AAEA,SAAO;AACX;","names":[]}
|
package/dist/chunk-OKXOCNXP.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { createRequire } from "module"; const require = createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
init_esm_shims
|
|
4
|
-
} from "./chunk-OYFWMYPG.js";
|
|
5
|
-
|
|
6
|
-
// src/utils/discovery.ts
|
|
7
|
-
init_esm_shims();
|
|
8
|
-
import { logger } from "@nexical/cli-core";
|
|
9
|
-
import path from "path";
|
|
10
|
-
import fs from "fs";
|
|
11
|
-
function discoverCommandDirectories(projectRoot) {
|
|
12
|
-
const directories = [];
|
|
13
|
-
const visited = /* @__PURE__ */ new Set();
|
|
14
|
-
const addDir = (dir) => {
|
|
15
|
-
const resolved = path.resolve(dir);
|
|
16
|
-
if (visited.has(resolved)) return;
|
|
17
|
-
if (fs.existsSync(resolved)) {
|
|
18
|
-
const isSrc = resolved.endsWith(path.join("src", "commands"));
|
|
19
|
-
const isDist = resolved.includes(path.join("dist", "src", "commands")) || resolved.endsWith(path.join("dist", "commands"));
|
|
20
|
-
if (isSrc) {
|
|
21
|
-
const distEquivalent1 = resolved.replace(path.sep + "src" + path.sep, path.sep + "dist" + path.sep + "src" + path.sep);
|
|
22
|
-
const distEquivalent2 = resolved.replace(path.sep + "src" + path.sep, path.sep + "dist" + path.sep);
|
|
23
|
-
if (visited.has(distEquivalent1) || visited.has(distEquivalent2)) {
|
|
24
|
-
logger.debug(`Skipping ${resolved} because a dist version is already registered`);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (isDist) {
|
|
29
|
-
const srcEquivalent1 = resolved.replace(path.sep + "dist" + path.sep, path.sep);
|
|
30
|
-
const srcEquivalent2 = resolved.replace(path.sep + "dist" + path.sep + "src" + path.sep, path.sep + "src" + path.sep);
|
|
31
|
-
if (visited.has(srcEquivalent1) || visited.has(srcEquivalent2)) {
|
|
32
|
-
logger.debug(`Skipping ${resolved} because a src version is already registered`);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
logger.debug(`Found command directory: ${resolved}`);
|
|
37
|
-
directories.push(resolved);
|
|
38
|
-
visited.add(resolved);
|
|
39
|
-
} else {
|
|
40
|
-
logger.debug(`Command directory not found (skipping): ${resolved}`);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
const possibleCorePaths = [
|
|
44
|
-
path.join(projectRoot, "src/commands")
|
|
45
|
-
];
|
|
46
|
-
possibleCorePaths.forEach(addDir);
|
|
47
|
-
const possibleModuleDirs = [
|
|
48
|
-
path.join(projectRoot, "modules"),
|
|
49
|
-
path.join(projectRoot, "src", "modules")
|
|
50
|
-
// Support both flat and src-nested
|
|
51
|
-
];
|
|
52
|
-
possibleModuleDirs.forEach((modulesDir) => {
|
|
53
|
-
if (fs.existsSync(modulesDir)) {
|
|
54
|
-
try {
|
|
55
|
-
const modules = fs.readdirSync(modulesDir);
|
|
56
|
-
for (const mod of modules) {
|
|
57
|
-
if (mod.startsWith(".")) continue;
|
|
58
|
-
const modPath = path.join(modulesDir, mod);
|
|
59
|
-
if (!fs.statSync(modPath).isDirectory()) continue;
|
|
60
|
-
const possibleCmdPaths = [
|
|
61
|
-
path.join(modPath, "dist/src/commands"),
|
|
62
|
-
path.join(modPath, "dist/commands"),
|
|
63
|
-
path.join(modPath, "src/commands")
|
|
64
|
-
];
|
|
65
|
-
for (const cmdPath of possibleCmdPaths) {
|
|
66
|
-
if (fs.existsSync(cmdPath) && fs.statSync(cmdPath).isDirectory()) {
|
|
67
|
-
addDir(cmdPath);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
} catch (e) {
|
|
72
|
-
logger.debug(`Error scanning modules directory ${modulesDir}: ${e.message}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
const packagesDir = path.join(projectRoot, "packages");
|
|
77
|
-
if (fs.existsSync(packagesDir)) {
|
|
78
|
-
try {
|
|
79
|
-
const packages = fs.readdirSync(packagesDir);
|
|
80
|
-
for (const pkg of packages) {
|
|
81
|
-
if (pkg.startsWith(".")) continue;
|
|
82
|
-
const pkgPath = path.join(packagesDir, pkg);
|
|
83
|
-
if (!fs.statSync(pkgPath).isDirectory()) continue;
|
|
84
|
-
const possibleCmdPaths = [
|
|
85
|
-
path.join(pkgPath, "dist/src/commands"),
|
|
86
|
-
path.join(pkgPath, "dist/commands"),
|
|
87
|
-
path.join(pkgPath, "src/commands")
|
|
88
|
-
];
|
|
89
|
-
for (const cmdPath of possibleCmdPaths) {
|
|
90
|
-
if (fs.existsSync(cmdPath) && fs.statSync(cmdPath).isDirectory()) {
|
|
91
|
-
addDir(cmdPath);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} catch (e) {
|
|
96
|
-
logger.debug(`Error scanning packages directory: ${e.message}`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return directories;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export {
|
|
103
|
-
discoverCommandDirectories
|
|
104
|
-
};
|
|
105
|
-
//# sourceMappingURL=chunk-OKXOCNXP.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/discovery.ts"],"sourcesContent":["import { logger } from '@nexical/cli-core';\nimport path from 'node:path';\nimport fs from 'node:fs';\n\n/**\n * Discovers command directories to load into the CLI.\n * \n * Scans for:\n * 1. Core commands (projectRoot/src/commands)\n * 2. Module commands (projectRoot/src/modules/ * /src/commands)\n * \n * @param projectRoot - The root directory of the project\n * @returns Array of absolute paths to command directories\n */\nexport function discoverCommandDirectories(projectRoot: string): string[] {\n const directories: string[] = [];\n const visited = new Set<string>();\n\n const addDir = (dir: string) => {\n const resolved = path.resolve(dir);\n if (visited.has(resolved)) return;\n\n if (fs.existsSync(resolved)) {\n // Check if we already have a similar path (e.g. dist/src/commands vs src/commands)\n // If we are adding src/commands and dist/src/commands already exists in visited, skip it\n // and vice versa.\n const isSrc = resolved.endsWith(path.join('src', 'commands'));\n const isDist = resolved.includes(path.join('dist', 'src', 'commands')) ||\n resolved.endsWith(path.join('dist', 'commands'));\n\n if (isSrc) {\n const distEquivalent1 = resolved.replace(path.sep + 'src' + path.sep, path.sep + 'dist' + path.sep + 'src' + path.sep);\n const distEquivalent2 = resolved.replace(path.sep + 'src' + path.sep, path.sep + 'dist' + path.sep);\n if (visited.has(distEquivalent1) || visited.has(distEquivalent2)) {\n logger.debug(`Skipping ${resolved} because a dist version is already registered`);\n return;\n }\n }\n\n if (isDist) {\n const srcEquivalent1 = resolved.replace(path.sep + 'dist' + path.sep, path.sep);\n const srcEquivalent2 = resolved.replace(path.sep + 'dist' + path.sep + 'src' + path.sep, path.sep + 'src' + path.sep);\n if (visited.has(srcEquivalent1) || visited.has(srcEquivalent2)) {\n // If we just added src, and now we find dist, we should actually REPLACE src with dist\n // but for now, the loop order prefers dist, so this case shouldn't happen much.\n // However, let's keep it simple.\n logger.debug(`Skipping ${resolved} because a src version is already registered`);\n return;\n }\n }\n\n logger.debug(`Found command directory: ${resolved}`);\n directories.push(resolved);\n visited.add(resolved);\n } else {\n logger.debug(`Command directory not found (skipping): ${resolved}`);\n }\n };\n\n // 1. Core commands\n // Search in projectRoot\n const possibleCorePaths = [\n path.join(projectRoot, 'src/commands'),\n ];\n\n possibleCorePaths.forEach(addDir);\n\n // 2. Module commands\n const possibleModuleDirs = [\n path.join(projectRoot, 'modules'),\n path.join(projectRoot, 'src', 'modules') // Support both flat and src-nested\n ];\n\n possibleModuleDirs.forEach(modulesDir => {\n if (fs.existsSync(modulesDir)) {\n try {\n const modules = fs.readdirSync(modulesDir);\n for (const mod of modules) {\n // exclude system files/dirs like .keep\n if (mod.startsWith('.')) continue;\n\n const modPath = path.join(modulesDir, mod);\n if (!fs.statSync(modPath).isDirectory()) continue;\n\n // Check for commands inside the module/package\n // Order matters: prefer dist if it exists\n const possibleCmdPaths = [\n path.join(modPath, 'dist/src/commands'),\n path.join(modPath, 'dist/commands'),\n path.join(modPath, 'src/commands')\n ];\n\n for (const cmdPath of possibleCmdPaths) {\n if (fs.existsSync(cmdPath) && fs.statSync(cmdPath).isDirectory()) {\n addDir(cmdPath);\n }\n }\n }\n } catch (e: any) {\n logger.debug(`Error scanning modules directory ${modulesDir}: ${e.message}`);\n }\n }\n });\n\n // 3. Package commands (e.g. packages/*)\n const packagesDir = path.join(projectRoot, 'packages');\n if (fs.existsSync(packagesDir)) {\n try {\n const packages = fs.readdirSync(packagesDir);\n for (const pkg of packages) {\n if (pkg.startsWith('.')) continue;\n\n const pkgPath = path.join(packagesDir, pkg);\n if (!fs.statSync(pkgPath).isDirectory()) continue;\n\n const possibleCmdPaths = [\n path.join(pkgPath, 'dist/src/commands'),\n path.join(pkgPath, 'dist/commands'),\n path.join(pkgPath, 'src/commands')\n ];\n\n for (const cmdPath of possibleCmdPaths) {\n if (fs.existsSync(cmdPath) && fs.statSync(cmdPath).isDirectory()) {\n addDir(cmdPath);\n }\n }\n }\n } catch (e: any) {\n logger.debug(`Error scanning packages directory: ${e.message}`);\n }\n }\n\n return directories;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/git.ts"],"sourcesContent":["import { logger, runCommand } from '@nexical/cli-core';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport async function clone(url: string, destination: string, options: { recursive?: boolean; depth?: number } = {}): Promise<void> {\n const { recursive = false, depth } = options;\n const cmd = `git clone ${recursive ? '--recursive ' : ''}${depth ? `--depth ${depth} ` : ''}${url} .`;\n logger.debug(`Git clone: ${url} to ${destination}`);\n await runCommand(cmd, destination);\n}\n\nexport async function getRemoteUrl(cwd: string, remote = 'origin'): Promise<string> {\n try {\n const { stdout } = await execAsync(`git remote get-url ${remote}`, { cwd });\n return stdout.trim();\n } catch (e) {\n console.error('getRemoteUrl failed:', e);\n return '';\n }\n}\n\nexport async function updateSubmodules(cwd: string): Promise<void> {\n logger.debug(`Updating submodules in ${cwd}`);\n await runCommand('git submodule foreach --recursive \"git checkout main && git pull origin main\"', cwd);\n}\n\nexport async function checkoutOrphan(branch: string, cwd: string): Promise<void> {\n await runCommand(`git checkout --orphan ${branch}`, cwd);\n}\n\nexport async function addAll(cwd: string): Promise<void> {\n await runCommand('git add -A', cwd);\n}\n\nexport async function commit(message: string, cwd: string): Promise<void> {\n // Escape quotes in message if needed, for now assuming simple messages\n await runCommand(`git commit -m \"${message}\"`, cwd);\n}\n\nexport async function deleteBranch(branch: string, cwd: string): Promise<void> {\n await runCommand(`git branch -D ${branch}`, cwd);\n}\n\nexport async function renameBranch(branch: string, cwd: string): Promise<void> {\n await runCommand(`git branch -m ${branch}`, cwd);\n}\n\nexport async function removeRemote(remote: string, cwd: string): Promise<void> {\n await runCommand(`git remote remove ${remote}`, cwd);\n}\n\nexport async function renameRemote(oldName: string, newName: string, cwd: string): Promise<void> {\n await runCommand(`git remote rename ${oldName} ${newName}`, cwd);\n}\n\nexport async function branchExists(branch: string, cwd: string): Promise<boolean> {\n try {\n await execAsync(`git show-ref --verify --quiet refs/heads/${branch}`, { cwd });\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;;AAAA;AAAA,SAAS,QAAQ,kBAAkB;AACnC,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAE1B,IAAM,YAAY,UAAU,IAAI;AAEhC,eAAsB,MAAM,KAAa,aAAqB,UAAmD,CAAC,GAAkB;AAChI,QAAM,EAAE,YAAY,OAAO,MAAM,IAAI;AACrC,QAAM,MAAM,aAAa,YAAY,iBAAiB,EAAE,GAAG,QAAQ,WAAW,KAAK,MAAM,EAAE,GAAG,GAAG;AACjG,SAAO,MAAM,cAAc,GAAG,OAAO,WAAW,EAAE;AAClD,QAAM,WAAW,KAAK,WAAW;AACrC;AAEA,eAAsB,aAAa,KAAa,SAAS,UAA2B;AAChF,MAAI;AACA,UAAM,EAAE,OAAO,IAAI,MAAM,UAAU,sBAAsB,MAAM,IAAI,EAAE,IAAI,CAAC;AAC1E,WAAO,OAAO,KAAK;AAAA,EACvB,SAAS,GAAG;AACR,YAAQ,MAAM,wBAAwB,CAAC;AACvC,WAAO;AAAA,EACX;AACJ;AAEA,eAAsB,iBAAiB,KAA4B;AAC/D,SAAO,MAAM,0BAA0B,GAAG,EAAE;AAC5C,QAAM,WAAW,iFAAiF,GAAG;AACzG;AAEA,eAAsB,eAAe,QAAgB,KAA4B;AAC7E,QAAM,WAAW,yBAAyB,MAAM,IAAI,GAAG;AAC3D;AAEA,eAAsB,OAAO,KAA4B;AACrD,QAAM,WAAW,cAAc,GAAG;AACtC;AAEA,eAAsB,OAAO,SAAiB,KAA4B;AAEtE,QAAM,WAAW,kBAAkB,OAAO,KAAK,GAAG;AACtD;AAEA,eAAsB,aAAa,QAAgB,KAA4B;AAC3E,QAAM,WAAW,iBAAiB,MAAM,IAAI,GAAG;AACnD;AAEA,eAAsB,aAAa,QAAgB,KAA4B;AAC3E,QAAM,WAAW,iBAAiB,MAAM,IAAI,GAAG;AACnD;AAEA,eAAsB,aAAa,QAAgB,KAA4B;AAC3E,QAAM,WAAW,qBAAqB,MAAM,IAAI,GAAG;AACvD;AAEA,eAAsB,aAAa,SAAiB,SAAiB,KAA4B;AAC7F,QAAM,WAAW,qBAAqB,OAAO,IAAI,OAAO,IAAI,GAAG;AACnE;AAEA,eAAsB,aAAa,QAAgB,KAA+B;AAC9E,MAAI;AACA,UAAM,UAAU,4CAA4C,MAAM,IAAI,EAAE,IAAI,CAAC;AAC7E,WAAO;AAAA,EACX,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;","names":[]}
|