@supunkalharajayasinghe/project-cli 1.3.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.
- package/LICENSE +21 -0
- package/README.md +380 -0
- package/dist/commands/create.d.ts +3 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +48 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/greet.d.ts +3 -0
- package/dist/commands/greet.d.ts.map +1 -0
- package/dist/commands/greet.js +10 -0
- package/dist/commands/greet.js.map +1 -0
- package/dist/generators/applyAiPlan.d.ts +3 -0
- package/dist/generators/applyAiPlan.d.ts.map +1 -0
- package/dist/generators/applyAiPlan.js +426 -0
- package/dist/generators/applyAiPlan.js.map +1 -0
- package/dist/generators/applyFeatureModules.d.ts +4 -0
- package/dist/generators/applyFeatureModules.d.ts.map +1 -0
- package/dist/generators/applyFeatureModules.js +242 -0
- package/dist/generators/applyFeatureModules.js.map +1 -0
- package/dist/generators/applyFullstackPlan.d.ts +3 -0
- package/dist/generators/applyFullstackPlan.d.ts.map +1 -0
- package/dist/generators/applyFullstackPlan.js +413 -0
- package/dist/generators/applyFullstackPlan.js.map +1 -0
- package/dist/generators/applyPlan.d.ts +3 -0
- package/dist/generators/applyPlan.d.ts.map +1 -0
- package/dist/generators/applyPlan.js +22 -0
- package/dist/generators/applyPlan.js.map +1 -0
- package/dist/generators/applyWebsitePlan.d.ts +3 -0
- package/dist/generators/applyWebsitePlan.d.ts.map +1 -0
- package/dist/generators/applyWebsitePlan.js +1053 -0
- package/dist/generators/applyWebsitePlan.js.map +1 -0
- package/dist/generators/createNextBase.d.ts +3 -0
- package/dist/generators/createNextBase.d.ts.map +1 -0
- package/dist/generators/createNextBase.js +20 -0
- package/dist/generators/createNextBase.js.map +1 -0
- package/dist/generators/generateBasicProject.d.ts +3 -0
- package/dist/generators/generateBasicProject.d.ts.map +1 -0
- package/dist/generators/generateBasicProject.js +65 -0
- package/dist/generators/generateBasicProject.js.map +1 -0
- package/dist/generators/starterBranding.d.ts +9 -0
- package/dist/generators/starterBranding.d.ts.map +1 -0
- package/dist/generators/starterBranding.js +48 -0
- package/dist/generators/starterBranding.js.map +1 -0
- package/dist/generators/writeGeneratedReadme.d.ts +3 -0
- package/dist/generators/writeGeneratedReadme.d.ts.map +1 -0
- package/dist/generators/writeGeneratedReadme.js +99 -0
- package/dist/generators/writeGeneratedReadme.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/askBasicScaffoldOptions.d.ts +3 -0
- package/dist/prompts/askBasicScaffoldOptions.d.ts.map +1 -0
- package/dist/prompts/askBasicScaffoldOptions.js +36 -0
- package/dist/prompts/askBasicScaffoldOptions.js.map +1 -0
- package/dist/prompts/askCreatePlan.d.ts +3 -0
- package/dist/prompts/askCreatePlan.d.ts.map +1 -0
- package/dist/prompts/askCreatePlan.js +232 -0
- package/dist/prompts/askCreatePlan.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/files.d.ts +14 -0
- package/dist/utils/files.d.ts.map +1 -0
- package/dist/utils/files.js +47 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/generateSecret.d.ts +2 -0
- package/dist/utils/generateSecret.d.ts.map +1 -0
- package/dist/utils/generateSecret.js +5 -0
- package/dist/utils/generateSecret.js.map +1 -0
- package/dist/utils/pathExists.d.ts +2 -0
- package/dist/utils/pathExists.d.ts.map +1 -0
- package/dist/utils/pathExists.js +11 -0
- package/dist/utils/pathExists.js.map +1 -0
- package/dist/utils/runCommand.d.ts +8 -0
- package/dist/utils/runCommand.d.ts.map +1 -0
- package/dist/utils/runCommand.js +59 -0
- package/dist/utils/runCommand.js.map +1 -0
- package/dist/utils/strings.d.ts +3 -0
- package/dist/utils/strings.d.ts.map +1 -0
- package/dist/utils/strings.js +15 -0
- package/dist/utils/strings.js.map +1 -0
- package/dist/utils/validateFreeText.d.ts +13 -0
- package/dist/utils/validateFreeText.d.ts.map +1 -0
- package/dist/utils/validateFreeText.js +19 -0
- package/dist/utils/validateFreeText.js.map +1 -0
- package/dist/utils/validateProjectName.d.ts +7 -0
- package/dist/utils/validateProjectName.d.ts.map +1 -0
- package/dist/utils/validateProjectName.js +42 -0
- package/dist/utils/validateProjectName.js.map +1 -0
- package/dist/utils/writeJson.d.ts +2 -0
- package/dist/utils/writeJson.d.ts.map +1 -0
- package/dist/utils/writeJson.js +2 -0
- package/dist/utils/writeJson.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"askCreatePlan.js","sourceRoot":"","sources":["../../src/prompts/askCreatePlan.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export interface PackageJson {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
description: string;
|
|
5
|
+
main: string;
|
|
6
|
+
scripts: Record<string, string>;
|
|
7
|
+
devDependencies: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
export interface EslintConfig {
|
|
10
|
+
env: {
|
|
11
|
+
node: boolean;
|
|
12
|
+
};
|
|
13
|
+
extends: string[];
|
|
14
|
+
parser?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface BasicScaffoldOptions {
|
|
17
|
+
projectName: string;
|
|
18
|
+
targetPath: string;
|
|
19
|
+
useTypeScript: boolean;
|
|
20
|
+
includeLint: boolean;
|
|
21
|
+
includeJest: boolean;
|
|
22
|
+
includeDocker: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Blueprint is the main project category selected by the user.
|
|
26
|
+
*/
|
|
27
|
+
export type Blueprint = 'website' | 'fullstack-product' | 'ai-app';
|
|
28
|
+
/**
|
|
29
|
+
* Website shapes describe public-facing website structures.
|
|
30
|
+
*/
|
|
31
|
+
export type WebsiteShape = 'one-page' | 'multi-page';
|
|
32
|
+
/**
|
|
33
|
+
* Full-stack shapes describe production-style app structures.
|
|
34
|
+
*/
|
|
35
|
+
export type FullstackShape = 'saas' | 'dashboard' | 'custom';
|
|
36
|
+
/**
|
|
37
|
+
* AI shapes describe AI-first app structures.
|
|
38
|
+
*/
|
|
39
|
+
export type AiShape = 'chat' | 'assistant' | 'content-generator';
|
|
40
|
+
/**
|
|
41
|
+
* Shape is the specific structure inside a blueprint.
|
|
42
|
+
*/
|
|
43
|
+
export type ProjectShape = WebsiteShape | FullstackShape | AiShape;
|
|
44
|
+
/**
|
|
45
|
+
* Feature modules are optional capabilities applied to the generated project.
|
|
46
|
+
*/
|
|
47
|
+
export type FeatureModule = 'seo' | 'contact-form' | 'prisma' | 'postgresql' | 'redis' | 'docker' | 'github-actions' | 'ai-sdk' | 'env-example';
|
|
48
|
+
/**
|
|
49
|
+
* CreatePlan is the central object used by the future blueprint generator.
|
|
50
|
+
*
|
|
51
|
+
* Prompt answers should be converted into this object first.
|
|
52
|
+
* Generators should read this object instead of depending directly on prompts.
|
|
53
|
+
*/
|
|
54
|
+
export interface CreatePlan {
|
|
55
|
+
projectName: string;
|
|
56
|
+
targetPath: string;
|
|
57
|
+
blueprint: Blueprint;
|
|
58
|
+
shape: ProjectShape;
|
|
59
|
+
pages: string[];
|
|
60
|
+
sections: string[];
|
|
61
|
+
modules: FeatureModule[];
|
|
62
|
+
installDependencies: boolean;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,mBAAmB,GAAG,QAAQ,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,YAAY,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,mBAAmB,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,cAAc,GAAG,OAAO,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,KAAK,GACL,cAAc,GACd,QAAQ,GACR,YAAY,GACZ,OAAO,GACP,QAAQ,GACR,gBAAgB,GAChB,QAAQ,GACR,aAAa,CAAC;AAElB;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,mBAAmB,EAAE,OAAO,CAAC;CAC9B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class UnsafePathError extends Error {
|
|
2
|
+
constructor(attemptedPath: string, root: string);
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Throws if targetPath resolves outside root. Always resolves both
|
|
6
|
+
* arguments internally — never compare un-resolved strings, and never
|
|
7
|
+
* use String.prototype.startsWith() for this check.
|
|
8
|
+
*/
|
|
9
|
+
export declare function assertPathSafe(targetPath: string, root?: string): void;
|
|
10
|
+
export declare function ensureDir(dirPath: string, root?: string): Promise<void>;
|
|
11
|
+
export declare function writeFileSafe(filePath: string, content: string, root?: string): Promise<void>;
|
|
12
|
+
export declare function readJsonFile<T>(filePath: string, root?: string): Promise<T>;
|
|
13
|
+
export declare function writeJsonFile(filePath: string, value: unknown, root?: string): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":"AAGA,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAIhD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,MAAsB,GAAG,IAAI,CAiBrF;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5F;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAsB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAsB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAsB,GAAG,OAAO,CAAC,CAAC,CAAC,CAIhG;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,MAAsB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export class UnsafePathError extends Error {
|
|
4
|
+
constructor(attemptedPath, root) {
|
|
5
|
+
super(`Refused to write outside the project root.\n Root: ${root}\n Attempted: ${attemptedPath}`);
|
|
6
|
+
this.name = 'UnsafePathError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Throws if targetPath resolves outside root. Always resolves both
|
|
11
|
+
* arguments internally — never compare un-resolved strings, and never
|
|
12
|
+
* use String.prototype.startsWith() for this check.
|
|
13
|
+
*/
|
|
14
|
+
export function assertPathSafe(targetPath, root = process.cwd()) {
|
|
15
|
+
const resolvedRoot = path.resolve(root);
|
|
16
|
+
const resolvedTarget = path.resolve(targetPath);
|
|
17
|
+
const rel = path.relative(resolvedRoot, resolvedTarget);
|
|
18
|
+
// rel === '' → targetPath IS root itself (allowed)
|
|
19
|
+
// rel.startsWith('..') → escapes root via parent traversal
|
|
20
|
+
// path.isAbsolute(rel) → on Windows, path.relative() between two
|
|
21
|
+
// different drive letters returns the
|
|
22
|
+
// absolute `to` path rather than a relative
|
|
23
|
+
// one (e.g. relative('C:\foo','D:\bar') ===
|
|
24
|
+
// 'D:\bar') — must be caught here too.
|
|
25
|
+
const escapesRoot = rel !== '' && (rel.startsWith('..') || path.isAbsolute(rel));
|
|
26
|
+
if (escapesRoot) {
|
|
27
|
+
throw new UnsafePathError(resolvedTarget, resolvedRoot);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function ensureDir(dirPath, root = process.cwd()) {
|
|
31
|
+
assertPathSafe(dirPath, root);
|
|
32
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
export async function writeFileSafe(filePath, content, root = process.cwd()) {
|
|
35
|
+
assertPathSafe(filePath, root);
|
|
36
|
+
await ensureDir(path.dirname(filePath), root);
|
|
37
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
38
|
+
}
|
|
39
|
+
export async function readJsonFile(filePath, root = process.cwd()) {
|
|
40
|
+
assertPathSafe(filePath, root);
|
|
41
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
42
|
+
return JSON.parse(content);
|
|
43
|
+
}
|
|
44
|
+
export async function writeJsonFile(filePath, value, root = process.cwd()) {
|
|
45
|
+
await writeFileSafe(filePath, `${JSON.stringify(value, null, 2)}\n`, root);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,aAAqB,EAAE,IAAY;QAC7C,KAAK,CAAC,uDAAuD,IAAI,kBAAkB,aAAa,EAAE,CAAC,CAAC;QACpG,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB,EAAE,OAAe,OAAO,CAAC,GAAG,EAAE;IAC7E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAExD,8DAA8D;IAC9D,4DAA4D;IAC5D,kEAAkE;IAClE,+DAA+D;IAC/D,qEAAqE;IACrE,qEAAqE;IACrE,gEAAgE;IAChE,MAAM,WAAW,GAAG,GAAG,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAEjF,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,eAAe,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe,EAAE,OAAe,OAAO,CAAC,GAAG,EAAE;IAC3E,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,OAAe,EACf,OAAe,OAAO,CAAC,GAAG,EAAE;IAE5B,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC/B,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,QAAgB,EAAE,OAAe,OAAO,CAAC,GAAG,EAAE;IAClF,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,KAAc,EACd,OAAe,OAAO,CAAC,GAAG,EAAE;IAE5B,MAAM,aAAa,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateSecret.d.ts","sourceRoot":"","sources":["../../src/utils/generateSecret.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,CAAC,KAAK,SAAK,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateSecret.js","sourceRoot":"","sources":["../../src/utils/generateSecret.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,UAAU,cAAc,CAAC,KAAK,GAAG,EAAE;IACvC,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathExists.d.ts","sourceRoot":"","sources":["../../src/utils/pathExists.ts"],"names":[],"mappings":"AAEA,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathExists.js","sourceRoot":"","sources":["../../src/utils/pathExists.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare const ALLOWED_COMMANDS: {
|
|
2
|
+
readonly npm: "npm.cmd" | "npm";
|
|
3
|
+
readonly npx: "npx.cmd" | "npx";
|
|
4
|
+
};
|
|
5
|
+
type AllowedCommand = keyof typeof ALLOWED_COMMANDS;
|
|
6
|
+
export declare function runCommand(command: AllowedCommand, args: string[], cwd: string): Promise<void>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=runCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCommand.d.ts","sourceRoot":"","sources":["../../src/utils/runCommand.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,gBAAgB;;;CAGZ,CAAC;AAEX,KAAK,cAAc,GAAG,MAAM,OAAO,gBAAgB,CAAC;AAEpD,wBAAsB,UAAU,CAC9B,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC,CA0Cf"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const ALLOWED_COMMANDS = {
|
|
4
|
+
npm: process.platform === 'win32' ? 'npm.cmd' : 'npm',
|
|
5
|
+
npx: process.platform === 'win32' ? 'npx.cmd' : 'npx',
|
|
6
|
+
};
|
|
7
|
+
export async function runCommand(command, args, cwd) {
|
|
8
|
+
const resolvedCommand = ALLOWED_COMMANDS[command];
|
|
9
|
+
if (!resolvedCommand) {
|
|
10
|
+
throw new Error(`Unapproved command execution blocked: ${command}`);
|
|
11
|
+
}
|
|
12
|
+
// Sanity check arguments for command injection sequences
|
|
13
|
+
for (const arg of args) {
|
|
14
|
+
if (/[\n\r;&|`$%^]/u.test(arg)) {
|
|
15
|
+
throw new Error(`Potential command injection attempt blocked in argument: ${arg}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
await new Promise((resolve, reject) => {
|
|
19
|
+
const child = process.platform === 'win32'
|
|
20
|
+
? spawn(getWindowsCommandProcessor(), ['/d', '/s', '/c', buildWindowsCommand(resolvedCommand, args)], {
|
|
21
|
+
cwd,
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
shell: false,
|
|
24
|
+
})
|
|
25
|
+
: spawn(resolvedCommand, args, {
|
|
26
|
+
cwd,
|
|
27
|
+
stdio: 'inherit',
|
|
28
|
+
shell: false,
|
|
29
|
+
});
|
|
30
|
+
child.on('error', reject);
|
|
31
|
+
child.on('close', (code) => {
|
|
32
|
+
if (code === 0) {
|
|
33
|
+
resolve();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
reject(new Error(`${resolvedCommand} ${args.join(' ')} failed with code ${code}`));
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function getWindowsCommandProcessor() {
|
|
41
|
+
return (process.env.ComSpec ??
|
|
42
|
+
path.join(process.env.SystemRoot ?? process.env.WINDIR ?? 'C:\\Windows', 'System32', 'cmd.exe'));
|
|
43
|
+
}
|
|
44
|
+
function buildWindowsCommand(command, args) {
|
|
45
|
+
return [command, ...args].map(quoteWindowsArg).join(' ');
|
|
46
|
+
}
|
|
47
|
+
function quoteWindowsArg(value) {
|
|
48
|
+
if (value.length === 0) {
|
|
49
|
+
return '""';
|
|
50
|
+
}
|
|
51
|
+
if (!/[\s"\\]/u.test(value)) {
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
const escapedValue = value
|
|
55
|
+
.replace(/\\/gu, '\\\\')
|
|
56
|
+
.replace(/"/gu, '\\"');
|
|
57
|
+
return `"${escapedValue}"`;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=runCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCommand.js","sourceRoot":"","sources":["../../src/utils/runCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/utils/strings.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7C"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function toPascal(value) {
|
|
2
|
+
return value
|
|
3
|
+
.split(/[-_\s]+/)
|
|
4
|
+
.filter(Boolean)
|
|
5
|
+
.map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)
|
|
6
|
+
.join('');
|
|
7
|
+
}
|
|
8
|
+
export function toTitle(value) {
|
|
9
|
+
return value
|
|
10
|
+
.split(/[-_\s]+/)
|
|
11
|
+
.filter(Boolean)
|
|
12
|
+
.map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)
|
|
13
|
+
.join(' ');
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=strings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.js","sourceRoot":"","sources":["../../src/utils/strings.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,OAAO,KAAK;SACT,KAAK,CAAC,SAAS,CAAC;SAChB,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,KAAK,CAAC,SAAS,CAAC;SAChB,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
reason?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function validateFreeText(value: string, opts: {
|
|
6
|
+
maxLength: number;
|
|
7
|
+
fieldName: string;
|
|
8
|
+
}): ValidationResult;
|
|
9
|
+
export declare function validateFreeTextPrompt(value: string, opts: {
|
|
10
|
+
maxLength: number;
|
|
11
|
+
fieldName: string;
|
|
12
|
+
}): true | string;
|
|
13
|
+
//# sourceMappingURL=validateFreeText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateFreeText.d.ts","sourceRoot":"","sources":["../../src/utils/validateFreeText.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC7C,gBAAgB,CAelB;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC7C,IAAI,GAAG,MAAM,CAGf"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function validateFreeText(value, opts) {
|
|
2
|
+
if (value.length > opts.maxLength) {
|
|
3
|
+
return { valid: false, reason: `${opts.fieldName} must be ${opts.maxLength} characters or fewer.` };
|
|
4
|
+
}
|
|
5
|
+
// Reject control characters other than tab/newline/carriage return.
|
|
6
|
+
// \x1B (ESC) is the one that matters most — it starts ANSI/VT100
|
|
7
|
+
// escape sequences, which could manipulate terminal output if this
|
|
8
|
+
// value is ever printed directly in a console summary.
|
|
9
|
+
// eslint-disable-next-line no-control-regex
|
|
10
|
+
if (/[\x00-\x08\x0B\x0C\x0E-\x1F]/.test(value)) {
|
|
11
|
+
return { valid: false, reason: `${opts.fieldName} contains invalid control characters.` };
|
|
12
|
+
}
|
|
13
|
+
return { valid: true };
|
|
14
|
+
}
|
|
15
|
+
export function validateFreeTextPrompt(value, opts) {
|
|
16
|
+
const result = validateFreeText(value, opts);
|
|
17
|
+
return result.valid ? true : (result.reason ?? 'Invalid input.');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=validateFreeText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateFreeText.js","sourceRoot":"","sources":["../../src/utils/validateFreeText.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,gBAAgB,CAC9B,KAAa,EACb,IAA8C;IAE9C,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,YAAY,IAAI,CAAC,SAAS,uBAAuB,EAAE,CAAC;IACtG,CAAC;IAED,oEAAoE;IACpE,iEAAiE;IACjE,mEAAmE;IACnE,uDAAuD;IACvD,4CAA4C;IAC5C,IAAI,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,uCAAuC,EAAE,CAAC;IAC5F,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAAa,EACb,IAA8C;IAE9C,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,gBAAgB,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
reason?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function validateProjectName(name: string): ValidationResult;
|
|
6
|
+
export declare function validateProjectNamePrompt(name: string): true | string;
|
|
7
|
+
//# sourceMappingURL=validateProjectName.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateProjectName.d.ts","sourceRoot":"","sources":["../../src/utils/validateProjectName.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAmClE;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
const WINDOWS_RESERVED = new Set([
|
|
3
|
+
'CON', 'PRN', 'AUX', 'NUL',
|
|
4
|
+
'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
|
|
5
|
+
'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9',
|
|
6
|
+
]);
|
|
7
|
+
const NAME_PATTERN = /^[a-z0-9][a-z0-9-_]*$/i;
|
|
8
|
+
const MAX_LENGTH = 100;
|
|
9
|
+
export function validateProjectName(name) {
|
|
10
|
+
if (!name || name.trim().length === 0) {
|
|
11
|
+
return { valid: false, reason: 'Project name cannot be empty.' };
|
|
12
|
+
}
|
|
13
|
+
const trimmed = name.trim();
|
|
14
|
+
if (trimmed.length > MAX_LENGTH) {
|
|
15
|
+
return { valid: false, reason: `Project name must be ${MAX_LENGTH} characters or fewer.` };
|
|
16
|
+
}
|
|
17
|
+
if (trimmed.includes('..') || trimmed.includes('/') || trimmed.includes('\\')) {
|
|
18
|
+
return { valid: false, reason: 'Project name cannot contain path separators or ".." sequences.' };
|
|
19
|
+
}
|
|
20
|
+
if (!NAME_PATTERN.test(trimmed)) {
|
|
21
|
+
return {
|
|
22
|
+
valid: false,
|
|
23
|
+
reason: 'Project name must start with a letter or number, and contain only letters, numbers, hyphens, and underscores.',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const upperName = trimmed.toUpperCase();
|
|
27
|
+
const baseName = upperName.split('.')[0] || '';
|
|
28
|
+
if (WINDOWS_RESERVED.has(upperName) || WINDOWS_RESERVED.has(baseName)) {
|
|
29
|
+
return { valid: false, reason: `"${trimmed}" is a reserved name on Windows and cannot be used.` };
|
|
30
|
+
}
|
|
31
|
+
const resolved = path.resolve(process.cwd(), trimmed);
|
|
32
|
+
const rel = path.relative(process.cwd(), resolved);
|
|
33
|
+
if (rel === '' || rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
34
|
+
return { valid: false, reason: 'Project name resolves outside the current directory.' };
|
|
35
|
+
}
|
|
36
|
+
return { valid: true };
|
|
37
|
+
}
|
|
38
|
+
export function validateProjectNamePrompt(name) {
|
|
39
|
+
const result = validateProjectName(name);
|
|
40
|
+
return result.valid ? true : (result.reason ?? 'Invalid project name.');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=validateProjectName.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateProjectName.js","sourceRoot":"","sources":["../../src/utils/validateProjectName.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IAC1B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACtE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CACvE,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAC9C,MAAM,UAAU,GAAG,GAAG,CAAC;AAOvB,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAE5B,IAAI,OAAO,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;QAChC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,UAAU,uBAAuB,EAAE,CAAC;IAC7F,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,gEAAgE,EAAE,CAAC;IACpG,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,+GAA+G;SACxH,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,OAAO,qDAAqD,EAAE,CAAC;IACpG,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IACnD,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,sDAAsD,EAAE,CAAC;IAC1F,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,uBAAuB,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeJson.d.ts","sourceRoot":"","sources":["../../src/utils/writeJson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeJson.js","sourceRoot":"","sources":["../../src/utils/writeJson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@supunkalharajayasinghe/project-cli",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "> A powerful, strongly-typed command-line interface.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"my-cli": "./dist/index.js",
|
|
8
|
+
"project-cli": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"dev": "tsx src/index.ts",
|
|
24
|
+
"start": "node dist/index.js",
|
|
25
|
+
"test": "vitest run"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/SupunKalharaJayasinghe/ts-cli-tool.git"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [],
|
|
32
|
+
"author": "Supun Kalhara Jayasinghe",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"type": "module",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/SupunKalharaJayasinghe/ts-cli-tool/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/SupunKalharaJayasinghe/ts-cli-tool#readme",
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@inquirer/prompts": "^8.5.2",
|
|
41
|
+
"commander": "^12.1.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^20.14.9",
|
|
45
|
+
"tsx": "^4.16.2",
|
|
46
|
+
"typescript": "^5.6.0",
|
|
47
|
+
"vitest": "^4.1.9"
|
|
48
|
+
}
|
|
49
|
+
}
|