@mxpicture/gcp-functions-tools 0.1.59
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/dist/change/ChangeHandler.d.ts +13 -0
- package/dist/change/ChangeHandler.js +144 -0
- package/dist/change/GitChanges.d.ts +34 -0
- package/dist/change/GitChanges.js +91 -0
- package/dist/change/index.d.ts +3 -0
- package/dist/change/index.js +4 -0
- package/dist/change/types.change.d.ts +32 -0
- package/dist/change/types.change.js +4 -0
- package/dist/common/Barrel.d.ts +23 -0
- package/dist/common/Barrel.js +75 -0
- package/dist/common/Collector.d.ts +22 -0
- package/dist/common/Collector.js +37 -0
- package/dist/common/Directories.d.ts +25 -0
- package/dist/common/Directories.js +52 -0
- package/dist/common/Evaluate.d.ts +12 -0
- package/dist/common/Evaluate.js +120 -0
- package/dist/common/Extractor.d.ts +35 -0
- package/dist/common/Extractor.js +198 -0
- package/dist/common/generator.common.d.ts +14 -0
- package/dist/common/generator.common.js +45 -0
- package/dist/common/index.d.ts +6 -0
- package/dist/common/index.js +7 -0
- package/dist/generator/Generator.d.ts +34 -0
- package/dist/generator/Generator.js +111 -0
- package/dist/generator/GeneratorAnnotations.d.ts +9 -0
- package/dist/generator/GeneratorAnnotations.js +23 -0
- package/dist/generator/GeneratorBackend.d.ts +13 -0
- package/dist/generator/GeneratorBackend.js +131 -0
- package/dist/generator/GeneratorDoc.d.ts +9 -0
- package/dist/generator/GeneratorDoc.js +23 -0
- package/dist/generator/GeneratorFrontend.d.ts +12 -0
- package/dist/generator/GeneratorFrontend.js +94 -0
- package/dist/generator/GeneratorRoutes.d.ts +11 -0
- package/dist/generator/GeneratorRoutes.js +53 -0
- package/dist/generator/GeneratorZod.d.ts +26 -0
- package/dist/generator/GeneratorZod.js +151 -0
- package/dist/generator/index.d.ts +7 -0
- package/dist/generator/index.js +8 -0
- package/dist/meta/index.d.ts +9 -0
- package/dist/meta/index.js +10 -0
- package/dist/meta/meta.annotations.d.ts +11 -0
- package/dist/meta/meta.annotations.js +1 -0
- package/dist/meta/meta.common.d.ts +42 -0
- package/dist/meta/meta.common.js +87 -0
- package/dist/meta/meta.decorators.d.ts +26 -0
- package/dist/meta/meta.decorators.js +21 -0
- package/dist/meta/meta.enum.d.ts +87 -0
- package/dist/meta/meta.enum.js +99 -0
- package/dist/meta/meta.imports.d.ts +11 -0
- package/dist/meta/meta.imports.js +54 -0
- package/dist/meta/meta.main.d.ts +32 -0
- package/dist/meta/meta.main.js +10 -0
- package/dist/meta/meta.names.d.ts +8 -0
- package/dist/meta/meta.names.js +35 -0
- package/dist/meta/meta.properties.d.ts +62 -0
- package/dist/meta/meta.properties.js +37 -0
- package/dist/meta/meta.types.d.ts +109 -0
- package/dist/meta/meta.types.js +26 -0
- package/dist/vscode/OSUser.d.ts +15 -0
- package/dist/vscode/OSUser.js +62 -0
- package/dist/vscode/VSCodeCommon.d.ts +50 -0
- package/dist/vscode/VSCodeCommon.js +133 -0
- package/dist/vscode/VSCodeSettings.d.ts +10 -0
- package/dist/vscode/VSCodeSettings.js +41 -0
- package/dist/vscode/VSCodeWorkspace.d.ts +22 -0
- package/dist/vscode/VSCodeWorkspace.js +43 -0
- package/dist/vscode/index.d.ts +4 -0
- package/dist/vscode/index.js +5 -0
- package/package.json +48 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ChangedHistory, ChangedResult, GitChangedContentsResult } from "./types.change.js";
|
|
2
|
+
import { GeneratorResultFile } from "../generator/Generator.js";
|
|
3
|
+
export declare class ChangeHandler {
|
|
4
|
+
protected _history: ChangedHistory | null;
|
|
5
|
+
constructor();
|
|
6
|
+
history(): Promise<ChangedHistory>;
|
|
7
|
+
writeHistory(): Promise<ChangedHistory | null>;
|
|
8
|
+
readChanges(sinceCommit?: string): Promise<GitChangedContentsResult>;
|
|
9
|
+
runGeneration(result: ChangedResult): GeneratorResultFile[];
|
|
10
|
+
writeFiles(files: GeneratorResultFile[]): Promise<void>;
|
|
11
|
+
buildTriggers(gitResult: GitChangedContentsResult): Promise<ChangedResult>;
|
|
12
|
+
commitChanges(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { dirname, join, resolve } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { formatJson } from "../meta/meta.common.js";
|
|
5
|
+
import { GitChanges } from "./GitChanges.js";
|
|
6
|
+
import pkg from "json5";
|
|
7
|
+
import { changedHistorySchema, } from "./types.change.js";
|
|
8
|
+
import micromatch from "micromatch";
|
|
9
|
+
import { extract, createExtractors } from "../common/Extractor.js";
|
|
10
|
+
import { Generator } from "../generator/Generator.js";
|
|
11
|
+
import { createGenerators } from "../common/generator.common.js";
|
|
12
|
+
import { directories } from "../common/Directories.js";
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const historyJsonDir = resolve(__dirname, "../../");
|
|
15
|
+
const historyJsonPath = join(historyJsonDir, "./history.json");
|
|
16
|
+
// export const execAsync = async (
|
|
17
|
+
// command: string,
|
|
18
|
+
// options?: ExecOptionsWithStringEncoding,
|
|
19
|
+
// ): Promise<string> =>
|
|
20
|
+
// new Promise<string>(async (resolve, reject) =>
|
|
21
|
+
// exec(command, options ?? {}, (error, stdout, stderr) =>
|
|
22
|
+
// error ? reject(stderr) : resolve(stdout),
|
|
23
|
+
// ),
|
|
24
|
+
// );
|
|
25
|
+
export class ChangeHandler {
|
|
26
|
+
_history = null;
|
|
27
|
+
constructor() { }
|
|
28
|
+
async history() {
|
|
29
|
+
if (this._history)
|
|
30
|
+
return this._history;
|
|
31
|
+
const content = await readFile(historyJsonPath, "utf8");
|
|
32
|
+
this._history = pkg.parse(content);
|
|
33
|
+
this._history = await changedHistorySchema.parseAsync(this._history);
|
|
34
|
+
return this._history;
|
|
35
|
+
}
|
|
36
|
+
async writeHistory() {
|
|
37
|
+
if (!this._history)
|
|
38
|
+
return null;
|
|
39
|
+
await mkdir(historyJsonDir, { recursive: true });
|
|
40
|
+
await writeFile(historyJsonPath, await formatJson(pkg.stringify(this._history)));
|
|
41
|
+
return this._history;
|
|
42
|
+
}
|
|
43
|
+
async readChanges(sinceCommit) {
|
|
44
|
+
const git = new GitChanges();
|
|
45
|
+
sinceCommit ??= (await this.history()).lastCommitHash;
|
|
46
|
+
if (!sinceCommit)
|
|
47
|
+
throw new Error("No commit hash found or provided");
|
|
48
|
+
return await git.readChangedFilesSince(sinceCommit);
|
|
49
|
+
}
|
|
50
|
+
runGeneration(result) {
|
|
51
|
+
// collect runners
|
|
52
|
+
const runners = [];
|
|
53
|
+
for (const trigger of result.triggers) {
|
|
54
|
+
for (const generator of trigger.generators) {
|
|
55
|
+
let foundRunner = runners.find((runner) => runner.gen === generator.gen);
|
|
56
|
+
if (!foundRunner) {
|
|
57
|
+
foundRunner = { gen: generator.gen, templateFiles: [] };
|
|
58
|
+
runners.push(foundRunner);
|
|
59
|
+
}
|
|
60
|
+
foundRunner.templateFiles.push(trigger.templateFile);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// run
|
|
64
|
+
const results = [];
|
|
65
|
+
for (const runner of runners)
|
|
66
|
+
results.push(...runner.gen.run(runner.templateFiles));
|
|
67
|
+
return results;
|
|
68
|
+
}
|
|
69
|
+
async writeFiles(files) {
|
|
70
|
+
return Generator.write(files);
|
|
71
|
+
}
|
|
72
|
+
async buildTriggers(gitResult) {
|
|
73
|
+
const changed = { ...gitResult, triggers: [] };
|
|
74
|
+
const generators = await createGenerators();
|
|
75
|
+
const addTrigger = (...trs) => {
|
|
76
|
+
for (const tr of trs) {
|
|
77
|
+
if (!changed.triggers.find((t) => t.templateFile.inputFilePath === tr.templateFile.inputFilePath))
|
|
78
|
+
changed.triggers.push(tr);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const templateFilePaths = await directories.templatesPathRead();
|
|
82
|
+
const templates = extract(createExtractors(templateFilePaths));
|
|
83
|
+
for (const changedFile of changed.files) {
|
|
84
|
+
// check templates
|
|
85
|
+
const foundTemplate = templates.find((m) => m.repoInputFilePath === changedFile.repoFilePath);
|
|
86
|
+
if (foundTemplate) {
|
|
87
|
+
// add all generators
|
|
88
|
+
addTrigger({
|
|
89
|
+
generators,
|
|
90
|
+
templateFile: foundTemplate,
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
// check super generator
|
|
95
|
+
if (changedFile.repoFilePath ===
|
|
96
|
+
"gen/generator/src/generator/Generator.ts" ||
|
|
97
|
+
changedFile.repoFilePath === "gen/generator/src/generator/index.ts") {
|
|
98
|
+
// add all generators to all templates
|
|
99
|
+
addTrigger(...templates.map((templ) => ({
|
|
100
|
+
generators,
|
|
101
|
+
templateFile: templ,
|
|
102
|
+
})));
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
// check generators
|
|
106
|
+
if (micromatch.isMatch(changedFile.repoFilePath, "gen/generator/**")) {
|
|
107
|
+
const foundGen = generators.find((generator) => generator.filePath === changedFile.absFilePath);
|
|
108
|
+
if (foundGen) {
|
|
109
|
+
addTrigger(...templates.map((templ) => ({
|
|
110
|
+
generators: [foundGen],
|
|
111
|
+
templateFile: templ,
|
|
112
|
+
})));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
addTrigger(...templates.map((templ) => ({
|
|
116
|
+
generators,
|
|
117
|
+
templateFile: templ,
|
|
118
|
+
})));
|
|
119
|
+
}
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
// check shared
|
|
123
|
+
if (micromatch.isMatch(changedFile.repoFilePath, "shared/**")) {
|
|
124
|
+
addTrigger(...templates.map((templ) => ({
|
|
125
|
+
generators,
|
|
126
|
+
templateFile: templ,
|
|
127
|
+
})));
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return changed;
|
|
132
|
+
}
|
|
133
|
+
async commitChanges() {
|
|
134
|
+
const git = new GitChanges();
|
|
135
|
+
const [hash, hist] = await Promise.all([
|
|
136
|
+
git.lastCommitHash(),
|
|
137
|
+
this.history(),
|
|
138
|
+
]);
|
|
139
|
+
if (!hash)
|
|
140
|
+
throw new Error("No last hash found");
|
|
141
|
+
hist.lastCommitHash = hash;
|
|
142
|
+
await this.writeHistory();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { SimpleGit } from "simple-git";
|
|
2
|
+
import { GitChangedResult, GitChangedContentsResult } from "./types.change.js";
|
|
3
|
+
export declare class GitChanges {
|
|
4
|
+
readonly rootDir: string;
|
|
5
|
+
constructor();
|
|
6
|
+
/**
|
|
7
|
+
* Checks if a specific file or directory has been changed since a given git commit.
|
|
8
|
+
* Includes both committed and uncommitted changes (staged + unstaged).
|
|
9
|
+
*
|
|
10
|
+
* @param target - Relative path to the file or directory to check.
|
|
11
|
+
* @param sinceCommit - The git commit hash (or ref like a tag/branch) to compare against.
|
|
12
|
+
* @returns A result object indicating whether changes were detected.
|
|
13
|
+
*/
|
|
14
|
+
hasChangedSince(path: string, sinceCommit: string): Promise<GitChangedResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Reads the current content of all files that have changed since a given git commit
|
|
17
|
+
* within a specific file or directory scope.
|
|
18
|
+
* Includes both committed and uncommitted changes (staged + unstaged).
|
|
19
|
+
*
|
|
20
|
+
* Deleted files are excluded from the result since they no longer exist on disk.
|
|
21
|
+
*
|
|
22
|
+
* @param target - Relative path to the file or directory to check.
|
|
23
|
+
* @param sinceCommit - The git commit hash (or ref like a tag/branch) to compare against.
|
|
24
|
+
* @param cwd - The working directory of the git repository (defaults to process.cwd()).
|
|
25
|
+
* @returns A result object containing the current content of each changed file.
|
|
26
|
+
*/
|
|
27
|
+
readChangedFilesSince(sinceCommit: string, readContent?: boolean): Promise<GitChangedContentsResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a SimpleGit instance and verifies the cwd is a repo
|
|
30
|
+
* and the commit ref is valid.
|
|
31
|
+
*/
|
|
32
|
+
verifiedGit(commitRef?: string): Promise<SimpleGit>;
|
|
33
|
+
lastCommitHash(): Promise<string | null>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { simpleGit } from "simple-git";
|
|
5
|
+
import { VSCodeWorkspace } from "../vscode/VSCodeWorkspace.js";
|
|
6
|
+
export class GitChanges {
|
|
7
|
+
rootDir;
|
|
8
|
+
constructor() {
|
|
9
|
+
this.rootDir = VSCodeWorkspace.load().getRoot();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Checks if a specific file or directory has been changed since a given git commit.
|
|
13
|
+
* Includes both committed and uncommitted changes (staged + unstaged).
|
|
14
|
+
*
|
|
15
|
+
* @param target - Relative path to the file or directory to check.
|
|
16
|
+
* @param sinceCommit - The git commit hash (or ref like a tag/branch) to compare against.
|
|
17
|
+
* @returns A result object indicating whether changes were detected.
|
|
18
|
+
*/
|
|
19
|
+
async hasChangedSince(path, sinceCommit) {
|
|
20
|
+
const resolvedTarget = resolve(this.rootDir, path);
|
|
21
|
+
if (!existsSync(resolvedTarget)) {
|
|
22
|
+
throw new Error(`Target path does not exist: ${resolvedTarget}`);
|
|
23
|
+
}
|
|
24
|
+
const git = await this.verifiedGit(sinceCommit);
|
|
25
|
+
// Compare commit to working directory (includes uncommitted changes)
|
|
26
|
+
const diff = await git.diffSummary([sinceCommit, "--", path]);
|
|
27
|
+
const changedFiles = diff.files.map((file) => file.file);
|
|
28
|
+
return {
|
|
29
|
+
path,
|
|
30
|
+
sinceCommit,
|
|
31
|
+
hasChanged: changedFiles.length > 0,
|
|
32
|
+
changedFiles,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Reads the current content of all files that have changed since a given git commit
|
|
37
|
+
* within a specific file or directory scope.
|
|
38
|
+
* Includes both committed and uncommitted changes (staged + unstaged).
|
|
39
|
+
*
|
|
40
|
+
* Deleted files are excluded from the result since they no longer exist on disk.
|
|
41
|
+
*
|
|
42
|
+
* @param target - Relative path to the file or directory to check.
|
|
43
|
+
* @param sinceCommit - The git commit hash (or ref like a tag/branch) to compare against.
|
|
44
|
+
* @param cwd - The working directory of the git repository (defaults to process.cwd()).
|
|
45
|
+
* @returns A result object containing the current content of each changed file.
|
|
46
|
+
*/
|
|
47
|
+
async readChangedFilesSince(sinceCommit, readContent) {
|
|
48
|
+
const git = await this.verifiedGit(sinceCommit);
|
|
49
|
+
// Compare commit to working directory (includes uncommitted changes)
|
|
50
|
+
const diff = await git.diffSummary([sinceCommit, "--", this.rootDir]);
|
|
51
|
+
const files = [];
|
|
52
|
+
for (const entry of diff.files) {
|
|
53
|
+
const repoFilePath = entry.file;
|
|
54
|
+
const absFilePath = resolve(this.rootDir, repoFilePath);
|
|
55
|
+
// Skip deleted files — they no longer exist on disk
|
|
56
|
+
if (!existsSync(absFilePath)) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// Read from the file system to capture uncommitted changes
|
|
60
|
+
const content = readContent ? await readFile(absFilePath, "utf-8") : null;
|
|
61
|
+
files.push({ absFilePath, content, repoFilePath });
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
path: this.rootDir,
|
|
65
|
+
sinceCommit,
|
|
66
|
+
files,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Creates a SimpleGit instance and verifies the cwd is a repo
|
|
71
|
+
* and the commit ref is valid.
|
|
72
|
+
*/
|
|
73
|
+
async verifiedGit(commitRef) {
|
|
74
|
+
const git = simpleGit(this.rootDir);
|
|
75
|
+
if (!(await git.checkIsRepo()))
|
|
76
|
+
throw new Error(`Not a git repository: ${this.rootDir}`);
|
|
77
|
+
if (!commitRef)
|
|
78
|
+
return git;
|
|
79
|
+
try {
|
|
80
|
+
await git.revparse(["--verify", commitRef]);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
throw new Error(`Invalid git commit reference: "${commitRef}"`);
|
|
84
|
+
}
|
|
85
|
+
return git;
|
|
86
|
+
}
|
|
87
|
+
async lastCommitHash() {
|
|
88
|
+
const git = await this.verifiedGit();
|
|
89
|
+
return (await git.log()).latest?.hash ?? null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { MetaMainData } from "../meta/meta.main.js";
|
|
3
|
+
import { GeneratorEntry } from "../common/generator.common.js";
|
|
4
|
+
export interface ChangedHistory {
|
|
5
|
+
lastCommitHash?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const changedHistorySchema: z.ZodObject<{
|
|
8
|
+
lastCommitHash: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
export interface ChangedTrigger {
|
|
11
|
+
templateFile: MetaMainData;
|
|
12
|
+
generators: GeneratorEntry[];
|
|
13
|
+
}
|
|
14
|
+
export interface ChangedResult extends GitChangedContentsResult {
|
|
15
|
+
triggers: ChangedTrigger[];
|
|
16
|
+
}
|
|
17
|
+
export interface GitChangedResult {
|
|
18
|
+
path: string;
|
|
19
|
+
sinceCommit: string;
|
|
20
|
+
hasChanged: boolean;
|
|
21
|
+
changedFiles: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface GitChangedContent {
|
|
24
|
+
absFilePath: string;
|
|
25
|
+
repoFilePath: string;
|
|
26
|
+
content: string | null;
|
|
27
|
+
}
|
|
28
|
+
export interface GitChangedContentsResult {
|
|
29
|
+
path: string;
|
|
30
|
+
sinceCommit: string;
|
|
31
|
+
files: GitChangedContent[];
|
|
32
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TargetType } from "../meta/meta.common.js";
|
|
2
|
+
export interface BarrelResult {
|
|
3
|
+
dirPath: string;
|
|
4
|
+
barrelFilePath: string;
|
|
5
|
+
exportsCode: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface BarrelFileGroup {
|
|
8
|
+
dirPath: string;
|
|
9
|
+
barrelFilename: string;
|
|
10
|
+
filenames: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare class Barrel {
|
|
13
|
+
readonly targetType: TargetType;
|
|
14
|
+
static instances: Barrel[];
|
|
15
|
+
protected filePaths: string[];
|
|
16
|
+
static instance(targetType: TargetType): Barrel;
|
|
17
|
+
protected constructor(targetType: TargetType);
|
|
18
|
+
add(...filePaths: string[]): void;
|
|
19
|
+
create(): BarrelResult[];
|
|
20
|
+
write(results: BarrelResult[]): Promise<void>;
|
|
21
|
+
ensurePackageBarrels(results: BarrelResult[]): Promise<void>;
|
|
22
|
+
protected groupPaths(filePaths: string[]): BarrelFileGroup[];
|
|
23
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { basename, dirname, join } from "node:path";
|
|
2
|
+
import { formatCode } from "../meta/meta.common.js";
|
|
3
|
+
import { mkdir, writeFile, readFile } from "node:fs/promises";
|
|
4
|
+
import { directories } from "./Directories.js";
|
|
5
|
+
export class Barrel {
|
|
6
|
+
targetType;
|
|
7
|
+
static instances = [];
|
|
8
|
+
filePaths = [];
|
|
9
|
+
static instance(targetType) {
|
|
10
|
+
let found = this.instances.find((barrel) => barrel.targetType === targetType);
|
|
11
|
+
if (!found) {
|
|
12
|
+
found = new Barrel(targetType);
|
|
13
|
+
this.instances.push(found);
|
|
14
|
+
}
|
|
15
|
+
return found;
|
|
16
|
+
}
|
|
17
|
+
constructor(targetType) {
|
|
18
|
+
this.targetType = targetType;
|
|
19
|
+
}
|
|
20
|
+
add(...filePaths) {
|
|
21
|
+
this.filePaths.push(...filePaths);
|
|
22
|
+
}
|
|
23
|
+
create() {
|
|
24
|
+
return this.groupPaths(this.filePaths).map((group) => ({
|
|
25
|
+
dirPath: group.dirPath,
|
|
26
|
+
barrelFilePath: join(group.dirPath, group.barrelFilename),
|
|
27
|
+
exportsCode: group.filenames.map((fielname) => `export * from "./${fielname}";`),
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
async write(results) {
|
|
31
|
+
const promises = [];
|
|
32
|
+
for (const result of results) {
|
|
33
|
+
promises.push((async () => {
|
|
34
|
+
const code = await formatCode(result.exportsCode.join("\n"));
|
|
35
|
+
await mkdir(result.dirPath, { recursive: true });
|
|
36
|
+
return writeFile(result.barrelFilePath, code);
|
|
37
|
+
})());
|
|
38
|
+
}
|
|
39
|
+
await Promise.all(promises);
|
|
40
|
+
}
|
|
41
|
+
async ensurePackageBarrels(results) {
|
|
42
|
+
const filePath = directories.targetPackageJson(this.targetType);
|
|
43
|
+
const raw = await readFile(filePath, "utf8");
|
|
44
|
+
const pkg = JSON.parse(raw);
|
|
45
|
+
for (const result of results) {
|
|
46
|
+
const parts = result.barrelFilePath.split("/src/");
|
|
47
|
+
if (parts.length < 2)
|
|
48
|
+
continue; // todo logging?
|
|
49
|
+
const indexPath = `./src/${parts[parts.length - 1]}`;
|
|
50
|
+
const expPath = dirname(`./${parts[parts.length - 1]}`);
|
|
51
|
+
if (!pkg.exports)
|
|
52
|
+
pkg.exports = {};
|
|
53
|
+
pkg.exports[expPath] = indexPath;
|
|
54
|
+
}
|
|
55
|
+
await writeFile(filePath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
|
56
|
+
}
|
|
57
|
+
groupPaths(filePaths) {
|
|
58
|
+
const groups = [];
|
|
59
|
+
for (const filePath of filePaths) {
|
|
60
|
+
const dirPath = dirname(filePath);
|
|
61
|
+
const filename = basename(filePath);
|
|
62
|
+
let group = groups.find((g) => g.dirPath === dirPath);
|
|
63
|
+
if (!group) {
|
|
64
|
+
group = {
|
|
65
|
+
dirPath,
|
|
66
|
+
filenames: [],
|
|
67
|
+
barrelFilename: "index.ts",
|
|
68
|
+
};
|
|
69
|
+
groups.push(group);
|
|
70
|
+
}
|
|
71
|
+
group.filenames.push(filename.replace(/\.ts$/, ".js"));
|
|
72
|
+
}
|
|
73
|
+
return groups;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { TargetType } from "../meta/meta.common.js";
|
|
2
|
+
import { MetaNames } from "../meta/meta.types.js";
|
|
3
|
+
export interface CollectorKey {
|
|
4
|
+
basename: string;
|
|
5
|
+
targetType: TargetType;
|
|
6
|
+
}
|
|
7
|
+
export interface CollectorData {
|
|
8
|
+
names: MetaNames;
|
|
9
|
+
}
|
|
10
|
+
export interface CollectorItem {
|
|
11
|
+
key: CollectorKey;
|
|
12
|
+
data: CollectorData;
|
|
13
|
+
}
|
|
14
|
+
export declare class Collector {
|
|
15
|
+
protected items: CollectorItem[];
|
|
16
|
+
static instance(): Collector;
|
|
17
|
+
constructor();
|
|
18
|
+
add(basename: string, targetType: TargetType, data: CollectorData): void;
|
|
19
|
+
find(basename: string, targetType: TargetType): CollectorItem | null;
|
|
20
|
+
findGeneric(name: string): CollectorItem[];
|
|
21
|
+
findFirst(name: string): CollectorItem | null;
|
|
22
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { metaNameProperties } from "../meta/meta.types.js";
|
|
2
|
+
let __instance = null;
|
|
3
|
+
export class Collector {
|
|
4
|
+
items = [];
|
|
5
|
+
static instance() {
|
|
6
|
+
if (!__instance)
|
|
7
|
+
__instance = new Collector();
|
|
8
|
+
return __instance;
|
|
9
|
+
}
|
|
10
|
+
constructor() { }
|
|
11
|
+
add(basename, targetType, data) {
|
|
12
|
+
if (this.find(basename, targetType))
|
|
13
|
+
return;
|
|
14
|
+
this.items.push({ key: { basename, targetType }, data: { ...data } });
|
|
15
|
+
}
|
|
16
|
+
find(basename, targetType) {
|
|
17
|
+
return (this.items.find((item) => item.key.basename === basename && item.key.targetType === targetType) ?? null);
|
|
18
|
+
}
|
|
19
|
+
findGeneric(name) {
|
|
20
|
+
const results = [];
|
|
21
|
+
for (const item of this.items) {
|
|
22
|
+
if (item.key.basename === name)
|
|
23
|
+
results.push(item);
|
|
24
|
+
for (const prop of metaNameProperties) {
|
|
25
|
+
if (item.data.names[prop] === name) {
|
|
26
|
+
results.push(item);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return results;
|
|
32
|
+
}
|
|
33
|
+
findFirst(name) {
|
|
34
|
+
const results = this.findGeneric(name);
|
|
35
|
+
return results.length > 0 ? results[0] : null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TargetType } from "../meta/meta.common.js";
|
|
2
|
+
import { MetaFileType } from "../meta/meta.enum.js";
|
|
3
|
+
export interface DirectoriesParams {
|
|
4
|
+
cwd: string;
|
|
5
|
+
templatesDir: string;
|
|
6
|
+
targetDirs: {
|
|
7
|
+
common: string;
|
|
8
|
+
frontend: string;
|
|
9
|
+
backend: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
declare class Directories {
|
|
13
|
+
protected _params: DirectoriesParams | null;
|
|
14
|
+
constructor();
|
|
15
|
+
setup(params: DirectoriesParams): void;
|
|
16
|
+
get templatesDir(): string;
|
|
17
|
+
targetDir(targetType: TargetType): string;
|
|
18
|
+
targetBasePath(targetType: TargetType): string;
|
|
19
|
+
toTargetPath(type: MetaFileType, filename: string, targetType: TargetType): string;
|
|
20
|
+
targetPackageJson(targetType: TargetType): string;
|
|
21
|
+
templatesPathRead(): Promise<string[]>;
|
|
22
|
+
protected get params(): DirectoriesParams;
|
|
23
|
+
}
|
|
24
|
+
export declare const directories: Directories;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { join, resolve } from "node:path";
|
|
2
|
+
import { isTemplateFile } from "../meta/meta.common.js";
|
|
3
|
+
import { readdir } from "node:fs/promises";
|
|
4
|
+
let __instance = null;
|
|
5
|
+
const instance = () => {
|
|
6
|
+
if (!__instance)
|
|
7
|
+
__instance = new Directories();
|
|
8
|
+
return __instance;
|
|
9
|
+
};
|
|
10
|
+
class Directories {
|
|
11
|
+
_params = null;
|
|
12
|
+
constructor() { }
|
|
13
|
+
setup(params) {
|
|
14
|
+
this._params = {
|
|
15
|
+
cwd: params.cwd,
|
|
16
|
+
templatesDir: resolve(params.cwd, params.templatesDir),
|
|
17
|
+
targetDirs: {
|
|
18
|
+
backend: resolve(params.cwd, params.targetDirs.backend),
|
|
19
|
+
frontend: resolve(params.cwd, params.targetDirs.frontend),
|
|
20
|
+
common: resolve(params.cwd, params.targetDirs.common),
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
get templatesDir() {
|
|
25
|
+
return this.params.templatesDir;
|
|
26
|
+
}
|
|
27
|
+
targetDir(targetType) {
|
|
28
|
+
return `${this.targetBasePath(targetType)}/src`;
|
|
29
|
+
}
|
|
30
|
+
targetBasePath(targetType) {
|
|
31
|
+
return targetType in this.params.targetDirs
|
|
32
|
+
? this.params.targetDirs[targetType]
|
|
33
|
+
: this.params.targetDirs.common;
|
|
34
|
+
}
|
|
35
|
+
toTargetPath(type, filename, targetType) {
|
|
36
|
+
return join(this.targetDir(targetType), type, filename);
|
|
37
|
+
}
|
|
38
|
+
targetPackageJson(targetType) {
|
|
39
|
+
return `${this.targetBasePath(targetType)}/package.json`;
|
|
40
|
+
}
|
|
41
|
+
async templatesPathRead() {
|
|
42
|
+
return (await readdir(this.templatesDir))
|
|
43
|
+
.filter(isTemplateFile)
|
|
44
|
+
.map((name) => join(this.templatesDir, name));
|
|
45
|
+
}
|
|
46
|
+
get params() {
|
|
47
|
+
if (!this._params)
|
|
48
|
+
throw new Error("Directories: setup needed!");
|
|
49
|
+
return this._params;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export const directories = instance();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
export declare class Evaluate {
|
|
3
|
+
protected checker: ts.TypeChecker;
|
|
4
|
+
protected seen: Set<ts.Node>;
|
|
5
|
+
constructor(checker: ts.TypeChecker, seen?: Set<ts.Node>);
|
|
6
|
+
protected array(expr: ts.Expression): any[] | undefined;
|
|
7
|
+
protected prop(expr: ts.Expression): any;
|
|
8
|
+
protected identifier(expr: ts.Expression): any;
|
|
9
|
+
protected object(expr: ts.Expression): Record<string, any> | undefined;
|
|
10
|
+
protected getNameText(name: ts.PropertyName): string | undefined;
|
|
11
|
+
run(expr: ts.Expression): any;
|
|
12
|
+
}
|