@nu-art/build-and-install 0.400.14 → 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.
Files changed (156) hide show
  1. package/BuildAndInstall.d.ts +40 -0
  2. package/BuildAndInstall.js +155 -0
  3. package/build-and-install-v3.d.ts +1 -32
  4. package/build-and-install-v3.js +1 -154
  5. package/build-and-install.js +11 -11
  6. package/config/consts.d.ts +43 -0
  7. package/config/consts.js +42 -0
  8. package/{core → config}/package/consts.d.ts +1 -1
  9. package/{core → config}/types/project-config.d.ts +3 -0
  10. package/core/FilesCache.d.ts +50 -0
  11. package/core/FilesCache.js +76 -0
  12. package/core/Unit_HelpPrinter.d.ts +16 -0
  13. package/core/Unit_HelpPrinter.js +47 -0
  14. package/core/params/params.d.ts +1 -41
  15. package/core/params/params.js +1 -334
  16. package/core/params.d.ts +50 -0
  17. package/core/params.js +441 -0
  18. package/{v3/core → core}/types.d.ts +1 -1
  19. package/{v3/UnitsDependencyMapper → dependencies}/UnitsDependencyMapper.d.ts +21 -1
  20. package/{v3/UnitsDependencyMapper → dependencies}/UnitsDependencyMapper.js +26 -3
  21. package/dependencies/types.d.ts +1 -0
  22. package/dependencies/types.js +1 -0
  23. package/exceptions/PhaseAggregatedException.d.ts +34 -0
  24. package/{core/exceptions → exceptions}/PhaseAggregatedException.js +26 -0
  25. package/exceptions/UnitPhaseException.d.ts +20 -0
  26. package/exceptions/UnitPhaseException.js +21 -0
  27. package/exports/ExportIndexCache.d.ts +25 -0
  28. package/exports/ExportIndexCache.js +115 -0
  29. package/exports/ExportMapper.d.ts +43 -0
  30. package/exports/ExportMapper.js +519 -0
  31. package/exports/IndicesMcpServer.d.ts +22 -0
  32. package/exports/IndicesMcpServer.js +220 -0
  33. package/exports/types.js +3 -0
  34. package/package.json +20 -9
  35. package/phases/PhaseManager.d.ts +130 -0
  36. package/phases/PhaseManager.js +267 -0
  37. package/{v3/phase → phases/definitions}/consts.d.ts +36 -0
  38. package/{v3/phase → phases/definitions}/consts.js +45 -2
  39. package/phases/definitions/types.d.ts +40 -0
  40. package/phases/index.d.ts +2 -0
  41. package/phases/index.js +2 -0
  42. package/run.js +10 -0
  43. package/runtime/RunningStatusHandler.d.ts +104 -0
  44. package/runtime/RunningStatusHandler.js +153 -0
  45. package/runtime/types.d.ts +1 -0
  46. package/runtime/types.js +2 -0
  47. package/{defaults → templates}/consts.d.ts +9 -0
  48. package/{defaults → templates}/consts.js +12 -2
  49. package/templates/firebase/functions/cloudbuild.yaml +17 -0
  50. package/templates/firebase/functions/dockerfile +19 -0
  51. package/templates/firebase/functions/service.yaml +49 -0
  52. package/{v3/units → units/base}/BaseUnit.d.ts +35 -3
  53. package/{v3/units → units/base}/BaseUnit.js +22 -2
  54. package/units/base/ProjectUnit.d.ts +32 -0
  55. package/units/base/ProjectUnit.js +25 -0
  56. package/units/base/types.js +1 -0
  57. package/units/discovery/UnitsMapper.d.ts +69 -0
  58. package/{v3/UnitsMapper → units/discovery}/UnitsMapper.js +51 -3
  59. package/units/discovery/resolvers/UnitMapper_Base.d.ts +65 -0
  60. package/units/discovery/resolvers/UnitMapper_Base.js +46 -0
  61. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseFunction.d.ts +5 -3
  62. package/units/discovery/resolvers/UnitMapper_FirebaseFunction.js +105 -0
  63. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseHosting.d.ts +3 -2
  64. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseHosting.js +14 -10
  65. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_Node.d.ts +1 -1
  66. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_Node.js +2 -2
  67. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeLib.d.ts +24 -1
  68. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeLib.js +24 -1
  69. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeProject.d.ts +22 -1
  70. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeProject.js +22 -1
  71. package/units/discovery/types.js +1 -0
  72. package/units/implementations/Unit_NodeProject.d.ts +59 -0
  73. package/{v3/units → units/implementations}/Unit_NodeProject.js +67 -6
  74. package/units/implementations/Unit_PackageJson.d.ts +56 -0
  75. package/{v3/units → units/implementations}/Unit_PackageJson.js +39 -3
  76. package/{v3/units → units/implementations}/Unit_TypescriptLib.d.ts +40 -4
  77. package/{v3/units → units/implementations}/Unit_TypescriptLib.js +167 -17
  78. package/units/implementations/firebase/Unit_FirebaseFunctionsApp.d.ts +233 -0
  79. package/units/implementations/firebase/Unit_FirebaseFunctionsApp.js +804 -0
  80. package/units/implementations/firebase/Unit_FirebaseHostingApp.d.ts +113 -0
  81. package/units/implementations/firebase/Unit_FirebaseHostingApp.js +320 -0
  82. package/units/implementations/firebase/common.d.ts +26 -0
  83. package/units/implementations/firebase/common.js +65 -0
  84. package/units/index.d.ts +6 -0
  85. package/units/index.js +6 -0
  86. package/v3/core/Unit_HelpPrinter.d.ts +1 -16
  87. package/v3/core/Unit_HelpPrinter.js +1 -47
  88. package/workspace/Workspace.d.ts +95 -0
  89. package/workspace/Workspace.js +192 -0
  90. package/core/consts.d.ts +0 -13
  91. package/core/consts.js +0 -12
  92. package/core/exceptions/PhaseAggregatedException.d.ts +0 -8
  93. package/core/exceptions/UnitPhaseException.d.ts +0 -5
  94. package/core/exceptions/UnitPhaseException.js +0 -6
  95. package/old/PhaseRunnerDispatcher.d.ts +0 -24
  96. package/old/PhaseRunnerDispatcher.js +0 -32
  97. package/old/runner-dispatchers.d.ts +0 -10
  98. package/old/runner-dispatchers.js +0 -3
  99. package/v3/PhaseManager.d.ts +0 -26
  100. package/v3/PhaseManager.js +0 -158
  101. package/v3/RunningStatusHandler.d.ts +0 -18
  102. package/v3/RunningStatusHandler.js +0 -67
  103. package/v3/UnitsMapper/UnitsMapper.d.ts +0 -21
  104. package/v3/UnitsMapper/resolvers/UnitMapper_Base.d.ts +0 -23
  105. package/v3/UnitsMapper/resolvers/UnitMapper_Base.js +0 -16
  106. package/v3/UnitsMapper/resolvers/UnitMapper_FirebaseFunction.js +0 -66
  107. package/v3/core/FilesCache.d.ts +0 -7
  108. package/v3/core/FilesCache.js +0 -33
  109. package/v3/phase/types.d.ts +0 -9
  110. package/v3/units/ProjectUnit.d.ts +0 -18
  111. package/v3/units/ProjectUnit.js +0 -11
  112. package/v3/units/Unit_NodeProject.d.ts +0 -30
  113. package/v3/units/Unit_PackageJson.d.ts +0 -17
  114. package/v3/units/firebase/Unit_FirebaseFunctionsApp.d.ts +0 -64
  115. package/v3/units/firebase/Unit_FirebaseFunctionsApp.js +0 -306
  116. package/v3/units/firebase/Unit_FirebaseHostingApp.d.ts +0 -49
  117. package/v3/units/firebase/Unit_FirebaseHostingApp.js +0 -114
  118. package/v3/units/firebase/common.d.ts +0 -3
  119. package/v3/units/firebase/common.js +0 -13
  120. package/v3/units/index.d.ts +0 -6
  121. package/v3/units/index.js +0 -6
  122. /package/{core → config}/package/consts.js +0 -0
  123. /package/{core → config}/types/configs/firebasejson.d.ts +0 -0
  124. /package/{core → config}/types/configs/firebasejson.js +0 -0
  125. /package/{core → config}/types/configs/firebaserc.d.ts +0 -0
  126. /package/{core → config}/types/configs/firebaserc.js +0 -0
  127. /package/{core → config}/types/configs/index.d.ts +0 -0
  128. /package/{core → config}/types/configs/index.js +0 -0
  129. /package/{core → config}/types/configs/package-json.d.ts +0 -0
  130. /package/{core → config}/types/configs/package-json.js +0 -0
  131. /package/{core → config}/types/core.d.ts +0 -0
  132. /package/{core → config}/types/core.js +0 -0
  133. /package/{core → config}/types/index.d.ts +0 -0
  134. /package/{core → config}/types/index.js +0 -0
  135. /package/{core → config}/types/package/index.d.ts +0 -0
  136. /package/{core → config}/types/package/index.js +0 -0
  137. /package/{core → config}/types/package/package.d.ts +0 -0
  138. /package/{core → config}/types/package/package.js +0 -0
  139. /package/{core → config}/types/package/runtime-package.d.ts +0 -0
  140. /package/{core → config}/types/package/runtime-package.js +0 -0
  141. /package/{core → config}/types/project-config.js +0 -0
  142. /package/{v3/core → core}/types.js +0 -0
  143. /package/{v3/UnitsMapper/types.js → exports/types.d.ts} +0 -0
  144. /package/{v3/phase → phases/definitions}/index.d.ts +0 -0
  145. /package/{v3/phase → phases/definitions}/index.js +0 -0
  146. /package/{v3/phase → phases/definitions}/types.js +0 -0
  147. /package/{v3/units/types.js → run.d.ts} +0 -0
  148. /package/{defaults/backend-proxy → templates/backend/proxy}/proxy._ts +0 -0
  149. /package/{defaults/.firebase_config → templates/firebase/config}/database.rules.json +0 -0
  150. /package/{defaults/.firebase_config → templates/firebase/config}/firestore.indexes.json +0 -0
  151. /package/{defaults/.firebase_config → templates/firebase/config}/firestore.rules +0 -0
  152. /package/{defaults/.firebase_config → templates/firebase/config}/storage.rules +0 -0
  153. /package/{v3/units → units/base}/types.d.ts +0 -0
  154. /package/{v3/UnitsMapper → units/discovery}/resolvers/index.d.ts +0 -0
  155. /package/{v3/UnitsMapper → units/discovery}/resolvers/index.js +0 -0
  156. /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,32 +1 @@
1
- import { Logger } from '@nu-art/ts-common';
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 { Unit_NodeProject } from './v3/units/index.js';
7
- import { BaseCliParam } from '@nu-art/commando/cli-params/types';
8
- import { RunningStatusHandler } from './v3/RunningStatusHandler.js';
9
- export declare const DefaultPhases: Phase<string>[][];
10
- type BAI_Options = {
11
- pathToProject: string;
12
- runtimeParams: BaseCliParam<string, any>[];
13
- };
14
- export declare class BuildAndInstall extends Logger {
15
- private unitsMapper;
16
- private phases;
17
- private pathToProject;
18
- private allUnits;
19
- readonly nodeProjectUnit: Unit_NodeProject;
20
- readonly runtimeParams: BaiParams;
21
- readonly projectUnits: ProjectUnit[];
22
- private unitsDependencyMapper;
23
- readonly runningStatus: RunningStatusHandler;
24
- constructor(config?: Partial<BAI_Options>);
25
- init(): Promise<void>;
26
- prepareUnitsMapper(unitsMapper: UnitsMapper): void;
27
- setApplicativeUnits(projectUnits: ProjectUnit[]): void;
28
- setPhases(phases: Phase<string>[][]): void;
29
- build(): Promise<ProjectUnit<import("./v3/units/ProjectUnit.js").Config_ProjectUnit>[]>;
30
- run(): Promise<void>;
31
- }
32
- export {};
1
+ export * from './BuildAndInstall.js';
@@ -1,154 +1 @@
1
- import { _keys, arrayToMap, BeLogged, DebugFlag, filterDuplicates, ImplementationMissingException, LogClient_Terminal, Logger, LogLevel, merge } from '@nu-art/ts-common';
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 { UnitsDependencyMapper } from './v3/UnitsDependencyMapper/UnitsDependencyMapper.js';
6
- import { FilesCache } from './v3/core/FilesCache.js';
7
- import { ProjectUnit } from './v3/units/ProjectUnit.js';
8
- import { PhaseManager } from './v3/PhaseManager.js';
9
- import { Unit_NodeProject } from './v3/units/index.js';
10
- import { resolve } from 'path';
11
- import { CONST_BaiConfig, CONST_NodeModules, CONST_VersionApp } from './core/consts.js';
12
- import { UnitMapper_FirebaseFunction, UnitMapper_FirebaseHosting, UnitMapper_NodeLib, UnitMapper_NodeProject } from './v3/UnitsMapper/resolvers/index.js';
13
- import { CLIParamsResolver } from '@nu-art/commando/cli-params/CLIParamsResolver';
14
- import { RunningStatusHandler } from './v3/RunningStatusHandler.js';
15
- import { FileSystemUtils } from '@nu-art/ts-common/utils/FileSystemUtils';
16
- export const DefaultPhases = [
17
- ...phases_Build,
18
- ...phases_Terminating,
19
- ...phases_Launch,
20
- ...phases_Deploy,
21
- ];
22
- export class BuildAndInstall extends Logger {
23
- unitsMapper;
24
- phases = DefaultPhases;
25
- pathToProject;
26
- allUnits = [];
27
- nodeProjectUnit;
28
- runtimeParams;
29
- projectUnits = [];
30
- unitsDependencyMapper;
31
- runningStatus;
32
- constructor(config = {}) {
33
- super();
34
- const defaultConfig = merge({
35
- pathToProject: process.env.INIT_CWD ?? process.cwd(),
36
- }, config);
37
- defaultConfig.runtimeParams = filterDuplicates([...(config.runtimeParams ?? []), ...AllBaiParams], param => param.keyName);
38
- this.runtimeParams = CLIParamsResolver.create(...defaultConfig.runtimeParams).resolveParamValue();
39
- BeLogged.addClient(LogClient_Terminal);
40
- this.pathToProject = defaultConfig.pathToProject;
41
- this.runningStatus = new RunningStatusHandler(this.pathToProject, this.runtimeParams);
42
- }
43
- async init() {
44
- await this.runningStatus.init();
45
- if (this.runtimeParams.debug)
46
- DebugFlag.DefaultLogLevel = LogLevel.Debug;
47
- if (this.runtimeParams.verbose)
48
- DebugFlag.DefaultLogLevel = LogLevel.Verbose;
49
- this.setMinLevel(DebugFlag.DefaultLogLevel);
50
- this.logDebug('Runtime params:', this.runtimeParams);
51
- this.unitsMapper = new UnitsMapper();
52
- this.prepareUnitsMapper(this.unitsMapper);
53
- }
54
- prepareUnitsMapper(unitsMapper) {
55
- unitsMapper
56
- .addRules(UnitMapper_NodeLib)
57
- .addRules(UnitMapper_NodeProject)
58
- .addRules(UnitMapper_FirebaseHosting)
59
- .addRules(UnitMapper_FirebaseFunction)
60
- .setRuntimeParams(this.runtimeParams);
61
- }
62
- setApplicativeUnits(projectUnits) {
63
- this.projectUnits.push(...projectUnits);
64
- }
65
- setPhases(phases) {
66
- this.phases = phases;
67
- }
68
- async build() {
69
- await this.init();
70
- this.logVerbose(`Resolving units from: ${this.pathToProject}`);
71
- this.allUnits = await this.unitsMapper.resolveUnits(this.pathToProject);
72
- Object.freeze(this.allUnits);
73
- this.logDebug('Units found:', this.allUnits.map(unit => `${unit.constructor?.['name']}: ${unit.config.key}`).join('\n'));
74
- const unitKeyToUnitMap = arrayToMap(this.allUnits, unit => unit.config.key);
75
- const allProjectUnits = this.allUnits.filter(unit => unit.isInstanceOf(ProjectUnit));
76
- const nodeProjectUnit = allProjectUnits.find(unit => unit.isInstanceOf(Unit_NodeProject));
77
- // @ts-ignore
78
- this['nodeProjectUnit'] = nodeProjectUnit;
79
- if (!this.nodeProjectUnit)
80
- throw new ImplementationMissingException('NodeProject unit not found. Make sure you have a Unit_NodeProject in your project.');
81
- this.nodeProjectUnit.assignUnit(allProjectUnits);
82
- this.logDebug(`Parent unit: ${this.nodeProjectUnit.config.key}`);
83
- this.logDebug(`Child units: ${allProjectUnits.map(unit => unit.config.key).join(', ')}`);
84
- const pathToBaiConfig = resolve(this.nodeProjectUnit.config.fullPath, CONST_BaiConfig);
85
- this.logVerbose(`Loading BAI-Config from: ${pathToBaiConfig}`);
86
- const baiConfig = await FilesCache.load.json(pathToBaiConfig);
87
- this.logDebug('Loaded BAI-Config', baiConfig);
88
- this.projectUnits.push(...allProjectUnits);
89
- Object.freeze(this.projectUnits);
90
- const unitsDependencies = this.projectUnits.map(unit => ({
91
- key: unit.config.key,
92
- dependsOn: _keys(unit.config.dependencies).filter(key => !!unitKeyToUnitMap[key])
93
- }));
94
- const globalOutputFolder = resolve(this.pathToProject, '.trash/output');
95
- this.unitsDependencyMapper = new UnitsDependencyMapper(unitsDependencies, globalOutputFolder);
96
- const versionFilePath = resolve(this.pathToProject, CONST_VersionApp);
97
- this.logInfo('loading version from: ', versionFilePath);
98
- const version = await FileSystemUtils.file.read.json(versionFilePath, { version: '1.0.0' });
99
- const runtimeContext = ({
100
- version: version.version,
101
- parentUnit: this.nodeProjectUnit,
102
- childUnits: allProjectUnits,
103
- baiConfig,
104
- runtimeParams: this.runtimeParams,
105
- unitsMapper: this.unitsDependencyMapper,
106
- unitsResolver: (keys, className) => {
107
- return keys.map(key => unitKeyToUnitMap[key]).filter(unit => unit.isInstanceOf(className));
108
- },
109
- globalOutputFolder,
110
- });
111
- this.projectUnits.forEach(unit => unit.setupRuntimeContext(runtimeContext));
112
- if (!(await FileSystemUtils.file.exists(resolve(this.nodeProjectUnit.config.fullPath, CONST_NodeModules)))) {
113
- this.logInfo(`root project is missing ${CONST_NodeModules} folder. Enabling install...`);
114
- this.runtimeParams.install = true;
115
- }
116
- return allProjectUnits;
117
- }
118
- async run() {
119
- const keyToUnitMap = arrayToMap(this.projectUnits, u => u.config.key);
120
- let topLevelAppKeys = this.projectUnits.filter(unit => unit.config.isTopLevelApp).map(unit => unit.config.key);
121
- this.logWarning('this.runtimeParams.includeApps', this.runtimeParams.includeApps);
122
- if (this.runtimeParams.includeApps?.length) {
123
- this.logWarning('HEREHREHREHRHERHER');
124
- const regexMatchers = this.runtimeParams.includeApps.map(filter => new RegExp(`.*?${filter}.*?`, 'i'));
125
- topLevelAppKeys = topLevelAppKeys.filter(unitKey => regexMatchers.some(matcher => matcher.test(unitKey)));
126
- }
127
- this.logDebug('topLevelAppKeys: ', topLevelAppKeys);
128
- const participatingUnitKeys = this.runtimeParams.allUnits
129
- ? undefined
130
- : [...this.unitsDependencyMapper.getTransitiveDependencies(topLevelAppKeys), ...topLevelAppKeys];
131
- const unitDependencyTree = (await this.unitsDependencyMapper.buildDependencyTree(participatingUnitKeys))
132
- .map(units => units.map(unitKey => keyToUnitMap[unitKey]));
133
- const phaseManager = new PhaseManager(this.runningStatus, this.phases, unitDependencyTree);
134
- const executionPlan = await phaseManager.calculateExecutionSteps();
135
- let killCounter = 0;
136
- process.on('SIGINT', async () => {
137
- this.logWarning('\n\n\n---------------------------------- Process Interrupted ----------------------------------\n\n\n');
138
- await phaseManager.break();
139
- killCounter++;
140
- if (killCounter > 5)
141
- process.exit(1);
142
- });
143
- try {
144
- await phaseManager.execute(executionPlan);
145
- this.logInfo('Completed successfully');
146
- this.logInfo('---------------------------------- Process Completed successfully ----------------------------------');
147
- }
148
- catch (e) {
149
- this.logInfo('Process Failed');
150
- this.logInfo('---------------------------------- Process Failed ----------------------------------');
151
- throw e;
152
- }
153
- }
154
- }
1
+ export * from './BuildAndInstall.js';
@@ -1,17 +1,17 @@
1
- import { BuildAndInstall } from './build-and-install-v3.js';
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(console.error)
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>;
@@ -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" | "dev" | "staging" | "prod")[];
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;
@@ -20,6 +20,9 @@ export type BAI_Config = {
20
20
  packageJson?: TypedMap<string>;
21
21
  };
22
22
  files?: {
23
+ docker?: {
24
+ dockerfile?: string;
25
+ };
23
26
  tests?: {
24
27
  firebase?: {
25
28
  'firebase.json'?: 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
+ };