@nu-art/build-and-install 0.401.0 → 0.401.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/BuildAndInstall.d.ts +40 -0
- package/BuildAndInstall.js +155 -0
- package/build-and-install-v3.d.ts +1 -44
- package/build-and-install-v3.js +1 -157
- package/build-and-install.js +11 -11
- package/config/consts.d.ts +43 -0
- package/config/consts.js +42 -0
- package/{core → config}/package/consts.d.ts +1 -1
- package/{core → config}/types/project-config.d.ts +3 -0
- package/core/FilesCache.d.ts +50 -0
- package/core/FilesCache.js +76 -0
- package/core/Unit_HelpPrinter.d.ts +16 -0
- package/core/Unit_HelpPrinter.js +47 -0
- package/core/params/params.d.ts +1 -41
- package/core/params/params.js +1 -332
- package/core/params.d.ts +50 -0
- package/core/params.js +441 -0
- package/{v3/core → core}/types.d.ts +1 -1
- package/{v3/UnitsDependencyMapper → dependencies}/UnitsDependencyMapper.d.ts +21 -1
- package/{v3/UnitsDependencyMapper → dependencies}/UnitsDependencyMapper.js +26 -3
- package/dependencies/types.d.ts +1 -0
- package/dependencies/types.js +1 -0
- package/exceptions/PhaseAggregatedException.d.ts +34 -0
- package/{core/exceptions → exceptions}/PhaseAggregatedException.js +26 -0
- package/exceptions/UnitPhaseException.d.ts +20 -0
- package/exceptions/UnitPhaseException.js +21 -0
- package/exports/ExportIndexCache.d.ts +25 -0
- package/exports/ExportIndexCache.js +115 -0
- package/exports/ExportMapper.d.ts +43 -0
- package/exports/ExportMapper.js +519 -0
- package/exports/IndicesMcpServer.d.ts +22 -0
- package/exports/IndicesMcpServer.js +220 -0
- package/exports/types.js +3 -0
- package/package.json +20 -9
- package/phases/PhaseManager.d.ts +130 -0
- package/{v3 → phases}/PhaseManager.js +99 -2
- package/{v3/phase → phases/definitions}/consts.d.ts +36 -0
- package/{v3/phase → phases/definitions}/consts.js +44 -2
- package/phases/definitions/types.d.ts +40 -0
- package/phases/index.d.ts +2 -0
- package/phases/index.js +2 -0
- package/run.js +10 -0
- package/runtime/RunningStatusHandler.d.ts +104 -0
- package/runtime/RunningStatusHandler.js +153 -0
- package/runtime/types.d.ts +1 -0
- package/runtime/types.js +2 -0
- package/{defaults → templates}/consts.d.ts +9 -0
- package/{defaults → templates}/consts.js +12 -2
- package/templates/firebase/functions/cloudbuild.yaml +17 -0
- package/templates/firebase/functions/dockerfile +19 -0
- package/templates/firebase/functions/service.yaml +49 -0
- package/{v3/units → units/base}/BaseUnit.d.ts +34 -4
- package/{v3/units → units/base}/BaseUnit.js +22 -2
- package/units/base/ProjectUnit.d.ts +32 -0
- package/units/base/ProjectUnit.js +25 -0
- package/units/base/types.js +1 -0
- package/units/discovery/UnitsMapper.d.ts +69 -0
- package/{v3/UnitsMapper → units/discovery}/UnitsMapper.js +50 -2
- package/units/discovery/resolvers/UnitMapper_Base.d.ts +65 -0
- package/units/discovery/resolvers/UnitMapper_Base.js +46 -0
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseFunction.d.ts +5 -3
- package/units/discovery/resolvers/UnitMapper_FirebaseFunction.js +105 -0
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseHosting.d.ts +3 -2
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseHosting.js +14 -10
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_Node.d.ts +1 -1
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_Node.js +2 -2
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeLib.d.ts +24 -1
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeLib.js +24 -1
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeProject.d.ts +22 -1
- package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeProject.js +22 -1
- package/units/discovery/types.js +1 -0
- package/units/implementations/Unit_NodeProject.d.ts +59 -0
- package/{v3/units → units/implementations}/Unit_NodeProject.js +65 -5
- package/units/implementations/Unit_PackageJson.d.ts +56 -0
- package/{v3/units → units/implementations}/Unit_PackageJson.js +39 -3
- package/{v3/units → units/implementations}/Unit_TypescriptLib.d.ts +40 -4
- package/{v3/units → units/implementations}/Unit_TypescriptLib.js +167 -17
- package/units/implementations/firebase/Unit_FirebaseFunctionsApp.d.ts +233 -0
- package/units/implementations/firebase/Unit_FirebaseFunctionsApp.js +804 -0
- package/units/implementations/firebase/Unit_FirebaseHostingApp.d.ts +113 -0
- package/units/implementations/firebase/Unit_FirebaseHostingApp.js +320 -0
- package/units/implementations/firebase/common.d.ts +26 -0
- package/units/implementations/firebase/common.js +65 -0
- package/units/index.d.ts +6 -0
- package/units/index.js +6 -0
- package/v3/core/Unit_HelpPrinter.d.ts +1 -16
- package/v3/core/Unit_HelpPrinter.js +1 -47
- package/{v3 → workspace}/Workspace.d.ts +30 -15
- package/{v3 → workspace}/Workspace.js +48 -35
- package/core/consts.d.ts +0 -13
- package/core/consts.js +0 -12
- package/core/exceptions/PhaseAggregatedException.d.ts +0 -8
- package/core/exceptions/UnitPhaseException.d.ts +0 -5
- package/core/exceptions/UnitPhaseException.js +0 -6
- package/old/PhaseRunnerDispatcher.d.ts +0 -24
- package/old/PhaseRunnerDispatcher.js +0 -32
- package/old/runner-dispatchers.d.ts +0 -10
- package/old/runner-dispatchers.js +0 -3
- package/v3/PhaseManager.d.ts +0 -27
- package/v3/RunningStatusHandler.d.ts +0 -18
- package/v3/RunningStatusHandler.js +0 -67
- package/v3/UnitsMapper/UnitsMapper.d.ts +0 -21
- package/v3/UnitsMapper/resolvers/UnitMapper_Base.d.ts +0 -23
- package/v3/UnitsMapper/resolvers/UnitMapper_Base.js +0 -16
- package/v3/UnitsMapper/resolvers/UnitMapper_FirebaseFunction.js +0 -66
- package/v3/core/FilesCache.d.ts +0 -7
- package/v3/core/FilesCache.js +0 -33
- package/v3/phase/types.d.ts +0 -10
- package/v3/units/ProjectUnit.d.ts +0 -18
- package/v3/units/ProjectUnit.js +0 -11
- package/v3/units/Unit_NodeProject.d.ts +0 -30
- package/v3/units/Unit_PackageJson.d.ts +0 -17
- package/v3/units/firebase/Unit_FirebaseFunctionsApp.d.ts +0 -64
- package/v3/units/firebase/Unit_FirebaseFunctionsApp.js +0 -306
- package/v3/units/firebase/Unit_FirebaseHostingApp.d.ts +0 -49
- package/v3/units/firebase/Unit_FirebaseHostingApp.js +0 -118
- package/v3/units/firebase/common.d.ts +0 -3
- package/v3/units/firebase/common.js +0 -13
- package/v3/units/index.d.ts +0 -6
- package/v3/units/index.js +0 -6
- /package/{core → config}/package/consts.js +0 -0
- /package/{core → config}/types/configs/firebasejson.d.ts +0 -0
- /package/{core → config}/types/configs/firebasejson.js +0 -0
- /package/{core → config}/types/configs/firebaserc.d.ts +0 -0
- /package/{core → config}/types/configs/firebaserc.js +0 -0
- /package/{core → config}/types/configs/index.d.ts +0 -0
- /package/{core → config}/types/configs/index.js +0 -0
- /package/{core → config}/types/configs/package-json.d.ts +0 -0
- /package/{core → config}/types/configs/package-json.js +0 -0
- /package/{core → config}/types/core.d.ts +0 -0
- /package/{core → config}/types/core.js +0 -0
- /package/{core → config}/types/index.d.ts +0 -0
- /package/{core → config}/types/index.js +0 -0
- /package/{core → config}/types/package/index.d.ts +0 -0
- /package/{core → config}/types/package/index.js +0 -0
- /package/{core → config}/types/package/package.d.ts +0 -0
- /package/{core → config}/types/package/package.js +0 -0
- /package/{core → config}/types/package/runtime-package.d.ts +0 -0
- /package/{core → config}/types/package/runtime-package.js +0 -0
- /package/{core → config}/types/project-config.js +0 -0
- /package/{v3/core → core}/types.js +0 -0
- /package/{v3/UnitsMapper/types.js → exports/types.d.ts} +0 -0
- /package/{v3/phase → phases/definitions}/index.d.ts +0 -0
- /package/{v3/phase → phases/definitions}/index.js +0 -0
- /package/{v3/phase → phases/definitions}/types.js +0 -0
- /package/{v3/units/types.js → run.d.ts} +0 -0
- /package/{defaults/backend-proxy → templates/backend/proxy}/proxy._ts +0 -0
- /package/{defaults/.firebase_config → templates/firebase/config}/database.rules.json +0 -0
- /package/{defaults/.firebase_config → templates/firebase/config}/firestore.indexes.json +0 -0
- /package/{defaults/.firebase_config → templates/firebase/config}/firestore.rules +0 -0
- /package/{defaults/.firebase_config → templates/firebase/config}/storage.rules +0 -0
- /package/{v3/units → units/base}/types.d.ts +0 -0
- /package/{v3/UnitsMapper → units/discovery}/resolvers/index.d.ts +0 -0
- /package/{v3/UnitsMapper → units/discovery}/resolvers/index.js +0 -0
- /package/{v3/UnitsMapper → units/discovery}/types.d.ts +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Logger } from '@nu-art/ts-common';
|
|
2
|
+
import { BaiParams } from './core/params.js';
|
|
3
|
+
import { Phase } from './phases/definitions/index.js';
|
|
4
|
+
import { UnitsMapper } from './units/discovery/UnitsMapper.js';
|
|
5
|
+
import { ProjectUnit } from './units/base/ProjectUnit.js';
|
|
6
|
+
import { PhaseManager } from './phases/PhaseManager.js';
|
|
7
|
+
import { Unit_NodeProject } from './units/index.js';
|
|
8
|
+
import { Workspace } from './workspace/Workspace.js';
|
|
9
|
+
import { BaseCliParam } from '@nu-art/commando/cli-params/types';
|
|
10
|
+
import { RunningStatusHandler } from './runtime/RunningStatusHandler.js';
|
|
11
|
+
export declare const DefaultPhases: Phase<string>[][];
|
|
12
|
+
type BAI_Options = {
|
|
13
|
+
pathToProject: string;
|
|
14
|
+
runtimeParams: BaseCliParam<string, any>[];
|
|
15
|
+
};
|
|
16
|
+
export declare class BuildAndInstall extends Logger {
|
|
17
|
+
private unitsMapper;
|
|
18
|
+
private phases;
|
|
19
|
+
private pathToProject;
|
|
20
|
+
readonly workspace: Workspace;
|
|
21
|
+
readonly nodeProjectUnit: Unit_NodeProject;
|
|
22
|
+
readonly runtimeParams: BaiParams;
|
|
23
|
+
readonly runningStatus: RunningStatusHandler;
|
|
24
|
+
readonly phaseManager: PhaseManager;
|
|
25
|
+
private _init;
|
|
26
|
+
constructor(config?: Partial<BAI_Options>);
|
|
27
|
+
init(): Promise<void>;
|
|
28
|
+
prepareUnitsMapper(unitsMapper: UnitsMapper): void;
|
|
29
|
+
setApplicativeUnits(projectUnits: ProjectUnit[]): void;
|
|
30
|
+
setPhases(phases: Phase<string>[][]): void;
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated Use workspace.projectUnits instead
|
|
33
|
+
* Backward compatibility getter for existing tests
|
|
34
|
+
*/
|
|
35
|
+
get projectUnits(): ReadonlyArray<ProjectUnit>;
|
|
36
|
+
run(): Promise<void>;
|
|
37
|
+
build(): Promise<void>;
|
|
38
|
+
private loadVersion;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { BeLogged, DebugFlag, filterDuplicates, ImplementationMissingException, LogClient_Terminal, Logger, LogLevel, merge } from '@nu-art/ts-common';
|
|
2
|
+
import { AllBaiParams } from './core/params.js';
|
|
3
|
+
import { phases_Build, phases_Deploy, phases_Launch, phases_Terminating } from './phases/definitions/index.js';
|
|
4
|
+
import { UnitsMapper } from './units/discovery/UnitsMapper.js';
|
|
5
|
+
import { FilesCache } from './core/FilesCache.js';
|
|
6
|
+
import { ProjectUnit } from './units/base/ProjectUnit.js';
|
|
7
|
+
import { PhaseManager } from './phases/PhaseManager.js';
|
|
8
|
+
import { Workspace } from './workspace/Workspace.js';
|
|
9
|
+
import { resolve } from 'path';
|
|
10
|
+
import { CONST_BaiConfig, CONST_NodeModules, CONST_VersionApp } from './config/consts.js';
|
|
11
|
+
import { UnitMapper_FirebaseFunction, UnitMapper_FirebaseHosting, UnitMapper_NodeLib, UnitMapper_NodeProject } from './units/discovery/resolvers/index.js';
|
|
12
|
+
import { CLIParamsResolver } from '@nu-art/commando/cli-params/CLIParamsResolver';
|
|
13
|
+
import { RunningStatusHandler } from './runtime/RunningStatusHandler.js';
|
|
14
|
+
import { FileSystemUtils } from '@nu-art/ts-common/utils/FileSystemUtils';
|
|
15
|
+
export const DefaultPhases = [
|
|
16
|
+
...phases_Build,
|
|
17
|
+
...phases_Terminating,
|
|
18
|
+
...phases_Launch,
|
|
19
|
+
...phases_Deploy,
|
|
20
|
+
];
|
|
21
|
+
export class BuildAndInstall extends Logger {
|
|
22
|
+
unitsMapper;
|
|
23
|
+
phases = DefaultPhases;
|
|
24
|
+
pathToProject;
|
|
25
|
+
workspace;
|
|
26
|
+
nodeProjectUnit;
|
|
27
|
+
runtimeParams;
|
|
28
|
+
runningStatus;
|
|
29
|
+
phaseManager;
|
|
30
|
+
_init = false;
|
|
31
|
+
constructor(config = {}) {
|
|
32
|
+
super();
|
|
33
|
+
const defaultConfig = merge({
|
|
34
|
+
pathToProject: process.env.INIT_CWD ?? process.cwd(),
|
|
35
|
+
}, config);
|
|
36
|
+
defaultConfig.runtimeParams = filterDuplicates([...(config.runtimeParams ?? []), ...AllBaiParams], param => param.keyName);
|
|
37
|
+
this.runtimeParams = CLIParamsResolver.create(...defaultConfig.runtimeParams).resolveParamValue();
|
|
38
|
+
BeLogged.addClient(LogClient_Terminal);
|
|
39
|
+
this.pathToProject = defaultConfig.pathToProject;
|
|
40
|
+
this.runningStatus = new RunningStatusHandler(this.pathToProject, this.runtimeParams);
|
|
41
|
+
this.workspace = new Workspace();
|
|
42
|
+
}
|
|
43
|
+
async init() {
|
|
44
|
+
if (this._init)
|
|
45
|
+
return;
|
|
46
|
+
this._init = true;
|
|
47
|
+
await this.runningStatus.init();
|
|
48
|
+
if (this.runtimeParams.debug)
|
|
49
|
+
DebugFlag.DefaultLogLevel = LogLevel.Debug;
|
|
50
|
+
if (this.runtimeParams.verbose)
|
|
51
|
+
DebugFlag.DefaultLogLevel = LogLevel.Verbose;
|
|
52
|
+
this.workspace.setMinLevel(DebugFlag.DefaultLogLevel);
|
|
53
|
+
this.setMinLevel(DebugFlag.DefaultLogLevel);
|
|
54
|
+
this.logDebug('Runtime params:', this.runtimeParams);
|
|
55
|
+
this.unitsMapper = new UnitsMapper();
|
|
56
|
+
this.prepareUnitsMapper(this.unitsMapper);
|
|
57
|
+
}
|
|
58
|
+
prepareUnitsMapper(unitsMapper) {
|
|
59
|
+
unitsMapper
|
|
60
|
+
.addRules(UnitMapper_NodeLib)
|
|
61
|
+
.addRules(UnitMapper_NodeProject)
|
|
62
|
+
.addRules(UnitMapper_FirebaseHosting)
|
|
63
|
+
.addRules(UnitMapper_FirebaseFunction)
|
|
64
|
+
.setRuntimeParams(this.runtimeParams);
|
|
65
|
+
}
|
|
66
|
+
setApplicativeUnits(projectUnits) {
|
|
67
|
+
this.workspace.addProjectUnits(projectUnits);
|
|
68
|
+
}
|
|
69
|
+
setPhases(phases) {
|
|
70
|
+
this.phases = phases;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* @deprecated Use workspace.projectUnits instead
|
|
74
|
+
* Backward compatibility getter for existing tests
|
|
75
|
+
*/
|
|
76
|
+
get projectUnits() {
|
|
77
|
+
return this.workspace.projectUnits;
|
|
78
|
+
}
|
|
79
|
+
async run() {
|
|
80
|
+
const executionPlan = await this.phaseManager.calculateExecutionSteps();
|
|
81
|
+
let killCounter = 0;
|
|
82
|
+
process.on('SIGINT', async () => {
|
|
83
|
+
this.logWarning('\n\n\n---------------------------------- Process Interrupted ----------------------------------\n\n\n');
|
|
84
|
+
await this.phaseManager.break();
|
|
85
|
+
killCounter++;
|
|
86
|
+
if (killCounter > 5)
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
|
89
|
+
try {
|
|
90
|
+
await this.phaseManager.execute(executionPlan);
|
|
91
|
+
this.logInfo('Completed successfully');
|
|
92
|
+
this.logInfo('---------------------------------- Process Completed successfully ----------------------------------');
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
this.logInfo('Process Failed');
|
|
96
|
+
this.logInfo('---------------------------------- Process Failed ----------------------------------');
|
|
97
|
+
throw e;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async build() {
|
|
101
|
+
await this.init();
|
|
102
|
+
// Scan units from workspace
|
|
103
|
+
await this.workspace.scanUnits(this.pathToProject, this.unitsMapper);
|
|
104
|
+
const nodeProjectUnit = this.workspace.getNodeProjectUnit();
|
|
105
|
+
if (!nodeProjectUnit)
|
|
106
|
+
throw new ImplementationMissingException('NodeProject unit not found. Make sure you have a Unit_NodeProject in your project.');
|
|
107
|
+
// @ts-ignore
|
|
108
|
+
this['nodeProjectUnit'] = nodeProjectUnit;
|
|
109
|
+
const pathToBaiConfig = resolve(nodeProjectUnit.config.fullPath, CONST_BaiConfig);
|
|
110
|
+
this.logDebug(`Loading BAI-Config from: ${pathToBaiConfig}`);
|
|
111
|
+
const baiConfig = await FilesCache.load.json(pathToBaiConfig);
|
|
112
|
+
this.logVerbose('Loaded BAI-Config', baiConfig);
|
|
113
|
+
const globalOutputFolder = resolve(this.pathToProject, '.trash/output');
|
|
114
|
+
this.workspace.initializeDependencyMapper(globalOutputFolder);
|
|
115
|
+
let version = await this.loadVersion();
|
|
116
|
+
if (!(await FileSystemUtils.file.exists(resolve(nodeProjectUnit.config.fullPath, CONST_NodeModules)))) {
|
|
117
|
+
this.logInfo(`root project is missing ${CONST_NodeModules} folder. Enabling install...`);
|
|
118
|
+
this.runtimeParams.install = true;
|
|
119
|
+
}
|
|
120
|
+
// Derive active and project units based on runtime params
|
|
121
|
+
const units = this.workspace.deriveActiveAndProjectUnits(this.runtimeParams);
|
|
122
|
+
const childProjectUnits = this.workspace.getUnitsByKeys(units.projectUnits, ProjectUnit);
|
|
123
|
+
nodeProjectUnit.assignUnit(childProjectUnits);
|
|
124
|
+
this.logDebug(`Parent unit: ${nodeProjectUnit.config.key}`);
|
|
125
|
+
const runtimeContext = ({
|
|
126
|
+
version: version.version,
|
|
127
|
+
parentUnit: nodeProjectUnit,
|
|
128
|
+
childUnits: childProjectUnits,
|
|
129
|
+
baiConfig,
|
|
130
|
+
runtimeParams: this.runtimeParams,
|
|
131
|
+
unitsMapper: this.workspace.getDependencyMapper(),
|
|
132
|
+
unitsResolver: (keys, className) => {
|
|
133
|
+
return this.workspace.getUnitsByKeys(keys, className);
|
|
134
|
+
},
|
|
135
|
+
globalOutputFolder,
|
|
136
|
+
workspace: this.workspace,
|
|
137
|
+
});
|
|
138
|
+
this.workspace.projectUnits.forEach(unit => unit.setupRuntimeContext(runtimeContext));
|
|
139
|
+
const unitDependencyTree = await this.workspace.buildDependencyTree(units.projectUnits);
|
|
140
|
+
const manager = new PhaseManager(this.runningStatus, this.phases, unitDependencyTree, units.activeUnits, units.projectUnits);
|
|
141
|
+
// @ts-ignore
|
|
142
|
+
this['phaseManager'] = manager;
|
|
143
|
+
}
|
|
144
|
+
async loadVersion() {
|
|
145
|
+
const versionFilePath = resolve(this.pathToProject, CONST_VersionApp);
|
|
146
|
+
if (await FileSystemUtils.file.exists(versionFilePath)) {
|
|
147
|
+
this.logDebug('Loading version from: ', versionFilePath);
|
|
148
|
+
return await FileSystemUtils.file.read.json(versionFilePath, { version: '1.0.0' });
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.logWarning(`No version file found at '${versionFilePath}', using default version: '1.0.0'`);
|
|
152
|
+
return { version: '1.0.0' };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -1,44 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { BaiParams } from './core/params/params.js';
|
|
3
|
-
import { Phase } from './v3/phase/index.js';
|
|
4
|
-
import { UnitsMapper } from './v3/UnitsMapper/UnitsMapper.js';
|
|
5
|
-
import { ProjectUnit } from './v3/units/ProjectUnit.js';
|
|
6
|
-
import { PhaseManager } from './v3/PhaseManager.js';
|
|
7
|
-
import { BaseUnit, Unit_NodeProject } from './v3/units/index.js';
|
|
8
|
-
import { Workspace } from './v3/Workspace.js';
|
|
9
|
-
import { BaseCliParam } from '@nu-art/commando/cli-params/types';
|
|
10
|
-
import { RunningStatusHandler } from './v3/RunningStatusHandler.js';
|
|
11
|
-
export declare const DefaultPhases: Phase<string>[][];
|
|
12
|
-
type BAI_Options = {
|
|
13
|
-
pathToProject: string;
|
|
14
|
-
runtimeParams: BaseCliParam<string, any>[];
|
|
15
|
-
};
|
|
16
|
-
export declare class BuildAndInstall extends Logger {
|
|
17
|
-
private unitsMapper;
|
|
18
|
-
private phases;
|
|
19
|
-
private pathToProject;
|
|
20
|
-
readonly workspace: Workspace;
|
|
21
|
-
readonly nodeProjectUnit: Unit_NodeProject;
|
|
22
|
-
readonly runtimeParams: BaiParams;
|
|
23
|
-
readonly runningStatus: RunningStatusHandler;
|
|
24
|
-
readonly phaseManager: PhaseManager;
|
|
25
|
-
constructor(config?: Partial<BAI_Options>);
|
|
26
|
-
init(): Promise<void>;
|
|
27
|
-
prepareUnitsMapper(unitsMapper: UnitsMapper): void;
|
|
28
|
-
setApplicativeUnits(projectUnits: ProjectUnit[]): void;
|
|
29
|
-
setPhases(phases: Phase<string>[][]): void;
|
|
30
|
-
/**
|
|
31
|
-
* @deprecated Use workspace.projectUnits instead
|
|
32
|
-
* Backward compatibility getter for existing tests
|
|
33
|
-
*/
|
|
34
|
-
get projectUnits(): ReadonlyArray<ProjectUnit>;
|
|
35
|
-
/**
|
|
36
|
-
* @deprecated Use workspace.scannedUnits instead
|
|
37
|
-
* Backward compatibility getter for existing tests
|
|
38
|
-
*/
|
|
39
|
-
get scannedUnits(): ReadonlyArray<BaseUnit<any>>;
|
|
40
|
-
run(): Promise<void>;
|
|
41
|
-
build(): Promise<void>;
|
|
42
|
-
private loadVersion;
|
|
43
|
-
}
|
|
44
|
-
export {};
|
|
1
|
+
export * from './BuildAndInstall.js';
|
package/build-and-install-v3.js
CHANGED
|
@@ -1,157 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { AllBaiParams } from './core/params/params.js';
|
|
3
|
-
import { phases_Build, phases_Deploy, phases_Launch, phases_Terminating } from './v3/phase/index.js';
|
|
4
|
-
import { UnitsMapper } from './v3/UnitsMapper/UnitsMapper.js';
|
|
5
|
-
import { FilesCache } from './v3/core/FilesCache.js';
|
|
6
|
-
import { PhaseManager } from './v3/PhaseManager.js';
|
|
7
|
-
import { Workspace } from './v3/Workspace.js';
|
|
8
|
-
import { resolve } from 'path';
|
|
9
|
-
import { CONST_BaiConfig, CONST_NodeModules, CONST_VersionApp } from './core/consts.js';
|
|
10
|
-
import { UnitMapper_FirebaseFunction, UnitMapper_FirebaseHosting, UnitMapper_NodeLib, UnitMapper_NodeProject } from './v3/UnitsMapper/resolvers/index.js';
|
|
11
|
-
import { CLIParamsResolver } from '@nu-art/commando/cli-params/CLIParamsResolver';
|
|
12
|
-
import { RunningStatusHandler } from './v3/RunningStatusHandler.js';
|
|
13
|
-
import { FileSystemUtils } from '@nu-art/ts-common/utils/FileSystemUtils';
|
|
14
|
-
export const DefaultPhases = [
|
|
15
|
-
...phases_Build,
|
|
16
|
-
...phases_Terminating,
|
|
17
|
-
...phases_Launch,
|
|
18
|
-
...phases_Deploy,
|
|
19
|
-
];
|
|
20
|
-
export class BuildAndInstall extends Logger {
|
|
21
|
-
unitsMapper;
|
|
22
|
-
phases = DefaultPhases;
|
|
23
|
-
pathToProject;
|
|
24
|
-
workspace;
|
|
25
|
-
nodeProjectUnit;
|
|
26
|
-
runtimeParams;
|
|
27
|
-
runningStatus;
|
|
28
|
-
phaseManager;
|
|
29
|
-
constructor(config = {}) {
|
|
30
|
-
super();
|
|
31
|
-
const defaultConfig = merge({
|
|
32
|
-
pathToProject: process.env.INIT_CWD ?? process.cwd(),
|
|
33
|
-
}, config);
|
|
34
|
-
defaultConfig.runtimeParams = filterDuplicates([...(config.runtimeParams ?? []), ...AllBaiParams], param => param.keyName);
|
|
35
|
-
this.runtimeParams = CLIParamsResolver.create(...defaultConfig.runtimeParams).resolveParamValue();
|
|
36
|
-
BeLogged.addClient(LogClient_Terminal);
|
|
37
|
-
this.pathToProject = defaultConfig.pathToProject;
|
|
38
|
-
this.runningStatus = new RunningStatusHandler(this.pathToProject, this.runtimeParams);
|
|
39
|
-
this.workspace = new Workspace();
|
|
40
|
-
this.workspace.setMinLevel(DebugFlag.DefaultLogLevel);
|
|
41
|
-
}
|
|
42
|
-
async init() {
|
|
43
|
-
await this.runningStatus.init();
|
|
44
|
-
if (this.runtimeParams.debug)
|
|
45
|
-
DebugFlag.DefaultLogLevel = LogLevel.Debug;
|
|
46
|
-
if (this.runtimeParams.verbose)
|
|
47
|
-
DebugFlag.DefaultLogLevel = LogLevel.Verbose;
|
|
48
|
-
this.setMinLevel(DebugFlag.DefaultLogLevel);
|
|
49
|
-
this.logDebug('Runtime params:', this.runtimeParams);
|
|
50
|
-
this.unitsMapper = new UnitsMapper();
|
|
51
|
-
this.prepareUnitsMapper(this.unitsMapper);
|
|
52
|
-
}
|
|
53
|
-
prepareUnitsMapper(unitsMapper) {
|
|
54
|
-
unitsMapper
|
|
55
|
-
.addRules(UnitMapper_NodeLib)
|
|
56
|
-
.addRules(UnitMapper_NodeProject)
|
|
57
|
-
.addRules(UnitMapper_FirebaseHosting)
|
|
58
|
-
.addRules(UnitMapper_FirebaseFunction)
|
|
59
|
-
.setRuntimeParams(this.runtimeParams);
|
|
60
|
-
}
|
|
61
|
-
setApplicativeUnits(projectUnits) {
|
|
62
|
-
this.workspace.addProjectUnits(projectUnits);
|
|
63
|
-
}
|
|
64
|
-
setPhases(phases) {
|
|
65
|
-
this.phases = phases;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* @deprecated Use workspace.projectUnits instead
|
|
69
|
-
* Backward compatibility getter for existing tests
|
|
70
|
-
*/
|
|
71
|
-
get projectUnits() {
|
|
72
|
-
return this.workspace.projectUnits;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* @deprecated Use workspace.scannedUnits instead
|
|
76
|
-
* Backward compatibility getter for existing tests
|
|
77
|
-
*/
|
|
78
|
-
get scannedUnits() {
|
|
79
|
-
return this.workspace.scannedUnits;
|
|
80
|
-
}
|
|
81
|
-
async run() {
|
|
82
|
-
const executionPlan = await this.phaseManager.calculateExecutionSteps();
|
|
83
|
-
let killCounter = 0;
|
|
84
|
-
process.on('SIGINT', async () => {
|
|
85
|
-
this.logWarning('\n\n\n---------------------------------- Process Interrupted ----------------------------------\n\n\n');
|
|
86
|
-
await this.phaseManager.break();
|
|
87
|
-
killCounter++;
|
|
88
|
-
if (killCounter > 5)
|
|
89
|
-
process.exit(1);
|
|
90
|
-
});
|
|
91
|
-
try {
|
|
92
|
-
await this.phaseManager.execute(executionPlan);
|
|
93
|
-
this.logInfo('Completed successfully');
|
|
94
|
-
this.logInfo('---------------------------------- Process Completed successfully ----------------------------------');
|
|
95
|
-
}
|
|
96
|
-
catch (e) {
|
|
97
|
-
this.logInfo('Process Failed');
|
|
98
|
-
this.logInfo('---------------------------------- Process Failed ----------------------------------');
|
|
99
|
-
throw e;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
async build() {
|
|
103
|
-
await this.init();
|
|
104
|
-
// Scan units from workspace
|
|
105
|
-
await this.workspace.scanUnits(this.pathToProject, this.unitsMapper);
|
|
106
|
-
const nodeProjectUnit = this.workspace.getNodeProjectUnit();
|
|
107
|
-
if (!nodeProjectUnit)
|
|
108
|
-
throw new ImplementationMissingException('NodeProject unit not found. Make sure you have a Unit_NodeProject in your project.');
|
|
109
|
-
// @ts-ignore
|
|
110
|
-
this['nodeProjectUnit'] = nodeProjectUnit;
|
|
111
|
-
const pathToBaiConfig = resolve(nodeProjectUnit.config.fullPath, CONST_BaiConfig);
|
|
112
|
-
this.logDebug(`Loading BAI-Config from: ${pathToBaiConfig}`);
|
|
113
|
-
const baiConfig = await FilesCache.load.json(pathToBaiConfig);
|
|
114
|
-
this.logVerbose('Loaded BAI-Config', baiConfig);
|
|
115
|
-
const globalOutputFolder = resolve(this.pathToProject, '.trash/output');
|
|
116
|
-
this.workspace.initializeDependencyMapper(globalOutputFolder);
|
|
117
|
-
let version = await this.loadVersion();
|
|
118
|
-
if (!(await FileSystemUtils.file.exists(resolve(nodeProjectUnit.config.fullPath, CONST_NodeModules)))) {
|
|
119
|
-
this.logInfo(`root project is missing ${CONST_NodeModules} folder. Enabling install...`);
|
|
120
|
-
this.runtimeParams.install = true;
|
|
121
|
-
}
|
|
122
|
-
// Derive active and project units based on runtime params
|
|
123
|
-
const units = this.workspace.deriveActiveAndProjectUnits(this.runtimeParams);
|
|
124
|
-
const childProjectUnits = this.workspace.getUnitsByKeys(units.projectUnits);
|
|
125
|
-
nodeProjectUnit.assignUnit(childProjectUnits);
|
|
126
|
-
this.logDebug(`Parent unit: ${nodeProjectUnit.config.key}`);
|
|
127
|
-
const runtimeContext = ({
|
|
128
|
-
version: version.version,
|
|
129
|
-
parentUnit: nodeProjectUnit,
|
|
130
|
-
childUnits: childProjectUnits,
|
|
131
|
-
baiConfig,
|
|
132
|
-
runtimeParams: this.runtimeParams,
|
|
133
|
-
unitsMapper: this.workspace.getDependencyMapper(),
|
|
134
|
-
unitsResolver: (keys, className) => {
|
|
135
|
-
return this.workspace.getUnitsByKeys(keys, className);
|
|
136
|
-
},
|
|
137
|
-
globalOutputFolder,
|
|
138
|
-
workspace: this.workspace,
|
|
139
|
-
});
|
|
140
|
-
this.workspace.projectUnits.forEach(unit => unit.setupRuntimeContext(runtimeContext));
|
|
141
|
-
const unitDependencyTree = await this.workspace.buildDependencyTree(units.projectUnits);
|
|
142
|
-
const manager = new PhaseManager(this.runningStatus, this.phases, unitDependencyTree, units.activeUnits, units.projectUnits);
|
|
143
|
-
// @ts-ignore
|
|
144
|
-
this['phaseManager'] = manager;
|
|
145
|
-
}
|
|
146
|
-
async loadVersion() {
|
|
147
|
-
const versionFilePath = resolve(this.pathToProject, CONST_VersionApp);
|
|
148
|
-
if (await FileSystemUtils.file.exists(versionFilePath)) {
|
|
149
|
-
this.logDebug('Loading version from: ', versionFilePath);
|
|
150
|
-
return await FileSystemUtils.file.read.json(versionFilePath, { version: '1.0.0' });
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
this.logWarning(`No version file found at '${versionFilePath}', using default version: '1.0.0'`);
|
|
154
|
-
return { version: '1.0.0' };
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
1
|
+
export * from './BuildAndInstall.js';
|
package/build-and-install.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for build-and-install CLI.
|
|
3
|
+
*
|
|
4
|
+
* Creates a BuildAndInstall instance, builds the workspace, and executes all phases.
|
|
5
|
+
* Exits with code 0 on success, or logs errors and exits with code 0 (should probably exit with 1 on error).
|
|
6
|
+
*/
|
|
7
|
+
import { BuildAndInstall } from './BuildAndInstall.js';
|
|
2
8
|
(async () => {
|
|
3
9
|
const buildAndInstall = new BuildAndInstall();
|
|
4
10
|
await buildAndInstall.build();
|
|
5
11
|
await buildAndInstall.run();
|
|
6
12
|
})()
|
|
7
|
-
.catch(
|
|
13
|
+
.catch((err) => {
|
|
14
|
+
console.error(err);
|
|
15
|
+
process.exit(2);
|
|
16
|
+
})
|
|
8
17
|
.then(() => process.exit(0));
|
|
9
|
-
// .execute()
|
|
10
|
-
// .then(() => {
|
|
11
|
-
// })
|
|
12
|
-
// .catch(err => {
|
|
13
|
-
// process.on('SIGINT', () => {
|
|
14
|
-
// console.log('Failed with error: ', err);
|
|
15
|
-
// return process.exit(1);
|
|
16
|
-
// });
|
|
17
|
-
// });
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for file names and configuration keys used throughout the build system.
|
|
3
|
+
*/
|
|
4
|
+
import { MemKey } from '@nu-art/ts-common/mem-storage/index';
|
|
5
|
+
import { RuntimeProjectConfig } from './types/index.js';
|
|
6
|
+
/** Version file name (version-app.json) */
|
|
7
|
+
export declare const CONST_VersionApp = "version-app.json";
|
|
8
|
+
/** Package.json template file name (__package.json) */
|
|
9
|
+
export declare const CONST_PackageJSONTemplate = "__package.json";
|
|
10
|
+
/** Package.json file name */
|
|
11
|
+
export declare const CONST_PackageJSON = "package.json";
|
|
12
|
+
/** Node modules folder name */
|
|
13
|
+
export declare const CONST_NodeModules = "node_modules";
|
|
14
|
+
/** BAI configuration file name (bai-config.json) */
|
|
15
|
+
export declare const CONST_BaiConfig = "bai-config.json";
|
|
16
|
+
/** Firebase RC file name (.firebaserc) */
|
|
17
|
+
export declare const CONST_FirebaseRC = ".firebaserc";
|
|
18
|
+
/** Firebase JSON configuration file name (firebase.json) */
|
|
19
|
+
export declare const CONST_FirebaseJSON = "firebase.json";
|
|
20
|
+
/** TypeScript configuration file name (tsconfig.json) */
|
|
21
|
+
export declare const CONST_TS_CONFIG = "tsconfig.json";
|
|
22
|
+
/** PNPM workspace file name (pnpm-workspace.yaml) */
|
|
23
|
+
export declare const CONST_PNPM_WORKSPACE = "pnpm-workspace.yaml";
|
|
24
|
+
/** PNPM lock file name (pnpm-lock.yaml) */
|
|
25
|
+
export declare const CONST_PNPM_LOCK = "pnpm-lock.yaml";
|
|
26
|
+
/** Trash directory name (.trash) */
|
|
27
|
+
export declare const CONST_TrashDir = ".trash";
|
|
28
|
+
/** Deployment metadata file name (deployment-metadata.json) */
|
|
29
|
+
export declare const CONST_DeploymentMetadata = "deployment-metadata.json";
|
|
30
|
+
/** Deployment ID metadata key (deployment-id) */
|
|
31
|
+
export declare const CONST_DeploymentId = "deployment-id";
|
|
32
|
+
/** Default version tag (latest) */
|
|
33
|
+
export declare const CONST_LatestTag = "latest";
|
|
34
|
+
/** Hosting build tarball name (hosting-build.tar.gz) */
|
|
35
|
+
export declare const CONST_HostingBuildTarball = "hosting-build.tar.gz";
|
|
36
|
+
/** Staging directory name (staging) */
|
|
37
|
+
export declare const CONST_StagingDir = "staging";
|
|
38
|
+
/** Deploy hosting temp directory name (deploy-hosting) */
|
|
39
|
+
export declare const CONST_DeployHostingDir = "deploy-hosting";
|
|
40
|
+
/** Build image temp directory name (build-image) */
|
|
41
|
+
export declare const CONST_BuildImageDir = "build-image";
|
|
42
|
+
/** Memory storage key for packages configuration */
|
|
43
|
+
export declare const MemKey_Packages: MemKey<RuntimeProjectConfig>;
|
package/config/consts.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for file names and configuration keys used throughout the build system.
|
|
3
|
+
*/
|
|
4
|
+
import { MemKey } from '@nu-art/ts-common/mem-storage/index';
|
|
5
|
+
/** Version file name (version-app.json) */
|
|
6
|
+
export const CONST_VersionApp = 'version-app.json';
|
|
7
|
+
/** Package.json template file name (__package.json) */
|
|
8
|
+
export const CONST_PackageJSONTemplate = '__package.json';
|
|
9
|
+
/** Package.json file name */
|
|
10
|
+
export const CONST_PackageJSON = 'package.json';
|
|
11
|
+
/** Node modules folder name */
|
|
12
|
+
export const CONST_NodeModules = 'node_modules';
|
|
13
|
+
/** BAI configuration file name (bai-config.json) */
|
|
14
|
+
export const CONST_BaiConfig = 'bai-config.json';
|
|
15
|
+
/** Firebase RC file name (.firebaserc) */
|
|
16
|
+
export const CONST_FirebaseRC = '.firebaserc';
|
|
17
|
+
/** Firebase JSON configuration file name (firebase.json) */
|
|
18
|
+
export const CONST_FirebaseJSON = 'firebase.json';
|
|
19
|
+
/** TypeScript configuration file name (tsconfig.json) */
|
|
20
|
+
export const CONST_TS_CONFIG = 'tsconfig.json';
|
|
21
|
+
/** PNPM workspace file name (pnpm-workspace.yaml) */
|
|
22
|
+
export const CONST_PNPM_WORKSPACE = 'pnpm-workspace.yaml';
|
|
23
|
+
/** PNPM lock file name (pnpm-lock.yaml) */
|
|
24
|
+
export const CONST_PNPM_LOCK = 'pnpm-lock.yaml';
|
|
25
|
+
/** Trash directory name (.trash) */
|
|
26
|
+
export const CONST_TrashDir = '.trash';
|
|
27
|
+
/** Deployment metadata file name (deployment-metadata.json) */
|
|
28
|
+
export const CONST_DeploymentMetadata = 'deployment-metadata.json';
|
|
29
|
+
/** Deployment ID metadata key (deployment-id) */
|
|
30
|
+
export const CONST_DeploymentId = 'deployment-id';
|
|
31
|
+
/** Default version tag (latest) */
|
|
32
|
+
export const CONST_LatestTag = 'latest';
|
|
33
|
+
/** Hosting build tarball name (hosting-build.tar.gz) */
|
|
34
|
+
export const CONST_HostingBuildTarball = 'hosting-build.tar.gz';
|
|
35
|
+
/** Staging directory name (staging) */
|
|
36
|
+
export const CONST_StagingDir = 'staging';
|
|
37
|
+
/** Deploy hosting temp directory name (deploy-hosting) */
|
|
38
|
+
export const CONST_DeployHostingDir = 'deploy-hosting';
|
|
39
|
+
/** Build image temp directory name (build-image) */
|
|
40
|
+
export const CONST_BuildImageDir = 'build-image';
|
|
41
|
+
/** Memory storage key for packages configuration */
|
|
42
|
+
export const MemKey_Packages = new MemKey('bai-packages', true);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FirebasePackageConfig } from '../types/index.js';
|
|
2
2
|
export type DefaultType_ProjectEnvs = 'local' | 'dev' | 'staging' | 'prod';
|
|
3
|
-
export declare const Default_ProjectEnvs: ("local" | "
|
|
3
|
+
export declare const Default_ProjectEnvs: ("local" | "staging" | "dev" | "prod")[];
|
|
4
4
|
export declare const Default_FunctionsIgnoreFiles: string[];
|
|
5
5
|
export declare const Default_HostingConfig: {
|
|
6
6
|
public: string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File cache for loading and caching file contents.
|
|
3
|
+
*
|
|
4
|
+
* **Purpose**: Avoids re-reading files multiple times during build process.
|
|
5
|
+
*
|
|
6
|
+
* **Caching Strategy**:
|
|
7
|
+
* - Files are cached in memory after first read
|
|
8
|
+
* - JSON files are parsed and frozen (immutable)
|
|
9
|
+
* - Text files are cached as strings
|
|
10
|
+
* - Cache persists for entire build session
|
|
11
|
+
*
|
|
12
|
+
* **Usage**: Used to load config files (bai-config.json, package.json, etc.)
|
|
13
|
+
* that are read multiple times during workspace scanning and unit initialization.
|
|
14
|
+
*
|
|
15
|
+
* **Clear Cache**: Call `FilesCache.clear()` to reset cache (useful for tests).
|
|
16
|
+
*/
|
|
17
|
+
export declare const FilesCache: {
|
|
18
|
+
/**
|
|
19
|
+
* Clears the file cache.
|
|
20
|
+
*
|
|
21
|
+
* Useful for tests or when files may have changed.
|
|
22
|
+
*/
|
|
23
|
+
clear: () => {};
|
|
24
|
+
load: {
|
|
25
|
+
/**
|
|
26
|
+
* Loads and caches a JSON file.
|
|
27
|
+
*
|
|
28
|
+
* **Behavior**:
|
|
29
|
+
* - Returns cached value if already loaded
|
|
30
|
+
* - Parses JSON and freezes result (immutable)
|
|
31
|
+
* - Throws `ImplementationMissingException` if file doesn't exist or is not a file
|
|
32
|
+
*
|
|
33
|
+
* @param pathToFile - Path to JSON file
|
|
34
|
+
* @returns Promise resolving to parsed and frozen JSON object
|
|
35
|
+
*/
|
|
36
|
+
json: <T>(pathToFile: string) => Promise<T>;
|
|
37
|
+
/**
|
|
38
|
+
* Loads and caches a text file.
|
|
39
|
+
*
|
|
40
|
+
* **Behavior**:
|
|
41
|
+
* - Returns cached value if already loaded
|
|
42
|
+
* - Reads file as UTF-8 text
|
|
43
|
+
* - Throws `ImplementationMissingException` if file doesn't exist or is not a file
|
|
44
|
+
*
|
|
45
|
+
* @param pathToFile - Path to text file
|
|
46
|
+
* @returns Promise resolving to file content as string
|
|
47
|
+
*/
|
|
48
|
+
text: (pathToFile: string) => Promise<string>;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ImplementationMissingException } from '@nu-art/ts-common';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
let cachedFiles = {};
|
|
4
|
+
const readFile = async (path) => {
|
|
5
|
+
try {
|
|
6
|
+
const fileStat = await fs.stat(path);
|
|
7
|
+
if (fileStat.isFile())
|
|
8
|
+
return await fs.readFile(path, 'utf-8');
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
if (error.code === 'ENOENT')
|
|
12
|
+
throw new ImplementationMissingException(`file does not exist: ${path}`);
|
|
13
|
+
throw error; // rethrow other errors
|
|
14
|
+
}
|
|
15
|
+
throw new ImplementationMissingException(`expected a file at: ${path}`);
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* File cache for loading and caching file contents.
|
|
19
|
+
*
|
|
20
|
+
* **Purpose**: Avoids re-reading files multiple times during build process.
|
|
21
|
+
*
|
|
22
|
+
* **Caching Strategy**:
|
|
23
|
+
* - Files are cached in memory after first read
|
|
24
|
+
* - JSON files are parsed and frozen (immutable)
|
|
25
|
+
* - Text files are cached as strings
|
|
26
|
+
* - Cache persists for entire build session
|
|
27
|
+
*
|
|
28
|
+
* **Usage**: Used to load config files (bai-config.json, package.json, etc.)
|
|
29
|
+
* that are read multiple times during workspace scanning and unit initialization.
|
|
30
|
+
*
|
|
31
|
+
* **Clear Cache**: Call `FilesCache.clear()` to reset cache (useful for tests).
|
|
32
|
+
*/
|
|
33
|
+
export const FilesCache = {
|
|
34
|
+
/**
|
|
35
|
+
* Clears the file cache.
|
|
36
|
+
*
|
|
37
|
+
* Useful for tests or when files may have changed.
|
|
38
|
+
*/
|
|
39
|
+
clear: () => cachedFiles = {},
|
|
40
|
+
load: {
|
|
41
|
+
/**
|
|
42
|
+
* Loads and caches a JSON file.
|
|
43
|
+
*
|
|
44
|
+
* **Behavior**:
|
|
45
|
+
* - Returns cached value if already loaded
|
|
46
|
+
* - Parses JSON and freezes result (immutable)
|
|
47
|
+
* - Throws `ImplementationMissingException` if file doesn't exist or is not a file
|
|
48
|
+
*
|
|
49
|
+
* @param pathToFile - Path to JSON file
|
|
50
|
+
* @returns Promise resolving to parsed and frozen JSON object
|
|
51
|
+
*/
|
|
52
|
+
json: async (pathToFile) => {
|
|
53
|
+
const json = cachedFiles[pathToFile];
|
|
54
|
+
if (!json)
|
|
55
|
+
cachedFiles[pathToFile] = Object.freeze(JSON.parse(await readFile(pathToFile)));
|
|
56
|
+
return cachedFiles[pathToFile];
|
|
57
|
+
},
|
|
58
|
+
/**
|
|
59
|
+
* Loads and caches a text file.
|
|
60
|
+
*
|
|
61
|
+
* **Behavior**:
|
|
62
|
+
* - Returns cached value if already loaded
|
|
63
|
+
* - Reads file as UTF-8 text
|
|
64
|
+
* - Throws `ImplementationMissingException` if file doesn't exist or is not a file
|
|
65
|
+
*
|
|
66
|
+
* @param pathToFile - Path to text file
|
|
67
|
+
* @returns Promise resolving to file content as string
|
|
68
|
+
*/
|
|
69
|
+
text: async (pathToFile) => {
|
|
70
|
+
const fileContent = cachedFiles[pathToFile];
|
|
71
|
+
if (!fileContent)
|
|
72
|
+
cachedFiles[pathToFile] = await readFile(pathToFile);
|
|
73
|
+
return cachedFiles[pathToFile];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|