@fnd-platform/cli 1.0.0-alpha.1
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 +224 -0
- package/lib/bin/fnd.d.ts +3 -0
- package/lib/bin/fnd.d.ts.map +1 -0
- package/lib/bin/fnd.js +9 -0
- package/lib/bin/fnd.js.map +1 -0
- package/lib/commands/add.d.ts +28 -0
- package/lib/commands/add.d.ts.map +1 -0
- package/lib/commands/add.js +547 -0
- package/lib/commands/add.js.map +1 -0
- package/lib/commands/build.d.ts +62 -0
- package/lib/commands/build.d.ts.map +1 -0
- package/lib/commands/build.js +155 -0
- package/lib/commands/build.js.map +1 -0
- package/lib/commands/deploy.d.ts +67 -0
- package/lib/commands/deploy.d.ts.map +1 -0
- package/lib/commands/deploy.js +160 -0
- package/lib/commands/deploy.js.map +1 -0
- package/lib/commands/index.d.ts +6 -0
- package/lib/commands/index.d.ts.map +1 -0
- package/lib/commands/index.js +14 -0
- package/lib/commands/index.js.map +1 -0
- package/lib/commands/new.d.ts +47 -0
- package/lib/commands/new.d.ts.map +1 -0
- package/lib/commands/new.js +199 -0
- package/lib/commands/new.js.map +1 -0
- package/lib/commands/synth.d.ts +39 -0
- package/lib/commands/synth.d.ts.map +1 -0
- package/lib/commands/synth.js +72 -0
- package/lib/commands/synth.js.map +1 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +43 -0
- package/lib/index.js.map +1 -0
- package/lib/lib/infra-generator.d.ts +24 -0
- package/lib/lib/infra-generator.d.ts.map +1 -0
- package/lib/lib/infra-generator.js +193 -0
- package/lib/lib/infra-generator.js.map +1 -0
- package/lib/lib/logger.d.ts +50 -0
- package/lib/lib/logger.d.ts.map +1 -0
- package/lib/lib/logger.js +102 -0
- package/lib/lib/logger.js.map +1 -0
- package/lib/lib/nx-stats.d.ts +69 -0
- package/lib/lib/nx-stats.d.ts.map +1 -0
- package/lib/lib/nx-stats.js +117 -0
- package/lib/lib/nx-stats.js.map +1 -0
- package/lib/lib/project.d.ts +17 -0
- package/lib/lib/project.d.ts.map +1 -0
- package/lib/lib/project.js +49 -0
- package/lib/lib/project.js.map +1 -0
- package/lib/lib/templates.d.ts +16 -0
- package/lib/lib/templates.d.ts.map +1 -0
- package/lib/lib/templates.js +42 -0
- package/lib/lib/templates.js.map +1 -0
- package/lib/lib/timer.d.ts +120 -0
- package/lib/lib/timer.d.ts.map +1 -0
- package/lib/lib/timer.js +127 -0
- package/lib/lib/timer.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CACHE_HIT_TARGET = void 0;
|
|
4
|
+
exports.parseNxOutput = parseNxOutput;
|
|
5
|
+
exports.getCacheDirectoryStats = getCacheDirectoryStats;
|
|
6
|
+
exports.formatCacheStats = formatCacheStats;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
/**
|
|
10
|
+
* Target cache hit ratio (80%).
|
|
11
|
+
*/
|
|
12
|
+
exports.CACHE_HIT_TARGET = 0.8;
|
|
13
|
+
/**
|
|
14
|
+
* Parses NX output to extract cache statistics.
|
|
15
|
+
*
|
|
16
|
+
* @param output - NX command output
|
|
17
|
+
* @returns Cache statistics or null if parsing fails
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const output = `
|
|
22
|
+
* > NX Successfully ran target build for 5 projects (234ms)
|
|
23
|
+
*
|
|
24
|
+
* Nx read the output from the cache instead of running the command for 4 out of 5 tasks.
|
|
25
|
+
* `;
|
|
26
|
+
* const stats = parseNxOutput(output);
|
|
27
|
+
* // { totalTasks: 5, cacheHits: 4, cacheMisses: 1, hitRatio: 0.8, ... }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
function parseNxOutput(output) {
|
|
31
|
+
// Match patterns like "4 out of 5 tasks" or "read from cache for X tasks"
|
|
32
|
+
const cacheMatch = output.match(/(?:instead of running the command for |from cache for )(\d+) out of (\d+) tasks/i);
|
|
33
|
+
if (cacheMatch) {
|
|
34
|
+
const cacheHits = parseInt(cacheMatch[1], 10);
|
|
35
|
+
const totalTasks = parseInt(cacheMatch[2], 10);
|
|
36
|
+
const cacheMisses = totalTasks - cacheHits;
|
|
37
|
+
const hitRatio = totalTasks > 0 ? cacheHits / totalTasks : 0;
|
|
38
|
+
return {
|
|
39
|
+
totalTasks,
|
|
40
|
+
cacheHits,
|
|
41
|
+
cacheMisses,
|
|
42
|
+
hitRatio,
|
|
43
|
+
hitRatioFormatted: `${(hitRatio * 100).toFixed(1)}%`,
|
|
44
|
+
meetsTarget: hitRatio >= exports.CACHE_HIT_TARGET,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// Check for "Successfully ran target X for N projects"
|
|
48
|
+
const successMatch = output.match(/Successfully ran target \w+ for (\d+) projects?/i);
|
|
49
|
+
if (successMatch) {
|
|
50
|
+
const totalTasks = parseInt(successMatch[1], 10);
|
|
51
|
+
// If no cache message, all were cache misses
|
|
52
|
+
return {
|
|
53
|
+
totalTasks,
|
|
54
|
+
cacheHits: 0,
|
|
55
|
+
cacheMisses: totalTasks,
|
|
56
|
+
hitRatio: 0,
|
|
57
|
+
hitRatioFormatted: '0.0%',
|
|
58
|
+
meetsTarget: false,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Gets cache statistics from the NX cache directory.
|
|
65
|
+
*
|
|
66
|
+
* @param projectRoot - Root directory of the project
|
|
67
|
+
* @returns Cache statistics based on cache directory analysis
|
|
68
|
+
*/
|
|
69
|
+
function getCacheDirectoryStats(projectRoot) {
|
|
70
|
+
const cacheDir = (0, path_1.join)(projectRoot, 'node_modules', '.cache', 'nx');
|
|
71
|
+
if (!(0, fs_1.existsSync)(cacheDir)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const walkDir = (dir, state) => {
|
|
75
|
+
const entries = (0, fs_1.readdirSync)(dir);
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
const fullPath = (0, path_1.join)(dir, entry);
|
|
78
|
+
const stat = (0, fs_1.statSync)(fullPath);
|
|
79
|
+
if (stat.isDirectory()) {
|
|
80
|
+
state.entryCount++;
|
|
81
|
+
walkDir(fullPath, state);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
state.totalSize += stat.size;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
try {
|
|
89
|
+
const state = { totalSize: 0, entryCount: 0 };
|
|
90
|
+
walkDir(cacheDir, state);
|
|
91
|
+
return {
|
|
92
|
+
cacheEntries: state.entryCount,
|
|
93
|
+
cacheSizeMB: Math.round((state.totalSize / (1024 * 1024)) * 100) / 100,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Creates a formatted report of NX cache statistics.
|
|
102
|
+
*
|
|
103
|
+
* @param stats - Cache statistics to report
|
|
104
|
+
* @returns Formatted string for display
|
|
105
|
+
*/
|
|
106
|
+
function formatCacheStats(stats) {
|
|
107
|
+
const lines = [
|
|
108
|
+
'NX Cache Statistics:',
|
|
109
|
+
` Total tasks: ${stats.totalTasks}`,
|
|
110
|
+
` Cache hits: ${stats.cacheHits}`,
|
|
111
|
+
` Cache misses: ${stats.cacheMisses}`,
|
|
112
|
+
` Hit ratio: ${stats.hitRatioFormatted}`,
|
|
113
|
+
` Target (>80%): ${stats.meetsTarget ? 'PASS' : 'FAIL'}`,
|
|
114
|
+
];
|
|
115
|
+
return lines.join('\n');
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=nx-stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nx-stats.js","sourceRoot":"","sources":["../../src/lib/nx-stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Searches upward from a starting directory to find the project root.
|
|
3
|
+
* The project root is identified by the presence of a .projenrc.ts file.
|
|
4
|
+
*
|
|
5
|
+
* @param startDir - Directory to start searching from (defaults to cwd)
|
|
6
|
+
* @returns The project root path, or null if not found
|
|
7
|
+
*/
|
|
8
|
+
export declare function findProjectRoot(startDir?: string): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Finds the project root or throws an error if not in a project.
|
|
11
|
+
*
|
|
12
|
+
* @param startDir - Directory to start searching from (defaults to cwd)
|
|
13
|
+
* @returns The project root path
|
|
14
|
+
* @throws Error if not inside an fnd-platform project
|
|
15
|
+
*/
|
|
16
|
+
export declare function requireProjectRoot(startDir?: string): string;
|
|
17
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/lib/project.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAoB/E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAU3E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findProjectRoot = findProjectRoot;
|
|
4
|
+
exports.requireProjectRoot = requireProjectRoot;
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
/**
|
|
8
|
+
* Searches upward from a starting directory to find the project root.
|
|
9
|
+
* The project root is identified by the presence of a .projenrc.ts file.
|
|
10
|
+
*
|
|
11
|
+
* @param startDir - Directory to start searching from (defaults to cwd)
|
|
12
|
+
* @returns The project root path, or null if not found
|
|
13
|
+
*/
|
|
14
|
+
function findProjectRoot(startDir = process.cwd()) {
|
|
15
|
+
let currentDir = (0, path_1.resolve)(startDir);
|
|
16
|
+
// Traverse up the directory tree
|
|
17
|
+
let reachedRoot = false;
|
|
18
|
+
while (!reachedRoot) {
|
|
19
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(currentDir, '.projenrc.ts'))) {
|
|
20
|
+
return currentDir;
|
|
21
|
+
}
|
|
22
|
+
const parent = (0, path_1.dirname)(currentDir);
|
|
23
|
+
if (parent === currentDir) {
|
|
24
|
+
// Reached filesystem root
|
|
25
|
+
reachedRoot = true;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
currentDir = parent;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Finds the project root or throws an error if not in a project.
|
|
35
|
+
*
|
|
36
|
+
* @param startDir - Directory to start searching from (defaults to cwd)
|
|
37
|
+
* @returns The project root path
|
|
38
|
+
* @throws Error if not inside an fnd-platform project
|
|
39
|
+
*/
|
|
40
|
+
function requireProjectRoot(startDir = process.cwd()) {
|
|
41
|
+
const root = findProjectRoot(startDir);
|
|
42
|
+
if (!root) {
|
|
43
|
+
throw new Error('Not inside an fnd-platform project. ' +
|
|
44
|
+
'Run this command from a project directory containing .projenrc.ts, ' +
|
|
45
|
+
'or create a new project with: fnd new <project-name>');
|
|
46
|
+
}
|
|
47
|
+
return root;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/lib/project.ts"],"names":[],"mappings":";;AAUA,0CAoBC;AASD,gDAUC;AAjDD,2BAAgC;AAChC,+BAA8C;AAE9C;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC9D,IAAI,UAAU,GAAG,IAAA,cAAO,EAAC,QAAQ,CAAC,CAAC;IAEnC,iCAAiC;IACjC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,OAAO,CAAC,WAAW,EAAE,CAAC;QACpB,IAAI,IAAA,eAAU,EAAC,IAAA,WAAI,EAAC,UAAU,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,cAAO,EAAC,UAAU,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,0BAA0B;YAC1B,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,MAAM,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IACjE,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,sCAAsC;YACpC,qEAAqE;YACrE,sDAAsD,CACzD,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template for .projenrc.ts file in new projects.
|
|
3
|
+
*
|
|
4
|
+
* @param projectName - The name of the project
|
|
5
|
+
* @returns The .projenrc.ts file content
|
|
6
|
+
*/
|
|
7
|
+
export declare function getProjenrcTemplate(projectName: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Template for initial package.json before Projen runs.
|
|
10
|
+
*
|
|
11
|
+
* @param projectName - The name of the project
|
|
12
|
+
* @param packageManager - The package manager to use
|
|
13
|
+
* @returns The package.json content as an object
|
|
14
|
+
*/
|
|
15
|
+
export declare function getInitialPackageJson(projectName: string, packageManager?: 'pnpm' | 'yarn'): Record<string, unknown>;
|
|
16
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/lib/templates.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAU/D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,MAAM,GAAG,MAAe,GACvC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getProjenrcTemplate = getProjenrcTemplate;
|
|
4
|
+
exports.getInitialPackageJson = getInitialPackageJson;
|
|
5
|
+
/**
|
|
6
|
+
* Template for .projenrc.ts file in new projects.
|
|
7
|
+
*
|
|
8
|
+
* @param projectName - The name of the project
|
|
9
|
+
* @returns The .projenrc.ts file content
|
|
10
|
+
*/
|
|
11
|
+
function getProjenrcTemplate(projectName) {
|
|
12
|
+
return `import { FndMonorepoProject } from '@fnd-platform/core';
|
|
13
|
+
|
|
14
|
+
const project = new FndMonorepoProject({
|
|
15
|
+
name: '${projectName}',
|
|
16
|
+
defaultReleaseBranch: 'main',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
project.synth();
|
|
20
|
+
`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Template for initial package.json before Projen runs.
|
|
24
|
+
*
|
|
25
|
+
* @param projectName - The name of the project
|
|
26
|
+
* @param packageManager - The package manager to use
|
|
27
|
+
* @returns The package.json content as an object
|
|
28
|
+
*/
|
|
29
|
+
function getInitialPackageJson(projectName, packageManager = 'pnpm') {
|
|
30
|
+
return {
|
|
31
|
+
name: projectName,
|
|
32
|
+
version: '0.0.0',
|
|
33
|
+
private: true,
|
|
34
|
+
devDependencies: {
|
|
35
|
+
'@fnd-platform/core': '^0.1.0',
|
|
36
|
+
projen: '^0.91.0',
|
|
37
|
+
typescript: '^5.6.3',
|
|
38
|
+
},
|
|
39
|
+
...(packageManager === 'pnpm' && { packageManager: 'pnpm@10.6.5' }),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/lib/templates.ts"],"names":[],"mappings":";;AAMA,kDAUC;AASD,sDAeC;AAxCD;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,WAAmB;IACrD,OAAO;;;WAGE,WAAW;;;;;CAKrB,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,qBAAqB,CACnC,WAAmB,EACnB,iBAAkC,MAAM;IAExC,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,IAAI;QACb,eAAe,EAAE;YACf,oBAAoB,EAAE,QAAQ;YAC9B,MAAM,EAAE,SAAS;YACjB,UAAU,EAAE,QAAQ;SACrB;QACD,GAAG,CAAC,cAAc,KAAK,MAAM,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;KACpE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance timing utilities for CLI profiling.
|
|
3
|
+
* Enable profiling with FND_PROFILE=true environment variable.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Result of a single timing measurement.
|
|
7
|
+
*/
|
|
8
|
+
export interface TimingResult {
|
|
9
|
+
/**
|
|
10
|
+
* Name/label for this timing.
|
|
11
|
+
*/
|
|
12
|
+
name: string;
|
|
13
|
+
/**
|
|
14
|
+
* Duration in milliseconds.
|
|
15
|
+
*/
|
|
16
|
+
durationMs: number;
|
|
17
|
+
/**
|
|
18
|
+
* Human-readable duration string.
|
|
19
|
+
*/
|
|
20
|
+
durationFormatted: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Complete profile report for a command execution.
|
|
24
|
+
*/
|
|
25
|
+
export interface ProfileReport {
|
|
26
|
+
/**
|
|
27
|
+
* Command that was profiled (e.g., 'fnd new', 'fnd build').
|
|
28
|
+
*/
|
|
29
|
+
command: string;
|
|
30
|
+
/**
|
|
31
|
+
* Total execution time in milliseconds.
|
|
32
|
+
*/
|
|
33
|
+
totalDurationMs: number;
|
|
34
|
+
/**
|
|
35
|
+
* Total execution time formatted for display.
|
|
36
|
+
*/
|
|
37
|
+
totalDurationFormatted: string;
|
|
38
|
+
/**
|
|
39
|
+
* Individual timing measurements.
|
|
40
|
+
*/
|
|
41
|
+
timings: TimingResult[];
|
|
42
|
+
/**
|
|
43
|
+
* Whether the command completed successfully.
|
|
44
|
+
*/
|
|
45
|
+
success: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Formats milliseconds into a human-readable string.
|
|
49
|
+
*
|
|
50
|
+
* @param ms - Duration in milliseconds
|
|
51
|
+
* @returns Formatted duration string
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* formatDuration(1234); // "1.23s"
|
|
56
|
+
* formatDuration(234); // "234ms"
|
|
57
|
+
* formatDuration(65000); // "1m 5.00s"
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function formatDuration(ms: number): string;
|
|
61
|
+
/**
|
|
62
|
+
* High-resolution performance timer for profiling CLI commands.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const timer = new PerformanceTimer('fnd new');
|
|
67
|
+
*
|
|
68
|
+
* timer.start('file-generation');
|
|
69
|
+
* // ... do file generation
|
|
70
|
+
* timer.end('file-generation');
|
|
71
|
+
*
|
|
72
|
+
* timer.start('git-init');
|
|
73
|
+
* // ... do git init
|
|
74
|
+
* timer.end('git-init');
|
|
75
|
+
*
|
|
76
|
+
* const report = timer.getReport(true);
|
|
77
|
+
* console.log(report.timings);
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare class PerformanceTimer {
|
|
81
|
+
private command;
|
|
82
|
+
private startTime;
|
|
83
|
+
private activeTimers;
|
|
84
|
+
private timings;
|
|
85
|
+
/**
|
|
86
|
+
* Creates a new performance timer.
|
|
87
|
+
*
|
|
88
|
+
* @param command - Name of the command being profiled
|
|
89
|
+
*/
|
|
90
|
+
constructor(command: string);
|
|
91
|
+
/**
|
|
92
|
+
* Starts timing a named phase.
|
|
93
|
+
*
|
|
94
|
+
* @param name - Name of the phase to time
|
|
95
|
+
* @throws Error if a timer with the same name is already running
|
|
96
|
+
*/
|
|
97
|
+
start(name: string): void;
|
|
98
|
+
/**
|
|
99
|
+
* Ends timing a named phase and records the result.
|
|
100
|
+
*
|
|
101
|
+
* @param name - Name of the phase to stop timing
|
|
102
|
+
* @returns The timing result
|
|
103
|
+
* @throws Error if no timer with the given name is running
|
|
104
|
+
*/
|
|
105
|
+
end(name: string): TimingResult;
|
|
106
|
+
/**
|
|
107
|
+
* Gets the complete profile report.
|
|
108
|
+
*
|
|
109
|
+
* @param success - Whether the command completed successfully
|
|
110
|
+
* @returns Complete profile report
|
|
111
|
+
*/
|
|
112
|
+
getReport(success: boolean): ProfileReport;
|
|
113
|
+
/**
|
|
114
|
+
* Checks if profiling is enabled via FND_PROFILE environment variable.
|
|
115
|
+
*
|
|
116
|
+
* @returns true if profiling is enabled
|
|
117
|
+
*/
|
|
118
|
+
static isEnabled(): boolean;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=timer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timer.d.ts","sourceRoot":"","sources":["../../src/lib/timer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,OAAO,EAAE,YAAY,EAAE,CAAC;IAExB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUjD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,OAAO,CAAsB;IAErC;;;;OAIG;gBACS,OAAO,EAAE,MAAM;IAK3B;;;;;OAKG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOzB;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAoB/B;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa;IAY1C;;;;OAIG;IACH,MAAM,CAAC,SAAS,IAAI,OAAO;CAG5B"}
|
package/lib/lib/timer.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Performance timing utilities for CLI profiling.
|
|
4
|
+
* Enable profiling with FND_PROFILE=true environment variable.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.PerformanceTimer = void 0;
|
|
8
|
+
exports.formatDuration = formatDuration;
|
|
9
|
+
/**
|
|
10
|
+
* Formats milliseconds into a human-readable string.
|
|
11
|
+
*
|
|
12
|
+
* @param ms - Duration in milliseconds
|
|
13
|
+
* @returns Formatted duration string
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* formatDuration(1234); // "1.23s"
|
|
18
|
+
* formatDuration(234); // "234ms"
|
|
19
|
+
* formatDuration(65000); // "1m 5.00s"
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
function formatDuration(ms) {
|
|
23
|
+
if (ms < 1000) {
|
|
24
|
+
return `${Math.round(ms)}ms`;
|
|
25
|
+
}
|
|
26
|
+
if (ms < 60000) {
|
|
27
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
28
|
+
}
|
|
29
|
+
const minutes = Math.floor(ms / 60000);
|
|
30
|
+
const seconds = ((ms % 60000) / 1000).toFixed(2);
|
|
31
|
+
return `${minutes}m ${seconds}s`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* High-resolution performance timer for profiling CLI commands.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const timer = new PerformanceTimer('fnd new');
|
|
39
|
+
*
|
|
40
|
+
* timer.start('file-generation');
|
|
41
|
+
* // ... do file generation
|
|
42
|
+
* timer.end('file-generation');
|
|
43
|
+
*
|
|
44
|
+
* timer.start('git-init');
|
|
45
|
+
* // ... do git init
|
|
46
|
+
* timer.end('git-init');
|
|
47
|
+
*
|
|
48
|
+
* const report = timer.getReport(true);
|
|
49
|
+
* console.log(report.timings);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
class PerformanceTimer {
|
|
53
|
+
command;
|
|
54
|
+
startTime;
|
|
55
|
+
activeTimers = new Map();
|
|
56
|
+
timings = [];
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new performance timer.
|
|
59
|
+
*
|
|
60
|
+
* @param command - Name of the command being profiled
|
|
61
|
+
*/
|
|
62
|
+
constructor(command) {
|
|
63
|
+
this.command = command;
|
|
64
|
+
this.startTime = performance.now();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Starts timing a named phase.
|
|
68
|
+
*
|
|
69
|
+
* @param name - Name of the phase to time
|
|
70
|
+
* @throws Error if a timer with the same name is already running
|
|
71
|
+
*/
|
|
72
|
+
start(name) {
|
|
73
|
+
if (this.activeTimers.has(name)) {
|
|
74
|
+
throw new Error(`Timer '${name}' is already running`);
|
|
75
|
+
}
|
|
76
|
+
this.activeTimers.set(name, performance.now());
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Ends timing a named phase and records the result.
|
|
80
|
+
*
|
|
81
|
+
* @param name - Name of the phase to stop timing
|
|
82
|
+
* @returns The timing result
|
|
83
|
+
* @throws Error if no timer with the given name is running
|
|
84
|
+
*/
|
|
85
|
+
end(name) {
|
|
86
|
+
const startTime = this.activeTimers.get(name);
|
|
87
|
+
if (startTime === undefined) {
|
|
88
|
+
throw new Error(`Timer '${name}' was not started`);
|
|
89
|
+
}
|
|
90
|
+
const endTime = performance.now();
|
|
91
|
+
const durationMs = endTime - startTime;
|
|
92
|
+
this.activeTimers.delete(name);
|
|
93
|
+
const result = {
|
|
94
|
+
name,
|
|
95
|
+
durationMs,
|
|
96
|
+
durationFormatted: formatDuration(durationMs),
|
|
97
|
+
};
|
|
98
|
+
this.timings.push(result);
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Gets the complete profile report.
|
|
103
|
+
*
|
|
104
|
+
* @param success - Whether the command completed successfully
|
|
105
|
+
* @returns Complete profile report
|
|
106
|
+
*/
|
|
107
|
+
getReport(success) {
|
|
108
|
+
const totalDurationMs = performance.now() - this.startTime;
|
|
109
|
+
return {
|
|
110
|
+
command: this.command,
|
|
111
|
+
totalDurationMs,
|
|
112
|
+
totalDurationFormatted: formatDuration(totalDurationMs),
|
|
113
|
+
timings: [...this.timings],
|
|
114
|
+
success,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Checks if profiling is enabled via FND_PROFILE environment variable.
|
|
119
|
+
*
|
|
120
|
+
* @returns true if profiling is enabled
|
|
121
|
+
*/
|
|
122
|
+
static isEnabled() {
|
|
123
|
+
return process.env.FND_PROFILE === 'true' || process.env.FND_PROFILE === '1';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.PerformanceTimer = PerformanceTimer;
|
|
127
|
+
//# sourceMappingURL=timer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timer.js","sourceRoot":"","sources":["../../src/lib/timer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAiEH,wCAUC;AAvBD;;;;;;;;;;;;GAYG;AACH,SAAgB,cAAc,CAAC,EAAU;IACvC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QACd,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;IAC/B,CAAC;IACD,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;QACf,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACtC,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAa,gBAAgB;IACnB,OAAO,CAAS;IAChB,SAAS,CAAS;IAClB,YAAY,GAAwB,IAAI,GAAG,EAAE,CAAC;IAC9C,OAAO,GAAmB,EAAE,CAAC;IAErC;;;;OAIG;IACH,YAAY,OAAe;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACrC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAY;QAChB,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,sBAAsB,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,IAAY;QACd,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,mBAAmB,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;QACvC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE/B,MAAM,MAAM,GAAiB;YAC3B,IAAI;YACJ,UAAU;YACV,iBAAiB,EAAE,cAAc,CAAC,UAAU,CAAC;SAC9C,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,OAAgB;QACxB,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;QAE3D,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe;YACf,sBAAsB,EAAE,cAAc,CAAC,eAAe,CAAC;YACvD,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YAC1B,OAAO;SACR,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,SAAS;QACd,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC;IAC/E,CAAC;CACF;AAlFD,4CAkFC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fnd-platform/cli",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"description": "CLI tool for fnd-platform monorepo scaffolding",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"fnd": "./lib/bin/fnd.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"lib/"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"chalk": "^5.3.0",
|
|
15
|
+
"commander": "^12.0.0",
|
|
16
|
+
"@fnd-platform/core": "1.0.0-alpha.1"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^20.0.0",
|
|
20
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
21
|
+
"@typescript-eslint/parser": "^7.18.0",
|
|
22
|
+
"@vitest/coverage-v8": "^1.6.0",
|
|
23
|
+
"eslint": "^8.57.0",
|
|
24
|
+
"typescript": "^5.6.3",
|
|
25
|
+
"vitest": "^1.6.0"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"cli",
|
|
29
|
+
"fnd-platform",
|
|
30
|
+
"monorepo",
|
|
31
|
+
"scaffolding",
|
|
32
|
+
"aws",
|
|
33
|
+
"typescript"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/your-org/fnd-platform",
|
|
42
|
+
"directory": "packages/cli"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc",
|
|
46
|
+
"postbuild": "chmod +x lib/bin/fnd.js",
|
|
47
|
+
"test": "vitest run",
|
|
48
|
+
"test:watch": "vitest",
|
|
49
|
+
"test:coverage": "vitest run --coverage",
|
|
50
|
+
"e2e": "vitest run --config vitest.config.e2e.ts",
|
|
51
|
+
"e2e:watch": "vitest --config vitest.config.e2e.ts",
|
|
52
|
+
"lint": "eslint src/ test/"
|
|
53
|
+
}
|
|
54
|
+
}
|