@codefast/cli 0.2.46-canary.6
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/.turbo/turbo-build.log +12 -0
- package/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +125 -0
- package/dist/cjs/commands/update-exports/analyze-imports.cjs +92 -0
- package/dist/cjs/commands/update-exports/analyze-imports.cjs.map +1 -0
- package/dist/cjs/commands/update-exports/command.cjs +58 -0
- package/dist/cjs/commands/update-exports/command.cjs.map +1 -0
- package/dist/cjs/commands/update-exports/config.cjs +113 -0
- package/dist/cjs/commands/update-exports/config.cjs.map +1 -0
- package/dist/cjs/commands/update-exports/file-utils.cjs +144 -0
- package/dist/cjs/commands/update-exports/file-utils.cjs.map +1 -0
- package/dist/cjs/commands/update-exports/generate-exports.cjs +76 -0
- package/dist/cjs/commands/update-exports/generate-exports.cjs.map +1 -0
- package/dist/cjs/commands/update-exports/index.cjs +36 -0
- package/dist/cjs/commands/update-exports/process-package.cjs +143 -0
- package/dist/cjs/commands/update-exports/process-package.cjs.map +1 -0
- package/dist/cjs/commands/update-exports/types.cjs +55 -0
- package/dist/cjs/commands/update-exports/types.cjs.map +1 -0
- package/dist/cjs/index.cjs +46 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/lib/logger.cjs +72 -0
- package/dist/cjs/lib/logger.cjs.map +1 -0
- package/dist/esm/commands/update-exports/analyze-imports.js +58 -0
- package/dist/esm/commands/update-exports/analyze-imports.js.map +1 -0
- package/dist/esm/commands/update-exports/command.js +24 -0
- package/dist/esm/commands/update-exports/command.js.map +1 -0
- package/dist/esm/commands/update-exports/config.js +62 -0
- package/dist/esm/commands/update-exports/config.js.map +1 -0
- package/dist/esm/commands/update-exports/file-utils.js +81 -0
- package/dist/esm/commands/update-exports/file-utils.js.map +1 -0
- package/dist/esm/commands/update-exports/generate-exports.js +42 -0
- package/dist/esm/commands/update-exports/generate-exports.js.map +1 -0
- package/dist/esm/commands/update-exports/index.js +3 -0
- package/dist/esm/commands/update-exports/process-package.js +93 -0
- package/dist/esm/commands/update-exports/process-package.js.map +1 -0
- package/dist/esm/commands/update-exports/types.js +18 -0
- package/dist/esm/commands/update-exports/types.js.map +1 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/logger.js +28 -0
- package/dist/esm/lib/logger.js.map +1 -0
- package/dist/types/src/commands/update-exports/analyze-imports.d.ts +9 -0
- package/dist/types/src/commands/update-exports/analyze-imports.d.ts.map +1 -0
- package/dist/types/src/commands/update-exports/command.d.ts +7 -0
- package/dist/types/src/commands/update-exports/command.d.ts.map +1 -0
- package/dist/types/src/commands/update-exports/config.d.ts +16 -0
- package/dist/types/src/commands/update-exports/config.d.ts.map +1 -0
- package/dist/types/src/commands/update-exports/file-utils.d.ts +47 -0
- package/dist/types/src/commands/update-exports/file-utils.d.ts.map +1 -0
- package/dist/types/src/commands/update-exports/generate-exports.d.ts +11 -0
- package/dist/types/src/commands/update-exports/generate-exports.d.ts.map +1 -0
- package/dist/types/src/commands/update-exports/index.d.ts +2 -0
- package/dist/types/src/commands/update-exports/index.d.ts.map +1 -0
- package/dist/types/src/commands/update-exports/process-package.d.ts +23 -0
- package/dist/types/src/commands/update-exports/process-package.d.ts.map +1 -0
- package/dist/types/src/commands/update-exports/types.d.ts +83 -0
- package/dist/types/src/commands/update-exports/types.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/lib/logger.d.ts +15 -0
- package/dist/types/src/lib/logger.d.ts.map +1 -0
- package/eslint.config.js +18 -0
- package/package.json +49 -0
- package/rslib.config.ts +40 -0
- package/src/commands/update-exports/analyze-imports.ts +112 -0
- package/src/commands/update-exports/command.ts +38 -0
- package/src/commands/update-exports/config.ts +99 -0
- package/src/commands/update-exports/file-utils.ts +178 -0
- package/src/commands/update-exports/generate-exports.ts +74 -0
- package/src/commands/update-exports/index.ts +1 -0
- package/src/commands/update-exports/process-package.ts +164 -0
- package/src/commands/update-exports/types.ts +94 -0
- package/src/index.ts +28 -0
- package/src/lib/logger.ts +39 -0
- package/tsconfig.build.json +5 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const PackageConfigSchema: z.ZodInterface<{
|
|
3
|
+
cjsOutputPattern: z.ZodString;
|
|
4
|
+
esmOutputPattern: z.ZodString;
|
|
5
|
+
packageJsonPath: z.ZodString;
|
|
6
|
+
srcIndexPath: z.ZodString;
|
|
7
|
+
typesOutputCjsPattern: z.ZodString;
|
|
8
|
+
typesOutputPattern: z.ZodString;
|
|
9
|
+
exportPathPrefixesToRemove: z.ZodArray<z.ZodString>;
|
|
10
|
+
}, {
|
|
11
|
+
optional: "exportPathPrefixesToRemove";
|
|
12
|
+
defaulted: never;
|
|
13
|
+
extra: {};
|
|
14
|
+
}>;
|
|
15
|
+
export declare const ScriptConfigSchema: z.ZodInterface<{
|
|
16
|
+
customPackageConfigs: z.ZodRecord<z.ZodString, z.ZodInterface<{
|
|
17
|
+
cjsOutputPattern: z.ZodOptional<z.ZodString>;
|
|
18
|
+
esmOutputPattern: z.ZodOptional<z.ZodString>;
|
|
19
|
+
packageJsonPath: z.ZodOptional<z.ZodString>;
|
|
20
|
+
srcIndexPath: z.ZodOptional<z.ZodString>;
|
|
21
|
+
typesOutputCjsPattern: z.ZodOptional<z.ZodString>;
|
|
22
|
+
typesOutputPattern: z.ZodOptional<z.ZodString>;
|
|
23
|
+
exportPathPrefixesToRemove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
24
|
+
}, {
|
|
25
|
+
optional: "cjsOutputPattern" | "esmOutputPattern" | "packageJsonPath" | "srcIndexPath" | "typesOutputCjsPattern" | "typesOutputPattern" | "exportPathPrefixesToRemove";
|
|
26
|
+
defaulted: never;
|
|
27
|
+
extra: {};
|
|
28
|
+
}>>;
|
|
29
|
+
defaultPackageConfig: z.ZodInterface<{
|
|
30
|
+
cjsOutputPattern: z.ZodString;
|
|
31
|
+
esmOutputPattern: z.ZodString;
|
|
32
|
+
packageJsonPath: z.ZodString;
|
|
33
|
+
srcIndexPath: z.ZodString;
|
|
34
|
+
typesOutputCjsPattern: z.ZodString;
|
|
35
|
+
typesOutputPattern: z.ZodString;
|
|
36
|
+
exportPathPrefixesToRemove: z.ZodArray<z.ZodString>;
|
|
37
|
+
}, {
|
|
38
|
+
optional: "exportPathPrefixesToRemove";
|
|
39
|
+
defaulted: never;
|
|
40
|
+
extra: {};
|
|
41
|
+
}>;
|
|
42
|
+
packagesGlob: z.ZodString;
|
|
43
|
+
}, {
|
|
44
|
+
optional: never;
|
|
45
|
+
defaulted: never;
|
|
46
|
+
extra: {};
|
|
47
|
+
}>;
|
|
48
|
+
export type PackageConfig = z.infer<typeof PackageConfigSchema>;
|
|
49
|
+
export type ScriptConfig = z.infer<typeof ScriptConfigSchema>;
|
|
50
|
+
export interface ImportPath {
|
|
51
|
+
directory: string;
|
|
52
|
+
exportPath: string;
|
|
53
|
+
name: string;
|
|
54
|
+
originalPath: string;
|
|
55
|
+
}
|
|
56
|
+
export interface AnalysisResult {
|
|
57
|
+
imports: ImportPath[];
|
|
58
|
+
}
|
|
59
|
+
export interface ExportConfig {
|
|
60
|
+
import: {
|
|
61
|
+
default: string;
|
|
62
|
+
types: string;
|
|
63
|
+
};
|
|
64
|
+
require: {
|
|
65
|
+
default: string;
|
|
66
|
+
types: string;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export type ExportTarget = ExportConfig | string;
|
|
70
|
+
export type PackageExports = Record<string, ExportTarget>;
|
|
71
|
+
export interface PackageJson {
|
|
72
|
+
[key: string]: unknown;
|
|
73
|
+
name: string;
|
|
74
|
+
version: string;
|
|
75
|
+
exports?: PackageExports;
|
|
76
|
+
}
|
|
77
|
+
export interface ProcessOptions {
|
|
78
|
+
dryRun: boolean;
|
|
79
|
+
verbose: boolean;
|
|
80
|
+
configPath?: string;
|
|
81
|
+
packageFilter?: string;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/commands/update-exports/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAsB9B,CAAC;AAGH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW7B,CAAC;AAGH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAG9D,MAAM,WAAW,UAAU;IAEzB,SAAS,EAAE,MAAM,CAAC;IAElB,UAAU,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IAEb,YAAY,EAAE,MAAM,CAAC;CACtB;AAGD,MAAM,WAAW,cAAc;IAE7B,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAGD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,MAAM,CAAC;AACjD,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAG1D,MAAM,WAAW,WAAW;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAGD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface LoggerOptions {
|
|
2
|
+
verbose?: boolean;
|
|
3
|
+
}
|
|
4
|
+
export declare class Logger {
|
|
5
|
+
private readonly verbose;
|
|
6
|
+
constructor(options?: LoggerOptions);
|
|
7
|
+
info(message: string, ...args: any[]): void;
|
|
8
|
+
success(message: string, ...args: any[]): void;
|
|
9
|
+
warn(message: string, ...args: any[]): void;
|
|
10
|
+
error(message: string, ...args: any[]): void;
|
|
11
|
+
debug(message: string, ...args: any[]): void;
|
|
12
|
+
table(data: any[]): void;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/lib/logger.ts"],"names":[],"mappings":"AAEA,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEtB,OAAO,GAAE,aAAkB;IAIvC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI9C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAM5C,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAGzB"}
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { config } from "@codefast/eslint-config/library";
|
|
2
|
+
|
|
3
|
+
/** @type {import('eslint').Linter.Config[]} */
|
|
4
|
+
export default [
|
|
5
|
+
...config,
|
|
6
|
+
{
|
|
7
|
+
rules: {
|
|
8
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
9
|
+
"@typescript-eslint/no-non-null-assertion": "off",
|
|
10
|
+
"@typescript-eslint/no-redundant-type-constituents": "off",
|
|
11
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
12
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
13
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
14
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
15
|
+
"no-console": "off",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codefast/cli",
|
|
3
|
+
"version": "0.2.46-canary.6",
|
|
4
|
+
"description": "CodeFast CLI - A development toolkit for CodeFast.",
|
|
5
|
+
"bugs": {
|
|
6
|
+
"url": "https://github.com/codefastlabs/codefast/issues"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/codefastlabs/codefast.git",
|
|
11
|
+
"directory": "packages/cli"
|
|
12
|
+
},
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "Vuong Phan <mr.thevuong@gmail.com>",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/cjs/index.js",
|
|
17
|
+
"module": "./dist/esm/index.js",
|
|
18
|
+
"types": "./dist/types/index.d.ts",
|
|
19
|
+
"bin": {
|
|
20
|
+
"codefast": "./dist/esm/index.js"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"chalk": "^5.4.1",
|
|
24
|
+
"commander": "^13.1.0",
|
|
25
|
+
"glob": "^11.0.1",
|
|
26
|
+
"lodash-es": "^4.17.21",
|
|
27
|
+
"ts-morph": "^25.0.1",
|
|
28
|
+
"zod": "4.0.0-beta.20250414T061543"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@rslib/core": "^0.6.3",
|
|
32
|
+
"@types/commander": "^2.12.5",
|
|
33
|
+
"@types/lodash-es": "^4.17.12",
|
|
34
|
+
"@types/node": "^22.14.1",
|
|
35
|
+
"eslint": "^9.24.0",
|
|
36
|
+
"ts-node": "^10.9.2",
|
|
37
|
+
"typescript": "^5.8.3",
|
|
38
|
+
"@codefast/eslint-config": "0.2.46-canary.6",
|
|
39
|
+
"@codefast/typescript-config": "0.2.46-canary.6"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "rslib build",
|
|
43
|
+
"check-types": "tsc --noEmit",
|
|
44
|
+
"clean": "rimraf node_modules dist",
|
|
45
|
+
"dev": "rslib build --watch",
|
|
46
|
+
"lint": "eslint --max-warnings 0",
|
|
47
|
+
"lint:inspect": "npx @eslint/config-inspector@latest"
|
|
48
|
+
}
|
|
49
|
+
}
|
package/rslib.config.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { defineConfig } from "@rslib/core";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
lib: [
|
|
5
|
+
{
|
|
6
|
+
bundle: false,
|
|
7
|
+
dts: {
|
|
8
|
+
distPath: "./dist/types",
|
|
9
|
+
},
|
|
10
|
+
format: "esm",
|
|
11
|
+
output: {
|
|
12
|
+
distPath: {
|
|
13
|
+
root: "./dist/esm",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
bundle: false,
|
|
19
|
+
format: "cjs",
|
|
20
|
+
output: {
|
|
21
|
+
distPath: {
|
|
22
|
+
root: "./dist/cjs",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
output: {
|
|
28
|
+
sourceMap: true,
|
|
29
|
+
},
|
|
30
|
+
performance: {
|
|
31
|
+
buildCache: true,
|
|
32
|
+
printFileSize: false,
|
|
33
|
+
},
|
|
34
|
+
source: {
|
|
35
|
+
entry: {
|
|
36
|
+
index: ["./src/**/*.{ts,tsx}", "!./src/**/*.{test,spec}.{ts,tsx}"],
|
|
37
|
+
},
|
|
38
|
+
tsconfigPath: "./tsconfig.build.json",
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { SourceFile } from "ts-morph";
|
|
2
|
+
|
|
3
|
+
import { Project } from "ts-morph";
|
|
4
|
+
|
|
5
|
+
import type { AnalysisResult, ImportPath, PackageConfig } from "@/commands/update-exports/types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Creates a regex to remove specified prefixes from paths
|
|
9
|
+
* @param prefixes - Array of prefixes to remove
|
|
10
|
+
* @returns RegExp matching any prefix
|
|
11
|
+
*/
|
|
12
|
+
function makeRegexPrefixesToRemove(prefixes: string[]): RegExp {
|
|
13
|
+
// Matches: ^\.?\/?(prefix1|prefix2)\/(.*)
|
|
14
|
+
// - ^\.?\/? : Optional ./ or /
|
|
15
|
+
// - (prefix1|prefix2): Any prefix from the list
|
|
16
|
+
// - \/(.*) : Remaining path after prefix
|
|
17
|
+
const prefixPattern = prefixes.join("|");
|
|
18
|
+
|
|
19
|
+
return new RegExp(`^.?\\/?(?:${prefixPattern})\\/(.*)$`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Processes an export path by removing specified prefixes
|
|
24
|
+
* @param modulePath - Path to process
|
|
25
|
+
* @param regexPattern - Regex for prefix removal
|
|
26
|
+
* @returns Processed path starting with ./
|
|
27
|
+
*/
|
|
28
|
+
function processExportPath(modulePath: string, regexPattern: RegExp): string {
|
|
29
|
+
let processedPath = modulePath;
|
|
30
|
+
const match = processedPath.match(regexPattern);
|
|
31
|
+
|
|
32
|
+
if (match) {
|
|
33
|
+
const remainingPath = match[1];
|
|
34
|
+
|
|
35
|
+
processedPath = remainingPath.startsWith("./") ? remainingPath : `./${remainingPath}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return processedPath;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Analyzes imports from an index.ts file
|
|
43
|
+
* @param indexFilePath - Path to index.ts
|
|
44
|
+
* @param packageConfig - Package configuration
|
|
45
|
+
* @returns AnalysisResult containing import paths
|
|
46
|
+
*/
|
|
47
|
+
export function analyzeImports(indexFilePath: string, packageConfig: PackageConfig): AnalysisResult {
|
|
48
|
+
const project = new Project();
|
|
49
|
+
let sourceFile: SourceFile;
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
sourceFile = project.addSourceFileAtPath(indexFilePath);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error(`Error loading source file at ${indexFilePath}:`, error);
|
|
55
|
+
|
|
56
|
+
return { imports: [] };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const imports: ImportPath[] = [];
|
|
60
|
+
const prefixesToRemove = packageConfig.exportPathPrefixesToRemove ?? [];
|
|
61
|
+
const regexPattern = makeRegexPrefixesToRemove(prefixesToRemove);
|
|
62
|
+
|
|
63
|
+
for (const exportDecl of sourceFile.getExportDeclarations()) {
|
|
64
|
+
let moduleSpecifier = exportDecl.getModuleSpecifierValue();
|
|
65
|
+
|
|
66
|
+
if (!moduleSpecifier) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Normalize @/ to ./
|
|
71
|
+
if (moduleSpecifier.startsWith("@/")) {
|
|
72
|
+
moduleSpecifier = `./${moduleSpecifier.slice(2)}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const isExternal = !moduleSpecifier.startsWith(".");
|
|
76
|
+
|
|
77
|
+
if (isExternal) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const parts = moduleSpecifier.split("/").filter(Boolean);
|
|
82
|
+
|
|
83
|
+
if (parts.length < 2) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let directory;
|
|
88
|
+
|
|
89
|
+
if (parts.length <= 1) {
|
|
90
|
+
directory = ".";
|
|
91
|
+
} else {
|
|
92
|
+
directory = parts.slice(0, -1).join("/");
|
|
93
|
+
|
|
94
|
+
if (directory.startsWith("./")) {
|
|
95
|
+
directory = directory.slice(2);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const name = parts.at(-1) ?? "";
|
|
100
|
+
|
|
101
|
+
const importPath: ImportPath = {
|
|
102
|
+
originalPath: moduleSpecifier,
|
|
103
|
+
directory,
|
|
104
|
+
name,
|
|
105
|
+
exportPath: processExportPath(moduleSpecifier, regexPattern),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
imports.push(importPath);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return { imports };
|
|
112
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import type { ProcessOptions } from "@/commands/update-exports/types";
|
|
4
|
+
|
|
5
|
+
import { processAllPackages } from "@/commands/update-exports/process-package";
|
|
6
|
+
import { Logger } from "@/lib/logger";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a commander command for updating exports
|
|
10
|
+
* @param program - Commander program instance
|
|
11
|
+
*/
|
|
12
|
+
export function createUpdateExportsCommand(program: Command): void {
|
|
13
|
+
// noinspection RequiredAttributes
|
|
14
|
+
program
|
|
15
|
+
.command("update-exports")
|
|
16
|
+
.description("Updates exports for all packages")
|
|
17
|
+
.option("-p, --package <package>", "Filter by package name")
|
|
18
|
+
.option("-d, --dry-run", "Run without making changes")
|
|
19
|
+
.option("-v, --verbose", "Show detailed output")
|
|
20
|
+
.option("-c, --config <path>", "Path to configuration file")
|
|
21
|
+
.action(async (options) => {
|
|
22
|
+
const processorOptions: ProcessOptions = {
|
|
23
|
+
packageFilter: options.package,
|
|
24
|
+
dryRun: Boolean(options.dryRun),
|
|
25
|
+
verbose: Boolean(options.verbose),
|
|
26
|
+
configPath: options.config,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const logger = new Logger({ verbose: processorOptions.verbose });
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
await processAllPackages(processorOptions, logger);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
logger.error("Error processing packages:", error);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { merge } from "lodash-es";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import type { PackageConfig, ScriptConfig } from "@/commands/update-exports/types";
|
|
6
|
+
|
|
7
|
+
import { ScriptConfigSchema } from "@/commands/update-exports/types";
|
|
8
|
+
|
|
9
|
+
// Cache for storing configuration to avoid repeated file reads
|
|
10
|
+
let cachedConfig: null | ScriptConfig = null;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Loads and validates configuration from a file
|
|
14
|
+
* @param configPath - Optional path to the config file
|
|
15
|
+
* @returns Partial ScriptConfig or empty object if not found/invalid
|
|
16
|
+
*/
|
|
17
|
+
function loadConfigFile(configPath?: string): Partial<ScriptConfig> {
|
|
18
|
+
if (!configPath) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const fullPath = path.resolve(configPath);
|
|
24
|
+
|
|
25
|
+
if (!fs.existsSync(fullPath)) {
|
|
26
|
+
console.warn(`Configuration file not found at ${fullPath}`);
|
|
27
|
+
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const configContent = fs.readFileSync(fullPath, "utf8");
|
|
32
|
+
const config = JSON.parse(configContent);
|
|
33
|
+
|
|
34
|
+
// Validate against schema
|
|
35
|
+
return ScriptConfigSchema.parse(config);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error("Error reading configuration file:", error);
|
|
38
|
+
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Retrieves merged configuration, using cache if no path is provided
|
|
45
|
+
* @param configPath - Optional path to override default config
|
|
46
|
+
* @returns Merged ScriptConfig
|
|
47
|
+
*/
|
|
48
|
+
export function getConfig(configPath?: string): ScriptConfig {
|
|
49
|
+
if (cachedConfig && !configPath) {
|
|
50
|
+
return cachedConfig;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const userConfig = loadConfigFile(configPath);
|
|
54
|
+
const config = merge({}, defaultConfig, userConfig) as ScriptConfig;
|
|
55
|
+
|
|
56
|
+
// Cache config if no path is provided
|
|
57
|
+
if (!configPath) {
|
|
58
|
+
cachedConfig = config;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return config;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Retrieves configuration for a specific package
|
|
66
|
+
* @param packageName - Name of the package
|
|
67
|
+
* @param config - Optional ScriptConfig to use
|
|
68
|
+
* @returns PackageConfig combining defaults and custom settings
|
|
69
|
+
*/
|
|
70
|
+
export function getPackageConfig(packageName: string, config?: ScriptConfig): PackageConfig {
|
|
71
|
+
const configObj = config ?? getConfig();
|
|
72
|
+
const customConfig = configObj.customPackageConfigs[packageName] ?? {};
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
...configObj.defaultPackageConfig,
|
|
76
|
+
...customConfig,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Default configuration for the script
|
|
81
|
+
export const defaultConfig: ScriptConfig = {
|
|
82
|
+
packagesGlob: "./packages/**/package.json",
|
|
83
|
+
defaultPackageConfig: {
|
|
84
|
+
cjsOutputPattern: "./dist/cjs/{dir}/{name}.cjs",
|
|
85
|
+
esmOutputPattern: "./dist/esm/{dir}/{name}.js",
|
|
86
|
+
packageJsonPath: "package.json",
|
|
87
|
+
srcIndexPath: "src/index.ts",
|
|
88
|
+
typesOutputCjsPattern: "./dist/types/{dir}/{name}.d.ts",
|
|
89
|
+
typesOutputPattern: "./dist/types/{dir}/{name}.d.ts",
|
|
90
|
+
},
|
|
91
|
+
customPackageConfigs: {
|
|
92
|
+
"@codefast/ui": {
|
|
93
|
+
exportPathPrefixesToRemove: ["components"],
|
|
94
|
+
},
|
|
95
|
+
"@codefast/style-guide": {
|
|
96
|
+
exportPathPrefixesToRemove: ["configs"],
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { AnalysisResult, PackageExports, PackageJson } from "@/commands/update-exports/types";
|
|
5
|
+
|
|
6
|
+
// Constants for file operations
|
|
7
|
+
const EXPORTS_ANALYSIS_DIR = ".exports-analysis";
|
|
8
|
+
const EXPORTS_PREVIEW_FILE = "exports-preview.json";
|
|
9
|
+
const EXPORTS_ANALYSIS_FILE = "exports-analysis.json";
|
|
10
|
+
const ENCODING = "utf8";
|
|
11
|
+
const JSON_INDENT = 2;
|
|
12
|
+
/**
|
|
13
|
+
* Utility functions for file and directory operations
|
|
14
|
+
*/
|
|
15
|
+
const FileUtils = {
|
|
16
|
+
/**
|
|
17
|
+
* Checks if a file exists
|
|
18
|
+
* @param filePath - Path to check
|
|
19
|
+
* @returns True if a file exists
|
|
20
|
+
*/
|
|
21
|
+
exists(filePath: string): boolean {
|
|
22
|
+
return fs.existsSync(filePath);
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a directory if it doesn't exist
|
|
27
|
+
* @param dirPath - Directory path
|
|
28
|
+
*/
|
|
29
|
+
ensureDirectoryExists(dirPath: string): void {
|
|
30
|
+
if (!fs.existsSync(dirPath)) {
|
|
31
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Reads and parses a JSON file
|
|
37
|
+
* @param filePath - Path to JSON file
|
|
38
|
+
* @returns Parsed content or null if error
|
|
39
|
+
*/
|
|
40
|
+
readJsonFile<T>(filePath: string): null | T {
|
|
41
|
+
try {
|
|
42
|
+
const content = fs.readFileSync(filePath, ENCODING);
|
|
43
|
+
|
|
44
|
+
return JSON.parse(content) as T;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error(`Error reading JSON file at ${filePath}:`, error);
|
|
47
|
+
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Writes content to a JSON file
|
|
54
|
+
* @param filePath - Path to write
|
|
55
|
+
* @param content - Content to write
|
|
56
|
+
* @returns True if successful
|
|
57
|
+
*/
|
|
58
|
+
writeJsonFile<T>(filePath: string, content: T): boolean {
|
|
59
|
+
try {
|
|
60
|
+
fs.writeFileSync(filePath, `${JSON.stringify(content, null, JSON_INDENT)}\n`, ENCODING);
|
|
61
|
+
|
|
62
|
+
return true;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error(`Error writing JSON file at ${filePath}:`, error);
|
|
65
|
+
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Gets the exports analysis directory path
|
|
72
|
+
* @param packageDir - Package directory
|
|
73
|
+
* @returns Analysis directory path
|
|
74
|
+
*/
|
|
75
|
+
getAnalysisDir(packageDir: string): string {
|
|
76
|
+
const outputDir = path.join(packageDir, EXPORTS_ANALYSIS_DIR);
|
|
77
|
+
|
|
78
|
+
this.ensureDirectoryExists(outputDir);
|
|
79
|
+
|
|
80
|
+
return outputDir;
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Creates a timestamped backup filename
|
|
85
|
+
* @param baseFilename - Original filename
|
|
86
|
+
* @returns Backup filename with timestamp
|
|
87
|
+
*/
|
|
88
|
+
createBackupFilename(baseFilename: string): string {
|
|
89
|
+
const timestamp = new Date().toISOString().replaceAll(/[:.]/g, "-");
|
|
90
|
+
|
|
91
|
+
return `${baseFilename}.backup.${timestamp}`;
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Checks if a file exists
|
|
97
|
+
* @param filePath - Path to check
|
|
98
|
+
* @returns True if a file exists
|
|
99
|
+
*/
|
|
100
|
+
export function fileExists(filePath: string): boolean {
|
|
101
|
+
return FileUtils.exists(filePath);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Reads and parses package.json content
|
|
106
|
+
* @param filePath - Path to package.json
|
|
107
|
+
* @returns Parsed PackageJson or null if error
|
|
108
|
+
*/
|
|
109
|
+
export function readPackageJson(filePath: string): null | PackageJson {
|
|
110
|
+
return FileUtils.readJsonFile<PackageJson>(filePath);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Creates a backup of package.json
|
|
115
|
+
* @param filePath - Path to package.json
|
|
116
|
+
* @returns True if backup was successful
|
|
117
|
+
*/
|
|
118
|
+
export function backupPackageJson(filePath: string): boolean {
|
|
119
|
+
try {
|
|
120
|
+
const content = fs.readFileSync(filePath, ENCODING);
|
|
121
|
+
const dir = path.dirname(filePath);
|
|
122
|
+
const backupDir = path.join(dir, EXPORTS_ANALYSIS_DIR);
|
|
123
|
+
|
|
124
|
+
FileUtils.ensureDirectoryExists(backupDir);
|
|
125
|
+
|
|
126
|
+
const baseName = path.basename(filePath);
|
|
127
|
+
const backupPath = path.join(backupDir, FileUtils.createBackupFilename(baseName));
|
|
128
|
+
|
|
129
|
+
fs.writeFileSync(backupPath, content, ENCODING);
|
|
130
|
+
|
|
131
|
+
return true;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error(`Error backing up package.json at ${filePath}:`, error);
|
|
134
|
+
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Saves updated package.json content
|
|
141
|
+
* @param filePath - Path to package.json
|
|
142
|
+
* @param content - Updated content
|
|
143
|
+
* @returns True if save was successful
|
|
144
|
+
*/
|
|
145
|
+
export function savePackageJson(filePath: string, content: PackageJson): boolean {
|
|
146
|
+
return FileUtils.writeJsonFile(filePath, content);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Saves the given JSON content to a specified file within the analysis directory.
|
|
151
|
+
*
|
|
152
|
+
* @param packageDir - The root directory where the analysis directory resides.
|
|
153
|
+
* @param fileName - The name of the file to which the JSON content will be written.
|
|
154
|
+
* @param content - The JSON content to save to the file.
|
|
155
|
+
*/
|
|
156
|
+
export function saveJsonToFile<T>(packageDir: string, fileName: string, content: T): void {
|
|
157
|
+
const outputDir = FileUtils.getAnalysisDir(packageDir);
|
|
158
|
+
|
|
159
|
+
FileUtils.writeJsonFile(path.join(outputDir, fileName), content);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Saves exports analysis results
|
|
164
|
+
* @param packageDir - Package directory
|
|
165
|
+
* @param analysis - Analysis results
|
|
166
|
+
*/
|
|
167
|
+
export function saveExportsAnalysis(packageDir: string, analysis: AnalysisResult): void {
|
|
168
|
+
saveJsonToFile(packageDir, EXPORTS_ANALYSIS_FILE, analysis);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Saves preview of generated exports
|
|
173
|
+
* @param packageDir - Package directory
|
|
174
|
+
* @param exports - Generated exports
|
|
175
|
+
*/
|
|
176
|
+
export function saveExportsPreview(packageDir: string, exports: PackageExports): void {
|
|
177
|
+
saveJsonToFile(packageDir, EXPORTS_PREVIEW_FILE, exports);
|
|
178
|
+
}
|