@nu-art/build-and-install 0.400.4 → 0.400.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-and-install-v3.d.ts +3 -0
- package/build-and-install-v3.js +14 -9
- package/core/params/params.d.ts +4 -4
- package/core/params/params.js +39 -18
- package/package.json +3 -3
- package/v3/PhaseManager.js +15 -2
- package/v3/RunningStatusHandler.d.ts +7 -5
- package/v3/RunningStatusHandler.js +21 -10
- package/v3/UnitsMapper/resolvers/UnitMapper_Node.js +41 -34
- package/v3/core/Unit_HelpPrinter.d.ts +1 -1
- package/v3/phase/consts.d.ts +1 -0
- package/v3/phase/consts.js +6 -1
- package/v3/units/Unit_TypescriptLib.js +71 -35
- package/v3/units/firebase/Unit_FirebaseFunctionsApp.d.ts +5 -2
- package/v3/units/firebase/Unit_FirebaseFunctionsApp.js +29 -16
- package/v3/units/firebase/Unit_FirebaseHostingApp.d.ts +3 -2
- package/v3/units/firebase/Unit_FirebaseHostingApp.js +16 -4
- package/v3/units/firebase/common.d.ts +3 -0
- package/v3/units/firebase/common.js +13 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Logger } from '@nu-art/ts-common';
|
|
2
2
|
import { BaiParams } from './core/params/params.js';
|
|
3
3
|
import { Phase } from './v3/phase/index.js';
|
|
4
|
+
import { UnitsMapper } from './v3/UnitsMapper/UnitsMapper.js';
|
|
4
5
|
import { ProjectUnit } from './v3/units/ProjectUnit.js';
|
|
5
6
|
import { Unit_NodeProject } from './v3/units/index.js';
|
|
6
7
|
import { BaseCliParam } from '@nu-art/commando/cli-params/types';
|
|
@@ -11,6 +12,7 @@ type BAI_Options = {
|
|
|
11
12
|
runtimeParams: BaseCliParam<string, any>[];
|
|
12
13
|
};
|
|
13
14
|
export declare class BuildAndInstall extends Logger {
|
|
15
|
+
private unitsMapper;
|
|
14
16
|
private phases;
|
|
15
17
|
private pathToProject;
|
|
16
18
|
private allUnits;
|
|
@@ -21,6 +23,7 @@ export declare class BuildAndInstall extends Logger {
|
|
|
21
23
|
readonly runningStatus: RunningStatusHandler;
|
|
22
24
|
constructor(config?: Partial<BAI_Options>);
|
|
23
25
|
init(): Promise<void>;
|
|
26
|
+
prepareUnitsMapper(unitsMapper: UnitsMapper): void;
|
|
24
27
|
setApplicativeUnits(projectUnits: ProjectUnit[]): void;
|
|
25
28
|
setPhases(phases: Phase<string>[][]): void;
|
|
26
29
|
build(): Promise<ProjectUnit<import("./v3/units/ProjectUnit.js").Config_ProjectUnit>[]>;
|
package/build-and-install-v3.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _keys, arrayToMap, BeLogged, DebugFlag, filterDuplicates, LogClient_Terminal, Logger, LogLevel, merge } from '@nu-art/ts-common';
|
|
2
2
|
import { AllBaiParams } from './core/params/params.js';
|
|
3
|
-
import { phases_Build, phases_Deploy, phases_Launch } from './v3/phase/index.js';
|
|
3
|
+
import { phases_Build, phases_Deploy, phases_Launch, phases_Terminating } from './v3/phase/index.js';
|
|
4
4
|
import { UnitsMapper } from './v3/UnitsMapper/UnitsMapper.js';
|
|
5
5
|
import { UnitsDependencyMapper } from './v3/UnitsDependencyMapper/UnitsDependencyMapper.js';
|
|
6
6
|
import { FilesCache } from './v3/core/FilesCache.js';
|
|
@@ -15,10 +15,12 @@ import { RunningStatusHandler } from './v3/RunningStatusHandler.js';
|
|
|
15
15
|
import { FileSystemUtils } from '@nu-art/ts-common/utils/FileSystemUtils';
|
|
16
16
|
export const DefaultPhases = [
|
|
17
17
|
...phases_Build,
|
|
18
|
+
...phases_Terminating,
|
|
18
19
|
...phases_Launch,
|
|
19
20
|
...phases_Deploy,
|
|
20
21
|
];
|
|
21
22
|
export class BuildAndInstall extends Logger {
|
|
23
|
+
unitsMapper;
|
|
22
24
|
phases = DefaultPhases;
|
|
23
25
|
pathToProject;
|
|
24
26
|
allUnits = [];
|
|
@@ -46,6 +48,16 @@ export class BuildAndInstall extends Logger {
|
|
|
46
48
|
DebugFlag.DefaultLogLevel = LogLevel.Verbose;
|
|
47
49
|
this.setMinLevel(DebugFlag.DefaultLogLevel);
|
|
48
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);
|
|
49
61
|
}
|
|
50
62
|
setApplicativeUnits(projectUnits) {
|
|
51
63
|
this.projectUnits.push(...projectUnits);
|
|
@@ -56,14 +68,7 @@ export class BuildAndInstall extends Logger {
|
|
|
56
68
|
async build() {
|
|
57
69
|
await this.init();
|
|
58
70
|
this.logVerbose(`Resolving units from: ${this.pathToProject}`);
|
|
59
|
-
|
|
60
|
-
this.allUnits = await unitsMapper
|
|
61
|
-
.addRules(UnitMapper_NodeLib)
|
|
62
|
-
.addRules(UnitMapper_NodeProject)
|
|
63
|
-
.addRules(UnitMapper_FirebaseHosting)
|
|
64
|
-
.addRules(UnitMapper_FirebaseFunction)
|
|
65
|
-
.setRuntimeParams(this.runtimeParams)
|
|
66
|
-
.resolveUnits(this.pathToProject);
|
|
71
|
+
this.allUnits = await this.unitsMapper.resolveUnits(this.pathToProject);
|
|
67
72
|
Object.freeze(this.allUnits);
|
|
68
73
|
this.logDebug('Units found:', this.allUnits.map(unit => `${unit.constructor?.['name']}: ${unit.config.key}`).join('\n'));
|
|
69
74
|
const unitKeyToUnitMap = arrayToMap(this.allUnits, unit => unit.config.key);
|
package/core/params/params.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { BaseCliParam, CliParams } from '@nu-art/commando/cli-params/types';
|
|
2
2
|
export declare const BaiParam_AllUnits: BaseCliParam<'allUnits', boolean>;
|
|
3
3
|
export declare const BaiParam_DependencyTree: BaseCliParam<'dependencyTree', boolean>;
|
|
4
|
-
export declare const BaiParam_CheckCyclicImports: BaseCliParam<'checkCyclicImports', boolean>;
|
|
5
4
|
export declare const BaiParam_continue: BaseCliParam<'continue', boolean>;
|
|
6
5
|
export declare const BaiParam_SetEnv: BaseCliParam<'environment', string>;
|
|
7
|
-
export declare const BaiParam_Setup: BaseCliParam<'setup', boolean>;
|
|
8
6
|
export declare const BaiParam_Install: BaseCliParam<'install', boolean>;
|
|
9
7
|
export declare const BaiParam_Clean: BaseCliParam<'clean', boolean>;
|
|
10
8
|
export declare const BaiParam_Purge: BaseCliParam<'purge', boolean>;
|
|
@@ -25,7 +23,7 @@ export declare const BaiParam_TestCase: BaseCliParam<'testCases', string[]>;
|
|
|
25
23
|
export declare const BaiParam_TestDebugPort: BaseCliParam<'testDebugPort', number>;
|
|
26
24
|
export declare const BaiParam_Launch: BaseCliParam<'launch', boolean>;
|
|
27
25
|
export declare const BaiParam_DebugBackend: BaseCliParam<'debugBackend', boolean>;
|
|
28
|
-
export declare const BaiParam_Deploy: BaseCliParam<'deploy',
|
|
26
|
+
export declare const BaiParam_Deploy: BaseCliParam<'deploy', boolean>;
|
|
29
27
|
export declare const BaiParam_Debug: BaseCliParam<'debug', boolean>;
|
|
30
28
|
export declare const BaiParam_DebugLifecycle: BaseCliParam<'debugLifecycle', boolean>;
|
|
31
29
|
export declare const BaiParam_Verbose: BaseCliParam<'verbose', boolean>;
|
|
@@ -33,8 +31,10 @@ export declare const BaiParam_QuickDeploy: BaseCliParam<'quickDeploy', boolean>;
|
|
|
33
31
|
type PromoteType = 'patch' | 'minor' | 'major';
|
|
34
32
|
export declare const BaiParam_Publish: BaseCliParam<'publish', PromoteType>;
|
|
35
33
|
export declare const BaiParam_UsePackage: BaseCliParam<'usePackage', string[]>;
|
|
34
|
+
export declare const BaiParam_includePackage: BaseCliParam<'includePackage', string[]>;
|
|
36
35
|
export declare const BaiParam_ToESM: BaseCliParam<'toESM', boolean>;
|
|
37
36
|
export declare const BaiParam_Simulate: BaseCliParam<'simulation', boolean>;
|
|
38
|
-
export declare const
|
|
37
|
+
export declare const BaiParam_CheckCyclicImports: BaseCliParam<'checkCyclicImports', boolean>;
|
|
38
|
+
export declare const AllBaiParams: (BaseCliParam<"allUnits", boolean> | BaseCliParam<"dependencyTree", boolean> | BaseCliParam<"continue", boolean> | BaseCliParam<"environment", string> | BaseCliParam<"install", boolean> | BaseCliParam<"clean", boolean> | BaseCliParam<"purge", boolean> | BaseCliParam<"generate", boolean> | BaseCliParam<"generateDocs", boolean> | BaseCliParam<"noBuild", boolean> | BaseCliParam<"prepare", boolean> | BaseCliParam<"dryRun", boolean> | BaseCliParam<"lint", boolean> | BaseCliParam<"watch", boolean> | BaseCliParam<"watchBuildTree", boolean> | BaseCliParam<"test", boolean> | BaseCliParam<"testType", string[]> | BaseCliParam<"testFiles", string[]> | BaseCliParam<"testCases", string[]> | BaseCliParam<"testDebugPort", number> | BaseCliParam<"launch", boolean> | BaseCliParam<"debugBackend", boolean> | BaseCliParam<"deploy", boolean> | BaseCliParam<"debug", boolean> | BaseCliParam<"debugLifecycle", boolean> | BaseCliParam<"verbose", boolean> | BaseCliParam<"publish", PromoteType> | BaseCliParam<"usePackage", string[]> | BaseCliParam<"includePackage", string[]> | BaseCliParam<"toESM", boolean> | BaseCliParam<"simulation", boolean> | BaseCliParam<"checkCyclicImports", boolean>)[];
|
|
39
39
|
export type BaiParams = CliParams<typeof AllBaiParams>;
|
|
40
40
|
export {};
|
package/core/params/params.js
CHANGED
|
@@ -12,13 +12,6 @@ export const BaiParam_DependencyTree = {
|
|
|
12
12
|
group: 'General',
|
|
13
13
|
description: 'Will print the projects packages dependencies tree into the .trash folder'
|
|
14
14
|
};
|
|
15
|
-
export const BaiParam_CheckCyclicImports = {
|
|
16
|
-
keys: ['--check-cyclic-imports', '-cci'],
|
|
17
|
-
keyName: 'checkCyclicImports',
|
|
18
|
-
type: 'boolean',
|
|
19
|
-
group: 'General',
|
|
20
|
-
description: 'will check for cyclic imports and render an svg with the import graph'
|
|
21
|
-
};
|
|
22
15
|
export const BaiParam_continue = {
|
|
23
16
|
keys: ['--continue', '-con'],
|
|
24
17
|
keyName: 'continue',
|
|
@@ -34,13 +27,6 @@ export const BaiParam_SetEnv = {
|
|
|
34
27
|
initialValue: 'local',
|
|
35
28
|
description: 'Will set the .config-${environment}.json as the current .config.json and prepare it as base 64 for local usage \ninput required: envName(string)'
|
|
36
29
|
};
|
|
37
|
-
export const BaiParam_Setup = {
|
|
38
|
-
keys: ['--setup'],
|
|
39
|
-
keyName: 'setup',
|
|
40
|
-
type: 'boolean',
|
|
41
|
-
group: 'Build',
|
|
42
|
-
description: 'Setup local project for developer'
|
|
43
|
-
};
|
|
44
30
|
export const BaiParam_Install = {
|
|
45
31
|
keys: ['--install', '-i'],
|
|
46
32
|
keyName: 'install',
|
|
@@ -184,9 +170,15 @@ export const BaiParam_DebugBackend = {
|
|
|
184
170
|
export const BaiParam_Deploy = {
|
|
185
171
|
keys: ['--deploy', '-dep'],
|
|
186
172
|
keyName: 'deploy',
|
|
187
|
-
type: '
|
|
173
|
+
type: 'boolean',
|
|
188
174
|
group: 'Apps',
|
|
189
|
-
description: 'Will add the provided App to the deploy list or all applications'
|
|
175
|
+
description: 'Will add the provided App to the deploy list or all applications',
|
|
176
|
+
dependencies: [
|
|
177
|
+
{ param: BaiParam_Launch, value: false },
|
|
178
|
+
{ param: BaiParam_Watch, value: false },
|
|
179
|
+
{ param: BaiParam_WatchBuildTree, value: false },
|
|
180
|
+
{ param: BaiParam_GenerateDocs, value: false },
|
|
181
|
+
]
|
|
190
182
|
};
|
|
191
183
|
export const BaiParam_Debug = {
|
|
192
184
|
keys: ['--debug', '-d'],
|
|
@@ -239,6 +231,19 @@ export const BaiParam_UsePackage = {
|
|
|
239
231
|
},
|
|
240
232
|
dependencies: [{ param: BaiParam_AllUnits, value: true }]
|
|
241
233
|
};
|
|
234
|
+
export const BaiParam_includePackage = {
|
|
235
|
+
keys: ['-in', '--include='],
|
|
236
|
+
keyName: 'includePackage',
|
|
237
|
+
type: 'string[]',
|
|
238
|
+
group: 'Other',
|
|
239
|
+
description: 'Will include the units to process',
|
|
240
|
+
process: (value) => {
|
|
241
|
+
if (!value)
|
|
242
|
+
return [];
|
|
243
|
+
return value.split(',').map(str => str.trim());
|
|
244
|
+
},
|
|
245
|
+
dependencies: []
|
|
246
|
+
};
|
|
242
247
|
export const BaiParam_ToESM = {
|
|
243
248
|
keys: ['-tesm', '--to-esm'],
|
|
244
249
|
keyName: 'toESM',
|
|
@@ -248,13 +253,29 @@ export const BaiParam_ToESM = {
|
|
|
248
253
|
dependencies: [{ param: BaiParam_AllUnits, value: true }]
|
|
249
254
|
};
|
|
250
255
|
export const BaiParam_Simulate = {
|
|
251
|
-
keys: ['--simulate', '-sim'],
|
|
256
|
+
keys: ['--simulate', '-sim', '--simulation'],
|
|
252
257
|
keyName: 'simulation',
|
|
253
258
|
type: 'boolean',
|
|
254
259
|
group: 'Other',
|
|
255
260
|
description: 'In combination with other params, will not perform the outbound operation, but instead simulate it',
|
|
256
261
|
dependencies: [{ param: BaiParam_AllUnits, value: true }]
|
|
257
262
|
};
|
|
263
|
+
export const BaiParam_CheckCyclicImports = {
|
|
264
|
+
keys: ['--check-cyclic-imports', '-cci'],
|
|
265
|
+
keyName: 'checkCyclicImports',
|
|
266
|
+
type: 'boolean',
|
|
267
|
+
group: 'General',
|
|
268
|
+
description: 'will check for cyclic imports and render an svg with the import graph',
|
|
269
|
+
dependencies: [
|
|
270
|
+
{ param: BaiParam_NoBuild, value: true },
|
|
271
|
+
{ param: BaiParam_Launch, value: false },
|
|
272
|
+
{ param: BaiParam_Install, value: false },
|
|
273
|
+
{ param: BaiParam_Deploy, value: false },
|
|
274
|
+
{ param: BaiParam_Publish, value: false },
|
|
275
|
+
{ param: BaiParam_Purge, value: false },
|
|
276
|
+
{ param: BaiParam_Clean, value: false },
|
|
277
|
+
]
|
|
278
|
+
};
|
|
258
279
|
export const AllBaiParams = [
|
|
259
280
|
BaiParam_AllUnits,
|
|
260
281
|
BaiParam_DependencyTree,
|
|
@@ -264,7 +285,6 @@ export const AllBaiParams = [
|
|
|
264
285
|
BaiParam_continue,
|
|
265
286
|
BaiParam_Prepare,
|
|
266
287
|
BaiParam_SetEnv,
|
|
267
|
-
BaiParam_Setup,
|
|
268
288
|
BaiParam_Install,
|
|
269
289
|
BaiParam_Generate, // TODO: to implement
|
|
270
290
|
BaiParam_GenerateDocs, // TODO: to implement
|
|
@@ -284,6 +304,7 @@ export const AllBaiParams = [
|
|
|
284
304
|
BaiParam_Debug,
|
|
285
305
|
BaiParam_Verbose,
|
|
286
306
|
BaiParam_Publish,
|
|
307
|
+
BaiParam_includePackage,
|
|
287
308
|
BaiParam_UsePackage,
|
|
288
309
|
BaiParam_ToESM,
|
|
289
310
|
BaiParam_Simulate,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nu-art/build-and-install",
|
|
3
|
-
"version": "0.400.
|
|
3
|
+
"version": "0.400.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"chokidar": "^3.6.0",
|
|
34
|
-
"@nu-art/ts-common": "0.400.
|
|
35
|
-
"@nu-art/commando": "0.400.
|
|
34
|
+
"@nu-art/ts-common": "0.400.6",
|
|
35
|
+
"@nu-art/commando": "0.400.6"
|
|
36
36
|
},
|
|
37
37
|
"unitConfig": {
|
|
38
38
|
"type": "typescript-lib"
|
package/v3/PhaseManager.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addItemToArray, exists, flatArray, Logger, removeItemFromArray, timeCounter } from '@nu-art/ts-common';
|
|
1
|
+
import { addItemToArray, asArray, exists, flatArray, Logger, removeItemFromArray, timeCounter } from '@nu-art/ts-common';
|
|
2
2
|
import { PhaseAggregatedException } from '../core/exceptions/PhaseAggregatedException.js';
|
|
3
3
|
export class PhaseManager extends Logger {
|
|
4
4
|
phases;
|
|
@@ -28,6 +28,12 @@ export class PhaseManager extends Logger {
|
|
|
28
28
|
const regexMatchers = usePackageKeys.map(filter => new RegExp(`.*?${filter}.*?`, 'i'));
|
|
29
29
|
this.activeUnits = allUnits.filter(unit => regexMatchers.some(matcher => matcher.test(unit.config.key))).map(unit => unit.config.key);
|
|
30
30
|
}
|
|
31
|
+
const packagesToInclude = this.runningStatus.runtimeParams.includePackage;
|
|
32
|
+
if (packagesToInclude?.length) {
|
|
33
|
+
const regexMatchers = asArray(packagesToInclude).map(filter => new RegExp(`.*?${filter}.*?`, 'i'));
|
|
34
|
+
this.activeUnits.push(...allUnits.filter(unit => regexMatchers.some(matcher => matcher.test(unit.config.key))).map(unit => unit.config.key));
|
|
35
|
+
this.activeUnits = [...new Set(this.activeUnits)];
|
|
36
|
+
}
|
|
31
37
|
this.keyToPhaseMap = flatArray(phases).reduce((acc, phase) => {
|
|
32
38
|
acc[phase.key] = phase;
|
|
33
39
|
return acc;
|
|
@@ -75,11 +81,15 @@ export class PhaseManager extends Logger {
|
|
|
75
81
|
break;
|
|
76
82
|
const scheduledStep = _steps[i];
|
|
77
83
|
const step = this.mapStep(scheduledStep);
|
|
84
|
+
await this.runningStatus.onStepStarted(i);
|
|
78
85
|
this.logDebug(`Executing step #${i + 1}/${_steps.length}`);
|
|
79
86
|
this.logVerbose(scheduledStep);
|
|
80
87
|
const errors = [];
|
|
81
88
|
let failedStep;
|
|
82
89
|
await Promise.all(step.units.map(async (unit) => {
|
|
90
|
+
if (this.runningStatus.isCompleted(unit.config.key))
|
|
91
|
+
return;
|
|
92
|
+
let failed = false;
|
|
83
93
|
for (const phase of step.phases) {
|
|
84
94
|
if (this.killed)
|
|
85
95
|
break;
|
|
@@ -103,16 +113,19 @@ export class PhaseManager extends Logger {
|
|
|
103
113
|
errors.push(error);
|
|
104
114
|
failedStep = scheduledStep;
|
|
105
115
|
this.killed = true;
|
|
116
|
+
failed = true;
|
|
106
117
|
break;
|
|
107
118
|
}
|
|
108
119
|
finally {
|
|
109
120
|
removeItemFromArray(this.runningUnits, unit);
|
|
110
121
|
}
|
|
111
122
|
}
|
|
123
|
+
if (!failed)
|
|
124
|
+
await this.runningStatus.onUnitCompleted(unit.config.key);
|
|
112
125
|
}));
|
|
113
|
-
await this.runningStatus.update(i);
|
|
114
126
|
if (failedStep && errors.length)
|
|
115
127
|
throw new PhaseAggregatedException(errors, failedStep);
|
|
128
|
+
await this.runningStatus.onStepEnded();
|
|
116
129
|
}
|
|
117
130
|
this.logInfo('All steps completed.');
|
|
118
131
|
}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { Logger } from '@nu-art/ts-common';
|
|
2
|
-
import { ScheduledStep } from './PhaseManager.js';
|
|
3
2
|
import { BaiParams } from '../core/params/params.js';
|
|
4
3
|
export declare class RunningStatusHandler extends Logger {
|
|
5
4
|
private isolated;
|
|
6
|
-
private
|
|
7
|
-
private
|
|
5
|
+
private readonly outputFolder;
|
|
6
|
+
private completedUnits;
|
|
8
7
|
runtimeParams: BaiParams;
|
|
9
8
|
startIndex: number;
|
|
10
9
|
constructor(outputFolder: string, runtimeParams: BaiParams);
|
|
11
10
|
init(): Promise<void>;
|
|
12
|
-
setSteps(steps: ScheduledStep[]): void;
|
|
13
11
|
isolate(): RunningStatusHandler;
|
|
14
|
-
|
|
12
|
+
isCompleted(unitKey: string): boolean;
|
|
13
|
+
onUnitCompleted(unitKey: string): Promise<void>;
|
|
14
|
+
onStepEnded(): Promise<void>;
|
|
15
|
+
onStepStarted(index: number): Promise<void>;
|
|
16
|
+
private saveStatus;
|
|
15
17
|
load(): Promise<any>;
|
|
16
18
|
}
|
|
@@ -2,8 +2,9 @@ import fs, { promises as _fs } from 'fs';
|
|
|
2
2
|
import { __stringify, Logger } from '@nu-art/ts-common';
|
|
3
3
|
export class RunningStatusHandler extends Logger {
|
|
4
4
|
isolated = false;
|
|
5
|
-
steps = [];
|
|
6
5
|
outputFolder;
|
|
6
|
+
// The completed units in the phase.. when running -con, these can be skipped
|
|
7
|
+
completedUnits = [];
|
|
7
8
|
runtimeParams;
|
|
8
9
|
startIndex = 0;
|
|
9
10
|
constructor(outputFolder, runtimeParams) {
|
|
@@ -20,31 +21,41 @@ export class RunningStatusHandler extends Logger {
|
|
|
20
21
|
this.runtimeParams = Object.assign(currentParams, this.runtimeParams);
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
setSteps(steps) {
|
|
24
|
-
if (this.runtimeParams.continue)
|
|
25
|
-
return;
|
|
26
|
-
this.steps = steps;
|
|
27
|
-
}
|
|
28
24
|
isolate() {
|
|
29
25
|
this.isolated = true;
|
|
30
26
|
return this;
|
|
31
27
|
}
|
|
32
|
-
|
|
28
|
+
isCompleted(unitKey) {
|
|
29
|
+
return this.completedUnits.includes(unitKey);
|
|
30
|
+
}
|
|
31
|
+
async onUnitCompleted(unitKey) {
|
|
32
|
+
this.logDebug(`On unit completed: ${unitKey}`);
|
|
33
|
+
this.completedUnits.push(unitKey);
|
|
34
|
+
await this.saveStatus();
|
|
35
|
+
}
|
|
36
|
+
async onStepEnded() {
|
|
37
|
+
this.logDebug(`On step ended successfully #${this.startIndex}`);
|
|
38
|
+
this.completedUnits = [];
|
|
39
|
+
}
|
|
40
|
+
async onStepStarted(index) {
|
|
33
41
|
this.startIndex = index;
|
|
42
|
+
this.logDebug(`Setting execution index to #${this.startIndex}`);
|
|
34
43
|
if (this.isolated)
|
|
35
44
|
return;
|
|
36
|
-
this.
|
|
45
|
+
await this.saveStatus();
|
|
46
|
+
}
|
|
47
|
+
async saveStatus() {
|
|
37
48
|
await _fs.writeFile(`${this.outputFolder}/running-status.json`, __stringify({
|
|
38
49
|
index: this.startIndex,
|
|
39
50
|
runtimeParams: this.runtimeParams,
|
|
40
|
-
|
|
51
|
+
completedUnits: this.completedUnits
|
|
41
52
|
}, true));
|
|
42
53
|
}
|
|
43
54
|
async load() {
|
|
44
55
|
try {
|
|
45
56
|
const data = JSON.parse(await _fs.readFile(`${this.outputFolder}/running-status.json`, { encoding: 'utf-8' }));
|
|
46
57
|
this.startIndex = data.index;
|
|
47
|
-
this.
|
|
58
|
+
this.completedUnits = data.completedUnits ?? [];
|
|
48
59
|
this.runtimeParams = data.runtimeParams;
|
|
49
60
|
return data.index;
|
|
50
61
|
}
|
|
@@ -19,40 +19,47 @@ export class UnitMapper_Node extends UnitMapper_Base {
|
|
|
19
19
|
const pathToFile = `${path}/__package.json`;
|
|
20
20
|
if (!await FileSystemUtils.file.exists(pathToFile))
|
|
21
21
|
return;
|
|
22
|
-
let packageJson
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
let packageJson;
|
|
23
|
+
try {
|
|
24
|
+
packageJson = await FilesCache.load.json(pathToFile);
|
|
25
|
+
if (!packageJson)
|
|
26
|
+
return;
|
|
27
|
+
if (!packageJson.unitConfig) {
|
|
28
|
+
this.logWarning(`Found a package.json without unitConfig at: ${pathToFile}`);
|
|
29
|
+
UnitMapper_Node.invalidPaths.push(path);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (tsValidateResult(packageJson.unitConfig.type, this.validator.type))
|
|
33
|
+
return; // not the expected type for this mapper
|
|
34
|
+
packageJson = deepClone(packageJson);
|
|
35
|
+
tsValidate(packageJson.unitConfig, this.validator);
|
|
36
|
+
const dependencies = packageJson.dependencies;
|
|
37
|
+
if (dependencies)
|
|
38
|
+
packageJson.dependencies = _keys(dependencies).reduce((acc, key) => {
|
|
39
|
+
acc[key] = dependencies[key] === '?' ? `{{${key}}}` : dependencies[key];
|
|
40
|
+
return acc;
|
|
41
|
+
}, {});
|
|
42
|
+
const devDependencies = packageJson.devDependencies;
|
|
43
|
+
if (devDependencies)
|
|
44
|
+
packageJson.devDependencies = _keys(devDependencies).reduce((acc, key) => {
|
|
45
|
+
acc[key] = devDependencies[key] === '?' ? `{{${key}}}` : devDependencies[key];
|
|
46
|
+
return acc;
|
|
47
|
+
}, {});
|
|
48
|
+
Object.freeze(packageJson);
|
|
49
|
+
const baseConfig = {
|
|
50
|
+
key: packageJson.name,
|
|
51
|
+
fullPath: path,
|
|
52
|
+
relativePath: path.replace(root, '.'),
|
|
53
|
+
label: packageJson.unitConfig.label ?? packageJson.name,
|
|
54
|
+
dependencies: { ...dependencies, ...packageJson.devDependencies },
|
|
55
|
+
};
|
|
56
|
+
const customESLintConfig = packageJson.unitConfig.customESLintConfig ?? false;
|
|
57
|
+
const customTSConfig = packageJson.unitConfig.customTSConfig ?? false;
|
|
58
|
+
return this.resolveNodeUnit({ path, root, packageJson, baseConfig, customESLintConfig, customTSConfig });
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
this.logError(`Failed to load package.json at: ${pathToFile}`, e);
|
|
62
|
+
throw e;
|
|
29
63
|
}
|
|
30
|
-
if (tsValidateResult(packageJson.unitConfig.type, this.validator.type))
|
|
31
|
-
return; // not the expected type for this mapper
|
|
32
|
-
packageJson = deepClone(packageJson);
|
|
33
|
-
tsValidate(packageJson.unitConfig, this.validator);
|
|
34
|
-
const dependencies = packageJson.dependencies;
|
|
35
|
-
if (dependencies)
|
|
36
|
-
packageJson.dependencies = _keys(dependencies).reduce((acc, key) => {
|
|
37
|
-
acc[key] = dependencies[key] === '?' ? `{{${key}}}` : dependencies[key];
|
|
38
|
-
return acc;
|
|
39
|
-
}, {});
|
|
40
|
-
const devDependencies = packageJson.devDependencies;
|
|
41
|
-
if (devDependencies)
|
|
42
|
-
packageJson.devDependencies = _keys(devDependencies).reduce((acc, key) => {
|
|
43
|
-
acc[key] = devDependencies[key] === '?' ? `{{${key}}}` : devDependencies[key];
|
|
44
|
-
return acc;
|
|
45
|
-
}, {});
|
|
46
|
-
Object.freeze(packageJson);
|
|
47
|
-
const baseConfig = {
|
|
48
|
-
key: packageJson.name,
|
|
49
|
-
fullPath: path,
|
|
50
|
-
relativePath: path.replace(root, '.'),
|
|
51
|
-
label: packageJson.unitConfig.label ?? packageJson.name,
|
|
52
|
-
dependencies: { ...dependencies, ...packageJson.devDependencies },
|
|
53
|
-
};
|
|
54
|
-
const customESLintConfig = packageJson.unitConfig.customESLintConfig ?? false;
|
|
55
|
-
const customTSConfig = packageJson.unitConfig.customTSConfig ?? false;
|
|
56
|
-
return this.resolveNodeUnit({ path, root, packageJson, baseConfig, customESLintConfig, customTSConfig });
|
|
57
64
|
}
|
|
58
65
|
}
|
|
@@ -3,7 +3,7 @@ import { UnitPhaseImplementor } from './types.js';
|
|
|
3
3
|
import { Phase } from '../phase/index.js';
|
|
4
4
|
import { ProjectUnit } from '../units/index.js';
|
|
5
5
|
export declare const BaiParam_Help: BaseCliParam<'help', boolean>;
|
|
6
|
-
declare const AllBaiParams_Help: (BaseCliParam<"allUnits", boolean> | BaseCliParam<"dependencyTree", boolean> | BaseCliParam<"
|
|
6
|
+
declare const AllBaiParams_Help: (BaseCliParam<"allUnits", boolean> | BaseCliParam<"dependencyTree", boolean> | BaseCliParam<"continue", boolean> | BaseCliParam<"environment", string> | BaseCliParam<"install", boolean> | BaseCliParam<"clean", boolean> | BaseCliParam<"purge", boolean> | BaseCliParam<"generate", boolean> | BaseCliParam<"generateDocs", boolean> | BaseCliParam<"noBuild", boolean> | BaseCliParam<"prepare", boolean> | BaseCliParam<"dryRun", boolean> | BaseCliParam<"lint", boolean> | BaseCliParam<"watch", boolean> | BaseCliParam<"watchBuildTree", boolean> | BaseCliParam<"test", boolean> | BaseCliParam<"testType", string[]> | BaseCliParam<"testFiles", string[]> | BaseCliParam<"testCases", string[]> | BaseCliParam<"testDebugPort", number> | BaseCliParam<"launch", boolean> | BaseCliParam<"debugBackend", boolean> | BaseCliParam<"deploy", boolean> | BaseCliParam<"debug", boolean> | BaseCliParam<"debugLifecycle", boolean> | BaseCliParam<"verbose", boolean> | BaseCliParam<"publish", "patch" | "minor" | "major"> | BaseCliParam<"usePackage", string[]> | BaseCliParam<"includePackage", string[]> | BaseCliParam<"toESM", boolean> | BaseCliParam<"simulation", boolean> | BaseCliParam<"checkCyclicImports", boolean> | BaseCliParam<"help", boolean>)[];
|
|
7
7
|
export type Help_BaiParams = CliParams<typeof AllBaiParams_Help>;
|
|
8
8
|
export type Phase_Help = typeof phase_Help;
|
|
9
9
|
export declare const phaseKey_Help = "help";
|
package/v3/phase/consts.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const phase_CheckCyclicImports: Phase<'checkCyclicImports'>;
|
|
|
8
8
|
export type Phase_ToESM = typeof phase_ToESM;
|
|
9
9
|
export declare const phaseKey_ToESM = "convertToESM";
|
|
10
10
|
export declare const phase_ToESM: Phase<'convertToESM'>;
|
|
11
|
+
export declare const phases_Terminating: Phase<string>[][];
|
|
11
12
|
export type Phase_Purge = typeof phase_Purge;
|
|
12
13
|
export declare const phaseKey_Purge = "purge";
|
|
13
14
|
export declare const phase_Purge: Phase<'purge'>;
|
package/v3/phase/consts.js
CHANGED
|
@@ -19,8 +19,12 @@ export const phase_ToESM = {
|
|
|
19
19
|
key: phaseKey_ToESM,
|
|
20
20
|
name: 'ToESM',
|
|
21
21
|
method: 'convertToESM',
|
|
22
|
-
filter: (baiParams) =>
|
|
22
|
+
filter: (baiParams) => baiParams.toESM,
|
|
23
23
|
};
|
|
24
|
+
export const phases_Terminating = [
|
|
25
|
+
[phase_PrintDependencyTree],
|
|
26
|
+
[phase_CheckCyclicImports],
|
|
27
|
+
];
|
|
24
28
|
export const phaseKey_Purge = 'purge';
|
|
25
29
|
export const phase_Purge = {
|
|
26
30
|
key: phaseKey_Purge,
|
|
@@ -88,6 +92,7 @@ export const phase_Watch = {
|
|
|
88
92
|
};
|
|
89
93
|
export const phases_Build = [
|
|
90
94
|
[phase_Purge, phase_Prepare],
|
|
95
|
+
[phase_ToESM],
|
|
91
96
|
[phase_Install],
|
|
92
97
|
[phase_Lint, phase_PreCompile, phase_Compile, phase_Test,],
|
|
93
98
|
[phase_Watch]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import { copyFileSync, existsSync, promises as _fs, readdirSync, statSync } from 'fs';
|
|
3
|
-
import { __stringify, arrayToMap, BadImplementationException,
|
|
3
|
+
import { __stringify, arrayToMap, BadImplementationException, ImplementationMissingException, LogLevel, NotImplementedYetException } from '@nu-art/ts-common';
|
|
4
4
|
import { CONST_BaiConfig, CONST_FirebaseJSON, CONST_FirebaseRC, CONST_NodeModules, CONST_PackageJSON, CONST_PackageJSONTemplate, CONST_TS_CONFIG } from '../../core/consts.js';
|
|
5
5
|
import { CommandoException } from '@nu-art/commando/shell/core/CliError';
|
|
6
6
|
import { Commando_NVM } from '@nu-art/commando/shell/plugins/nvm';
|
|
@@ -259,15 +259,18 @@ export class Unit_TypescriptLib extends Unit_PackageJson {
|
|
|
259
259
|
}
|
|
260
260
|
async checkCyclicImports() {
|
|
261
261
|
this.logDebug(`Checking Cyclic Imports - ${this.config.label}`);
|
|
262
|
+
const pathToMain = pathResolve(this.config.fullPath, './src/main');
|
|
263
|
+
const pathToTsConfig = pathResolve(pathToMain, './tsconfig.json');
|
|
262
264
|
await this.allocateCommando(Commando_Basic)
|
|
263
265
|
.cd(this.config.fullPath)
|
|
264
266
|
// .setStdErrorValidator(stderr => {
|
|
265
267
|
// return !stderr.includes('Finding files') && !stderr.includes('Image created');
|
|
266
268
|
// })
|
|
267
|
-
.append(`npx madge --no-spinner --image "./imports-${this.config.key}.svg" --circular ${
|
|
269
|
+
.append(`npx madge --no-spinner --ts-config ${pathToTsConfig} --image "./imports-${this.config.key}.svg" --extensions ts,tsx,mts,js,mjs --circular ${pathToMain} `)
|
|
268
270
|
.append('echo $?')
|
|
269
271
|
.execute();
|
|
270
272
|
}
|
|
273
|
+
// npx madge --circular --ts-config ./tsconfig.json --extensions ts,tsx,mts,js,mjs ./src/main
|
|
271
274
|
async lint() {
|
|
272
275
|
// need to move the copy of the default eslint rules to here
|
|
273
276
|
const pathToLint = pathResolve(this.config.fullPath, `src/main`);
|
|
@@ -383,55 +386,88 @@ export class Unit_TypescriptLib extends Unit_PackageJson {
|
|
|
383
386
|
const specificFiles = [CONST_PackageJSONTemplate];
|
|
384
387
|
const fileExtensions = ['.ts', '.tsx', '.mts', '.js', '.jsx', '.mjs'];
|
|
385
388
|
const units = arrayToMap(this.runtimeContext.childUnits, unit => unit.config.key);
|
|
386
|
-
const toESM = async (pathTofile,
|
|
387
|
-
|
|
388
|
-
if (
|
|
389
|
-
return
|
|
389
|
+
const toESM = async (pathTofile, originImportPath) => {
|
|
390
|
+
originImportPath = originImportPath.replace(/\/+/g, '/');
|
|
391
|
+
if (originImportPath.endsWith('.js'))
|
|
392
|
+
return originImportPath;
|
|
393
|
+
if (originImportPath.endsWith('.json'))
|
|
394
|
+
return originImportPath;
|
|
390
395
|
for (const extension of fileExtensions) {
|
|
391
|
-
if (!
|
|
396
|
+
if (!originImportPath.endsWith(extension))
|
|
392
397
|
continue;
|
|
393
|
-
|
|
398
|
+
originImportPath = originImportPath.replace(extension, '');
|
|
394
399
|
break;
|
|
395
400
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
initialPath = `${unit.config.fullPath}/src/main`;
|
|
409
|
-
relativePathToFile = relativePathParts.join('/');
|
|
410
|
-
}
|
|
401
|
+
// this can be ./path/to/folder => ./path/to/folder/index.js
|
|
402
|
+
// this can be ./path/to/file => ./path/to/file.js
|
|
403
|
+
if (originImportPath.startsWith('.') || originImportPath.startsWith('/')) {
|
|
404
|
+
const initialPath = path.dirname(pathTofile);
|
|
405
|
+
let relativePathToFile = originImportPath;
|
|
406
|
+
const fullPath = path.resolve(initialPath, relativePathToFile);
|
|
407
|
+
if (await FileSystemUtils.exists(fullPath) && await FileSystemUtils.folder.isFolder(fullPath))
|
|
408
|
+
relativePathToFile = `${relativePathToFile}/index`;
|
|
409
|
+
// either way we need to add a .js
|
|
410
|
+
relativePathToFile += '.js';
|
|
411
|
+
relativePathToFile = relativePathToFile.replace(/\/+/g, '/');
|
|
412
|
+
return relativePathToFile;
|
|
411
413
|
}
|
|
412
|
-
|
|
414
|
+
const resolveImportPathFromUnit = async (packageName, relativePathToFile) => {
|
|
415
|
+
const unit = units[packageName];
|
|
416
|
+
if (!unit)
|
|
417
|
+
return;
|
|
418
|
+
let initialPath = `${unit.config.fullPath}/src/main`;
|
|
419
|
+
const fullPath = path.resolve(initialPath, relativePathToFile);
|
|
420
|
+
if (await FileSystemUtils.exists(fullPath) && await FileSystemUtils.folder.isFolder(fullPath))
|
|
421
|
+
relativePathToFile = `${relativePathToFile}/index`;
|
|
422
|
+
const importPath = `${packageName}/${relativePathToFile}`.replace(/\/+/g, '/');
|
|
423
|
+
if (importPath === `${packageName}/index`)
|
|
424
|
+
return `${packageName}`;
|
|
413
425
|
return importPath;
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
426
|
+
};
|
|
427
|
+
// this can be {{libName}}/path/to/file => {{libName}}/path/to/file
|
|
428
|
+
let [libName1, ...rest1] = originImportPath.split('/');
|
|
429
|
+
let esmImportPath = await resolveImportPathFromUnit(libName1, rest1.join('/'));
|
|
430
|
+
if (esmImportPath)
|
|
431
|
+
return esmImportPath;
|
|
432
|
+
let [libOrg, libName2, ...rest2] = originImportPath.split('/');
|
|
433
|
+
esmImportPath = await resolveImportPathFromUnit(`${libOrg}/${libName2}`, rest2.join('/'));
|
|
434
|
+
if (esmImportPath)
|
|
435
|
+
return esmImportPath;
|
|
436
|
+
return originImportPath;
|
|
421
437
|
};
|
|
422
438
|
const importMatchers = [
|
|
423
439
|
{
|
|
424
|
-
regex: /from\s+
|
|
440
|
+
regex: /from\s+"(\S+)?"/g,
|
|
425
441
|
replacer: async (pathTofile, importPath) => `from "${await toESM(pathTofile, importPath)}"`
|
|
426
442
|
},
|
|
427
443
|
{
|
|
428
|
-
regex: /
|
|
429
|
-
replacer: async (pathTofile, importPath) => `
|
|
444
|
+
regex: /from\s+'(\S+)?'/g,
|
|
445
|
+
replacer: async (pathTofile, importPath) => `from '${await toESM(pathTofile, importPath)}'`
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
regex: /\srequire\((\S+)?\)/g,
|
|
449
|
+
replacer: async (pathTofile, importPath) => ` await import("${await toESM(pathTofile, importPath)}")`
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
regex: /\srequire\((\S+)?\)/g,
|
|
453
|
+
replacer: async (pathTofile, importPath) => ` await import('${await toESM(pathTofile, importPath)}')`
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
regex: /\srequire\(\s*"(\S+)?"\s*\)/g,
|
|
457
|
+
replacer: async (pathTofile, importPath) => ` await import("${await toESM(pathTofile, importPath)}")`
|
|
430
458
|
},
|
|
431
459
|
{
|
|
432
|
-
regex:
|
|
460
|
+
regex: /\srequire\(\s*'(\S+)?'\s*\)/g,
|
|
461
|
+
replacer: async (pathTofile, importPath) => ` await import('${await toESM(pathTofile, importPath)}')`
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
regex: /import\(\s*"(\S+)?"\s*\)/g,
|
|
433
465
|
replacer: async (pathTofile, importPath) => `import("${await toESM(pathTofile, importPath)}")`
|
|
434
466
|
},
|
|
467
|
+
{
|
|
468
|
+
regex: /import\(\s*'(\S+)?'\s*\)/g,
|
|
469
|
+
replacer: async (pathTofile, importPath) => `import('${await toESM(pathTofile, importPath)}')`
|
|
470
|
+
},
|
|
435
471
|
];
|
|
436
472
|
const updateImports = async (pathToEntry) => {
|
|
437
473
|
let content = await FileSystemUtils.file.read(pathToEntry);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Unit_TypescriptLib, Unit_TypescriptLib_Config } from '../index.js';
|
|
2
1
|
import { UnitPhaseImplementor } from '../../core/types.js';
|
|
3
2
|
import { FirebasePackageConfig } from '../../../core/types/index.js';
|
|
3
|
+
import { StringMap } from '@nu-art/ts-common';
|
|
4
4
|
import { Phase_Deploy, Phase_Launch } from '../../phase/index.js';
|
|
5
|
+
import { Unit_TypescriptLib, Unit_TypescriptLib_Config } from '../Unit_TypescriptLib.js';
|
|
5
6
|
export declare const firebaseFunctionEmulator_ErrorStrings: string[];
|
|
6
7
|
export declare const firebaseFunctionEmulator_WarningStrings: string[];
|
|
7
8
|
type EnvConfig = {
|
|
@@ -23,6 +24,7 @@ export type Unit_FirebaseFunctionsApp_Config = Unit_TypescriptLib_Config & {
|
|
|
23
24
|
sources?: string[];
|
|
24
25
|
};
|
|
25
26
|
export declare class Unit_FirebaseFunctionsApp<C extends Unit_FirebaseFunctionsApp_Config = Unit_FirebaseFunctionsApp_Config> extends Unit_TypescriptLib<C> implements UnitPhaseImplementor<[Phase_Launch, Phase_Deploy]> {
|
|
27
|
+
functions: StringMap;
|
|
26
28
|
static staggerCount: number;
|
|
27
29
|
static DefaultConfig_FirebaseFunction: {
|
|
28
30
|
pathToFirebaseConfig: string;
|
|
@@ -48,11 +50,12 @@ export declare class Unit_FirebaseFunctionsApp<C extends Unit_FirebaseFunctionsA
|
|
|
48
50
|
private getEnvConfig;
|
|
49
51
|
private resolveFunctionsRC;
|
|
50
52
|
private resolveProxyFile;
|
|
53
|
+
private pathToProxy;
|
|
51
54
|
private resolveConfigDir;
|
|
52
55
|
private resolveFunctionsJSON;
|
|
53
56
|
private resolveFunctionsRuntimeConfig;
|
|
54
57
|
private createAppVersionFile;
|
|
55
|
-
protected deriveDistDependencies():
|
|
58
|
+
protected deriveDistDependencies(): StringMap;
|
|
56
59
|
private createDependenciesDir;
|
|
57
60
|
private runProxy;
|
|
58
61
|
private runEmulator;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CONST_FirebaseJSON, CONST_FirebaseRC, CONST_PackageJSON } from '../../../core/consts.js';
|
|
1
|
+
import { CONST_FirebaseJSON, CONST_FirebaseRC, CONST_NodeModules, CONST_PackageJSON } from '../../../core/consts.js';
|
|
3
2
|
import { promises as _fs } from 'fs';
|
|
4
3
|
import { __stringify, _logger_logPrefixes, deepClone, ImplementationMissingException, LogLevel, reduceObject, Second, sleep } from '@nu-art/ts-common';
|
|
5
4
|
import { Const_FirebaseConfigKeys, Const_FirebaseDefaultsKeyToFile } from '../../../defaults/consts.js';
|
|
6
5
|
import { Commando_NVM } from '@nu-art/commando/shell/plugins/nvm';
|
|
7
6
|
import { resolve } from 'path';
|
|
8
7
|
import { DEFAULT_OLD_TEMPLATE_PATTERN, FileSystemUtils } from '@nu-art/ts-common/utils/FileSystemUtils';
|
|
8
|
+
import { Unit_TypescriptLib } from '../Unit_TypescriptLib.js';
|
|
9
|
+
import { CommandoException } from '@nu-art/commando/shell/core/CliError';
|
|
10
|
+
import { deployLogFilter } from './common.js';
|
|
9
11
|
export const firebaseFunctionEmulator_ErrorStrings = [
|
|
10
12
|
'functions: Failed',
|
|
11
13
|
];
|
|
@@ -14,6 +16,7 @@ export const firebaseFunctionEmulator_WarningStrings = [
|
|
|
14
16
|
];
|
|
15
17
|
// const CONST_VersionApp = 'version-app.json';
|
|
16
18
|
export class Unit_FirebaseFunctionsApp extends Unit_TypescriptLib {
|
|
19
|
+
functions = {};
|
|
17
20
|
static staggerCount = 0;
|
|
18
21
|
static DefaultConfig_FirebaseFunction = {
|
|
19
22
|
pathToFirebaseConfig: '.firebase_config',
|
|
@@ -59,6 +62,7 @@ export class Unit_FirebaseFunctionsApp extends Unit_TypescriptLib {
|
|
|
59
62
|
return await FileSystemUtils.folder.delete(path);
|
|
60
63
|
});
|
|
61
64
|
await FileSystemUtils.folder.create(resolve(this.config.fullPath, this.config.pathToEmulatorData));
|
|
65
|
+
await FileSystemUtils.file.delete(this.pathToProxy());
|
|
62
66
|
await this.resolveConfigs();
|
|
63
67
|
}
|
|
64
68
|
async resolveConfigs() {
|
|
@@ -89,8 +93,18 @@ export class Unit_FirebaseFunctionsApp extends Unit_TypescriptLib {
|
|
|
89
93
|
.ls()
|
|
90
94
|
.cat('package.json')
|
|
91
95
|
.cat('index.js')
|
|
92
|
-
.cd(this.config.fullPath)
|
|
93
|
-
|
|
96
|
+
.cd(this.config.fullPath)
|
|
97
|
+
.setLogLevelFilter(deployLogFilter)
|
|
98
|
+
// example: Function URL (hello(us-central1)): https://hello-kv65k7yylq-uc.a.run.app
|
|
99
|
+
.onLog(/.*Function URL.*?\((.*?)\(.*(https:\/\/.*?)$/, match => {
|
|
100
|
+
this.functions[match[1]] = match[2];
|
|
101
|
+
});
|
|
102
|
+
const debug = this.runtimeContext.runtimeParams.verbose ? ' --debug' : '';
|
|
103
|
+
await this.executeAsyncCommando(commando, `firebase${debug} deploy --only functions --force`, (stdout, stderr, exitCode) => {
|
|
104
|
+
if (exitCode !== 0)
|
|
105
|
+
throw new CommandoException('Failed to deploy function', stdout, stderr, exitCode);
|
|
106
|
+
});
|
|
107
|
+
this.logInfo(`Functions: `, this.functions);
|
|
94
108
|
}
|
|
95
109
|
//######################### ResolveConfig Logic #########################
|
|
96
110
|
getEnvConfig() {
|
|
@@ -118,7 +132,7 @@ export class Unit_FirebaseFunctionsApp extends Unit_TypescriptLib {
|
|
|
118
132
|
}
|
|
119
133
|
async resolveProxyFile() {
|
|
120
134
|
const envConfig = this.getEnvConfig();
|
|
121
|
-
const targetPath =
|
|
135
|
+
const targetPath = this.pathToProxy();
|
|
122
136
|
const path = this.runtimeContext.baiConfig.files?.backend?.proxy;
|
|
123
137
|
if (!path)
|
|
124
138
|
return;
|
|
@@ -131,15 +145,13 @@ export class Unit_FirebaseFunctionsApp extends Unit_TypescriptLib {
|
|
|
131
145
|
};
|
|
132
146
|
await FileSystemUtils.file.template.copy(path, targetPath, params);
|
|
133
147
|
}
|
|
148
|
+
pathToProxy() {
|
|
149
|
+
return resolve(this.config.fullPath, 'src/main/proxy.ts');
|
|
150
|
+
}
|
|
134
151
|
async resolveConfigDir() {
|
|
135
152
|
//Create the dir if it doesn't exist
|
|
136
153
|
const pathToFirebaseConfigFolder = `${this.config.fullPath}/${this.config.pathToFirebaseConfig}`;
|
|
137
|
-
|
|
138
|
-
await _fs.access(pathToFirebaseConfigFolder);
|
|
139
|
-
}
|
|
140
|
-
catch (e) {
|
|
141
|
-
await _fs.mkdir(pathToFirebaseConfigFolder, { recursive: true });
|
|
142
|
-
}
|
|
154
|
+
await FileSystemUtils.folder.create(pathToFirebaseConfigFolder);
|
|
143
155
|
//Fill config dir with relevant files for each file that doesn't exist
|
|
144
156
|
const defaultFiles = this.runtimeContext.baiConfig.files?.firebase;
|
|
145
157
|
if (!defaultFiles) {
|
|
@@ -148,11 +160,10 @@ export class Unit_FirebaseFunctionsApp extends Unit_TypescriptLib {
|
|
|
148
160
|
}
|
|
149
161
|
await Promise.all(Const_FirebaseConfigKeys.map(async (firebaseConfigKey) => {
|
|
150
162
|
const pathToConfigFile = `${pathToFirebaseConfigFolder}/${Const_FirebaseDefaultsKeyToFile[firebaseConfigKey]}`;
|
|
151
|
-
|
|
152
|
-
if (!path)
|
|
163
|
+
if (!defaultFiles[firebaseConfigKey])
|
|
153
164
|
return;
|
|
154
|
-
const
|
|
155
|
-
await
|
|
165
|
+
const path = resolve(this.runtimeContext.parentUnit.config.fullPath, defaultFiles[firebaseConfigKey]);
|
|
166
|
+
await FileSystemUtils.file.copy(path, pathToConfigFile);
|
|
156
167
|
}));
|
|
157
168
|
}
|
|
158
169
|
async resolveFunctionsJSON() {
|
|
@@ -205,6 +216,7 @@ export class Unit_FirebaseFunctionsApp extends Unit_TypescriptLib {
|
|
|
205
216
|
functions: {
|
|
206
217
|
source: this.config.output.replace(`${this.config.fullPath}/`, ''),
|
|
207
218
|
ignore: this.config.ignore,
|
|
219
|
+
runtime: 'nodejs22',
|
|
208
220
|
}
|
|
209
221
|
};
|
|
210
222
|
}
|
|
@@ -259,7 +271,8 @@ export class Unit_FirebaseFunctionsApp extends Unit_TypescriptLib {
|
|
|
259
271
|
await this.resolveProxyFile();
|
|
260
272
|
const commando = this.allocateCommando(Commando_NVM).applyNVM()
|
|
261
273
|
.cd(this.config.fullPath);
|
|
262
|
-
|
|
274
|
+
const command = `${this.runtimeContext.parentUnit.config.fullPath}/${CONST_NodeModules}/.bin/tsx`;
|
|
275
|
+
await this.executeAsyncCommando(commando, `${command} src/main/proxy.ts`);
|
|
263
276
|
this.logWarning('PROXY TERMINATED');
|
|
264
277
|
}
|
|
265
278
|
async runEmulator() {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Unit_TypescriptLib, Unit_TypescriptLib_Config } from '../index.js';
|
|
2
1
|
import { FirebasePackageConfig } from '../../../core/types/index.js';
|
|
3
2
|
import { UnitPhaseImplementor } from '../../core/types.js';
|
|
4
|
-
import { TS_Object, TypedMap } from '@nu-art/ts-common';
|
|
3
|
+
import { StringMap, TS_Object, TypedMap } from '@nu-art/ts-common';
|
|
5
4
|
import { UnitConfigJSON_Node } from '../../UnitsMapper/resolvers/UnitMapper_Node.js';
|
|
6
5
|
import { Phase_Deploy, Phase_Launch } from '../../phase/index.js';
|
|
6
|
+
import { Unit_TypescriptLib, Unit_TypescriptLib_Config } from '../Unit_TypescriptLib.js';
|
|
7
7
|
export type FirebaseHostingConfig = {
|
|
8
8
|
public: string;
|
|
9
9
|
rewrites: {
|
|
@@ -29,6 +29,7 @@ export type Unit_FirebaseHostingApp_Config = Unit_TypescriptLib_Config & {
|
|
|
29
29
|
sources?: string[];
|
|
30
30
|
};
|
|
31
31
|
export declare class Unit_FirebaseHostingApp<C extends Unit_FirebaseHostingApp_Config = Unit_FirebaseHostingApp_Config> extends Unit_TypescriptLib<C> implements UnitPhaseImplementor<[Phase_Launch, Phase_Deploy]> {
|
|
32
|
+
hosting: StringMap;
|
|
32
33
|
static DefaultConfig_FirebaseHosting: {
|
|
33
34
|
servingPort: number;
|
|
34
35
|
output: string;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { Unit_TypescriptLib } from '../index.js';
|
|
2
1
|
import { ImplementationMissingException, LogLevel } from '@nu-art/ts-common';
|
|
3
2
|
import { promises as _fs } from 'fs';
|
|
4
3
|
import { CONST_FirebaseJSON, CONST_FirebaseRC } from '../../../core/consts.js';
|
|
5
4
|
import { Commando_NVM } from '@nu-art/commando/shell/plugins/nvm';
|
|
6
5
|
import { Commando_Basic } from '@nu-art/commando/shell/plugins/basic';
|
|
7
6
|
import { resolve } from 'path';
|
|
7
|
+
import { Unit_TypescriptLib } from '../Unit_TypescriptLib.js';
|
|
8
|
+
import { CommandoException } from '@nu-art/commando/shell/core/CliError';
|
|
9
|
+
import { deployLogFilter } from './common.js';
|
|
8
10
|
const CONST_VersionApp = 'version-app.json';
|
|
9
11
|
export class Unit_FirebaseHostingApp extends Unit_TypescriptLib {
|
|
12
|
+
hosting = {};
|
|
10
13
|
static DefaultConfig_FirebaseHosting = {
|
|
11
14
|
servingPort: 8100,
|
|
12
15
|
output: 'dist',
|
|
@@ -38,8 +41,14 @@ export class Unit_FirebaseHostingApp extends Unit_TypescriptLib {
|
|
|
38
41
|
}
|
|
39
42
|
async deploy() {
|
|
40
43
|
const commando = this.allocateCommando(Commando_NVM).applyNVM()
|
|
41
|
-
.cd(this.config.fullPath)
|
|
42
|
-
|
|
44
|
+
.cd(this.config.fullPath)
|
|
45
|
+
.setLogLevelFilter(deployLogFilter)
|
|
46
|
+
// example: Function URL (hello(us-central1)): https://hello-kv65k7yylq-uc.a.run.app
|
|
47
|
+
.onLog(/.*Hosting URL.*(https:\/\/.*?)$/, match => {
|
|
48
|
+
this.hosting[match[1]] = match[2];
|
|
49
|
+
});
|
|
50
|
+
const debug = this.runtimeContext.runtimeParams.verbose ? ' --debug' : '';
|
|
51
|
+
await this.executeAsyncCommando(commando, `firebase${debug} deploy --only hosting`);
|
|
43
52
|
}
|
|
44
53
|
//######################### ResolveConfig Logic #########################
|
|
45
54
|
getEnvConfig() {
|
|
@@ -74,7 +83,10 @@ export class Unit_FirebaseHostingApp extends Unit_TypescriptLib {
|
|
|
74
83
|
async compileImpl() {
|
|
75
84
|
const commando = this.allocateCommando(Commando_NVM, Commando_Basic).applyNVM()
|
|
76
85
|
.cd(this.config.fullPath);
|
|
77
|
-
await this.executeAsyncCommando(commando, `ENV=${this.runtimeContext.runtimeParams.environment} npm run build
|
|
86
|
+
await this.executeAsyncCommando(commando, `ENV=${this.runtimeContext.runtimeParams.environment} npm run build`, (stdout, stderr, exitCode) => {
|
|
87
|
+
if (exitCode > 0)
|
|
88
|
+
throw new CommandoException(`Error compiling`, stdout, stderr, exitCode);
|
|
89
|
+
});
|
|
78
90
|
}
|
|
79
91
|
async createAppVersionFile() {
|
|
80
92
|
//Writing the file to the package source instead of the output is fine,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LogLevel } from '@nu-art/ts-common';
|
|
2
|
+
const warn = ['missing required API'];
|
|
3
|
+
const info = ['=== Deploying', 'functions: Successfully deployed function'];
|
|
4
|
+
const infoStartsWith = ['✔ ', 'i '];
|
|
5
|
+
export const deployLogFilter = (log, std) => {
|
|
6
|
+
if (log.startsWith('⚠ ') || warn.find(str => log.includes(str)))
|
|
7
|
+
return LogLevel.Warning;
|
|
8
|
+
if (infoStartsWith.find(str => log.startsWith(str)) || info.find(str => log.includes(str)))
|
|
9
|
+
return LogLevel.Info;
|
|
10
|
+
if (log.includes('Error:'))
|
|
11
|
+
return LogLevel.Error;
|
|
12
|
+
return LogLevel.Debug;
|
|
13
|
+
};
|