@powerlines/engine 0.45.3 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/worker.cjs +844 -789
- package/dist/_internal/worker.mjs +847 -792
- package/dist/_internal/worker.mjs.map +1 -1
- package/dist/api.cjs +292 -323
- package/dist/api.d.cts +44 -11
- package/dist/api.d.cts.map +1 -1
- package/dist/api.d.mts +44 -11
- package/dist/api.d.mts.map +1 -1
- package/dist/api.mjs +292 -323
- package/dist/api.mjs.map +1 -1
- package/dist/{base-context-Byizvf4F.cjs → base-context-BCG0xN2e.cjs} +70 -64
- package/dist/{base-context-BSAC5sO9.mjs → base-context-Cmo6TTh7.mjs} +73 -67
- package/dist/base-context-Cmo6TTh7.mjs.map +1 -0
- package/dist/context/index.cjs +3 -3
- package/dist/context/index.d.cts +44 -617
- package/dist/context/index.d.cts.map +1 -1
- package/dist/context/index.d.mts +44 -617
- package/dist/context/index.d.mts.map +1 -1
- package/dist/context/index.mjs +3 -3
- package/dist/engine-context-BjFMVQEE.mjs +86 -0
- package/dist/engine-context-BjFMVQEE.mjs.map +1 -0
- package/dist/engine-context-DOsGtgD9.cjs +91 -0
- package/dist/execution-context-BdZt7wWa.d.mts +631 -0
- package/dist/execution-context-BdZt7wWa.d.mts.map +1 -0
- package/dist/execution-context-CU6iNchD.d.cts +631 -0
- package/dist/execution-context-CU6iNchD.d.cts.map +1 -0
- package/dist/{execution-context-Bkxp1fML.mjs → execution-context-Cp32TarF.mjs} +421 -364
- package/dist/execution-context-Cp32TarF.mjs.map +1 -0
- package/dist/{execution-context-BYGFYty0.cjs → execution-context-DgqxcDDx.cjs} +419 -362
- package/dist/index.cjs +15 -16
- package/dist/index.d.cts +3 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +15 -16
- package/dist/index.mjs.map +1 -1
- package/dist/{tsconfig-QMSxSwBD.cjs → tsconfig-BUDqmOaT.cjs} +13 -13
- package/dist/{tsconfig-CI6bla4E.mjs → tsconfig-MeFEs21S.mjs} +14 -14
- package/dist/tsconfig-MeFEs21S.mjs.map +1 -0
- package/dist/typescript/index.cjs +1 -1
- package/dist/typescript/index.d.cts +6 -6
- package/dist/typescript/index.d.cts.map +1 -1
- package/dist/typescript/index.d.mts +6 -6
- package/dist/typescript/index.d.mts.map +1 -1
- package/dist/typescript/index.mjs +1 -1
- package/package.json +17 -17
- package/dist/base-context-BSAC5sO9.mjs.map +0 -1
- package/dist/engine-context-CI_0NWIk.cjs +0 -73
- package/dist/engine-context-_RMFwG4J.mjs +0 -68
- package/dist/engine-context-_RMFwG4J.mjs.map +0 -1
- package/dist/execution-context-Bkxp1fML.mjs.map +0 -1
- package/dist/tsconfig-CI6bla4E.mjs.map +0 -1
|
@@ -24,7 +24,7 @@ import { isError } from "@stryke/type-checks/is-error";
|
|
|
24
24
|
import { isFunction } from "@stryke/type-checks/is-function";
|
|
25
25
|
import { isNumber } from "@stryke/type-checks/is-number";
|
|
26
26
|
import { isObject } from "@stryke/type-checks/is-object";
|
|
27
|
-
import { isPromiseLike } from "@stryke/type-checks/is-promise";
|
|
27
|
+
import { isPromise, isPromiseLike } from "@stryke/type-checks/is-promise";
|
|
28
28
|
import { isSet } from "@stryke/type-checks/is-set";
|
|
29
29
|
import { isSetObject } from "@stryke/type-checks/is-set-object";
|
|
30
30
|
import { isSetString } from "@stryke/type-checks/is-set-string";
|
|
@@ -38,21 +38,21 @@ import { deepClone } from "@stryke/helpers/deep-clone";
|
|
|
38
38
|
import { joinPaths as joinPaths$1 } from "@stryke/path/join";
|
|
39
39
|
import { uuid } from "@stryke/unique-id/uuid";
|
|
40
40
|
import { getUniqueInputs, isTypeDefinition, resolveInputsSync } from "@powerlines/core/lib/entry";
|
|
41
|
-
import { toBool } from "@stryke/convert/to-bool";
|
|
42
41
|
import { getEnvPaths } from "@stryke/env/get-env-paths";
|
|
43
42
|
import { relativeToWorkspaceRoot } from "@stryke/fs/get-workspace-root";
|
|
44
43
|
import { murmurhash } from "@stryke/hash";
|
|
45
44
|
import { hashDirectory } from "@stryke/hash/node";
|
|
46
45
|
import { fetchRequest } from "@stryke/http/fetch";
|
|
47
46
|
import { isEqual } from "@stryke/path/is-equal";
|
|
48
|
-
import { kebabCase } from "@stryke/string-format/kebab-case";
|
|
49
47
|
import { match, tsconfigPathsToRegExp } from "bundle-require";
|
|
50
48
|
import { resolveCompatibilityDates } from "compatx";
|
|
51
49
|
import { create } from "flat-cache";
|
|
52
50
|
import { parse } from "oxc-parser";
|
|
53
51
|
import { Agent, Response, interceptors, setGlobalDispatcher } from "undici";
|
|
54
52
|
import "@stryke/fs/remove-file";
|
|
53
|
+
import { kebabCase } from "@stryke/string-format/kebab-case";
|
|
55
54
|
import { LogCategories } from "@powerlines/core";
|
|
55
|
+
import { messageParent } from "jest-worker";
|
|
56
56
|
import * as $ from "@stryke/capnp";
|
|
57
57
|
import { readFileBuffer, readFileBufferSync, writeFileBuffer } from "@stryke/fs/buffer";
|
|
58
58
|
import { correctPath, stripStars } from "@stryke/path/correct-path";
|
|
@@ -73,8 +73,8 @@ import ts from "typescript";
|
|
|
73
73
|
import { loadUserConfigFile } from "@powerlines/core/lib/config";
|
|
74
74
|
import { tryGetWorkspaceConfig } from "@storm-software/config-tools/get-config";
|
|
75
75
|
import { isDevelopment, isProduction, isTest } from "@stryke/env/environment-checks";
|
|
76
|
-
import { readJsonFile as readJsonFile$1 } from "@stryke/fs";
|
|
77
|
-
import { joinPaths as joinPaths$2 } from "@stryke/path";
|
|
76
|
+
import { isFile as isFile$1, readJsonFile as readJsonFile$1 } from "@stryke/fs";
|
|
77
|
+
import { findFilePath as findFilePath$1, joinPaths as joinPaths$2, relativePath as relativePath$1 } from "@stryke/path";
|
|
78
78
|
import { formatDistanceToNowStrict } from "date-fns/formatDistanceToNowStrict";
|
|
79
79
|
import { createJiti } from "jiti";
|
|
80
80
|
import { getField } from "@stryke/helpers/get-field";
|
|
@@ -84,9 +84,9 @@ import { getObjectDiff } from "@donedeal0/superdiff";
|
|
|
84
84
|
import { StormJSON } from "@stryke/json/storm-json";
|
|
85
85
|
|
|
86
86
|
//#region src/_internal/helpers/environment.ts
|
|
87
|
-
function createEnvironment(name, config
|
|
87
|
+
function createEnvironment(name, config) {
|
|
88
88
|
return defu(config.environments?.[name] ?? {}, {
|
|
89
|
-
|
|
89
|
+
id: uuid(),
|
|
90
90
|
name,
|
|
91
91
|
title: config.title ?? titleCase(config.name),
|
|
92
92
|
ssr: false,
|
|
@@ -112,7 +112,7 @@ function createEnvironment(name, config = {}) {
|
|
|
112
112
|
} : void 0
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
|
-
function createDefaultEnvironment(config
|
|
115
|
+
function createDefaultEnvironment(config) {
|
|
116
116
|
return createEnvironment(DEFAULT_ENVIRONMENT, config);
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -169,16 +169,16 @@ async function writeMetaFile(context) {
|
|
|
169
169
|
|
|
170
170
|
//#endregion
|
|
171
171
|
//#region src/_internal/ipc/send.ts
|
|
172
|
-
function
|
|
172
|
+
function formatWriteLogMessage(context, meta, message) {
|
|
173
173
|
const combinedMeta = {
|
|
174
174
|
...context.logger.options,
|
|
175
175
|
...isSetObject(meta) ? meta : { type: meta }
|
|
176
176
|
};
|
|
177
|
-
|
|
177
|
+
return {
|
|
178
178
|
id: uuid(),
|
|
179
179
|
type: "write-log",
|
|
180
|
-
executionId: combinedMeta.executionId || context.
|
|
181
|
-
executionIndex: combinedMeta.executionIndex ?? context.
|
|
180
|
+
executionId: combinedMeta.executionId || context.options.executionId,
|
|
181
|
+
executionIndex: combinedMeta.executionIndex ?? context.options.executionIndex,
|
|
182
182
|
environment: combinedMeta.environment,
|
|
183
183
|
timestamp: Date.now(),
|
|
184
184
|
payload: {
|
|
@@ -188,8 +188,8 @@ function sendWriteLogMessage(context, meta, message) {
|
|
|
188
188
|
logId: combinedMeta.logId || uuid(),
|
|
189
189
|
timestamp: combinedMeta.timestamp ?? Date.now(),
|
|
190
190
|
name: combinedMeta.name || context.config.name,
|
|
191
|
-
executionId: combinedMeta.executionId || context.
|
|
192
|
-
executionIndex: combinedMeta.executionIndex ?? context.
|
|
191
|
+
executionId: combinedMeta.executionId || context.options.executionId,
|
|
192
|
+
executionIndex: combinedMeta.executionIndex ?? context.options.executionIndex,
|
|
193
193
|
command: combinedMeta.command || context.config.command,
|
|
194
194
|
hook: combinedMeta.hook,
|
|
195
195
|
environment: combinedMeta.environment,
|
|
@@ -198,7 +198,21 @@ function sendWriteLogMessage(context, meta, message) {
|
|
|
198
198
|
},
|
|
199
199
|
message
|
|
200
200
|
}
|
|
201
|
-
}
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function childProcessSend(message) {
|
|
204
|
+
process.send?.(message);
|
|
205
|
+
}
|
|
206
|
+
function workerThreadSend(message) {
|
|
207
|
+
messageParent(message);
|
|
208
|
+
}
|
|
209
|
+
function send(message) {
|
|
210
|
+
if (process.env.POWERLINES_EXECUTION_THREAD_TYPE === "child-process") childProcessSend(message);
|
|
211
|
+
else if (process.env.POWERLINES_EXECUTION_THREAD_TYPE === "worker-thread") workerThreadSend(message);
|
|
212
|
+
else console.warn("No IPC mechanism available to send message:", message);
|
|
213
|
+
}
|
|
214
|
+
function sendWriteLogMessage(context, meta, message) {
|
|
215
|
+
send(formatWriteLogMessage(context, meta, message));
|
|
202
216
|
}
|
|
203
217
|
|
|
204
218
|
//#endregion
|
|
@@ -1996,40 +2010,40 @@ var VirtualFileSystem = class VirtualFileSystem {
|
|
|
1996
2010
|
/**
|
|
1997
2011
|
* Get the path to the tsconfig.json file.
|
|
1998
2012
|
*
|
|
1999
|
-
* @param
|
|
2000
|
-
* @param
|
|
2013
|
+
* @param cwd - The root directory of the workspace.
|
|
2014
|
+
* @param root - The root directory of the project.
|
|
2001
2015
|
* @param tsconfig - The path to the tsconfig.json file.
|
|
2002
2016
|
* @returns The absolute path to the tsconfig.json file.
|
|
2003
2017
|
* @throws If the tsconfig.json file does not exist.
|
|
2004
2018
|
*/
|
|
2005
|
-
function getTsconfigFilePath(
|
|
2019
|
+
function getTsconfigFilePath(cwd, root, tsconfig) {
|
|
2006
2020
|
let tsconfigFilePath;
|
|
2007
|
-
if (tsconfig) tsconfigFilePath = tryTsconfigFilePath(
|
|
2021
|
+
if (tsconfig) tsconfigFilePath = tryTsconfigFilePath(cwd, root, tsconfig);
|
|
2008
2022
|
else {
|
|
2009
|
-
tsconfigFilePath = tryTsconfigFilePath(
|
|
2023
|
+
tsconfigFilePath = tryTsconfigFilePath(cwd, root, "tsconfig.app.json");
|
|
2010
2024
|
if (!tsconfigFilePath) {
|
|
2011
|
-
tsconfigFilePath = tryTsconfigFilePath(
|
|
2012
|
-
if (!tsconfigFilePath) tsconfigFilePath = tryTsconfigFilePath(
|
|
2025
|
+
tsconfigFilePath = tryTsconfigFilePath(cwd, root, "tsconfig.lib.json");
|
|
2026
|
+
if (!tsconfigFilePath) tsconfigFilePath = tryTsconfigFilePath(cwd, root, "tsconfig.json");
|
|
2013
2027
|
}
|
|
2014
2028
|
}
|
|
2015
|
-
if (!tsconfigFilePath) throw new Error(`Cannot find the \`tsconfig.json\` configuration file for the project at ${
|
|
2029
|
+
if (!tsconfigFilePath) throw new Error(`Cannot find the \`tsconfig.json\` configuration file for the project at ${root}.`);
|
|
2016
2030
|
return tsconfigFilePath;
|
|
2017
2031
|
}
|
|
2018
2032
|
/**
|
|
2019
2033
|
* Get the path to the tsconfig.json file.
|
|
2020
2034
|
*
|
|
2021
|
-
* @param
|
|
2022
|
-
* @param
|
|
2035
|
+
* @param cwd - The root directory of the workspace.
|
|
2036
|
+
* @param root - The root directory of the project.
|
|
2023
2037
|
* @param tsconfig - The path to the tsconfig.json file.
|
|
2024
2038
|
* @returns The absolute path to the tsconfig.json file.
|
|
2025
2039
|
* @throws If the tsconfig.json file does not exist.
|
|
2026
2040
|
*/
|
|
2027
|
-
function tryTsconfigFilePath(
|
|
2041
|
+
function tryTsconfigFilePath(cwd, root, tsconfig) {
|
|
2028
2042
|
let tsconfigFilePath = tsconfig;
|
|
2029
2043
|
if (!existsSync(tsconfigFilePath)) {
|
|
2030
|
-
tsconfigFilePath = appendPath(tsconfig,
|
|
2044
|
+
tsconfigFilePath = appendPath(tsconfig, root);
|
|
2031
2045
|
if (!existsSync(tsconfigFilePath)) {
|
|
2032
|
-
tsconfigFilePath = appendPath(tsconfig, appendPath(
|
|
2046
|
+
tsconfigFilePath = appendPath(tsconfig, appendPath(root, cwd));
|
|
2033
2047
|
if (!existsSync(tsconfigFilePath)) return;
|
|
2034
2048
|
}
|
|
2035
2049
|
}
|
|
@@ -2167,17 +2181,17 @@ var PowerlinesBaseContext = class PowerlinesBaseContext {
|
|
|
2167
2181
|
*/
|
|
2168
2182
|
resolver;
|
|
2169
2183
|
/**
|
|
2170
|
-
* The options provided to the Powerlines process
|
|
2184
|
+
* The options provided to the Powerlines process, resolved with default values and merged with any configuration provided by plugins or other sources. This is typically the final configuration used during the build process, but may also include additional options that are relevant to the context and its interactions with the Powerlines engine.
|
|
2171
2185
|
*/
|
|
2172
2186
|
options;
|
|
2173
2187
|
/**
|
|
2174
|
-
* The
|
|
2188
|
+
* The parsed `package.json` file for the project
|
|
2175
2189
|
*/
|
|
2176
|
-
|
|
2190
|
+
packageJson;
|
|
2177
2191
|
/**
|
|
2178
|
-
* The
|
|
2192
|
+
* The parsed `project.json` file for the project
|
|
2179
2193
|
*/
|
|
2180
|
-
|
|
2194
|
+
projectJson = void 0;
|
|
2181
2195
|
/**
|
|
2182
2196
|
* The parsed configuration file for the project
|
|
2183
2197
|
*/
|
|
@@ -2216,8 +2230,8 @@ var PowerlinesBaseContext = class PowerlinesBaseContext {
|
|
|
2216
2230
|
* @returns A promise that resolves to the cloned context.
|
|
2217
2231
|
*/
|
|
2218
2232
|
async clone() {
|
|
2219
|
-
const clone = new PowerlinesBaseContext();
|
|
2220
|
-
await clone.init(
|
|
2233
|
+
const clone = new PowerlinesBaseContext(this.options, this.initialConfig);
|
|
2234
|
+
await clone.init();
|
|
2221
2235
|
return clone;
|
|
2222
2236
|
}
|
|
2223
2237
|
/**
|
|
@@ -2300,7 +2314,7 @@ var PowerlinesBaseContext = class PowerlinesBaseContext {
|
|
|
2300
2314
|
* @returns A logger client instance that can be used to generate log messages with consistent formatting and metadata.
|
|
2301
2315
|
*/
|
|
2302
2316
|
createLogger(options, logFn) {
|
|
2303
|
-
return createLogger$1(this.options.name || this.options.root, {
|
|
2317
|
+
return createLogger$1(this.options.name || this.options.root || "powerlines", {
|
|
2304
2318
|
...this.configFile.config,
|
|
2305
2319
|
...this.options,
|
|
2306
2320
|
...options
|
|
@@ -2316,6 +2330,24 @@ var PowerlinesBaseContext = class PowerlinesBaseContext {
|
|
|
2316
2330
|
return extendLogger(this.logger, options);
|
|
2317
2331
|
}
|
|
2318
2332
|
/**
|
|
2333
|
+
* The input options used to initialize the context, which may be used when cloning the context to ensure the same configuration is applied to the new context
|
|
2334
|
+
*/
|
|
2335
|
+
initialOptions = {};
|
|
2336
|
+
/**
|
|
2337
|
+
* The initial configuration provided when initializing the context, which may be used during the setup process to ensure that the configuration is properly merged and applied to the context. This is typically the user configuration provided in the Powerlines configuration file, but may also include additional configuration options provided by plugins or other sources.
|
|
2338
|
+
*/
|
|
2339
|
+
initialConfig = {};
|
|
2340
|
+
/**
|
|
2341
|
+
* Initialize the context with the provided configuration options and set up the resolver and user configuration file. This method is called during the construction of the context and can also be called when cloning the context to ensure that the new context has the same configuration and resolver setup as the original context.
|
|
2342
|
+
*
|
|
2343
|
+
* @param options - The configuration options to initialize the context with, which can include properties such as the project root, mode, log level, and other settings that affect the behavior of the context and its plugins.
|
|
2344
|
+
* @param initialConfig - The initial configuration to initialize the context with, which is typically the user configuration provided in the Powerlines configuration file. This can also include additional configuration options provided by plugins or other sources that should be merged with the user configuration during initialization
|
|
2345
|
+
*/
|
|
2346
|
+
constructor(options, initialConfig = {}) {
|
|
2347
|
+
this.initialOptions = options;
|
|
2348
|
+
this.initialConfig = initialConfig;
|
|
2349
|
+
}
|
|
2350
|
+
/**
|
|
2319
2351
|
* Retrieve the workspace configuration for the current project, if it exists. This function will look for a configuration file in the project root and return its contents as a JavaScript object. If no configuration file is found, it will return undefined.
|
|
2320
2352
|
*
|
|
2321
2353
|
* @returns A promise that resolves to the workspace configuration object, or undefined if no configuration file is found.
|
|
@@ -2327,64 +2359,47 @@ var PowerlinesBaseContext = class PowerlinesBaseContext {
|
|
|
2327
2359
|
} : void 0);
|
|
2328
2360
|
}
|
|
2329
2361
|
/**
|
|
2330
|
-
* Determine the default mode for the current execution based on the environment and workspace configuration. This function will check the `NODE_ENV` environment variable to determine if the current environment is development, production, or test. If `NODE_ENV` is not set, it will look for a `mode` property in the workspace configuration file. If no mode is specified in the workspace configuration, it will default to "production".
|
|
2331
|
-
*
|
|
2332
|
-
* @returns A promise that resolves to the default mode for the current execution, which can be "development", "production", or "test".
|
|
2333
|
-
*/
|
|
2334
|
-
async getDefaultMode() {
|
|
2335
|
-
const workspaceConfig = await this.getWorkspaceConfig();
|
|
2336
|
-
return isProduction ? "production" : isDevelopment ? "development" : isTest ? "test" : workspaceConfig?.mode || "production";
|
|
2337
|
-
}
|
|
2338
|
-
/**
|
|
2339
|
-
* Determine the default log level for the current execution based on the environment and workspace configuration. This function will check the `logLevel` property in the workspace configuration file and resolve it to a `LogLevelResolvedConfig` value. If no log level is specified in the workspace configuration, it will default to "info" for development mode and "warn" for production mode.
|
|
2340
|
-
*
|
|
2341
|
-
* @returns A promise that resolves to the default log level for the current execution, which can be "fatal", "error", "warn", "info", "debug", or "trace".
|
|
2342
|
-
*/
|
|
2343
|
-
async getDefaultLogLevel() {
|
|
2344
|
-
const workspaceConfig = await this.getWorkspaceConfig();
|
|
2345
|
-
return resolveLogLevel(workspaceConfig?.logLevel ? workspaceConfig.logLevel === "success" || workspaceConfig.logLevel === "performance" ? "info" : workspaceConfig.logLevel === "all" ? "debug" : workspaceConfig.logLevel === "fatal" ? "error" : workspaceConfig.logLevel : void 0, this.options?.mode || this.initialOptions?.mode || workspaceConfig?.mode || await this.getDefaultMode());
|
|
2346
|
-
}
|
|
2347
|
-
/**
|
|
2348
2362
|
* Initialize the context with the provided configuration options
|
|
2349
2363
|
*
|
|
2350
2364
|
* @remarks
|
|
2351
2365
|
* This method will set up the resolver and load the user configuration file based on the provided options. It is called during the construction of the context and can also be called when cloning the context to ensure that the new context has the same configuration and resolver setup.
|
|
2352
|
-
*
|
|
2353
|
-
* @param options - The configuration options to initialize the context with
|
|
2354
|
-
* @param initialConfig - The initial configuration to initialize the context with
|
|
2355
2366
|
*/
|
|
2356
|
-
async init(
|
|
2357
|
-
this.initialOptions = { ...options };
|
|
2358
|
-
this.initialConfig = { ...initialConfig };
|
|
2367
|
+
async init() {
|
|
2359
2368
|
if (!this.powerlinesPath) {
|
|
2360
2369
|
const powerlinesPath = await resolvePackage("powerlines");
|
|
2361
2370
|
if (!powerlinesPath) throw new Error("Could not resolve `powerlines` package location.");
|
|
2362
2371
|
this.powerlinesPath = powerlinesPath;
|
|
2363
2372
|
}
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
this.options = defu({
|
|
2367
|
-
name: options.name || this.initialConfig.name,
|
|
2368
|
-
root,
|
|
2369
|
-
cwd,
|
|
2370
|
-
mode: options.mode || this.initialConfig.mode,
|
|
2371
|
-
logLevel: options.logLevel || this.initialConfig.logLevel,
|
|
2372
|
-
framework: options.framework || this.initialConfig.framework,
|
|
2373
|
-
organization: options.organization || this.initialConfig.organization,
|
|
2374
|
-
configFile: options.configFile || this.initialConfig.configFile
|
|
2375
|
-
}, this.options ?? {}, {
|
|
2373
|
+
this.options = defu(this.initialOptions, this.initialConfig, {
|
|
2374
|
+
cwd: process.cwd(),
|
|
2376
2375
|
mode: await this.getDefaultMode(),
|
|
2377
|
-
logLevel: await this.getDefaultLogLevel()
|
|
2376
|
+
logLevel: await this.getDefaultLogLevel(),
|
|
2377
|
+
framework: "powerlines"
|
|
2378
2378
|
});
|
|
2379
|
+
if (!this.options.root) if (this.options.configFile) {
|
|
2380
|
+
const configFile = appendPath(this.options.configFile, this.options.cwd);
|
|
2381
|
+
if (!existsSync$1(configFile)) throw new Error(`The user-provided configuration file at "${this.options.configFile}" does not exist. Please ensure this path is correct and try again.`);
|
|
2382
|
+
if (!isFile$1(configFile)) throw new Error(`The user-provided configuration file at "${this.options.configFile}" is not a file. Please ensure this path is correct and try again.`);
|
|
2383
|
+
this.options.root = relativePath$1(this.options.cwd, findFilePath$1(configFile));
|
|
2384
|
+
} else this.options.root = ".";
|
|
2385
|
+
else this.options.root = replacePath(this.options.root, this.options.cwd);
|
|
2379
2386
|
this.resolver = createResolver({
|
|
2380
|
-
workspaceRoot: cwd,
|
|
2381
|
-
root,
|
|
2387
|
+
workspaceRoot: this.options.cwd,
|
|
2388
|
+
root: this.options.root,
|
|
2382
2389
|
cacheDir: this.envPaths.cache,
|
|
2383
2390
|
mode: this.options.mode
|
|
2384
2391
|
});
|
|
2392
|
+
const projectJsonPath = joinPaths$2(appendPath(this.options.root, this.options.cwd), "project.json");
|
|
2393
|
+
if (existsSync$1(projectJsonPath)) this.projectJson = await readJsonFile$1(projectJsonPath);
|
|
2394
|
+
const packageJsonPath = joinPaths$2(appendPath(this.options.root, this.options.cwd), "package.json");
|
|
2395
|
+
if (existsSync$1(packageJsonPath)) {
|
|
2396
|
+
this.packageJson = await readJsonFile$1(packageJsonPath);
|
|
2397
|
+
this.options.organization ??= isSetObject(this.packageJson?.author) ? kebabCase(this.packageJson?.author?.name) : kebabCase(this.packageJson?.author);
|
|
2398
|
+
}
|
|
2385
2399
|
this.configFile = await loadUserConfigFile(this.options, this.resolver);
|
|
2386
|
-
if (
|
|
2387
|
-
if (this.configFile.
|
|
2400
|
+
if (this.configFile.config) {
|
|
2401
|
+
if (isSetString(this.configFile.configFile)) this.options.configFile ??= replacePath(this.configFile.configFile, this.options.cwd);
|
|
2402
|
+
if (!this.options.name) {
|
|
2388
2403
|
if (isSetObject(this.configFile.config) && isSetString(this.configFile.config.name)) this.options.name = this.configFile.config.name;
|
|
2389
2404
|
else if (Array.isArray(this.configFile.config)) {
|
|
2390
2405
|
for (const config of this.configFile.config) if (isSetObject(config) && isSetString(config.name)) {
|
|
@@ -2393,22 +2408,27 @@ var PowerlinesBaseContext = class PowerlinesBaseContext {
|
|
|
2393
2408
|
}
|
|
2394
2409
|
}
|
|
2395
2410
|
}
|
|
2396
|
-
if (!this.options.name)
|
|
2397
|
-
const packageJsonPath = joinPaths$2(appendPath(this.options.root, this.options.cwd), "package.json");
|
|
2398
|
-
if (existsSync$1(packageJsonPath)) {
|
|
2399
|
-
const packageJson = await readJsonFile$1(packageJsonPath);
|
|
2400
|
-
this.options.name = packageJson.name;
|
|
2401
|
-
}
|
|
2402
|
-
if (!this.options.name) {
|
|
2403
|
-
const projectJsonPath = joinPaths$2(appendPath(this.options.root, this.options.cwd), "project.json");
|
|
2404
|
-
if (existsSync$1(projectJsonPath)) {
|
|
2405
|
-
const projectJson = await readJsonFile$1(projectJsonPath);
|
|
2406
|
-
this.options.name = projectJson.name;
|
|
2407
|
-
}
|
|
2408
|
-
}
|
|
2409
|
-
}
|
|
2411
|
+
if (!this.options.name) this.options.name = this.projectJson?.name || this.packageJson?.name;
|
|
2410
2412
|
}
|
|
2411
2413
|
}
|
|
2414
|
+
/**
|
|
2415
|
+
* Determine the default mode for the current execution based on the environment and workspace configuration. This function will check the `NODE_ENV` environment variable to determine if the current environment is development, production, or test. If `NODE_ENV` is not set, it will look for a `mode` property in the workspace configuration file. If no mode is specified in the workspace configuration, it will default to "production".
|
|
2416
|
+
*
|
|
2417
|
+
* @returns A promise that resolves to the default mode for the current execution, which can be "development", "production", or "test".
|
|
2418
|
+
*/
|
|
2419
|
+
async getDefaultMode() {
|
|
2420
|
+
const workspaceConfig = await this.getWorkspaceConfig();
|
|
2421
|
+
return isProduction ? "production" : isDevelopment ? "development" : isTest ? "test" : workspaceConfig?.mode || "production";
|
|
2422
|
+
}
|
|
2423
|
+
/**
|
|
2424
|
+
* Determine the default log level for the current execution based on the environment and workspace configuration. This function will check the `logLevel` property in the workspace configuration file and resolve it to a `LogLevelResolvedConfig` value. If no log level is specified in the workspace configuration, it will default to "info" for development mode and "warn" for production mode.
|
|
2425
|
+
*
|
|
2426
|
+
* @returns A promise that resolves to the default log level for the current execution, which can be "fatal", "error", "warn", "info", "debug", or "trace".
|
|
2427
|
+
*/
|
|
2428
|
+
async getDefaultLogLevel() {
|
|
2429
|
+
const workspaceConfig = await this.getWorkspaceConfig();
|
|
2430
|
+
return resolveLogLevel(workspaceConfig?.logLevel ? workspaceConfig.logLevel === "success" || workspaceConfig.logLevel === "performance" ? "info" : workspaceConfig.logLevel === "all" ? "debug" : workspaceConfig.logLevel === "fatal" ? "error" : workspaceConfig.logLevel : void 0, this.options?.mode || this.initialOptions?.mode || workspaceConfig?.mode || await this.getDefaultMode());
|
|
2431
|
+
}
|
|
2412
2432
|
};
|
|
2413
2433
|
|
|
2414
2434
|
//#endregion
|
|
@@ -2420,27 +2440,13 @@ setGlobalDispatcher(new Agent({ keepAliveTimeout: 1e4 }).compose(interceptors.re
|
|
|
2420
2440
|
timeoutFactor: 2,
|
|
2421
2441
|
retryAfter: true
|
|
2422
2442
|
})));
|
|
2423
|
-
const
|
|
2424
|
-
"
|
|
2425
|
-
"
|
|
2426
|
-
"
|
|
2427
|
-
"
|
|
2428
|
-
"projectJson",
|
|
2429
|
-
"tsconfig",
|
|
2430
|
-
"resolver",
|
|
2431
|
-
"fs",
|
|
2432
|
-
"$$internal"
|
|
2443
|
+
const UNRESOLVED_CONFIG_NAMES = [
|
|
2444
|
+
"initialConfig",
|
|
2445
|
+
"userConfig",
|
|
2446
|
+
"inlineConfig",
|
|
2447
|
+
"pluginConfig"
|
|
2433
2448
|
];
|
|
2434
2449
|
var PowerlinesContext = class PowerlinesContext extends PowerlinesBaseContext {
|
|
2435
|
-
/**
|
|
2436
|
-
* Internal references storage
|
|
2437
|
-
*
|
|
2438
|
-
* @danger
|
|
2439
|
-
* This field is for internal use only and should not be accessed or modified directly. It is unstable and can be changed at anytime.
|
|
2440
|
-
*
|
|
2441
|
-
* @internal
|
|
2442
|
-
*/
|
|
2443
|
-
#internal = {};
|
|
2444
2450
|
#checksum = null;
|
|
2445
2451
|
#buildId = uuid();
|
|
2446
2452
|
#releaseId = uuid();
|
|
@@ -2448,24 +2454,22 @@ var PowerlinesContext = class PowerlinesContext extends PowerlinesBaseContext {
|
|
|
2448
2454
|
#tsconfig;
|
|
2449
2455
|
#parserCache;
|
|
2450
2456
|
#requestCache;
|
|
2457
|
+
#configProxy;
|
|
2451
2458
|
/**
|
|
2452
|
-
* Create a new
|
|
2459
|
+
* Create a new context from the workspace root and user config.
|
|
2453
2460
|
*
|
|
2454
2461
|
* @param options - The options for resolving the context.
|
|
2455
2462
|
* @returns A promise that resolves to the new context.
|
|
2456
2463
|
*/
|
|
2457
|
-
static async
|
|
2458
|
-
const context = new PowerlinesContext(options);
|
|
2459
|
-
await context.init(
|
|
2460
|
-
const powerlinesPath = await resolvePackage("powerlines");
|
|
2461
|
-
if (!powerlinesPath) throw new Error("Could not resolve `powerlines` package location.");
|
|
2462
|
-
context.powerlinesPath = powerlinesPath;
|
|
2464
|
+
static async fromInitialConfig(options, initialConfig) {
|
|
2465
|
+
const context = new PowerlinesContext(options, initialConfig);
|
|
2466
|
+
await context.init();
|
|
2463
2467
|
return context;
|
|
2464
2468
|
}
|
|
2465
2469
|
/**
|
|
2466
|
-
* The options provided to the Powerlines process
|
|
2470
|
+
* The options provided to the Powerlines process, resolved with default values and merged with any configuration provided by plugins or other sources. This is typically the final configuration used during the build process, but may also include additional options that are relevant to the context and its interactions with the Powerlines engine.
|
|
2467
2471
|
*/
|
|
2468
|
-
options;
|
|
2472
|
+
options = {};
|
|
2469
2473
|
/**
|
|
2470
2474
|
* An object containing the dependencies that should be installed for the project
|
|
2471
2475
|
*/
|
|
@@ -2479,39 +2483,33 @@ var PowerlinesContext = class PowerlinesContext extends PowerlinesBaseContext {
|
|
|
2479
2483
|
*/
|
|
2480
2484
|
persistedMeta = void 0;
|
|
2481
2485
|
/**
|
|
2482
|
-
* The
|
|
2486
|
+
* The resolved tsconfig file paths for the project
|
|
2483
2487
|
*/
|
|
2484
|
-
|
|
2488
|
+
resolvePatterns = [];
|
|
2485
2489
|
/**
|
|
2486
|
-
* The
|
|
2490
|
+
* The input options used to initialize the context, which may be used when cloning the context to ensure the same configuration is applied to the new context
|
|
2487
2491
|
*/
|
|
2488
|
-
|
|
2492
|
+
initialOptions = {};
|
|
2489
2493
|
/**
|
|
2490
|
-
* The resolved
|
|
2494
|
+
* The resolved configuration for this context
|
|
2491
2495
|
*/
|
|
2492
|
-
|
|
2496
|
+
resolvedConfig = {};
|
|
2493
2497
|
/**
|
|
2494
|
-
*
|
|
2495
|
-
*
|
|
2496
|
-
* @danger
|
|
2497
|
-
* This field is for internal use only and should not be accessed or modified directly. It is unstable and can be changed at anytime.
|
|
2498
|
-
*
|
|
2499
|
-
* @internal
|
|
2498
|
+
* The configuration options that were overridden by plugins during the build process, which may include additional properties or modifications made during the configuration loading process.
|
|
2500
2499
|
*/
|
|
2501
|
-
|
|
2502
|
-
return this.#internal;
|
|
2503
|
-
}
|
|
2500
|
+
overriddenConfig = {};
|
|
2504
2501
|
/**
|
|
2505
|
-
*
|
|
2506
|
-
*
|
|
2507
|
-
* @danger
|
|
2508
|
-
* This field is for internal use only and should not be accessed or modified directly. It is unstable and can be changed at anytime.
|
|
2509
|
-
*
|
|
2510
|
-
* @internal
|
|
2502
|
+
* The configuration options provided inline during execution, such as CLI flags or other parameters that may be relevant to the command being executed. These options can be used to override or supplement the configuration options defined in a configuration file on disk, and are typically provided as part of the execution context when running a Powerlines command.
|
|
2511
2503
|
*/
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2504
|
+
inlineConfig = {};
|
|
2505
|
+
/**
|
|
2506
|
+
* The configuration options read from a configuration file on disk, which may be used to resolve the final configuration for the context. This typically includes the user configuration options defined in the `powerlines.config.ts` file, as well as any inline configuration options provided during execution.
|
|
2507
|
+
*/
|
|
2508
|
+
userConfig = {};
|
|
2509
|
+
/**
|
|
2510
|
+
* The configuration options provided by plugins added by the user (and other plugins)
|
|
2511
|
+
*/
|
|
2512
|
+
pluginConfig = {};
|
|
2515
2513
|
/**
|
|
2516
2514
|
* The resolved entry type definitions for the project
|
|
2517
2515
|
*/
|
|
@@ -2566,13 +2564,14 @@ var PowerlinesContext = class PowerlinesContext extends PowerlinesBaseContext {
|
|
|
2566
2564
|
* The resolved configuration options
|
|
2567
2565
|
*/
|
|
2568
2566
|
get config() {
|
|
2569
|
-
|
|
2567
|
+
if (!this.#configProxy) this.#configProxy = this.createConfigProxy();
|
|
2568
|
+
return this.#configProxy;
|
|
2570
2569
|
}
|
|
2571
2570
|
/**
|
|
2572
2571
|
* Get the path to the artifacts directory for the project
|
|
2573
2572
|
*/
|
|
2574
2573
|
get artifactsPath() {
|
|
2575
|
-
return joinPaths$1(this.config.cwd, this.config.root, this.config.output.
|
|
2574
|
+
return joinPaths$1(this.config.cwd, this.config.root, this.config.output?.artifactsPath || `.${this.config.framework || "powerlines"}`);
|
|
2576
2575
|
}
|
|
2577
2576
|
/**
|
|
2578
2577
|
* Get the path to the builtin modules used by the project
|
|
@@ -2629,7 +2628,7 @@ var PowerlinesContext = class PowerlinesContext extends PowerlinesBaseContext {
|
|
|
2629
2628
|
* Additional arguments provided during execution of the command, such as CLI flags or other parameters that may be relevant to the command being executed.
|
|
2630
2629
|
*/
|
|
2631
2630
|
get additionalArgs() {
|
|
2632
|
-
return Object.entries(this.config.inlineConfig
|
|
2631
|
+
return Object.entries(this.config.inlineConfig.additionalArgs ?? {}).reduce((ret, [key, value]) => {
|
|
2633
2632
|
const formattedKey = key.replace(/^--?/, "");
|
|
2634
2633
|
if (ret[formattedKey]) if (Array.isArray(ret[formattedKey])) if (Array.isArray(value)) ret[formattedKey] = [...toArray(ret[formattedKey]), ...value];
|
|
2635
2634
|
else ret[formattedKey] = [...toArray(ret[formattedKey]), value];
|
|
@@ -2658,29 +2657,6 @@ var PowerlinesContext = class PowerlinesContext extends PowerlinesBaseContext {
|
|
|
2658
2657
|
}, {}) : this.config.resolve.alias : {});
|
|
2659
2658
|
}
|
|
2660
2659
|
/**
|
|
2661
|
-
* Create a new logger instance
|
|
2662
|
-
*
|
|
2663
|
-
* @param options - The configuration options to use for the logger instance, which can be used to customize the appearance and behavior of the log messages generated by the logger. This is typically the name of the plugin or module that is creating the logger instance.
|
|
2664
|
-
* @param logFn - The custom logging function to use for logging messages, which can be used to override the default logging behavior of the original logger.
|
|
2665
|
-
* @returns A logger client instance that can be used to generate log messages with consistent formatting and metadata.
|
|
2666
|
-
*/
|
|
2667
|
-
createLogger(options, logFn) {
|
|
2668
|
-
let logger;
|
|
2669
|
-
if (toBool(process.env.POWERLINES_WORKER_THREAD_EXECUTION)) logger = createLogger(this.config.name, {
|
|
2670
|
-
...this.options,
|
|
2671
|
-
...this.config,
|
|
2672
|
-
...options
|
|
2673
|
-
}, (meta, message) => sendWriteLogMessage(this, meta, message));
|
|
2674
|
-
else logger = createLogger(this.config.name, {
|
|
2675
|
-
...this.options,
|
|
2676
|
-
...this.config,
|
|
2677
|
-
...options
|
|
2678
|
-
});
|
|
2679
|
-
if (this.config.customLogger) logger = withCustomLogger(logger, this.config.customLogger);
|
|
2680
|
-
if (logFn) logger = withLogFn(logger, logFn);
|
|
2681
|
-
return logger;
|
|
2682
|
-
}
|
|
2683
|
-
/**
|
|
2684
2660
|
* The log level for the context, which determines the minimum level of log messages that will be emitted by the logger. This is resolved based on the configuration options provided by the user, and can be set to different levels for development, production, and test environments. The log level can also be overridden by plugins or other parts of the build process to provide more granular control over logging output.
|
|
2685
2661
|
*/
|
|
2686
2662
|
get logLevel() {
|
|
@@ -2742,25 +2718,38 @@ var PowerlinesContext = class PowerlinesContext extends PowerlinesBaseContext {
|
|
|
2742
2718
|
}).filter(Boolean);
|
|
2743
2719
|
}
|
|
2744
2720
|
/**
|
|
2745
|
-
* Creates a new
|
|
2721
|
+
* Creates a new Context instance.
|
|
2746
2722
|
*
|
|
2747
2723
|
* @param options - The options to use for creating the context, including the resolved configuration and workspace settings.
|
|
2724
|
+
* @param initialConfig - The initial configuration provided by the user, which can be used to resolve the final configuration for the context. This typically includes the user configuration options defined in the `powerlines.config.ts` file, as well as any inline configuration options provided during execution.
|
|
2748
2725
|
*/
|
|
2749
|
-
constructor(options) {
|
|
2750
|
-
super();
|
|
2751
|
-
this.
|
|
2726
|
+
constructor(options, initialConfig) {
|
|
2727
|
+
super(options, initialConfig);
|
|
2728
|
+
this.initialOptions = options;
|
|
2729
|
+
this.initialConfig = initialConfig;
|
|
2752
2730
|
}
|
|
2753
2731
|
/**
|
|
2754
|
-
*
|
|
2755
|
-
*
|
|
2756
|
-
* @remarks
|
|
2757
|
-
* The cloned context will have the same configuration and workspace settings as the original context, but will have a different build ID, release ID, and timestamp. The virtual file system and caches will also be separate between the original and cloned contexts.
|
|
2732
|
+
* Create a new logger instance
|
|
2758
2733
|
*
|
|
2759
|
-
* @
|
|
2734
|
+
* @param options - The configuration options to use for the logger instance, which can be used to customize the appearance and behavior of the log messages generated by the logger. This is typically the name of the plugin or module that is creating the logger instance.
|
|
2735
|
+
* @param logFn - The custom logging function to use for logging messages, which can be used to override the default logging behavior of the original logger.
|
|
2736
|
+
* @returns A logger client instance that can be used to generate log messages with consistent formatting and metadata.
|
|
2760
2737
|
*/
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2738
|
+
createLogger(options, logFn) {
|
|
2739
|
+
let logger;
|
|
2740
|
+
if (isSetString(process.env.POWERLINES_EXECUTION_THREAD_TYPE)) logger = createLogger(this.config.name, {
|
|
2741
|
+
...this.options,
|
|
2742
|
+
...this.config,
|
|
2743
|
+
...options
|
|
2744
|
+
}, (meta, message) => sendWriteLogMessage(this, meta, message));
|
|
2745
|
+
else logger = createLogger(this.config.name, {
|
|
2746
|
+
...this.options,
|
|
2747
|
+
...this.config,
|
|
2748
|
+
...options
|
|
2749
|
+
});
|
|
2750
|
+
if (this.config.customLogger) logger = withCustomLogger(logger, this.config.customLogger);
|
|
2751
|
+
if (logFn) logger = withLogFn(logger, logFn);
|
|
2752
|
+
return logger;
|
|
2764
2753
|
}
|
|
2765
2754
|
/**
|
|
2766
2755
|
* A function to perform HTTP fetch requests
|
|
@@ -3090,206 +3079,233 @@ var PowerlinesContext = class PowerlinesContext extends PowerlinesBaseContext {
|
|
|
3090
3079
|
/**
|
|
3091
3080
|
* Generates a checksum representing the current context state
|
|
3092
3081
|
*
|
|
3093
|
-
* @param
|
|
3082
|
+
* @param path - The root directory of the project to generate the checksum for
|
|
3094
3083
|
* @returns A promise that resolves to a string representing the checksum
|
|
3095
3084
|
*/
|
|
3096
|
-
async generateChecksum(
|
|
3097
|
-
|
|
3098
|
-
"node_modules",
|
|
3099
|
-
".git",
|
|
3100
|
-
".nx",
|
|
3101
|
-
".cache",
|
|
3102
|
-
"tmp",
|
|
3103
|
-
"dist"
|
|
3104
|
-
] });
|
|
3105
|
-
return this.#checksum;
|
|
3085
|
+
async generateChecksum(path) {
|
|
3086
|
+
return hashDirectory(path || appendPath(this.options.root, this.options.cwd));
|
|
3106
3087
|
}
|
|
3107
3088
|
/**
|
|
3108
|
-
*
|
|
3089
|
+
* A setter function to populate the inline config values provided during execution of the command, such as CLI flags or other parameters that may be relevant to the command being executed. This function can be used to update the context with the inline configuration values, which may be used during the configuration resolution process to ensure that the final configuration reflects both the user configuration and any inline configuration provided during execution.
|
|
3090
|
+
*
|
|
3091
|
+
* @param config - The inline configuration values to set.
|
|
3092
|
+
* @returns A promise that resolves when the inline configuration values have been set.
|
|
3109
3093
|
*/
|
|
3110
|
-
async
|
|
3111
|
-
this.
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3094
|
+
async setInlineConfig(config) {
|
|
3095
|
+
this.logger.debug({
|
|
3096
|
+
meta: { category: "config" },
|
|
3097
|
+
message: `Updating inline configuration object: \n${this.logConfig(config)}`
|
|
3098
|
+
});
|
|
3099
|
+
this.inlineConfig = config;
|
|
3100
|
+
await this.resolveConfig();
|
|
3101
|
+
}
|
|
3102
|
+
/**
|
|
3103
|
+
* A setter function to populate the plugin config values provided during execution of the command, such as CLI flags or other parameters that may be relevant to the command being executed. This function can be used to update the context with the plugin configuration values, which may be used during the configuration resolution process to ensure that the final configuration reflects both the user configuration and any plugin configuration provided during execution.
|
|
3104
|
+
*
|
|
3105
|
+
* @param config - The plugin configuration values to set.
|
|
3106
|
+
* @returns A promise that resolves when the plugin configuration values have been set.
|
|
3107
|
+
*/
|
|
3108
|
+
async setPluginConfig(config) {
|
|
3109
|
+
this.logger.debug({
|
|
3110
|
+
meta: { category: "config" },
|
|
3111
|
+
message: `Updating plugin configuration object: \n${this.logConfig(config)}`
|
|
3112
|
+
});
|
|
3113
|
+
this.pluginConfig = config;
|
|
3114
|
+
await this.resolveConfig();
|
|
3115
|
+
}
|
|
3116
|
+
/**
|
|
3117
|
+
* A function to merge the various configuration objects (initial, user, inline, and plugin) into a single resolved configuration object that can be used throughout the Powerlines process. This function takes into account the different sources of configuration and their respective priorities, ensuring that the final configuration reflects the intended settings for the project. The merged configuration is then returned as a new object that can be accessed through the `config` property of the context.
|
|
3118
|
+
*
|
|
3119
|
+
* @returns The merged configuration object that combines the initial, user, inline, and plugin configurations.
|
|
3120
|
+
*/
|
|
3121
|
+
mergeConfig() {
|
|
3122
|
+
return mergeConfig({
|
|
3123
|
+
mode: this.initialOptions.mode,
|
|
3124
|
+
framework: this.initialOptions.framework,
|
|
3125
|
+
initialOptions: this.initialOptions,
|
|
3126
|
+
options: this.options,
|
|
3127
|
+
inlineConfig: this.inlineConfig,
|
|
3128
|
+
userConfig: this.userConfig,
|
|
3129
|
+
initialConfig: this.initialConfig,
|
|
3130
|
+
pluginConfig: this.pluginConfig
|
|
3131
|
+
}, getConfigProps(this.overriddenConfig), omit(this.options, ["mode", "framework"]), getConfigProps(this.inlineConfig), getConfigProps(this.userConfig), getConfigProps(this.initialConfig), getConfigProps(this.pluginConfig), {
|
|
3120
3132
|
version: this.packageJson?.version,
|
|
3121
3133
|
description: this.packageJson?.description
|
|
3122
3134
|
}, {
|
|
3123
3135
|
environments: {},
|
|
3124
3136
|
resolve: {}
|
|
3125
3137
|
});
|
|
3126
|
-
await this.innerSetup();
|
|
3127
3138
|
}
|
|
3128
3139
|
/**
|
|
3129
|
-
*
|
|
3130
|
-
*/
|
|
3131
|
-
resolvedConfig = {};
|
|
3132
|
-
/**
|
|
3133
|
-
* Creates a clone of the current context with the same configuration and workspace settings. This can be useful for running multiple builds in parallel or for creating isolated contexts for different parts of the build process.
|
|
3134
|
-
*
|
|
3135
|
-
* @remarks
|
|
3136
|
-
* The cloned context will have the same configuration and workspace settings as the original context, but will have a different build ID, release ID, and timestamp. The virtual file system and caches will also be separate between the original and cloned contexts.
|
|
3140
|
+
* A setter function to populate the user config values provided during execution of the command, such as CLI flags or other parameters that may be relevant to the command being executed. This function can be used to update the context with the user configuration values, which may be used during the configuration resolution process to ensure that the final configuration reflects both the user configuration and any inline configuration provided during execution.
|
|
3137
3141
|
*
|
|
3138
|
-
* @
|
|
3142
|
+
* @param config - The user configuration values to set.
|
|
3143
|
+
* @returns A promise that resolves when the user configuration values have been set.
|
|
3139
3144
|
*/
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
context.devDependencies = deepClone(this.devDependencies);
|
|
3148
|
-
context.persistedMeta = this.persistedMeta ? deepClone(this.persistedMeta) : void 0;
|
|
3149
|
-
context.packageJson = deepClone(this.packageJson);
|
|
3150
|
-
context.projectJson = this.projectJson ? deepClone(this.projectJson) : void 0;
|
|
3151
|
-
context.tsconfig ??= deepClone(this.tsconfig);
|
|
3152
|
-
context.resolver ??= this.resolver;
|
|
3153
|
-
context.fs ??= this.#fs;
|
|
3154
|
-
context.$$internal = this.$$internal;
|
|
3155
|
-
return context;
|
|
3145
|
+
async setUserConfig(config) {
|
|
3146
|
+
this.logger.debug({
|
|
3147
|
+
meta: { category: "config" },
|
|
3148
|
+
message: `Updating user configuration object: \n${this.logConfig(config)}`
|
|
3149
|
+
});
|
|
3150
|
+
this.userConfig = config;
|
|
3151
|
+
await this.resolveConfig();
|
|
3156
3152
|
}
|
|
3157
3153
|
/**
|
|
3158
3154
|
* Initialize the context with the provided configuration options
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
this.
|
|
3168
|
-
this.options.executionIndex = options.executionIndex ?? this.options.executionIndex ?? 0;
|
|
3169
|
-
const projectJsonPath = joinPaths$1(this.options.cwd, this.options.root, "project.json");
|
|
3170
|
-
if (existsSync(projectJsonPath)) this.projectJson = await readJsonFile(projectJsonPath);
|
|
3171
|
-
const packageJsonPath = joinPaths$1(this.options.cwd, this.options.root, "package.json");
|
|
3172
|
-
if (existsSync(packageJsonPath)) {
|
|
3173
|
-
this.packageJson = await readJsonFile(packageJsonPath);
|
|
3174
|
-
this.options.organization ??= isSetObject(this.packageJson?.author) ? kebabCase(this.packageJson?.author?.name) : kebabCase(this.packageJson?.author);
|
|
3175
|
-
}
|
|
3176
|
-
this.#checksum = await this.generateChecksum(joinPaths$1(this.options.cwd, this.options.root));
|
|
3177
|
-
const userConfig = this.configFile.config ? Array.isArray(this.configFile.config) && this.configFile.config.length > this.options.executionIndex ? this.configFile.config[this.options.executionIndex] : this.configFile.config : {};
|
|
3178
|
-
this.resolvedConfig = {
|
|
3179
|
-
cwd: this.options.cwd,
|
|
3180
|
-
root: this.options.root,
|
|
3181
|
-
...this.initialOptions,
|
|
3182
|
-
...initialConfig,
|
|
3183
|
-
...userConfig,
|
|
3184
|
-
inlineConfig: {},
|
|
3185
|
-
pluginConfig: {},
|
|
3186
|
-
initialConfig,
|
|
3187
|
-
userConfig
|
|
3188
|
-
};
|
|
3155
|
+
*/
|
|
3156
|
+
async init() {
|
|
3157
|
+
await super.init();
|
|
3158
|
+
this.options.executionId = this.initialOptions.executionId || uuid();
|
|
3159
|
+
this.options.executionIndex = this.initialOptions.executionIndex ?? 0;
|
|
3160
|
+
this.#checksum = await this.generateChecksum();
|
|
3161
|
+
const result = this.configFile.config && toArray(this.configFile.config).length > this.options.executionIndex ? toArray(this.configFile.config)[this.options.executionIndex] : this.configFile.config;
|
|
3162
|
+
if (!result) this.logger.warn(`No configuration found in ${this.options.configFile} for execution index ${this.options.executionIndex}.`);
|
|
3163
|
+
else await this.setUserConfig(isFunction(result) ? await Promise.resolve(result(this.options)) : result);
|
|
3189
3164
|
}
|
|
3190
3165
|
/**
|
|
3191
3166
|
* Initialize the context with the provided configuration options
|
|
3192
3167
|
*/
|
|
3193
|
-
async
|
|
3194
|
-
const
|
|
3195
|
-
this.
|
|
3196
|
-
|
|
3168
|
+
async resolveConfig() {
|
|
3169
|
+
const mergedConfig = this.mergeConfig();
|
|
3170
|
+
this.logger.trace({
|
|
3171
|
+
meta: { category: "config" },
|
|
3172
|
+
message: `Pre-setup Powerlines configuration object: \n --- Pre-Resolved Config --- \n${this.logConfig(mergedConfig)} \n --- Initial Config --- \n${this.logConfig(this.initialConfig)} \n --- User Config --- \n${this.logConfig(this.userConfig)} \n --- Inline Config --- \n${this.logConfig(this.inlineConfig)} \n --- Plugin Config --- \n${this.logConfig(this.pluginConfig)}`
|
|
3173
|
+
});
|
|
3174
|
+
mergedConfig.output = defu(mergedConfig.output ?? {}, {
|
|
3197
3175
|
copy: { assets: [
|
|
3198
3176
|
{ glob: "LICENSE" },
|
|
3199
3177
|
{
|
|
3200
|
-
input:
|
|
3178
|
+
input: mergedConfig.root,
|
|
3201
3179
|
glob: "*.md"
|
|
3202
3180
|
},
|
|
3203
3181
|
{
|
|
3204
|
-
input:
|
|
3182
|
+
input: mergedConfig.root,
|
|
3205
3183
|
glob: "package.json"
|
|
3206
3184
|
}
|
|
3207
3185
|
] },
|
|
3208
3186
|
dts: true
|
|
3209
3187
|
});
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
if (!this.initialOptions.mode && !this.config.userConfig?.mode && !this.config.inlineConfig?.mode && !this.config.initialConfig?.mode && !this.config.pluginConfig?.mode) {
|
|
3224
|
-
this.options.mode = "production";
|
|
3225
|
-
this.config.mode = "production";
|
|
3226
|
-
}
|
|
3227
|
-
if (!this.initialOptions.framework && !this.config.userConfig?.framework && !this.config.inlineConfig?.framework && !this.config.initialConfig?.framework && !this.config.pluginConfig?.framework) {
|
|
3228
|
-
this.options.framework = "powerlines";
|
|
3229
|
-
this.config.framework = "powerlines";
|
|
3230
|
-
}
|
|
3231
|
-
if (!this.config.userConfig?.projectType && !this.config.inlineConfig?.projectType && !this.config.initialConfig?.projectType && !this.config.pluginConfig?.projectType) this.config.projectType = "application";
|
|
3232
|
-
if (!this.config.userConfig?.platform && !this.config.inlineConfig?.platform && !this.config.initialConfig?.platform && !this.config.pluginConfig?.platform) this.config.platform = "neutral";
|
|
3233
|
-
this.config.compatibilityDate = resolveCompatibilityDates(this.config.inlineConfig.compatibilityDate ?? this.config.userConfig.compatibilityDate ?? this.config.initialConfig.compatibilityDate ?? this.config.pluginConfig.compatibilityDate, "latest");
|
|
3234
|
-
this.config.input = getUniqueInputs(this.config.input);
|
|
3235
|
-
if (this.config.name?.startsWith("@") && this.config.name.split("/").filter(Boolean).length > 1) this.config.name = this.config.name.split("/").filter(Boolean)[1];
|
|
3236
|
-
this.config.title ??= titleCase(this.config.name);
|
|
3237
|
-
if (this.config.resolve.external) this.config.resolve.external = getUnique(this.config.resolve.external);
|
|
3238
|
-
if (this.config.resolve.noExternal) this.config.resolve.noExternal = getUnique(this.config.resolve.noExternal);
|
|
3239
|
-
this.config.plugins = (this.config.plugins ?? []).flatMap((plugin) => toArray(plugin)).filter(Boolean).reduce((ret, plugin) => {
|
|
3188
|
+
if (!mergedConfig.mode) mergedConfig.mode = "production";
|
|
3189
|
+
if (!mergedConfig.framework) mergedConfig.framework = "powerlines";
|
|
3190
|
+
if (!mergedConfig.projectType) mergedConfig.projectType = "application";
|
|
3191
|
+
if (!mergedConfig.platform) mergedConfig.platform = "neutral";
|
|
3192
|
+
mergedConfig.compatibilityDate = resolveCompatibilityDates(mergedConfig.compatibilityDate, "latest");
|
|
3193
|
+
this.resolvedConfig = mergedConfig;
|
|
3194
|
+
this.#configProxy = this.createConfigProxy();
|
|
3195
|
+
mergedConfig.input = getUniqueInputs(mergedConfig.input);
|
|
3196
|
+
if (mergedConfig.name?.startsWith("@") && mergedConfig.name.split("/").filter(Boolean).length > 1) mergedConfig.name = mergedConfig.name.split("/").filter(Boolean)[1];
|
|
3197
|
+
mergedConfig.title ??= titleCase(mergedConfig.name);
|
|
3198
|
+
if (mergedConfig.resolve.external) mergedConfig.resolve.external = getUnique(mergedConfig.resolve.external);
|
|
3199
|
+
if (mergedConfig.resolve.noExternal) mergedConfig.resolve.noExternal = getUnique(mergedConfig.resolve.noExternal);
|
|
3200
|
+
mergedConfig.plugins = (mergedConfig.plugins ?? []).flatMap((plugin) => toArray(plugin)).filter(Boolean).reduce((ret, plugin) => {
|
|
3240
3201
|
if (isPlugin(plugin) && isDuplicate(plugin, ret.filter((p) => isPlugin(p)))) return ret;
|
|
3241
3202
|
ret.push(plugin);
|
|
3242
3203
|
return ret;
|
|
3243
3204
|
}, []);
|
|
3244
|
-
if (!
|
|
3245
|
-
else if (
|
|
3246
|
-
else
|
|
3247
|
-
if (
|
|
3248
|
-
else
|
|
3249
|
-
|
|
3250
|
-
if (
|
|
3251
|
-
else
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
if (this.config.output.types !== false) this.config.output.types = appendPath(replacePathTokens(this, this.config.userConfig?.output?.types || this.config.inlineConfig?.output?.types || this.config.initialConfig?.output?.types || this.config.pluginConfig?.output?.types || joinPaths$1(this.config.root, `${this.config.framework ?? "powerlines"}.d.ts`)), this.config.cwd);
|
|
3258
|
-
if (this.config.output.copy && this.config.output.copy.path && this.config.output.copy.assets && Array.isArray(this.config.output.copy.assets)) this.config.output.copy.assets = getUniqueBy(this.config.output.copy.assets.map((asset) => {
|
|
3205
|
+
if (!mergedConfig.logLevel) if (mergedConfig.mode === "development") mergedConfig.logLevel = DEFAULT_DEVELOPMENT_LOG_LEVEL;
|
|
3206
|
+
else if (mergedConfig.mode === "test") mergedConfig.logLevel = DEFAULT_TEST_LOG_LEVEL;
|
|
3207
|
+
else mergedConfig.logLevel = DEFAULT_PRODUCTION_LOG_LEVEL;
|
|
3208
|
+
if (mergedConfig.tsconfig) mergedConfig.tsconfig = replacePath(replacePathTokens(this, mergedConfig.tsconfig), mergedConfig.cwd);
|
|
3209
|
+
else mergedConfig.tsconfig = getTsconfigFilePath(mergedConfig.cwd, mergedConfig.root);
|
|
3210
|
+
mergedConfig.output.format = getUnique(toArray(mergedConfig.output?.format ?? (mergedConfig.projectType === "library" ? ["cjs", "esm"] : ["esm"])));
|
|
3211
|
+
if (mergedConfig.output.path) mergedConfig.output.path = appendPath(replacePathTokens(this, mergedConfig.output.path), mergedConfig.cwd);
|
|
3212
|
+
else mergedConfig.output.path = appendPath(joinPaths$1(mergedConfig.root, "dist"), mergedConfig.cwd);
|
|
3213
|
+
mergedConfig.output.copy ??= {};
|
|
3214
|
+
if (mergedConfig.output.copy !== false) if (!mergedConfig.root.replace(/^\.\/?/, "")) mergedConfig.output.copy.path = mergedConfig.output.copy.path ? appendPath(replacePathTokens(this, mergedConfig.output.copy.path), mergedConfig.cwd) : mergedConfig.output.path;
|
|
3215
|
+
else mergedConfig.output.copy.path = appendPath(replacePathTokens(this, mergedConfig.output.copy.path || joinPaths$1("dist", mergedConfig.root)), mergedConfig.cwd);
|
|
3216
|
+
if (mergedConfig.output.types !== false) mergedConfig.output.types = appendPath(replacePathTokens(this, mergedConfig.output.types || joinPaths$1(mergedConfig.root, `${mergedConfig.framework ?? "powerlines"}.d.ts`)), mergedConfig.cwd);
|
|
3217
|
+
if (mergedConfig.output.copy && mergedConfig.output.copy.path && mergedConfig.output.copy.assets && Array.isArray(mergedConfig.output.copy.assets)) mergedConfig.output.copy.assets = getUniqueBy(mergedConfig.output.copy.assets.map((asset) => {
|
|
3259
3218
|
return {
|
|
3260
3219
|
glob: isSetObject(asset) ? asset.glob : asset,
|
|
3261
|
-
input: isString(asset) || !asset.input || asset.input === "." || asset.input === "/" || asset.input === "./" ?
|
|
3262
|
-
output: isSetObject(asset) && asset.output ? isParentPath(asset.output,
|
|
3220
|
+
input: isString(asset) || !asset.input || asset.input === "." || asset.input === "/" || asset.input === "./" ? mergedConfig.cwd : isParentPath(asset.input, mergedConfig.cwd) || isEqual(asset.input, mergedConfig.cwd) ? asset.input : appendPath(asset.input, mergedConfig.cwd),
|
|
3221
|
+
output: isSetObject(asset) && asset.output ? isParentPath(asset.output, mergedConfig.cwd) ? asset.output : appendPath(joinPaths$1(mergedConfig.output.copy.path, replacePath(replacePath(asset.output, replacePath(mergedConfig.output.copy.path, mergedConfig.cwd)), mergedConfig.output.copy.path)), mergedConfig.cwd) : appendPath(mergedConfig.output.copy.path, mergedConfig.cwd),
|
|
3263
3222
|
ignore: isSetObject(asset) && asset.ignore ? toArray(asset.ignore) : void 0
|
|
3264
3223
|
};
|
|
3265
3224
|
}), (a) => `${a.input}-${a.glob}-${a.output}`);
|
|
3266
|
-
if (!
|
|
3267
|
-
else
|
|
3268
|
-
if (!
|
|
3269
|
-
else
|
|
3270
|
-
if (!
|
|
3271
|
-
if (
|
|
3225
|
+
if (!mergedConfig.output?.sourceMap) if (mergedConfig.mode === "development") mergedConfig.output.sourceMap = true;
|
|
3226
|
+
else mergedConfig.output.sourceMap = false;
|
|
3227
|
+
if (!mergedConfig.output.minify) if (mergedConfig.mode === "production") mergedConfig.output.minify = true;
|
|
3228
|
+
else mergedConfig.output.minify = false;
|
|
3229
|
+
if (!mergedConfig.output.artifactsPath) mergedConfig.output.artifactsPath = `.${mergedConfig.framework || "powerlines"}`;
|
|
3230
|
+
if (mergedConfig.output.copy && mergedConfig.output.copy.assets) mergedConfig.output.copy.assets = mergedConfig.output.copy.assets.map((asset) => ({
|
|
3272
3231
|
...asset,
|
|
3273
3232
|
glob: replacePathTokens(this, asset.glob),
|
|
3274
3233
|
ignore: asset.ignore ? asset.ignore.map((ignore) => replacePathTokens(this, ignore)) : void 0,
|
|
3275
3234
|
input: replacePathTokens(this, asset.input),
|
|
3276
3235
|
output: replacePathTokens(this, asset.output)
|
|
3277
3236
|
}));
|
|
3278
|
-
if (isSetString(
|
|
3237
|
+
if (isSetString(mergedConfig.output?.storage) && mergedConfig.output.storage === "virtual" || isSetObject(mergedConfig.output?.storage) && Object.values(mergedConfig.output.storage).every((adapter) => adapter.preset === "virtual")) mergedConfig.output.overwrite = true;
|
|
3238
|
+
this.resolvedConfig = mergedConfig;
|
|
3239
|
+
this.#configProxy = this.createConfigProxy();
|
|
3240
|
+
this.logger.debug({
|
|
3241
|
+
meta: { category: "config" },
|
|
3242
|
+
message: `Resolved Powerlines configuration object: \n --- Resolved Config --- \n${this.logConfig(this.resolvedConfig)} \n --- Initial Config --- \n${this.logConfig(this.initialConfig)} \n --- User Config --- \n${this.logConfig(this.userConfig)} \n --- Inline Config --- \n${this.logConfig(this.inlineConfig)} \n --- Plugin Config --- \n${this.logConfig(this.pluginConfig)}`
|
|
3243
|
+
});
|
|
3279
3244
|
this.#fs ??= await VirtualFileSystem.create(this);
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3245
|
+
}
|
|
3246
|
+
logConfig(config) {
|
|
3247
|
+
return formatLogMessage({
|
|
3248
|
+
...omit(config, ["plugins"]),
|
|
3249
|
+
plugins: config.plugins ? config.plugins.flatMap((plugin) => toArray(plugin)).map((plugin) => String(isSetString(plugin) ? plugin : isPromise(plugin) ? "<promise>" : isFunction(plugin) ? plugin.name || "<anonymous function>" : Array.isArray(plugin) ? plugin[0] || "<anonymous function plugin>" : "<unknown plugin>")) : void 0
|
|
3250
|
+
});
|
|
3251
|
+
}
|
|
3252
|
+
createConfigProxy() {
|
|
3253
|
+
return new Proxy(this.resolvedConfig, {
|
|
3254
|
+
/**
|
|
3255
|
+
* A trap for the `delete` operator.
|
|
3256
|
+
* @param target - The original object which is being proxied.
|
|
3257
|
+
* @param key - The name or `Symbol` of the property to delete.
|
|
3258
|
+
* @returns A `boolean` indicating whether or not the property was deleted.
|
|
3259
|
+
*/
|
|
3260
|
+
deleteProperty: (target, key) => {
|
|
3261
|
+
if (UNRESOLVED_CONFIG_NAMES.includes(key.toString())) throw new Error(`Cannot delete property ${key.toString()} from config - it is only intended to be used as a reference.`);
|
|
3262
|
+
Reflect.deleteProperty(this.overriddenConfig, key);
|
|
3263
|
+
return Reflect.deleteProperty(target, key);
|
|
3264
|
+
},
|
|
3265
|
+
/**
|
|
3266
|
+
* A trap for getting a property value.
|
|
3267
|
+
* @param target - The original object which is being proxied.
|
|
3268
|
+
* @param key - The name or `Symbol` of the property to get.
|
|
3269
|
+
* @param receiver - The proxy or an object that inherits from the proxy.
|
|
3270
|
+
*/
|
|
3271
|
+
get: (target, key, receiver) => {
|
|
3272
|
+
if (UNRESOLVED_CONFIG_NAMES.includes(key.toString())) {
|
|
3273
|
+
if (key === "initialConfig") return this.initialConfig;
|
|
3274
|
+
if (key === "userConfig") return this.userConfig;
|
|
3275
|
+
if (key === "inlineConfig") return this.inlineConfig;
|
|
3276
|
+
if (key === "pluginConfig") return this.pluginConfig;
|
|
3277
|
+
}
|
|
3278
|
+
return Reflect.get(target, key, receiver);
|
|
3279
|
+
},
|
|
3280
|
+
/**
|
|
3281
|
+
* A trap for the `in` operator.
|
|
3282
|
+
* @param target - The original object which is being proxied.
|
|
3283
|
+
* @param key - The name or `Symbol` of the property to check for existence.
|
|
3284
|
+
*/
|
|
3285
|
+
has: (target, key) => {
|
|
3286
|
+
return Reflect.has(target, key) || UNRESOLVED_CONFIG_NAMES.includes(key.toString());
|
|
3287
|
+
},
|
|
3288
|
+
/**
|
|
3289
|
+
* A trap for `Reflect.ownKeys()`.
|
|
3290
|
+
* @param target - The original object which is being proxied.
|
|
3291
|
+
*/
|
|
3292
|
+
ownKeys: (target) => {
|
|
3293
|
+
return getUnique([...Reflect.ownKeys(target), ...UNRESOLVED_CONFIG_NAMES]);
|
|
3294
|
+
},
|
|
3295
|
+
/**
|
|
3296
|
+
* A trap for setting a property value.
|
|
3297
|
+
* @param target - The original object which is being proxied.
|
|
3298
|
+
* @param key - The name or `Symbol` of the property to set.
|
|
3299
|
+
* @param newValue - The new value to assign to the property.
|
|
3300
|
+
* @param receiver - The object to which the assignment was originally directed.
|
|
3301
|
+
* @returns A `boolean` indicating whether or not the property was set.
|
|
3302
|
+
*/
|
|
3303
|
+
set: (target, key, newValue, receiver) => {
|
|
3304
|
+
if (UNRESOLVED_CONFIG_NAMES.includes(key.toString())) throw new Error(`Cannot change property ${key.toString()} from config - it is only intended to be used as a reference.`);
|
|
3305
|
+
Reflect.set(this.overriddenConfig, key, newValue, receiver);
|
|
3306
|
+
return Reflect.set(target, key, newValue, receiver);
|
|
3307
|
+
}
|
|
3308
|
+
});
|
|
3293
3309
|
}
|
|
3294
3310
|
};
|
|
3295
3311
|
|
|
@@ -3434,7 +3450,7 @@ function createPluginContext(pluginId, plugin, environment) {
|
|
|
3434
3450
|
return {
|
|
3435
3451
|
meta: {
|
|
3436
3452
|
...isSetObject(message) ? message.meta : {},
|
|
3437
|
-
environment: environment.environment
|
|
3453
|
+
environment: environment.config.environment.name,
|
|
3438
3454
|
plugin: plugin.name
|
|
3439
3455
|
},
|
|
3440
3456
|
message: isString(message) ? message : message.message
|
|
@@ -3457,6 +3473,8 @@ function createPluginContext(pluginId, plugin, environment) {
|
|
|
3457
3473
|
callHook: callHookFn,
|
|
3458
3474
|
meta
|
|
3459
3475
|
};
|
|
3476
|
+
if (prop === "api") return environment.$$internal.api;
|
|
3477
|
+
if (prop === "environment") return environment;
|
|
3460
3478
|
if (prop === "id") return pluginId;
|
|
3461
3479
|
if (prop === "logger") return logger;
|
|
3462
3480
|
if (prop === "log") return (type, message) => {
|
|
@@ -3509,6 +3527,15 @@ function createPluginContext(pluginId, plugin, environment) {
|
|
|
3509
3527
|
//#endregion
|
|
3510
3528
|
//#region src/context/environment-context.ts
|
|
3511
3529
|
var PowerlinesEnvironmentContext = class PowerlinesEnvironmentContext extends PowerlinesContext {
|
|
3530
|
+
/**
|
|
3531
|
+
* Internal references storage
|
|
3532
|
+
*
|
|
3533
|
+
* @danger
|
|
3534
|
+
* This field is for internal use only and should not be accessed or modified directly. It is unstable and can be changed at anytime.
|
|
3535
|
+
*
|
|
3536
|
+
* @internal
|
|
3537
|
+
*/
|
|
3538
|
+
#internal = {};
|
|
3512
3539
|
/**
|
|
3513
3540
|
* The hooks registered by plugins in this environment
|
|
3514
3541
|
*/
|
|
@@ -3518,37 +3545,72 @@ var PowerlinesEnvironmentContext = class PowerlinesEnvironmentContext extends Po
|
|
|
3518
3545
|
*
|
|
3519
3546
|
* @param options - The resolved execution options.
|
|
3520
3547
|
* @param config - The user configuration options.
|
|
3521
|
-
* @
|
|
3548
|
+
* @param overriddenConfig - The configuration options that should override all other configuration sources, such as CLI flags or environment variables. This is used to ensure that certain configuration values take precedence over any other settings defined in the user configuration or environment configuration, allowing for dynamic overrides based on the execution context.
|
|
3549
|
+
* @param environment - The resolved environment configuration, which may include additional properties or modifications made during the configuration loading process. This is used to provide context about the environment in which the command is being executed, allowing for environment-specific behavior and configuration resolution.
|
|
3550
|
+
* @returns A promise that resolves to an instance of the PowerlinesEnvironmentContext class, initialized with the provided configuration and environment data.
|
|
3522
3551
|
*/
|
|
3523
|
-
static async
|
|
3524
|
-
const context = new PowerlinesEnvironmentContext(options, config,
|
|
3525
|
-
await context.
|
|
3526
|
-
const powerlinesPath = await resolvePackage("powerlines");
|
|
3527
|
-
if (!powerlinesPath) throw new Error("Could not resolve `powerlines` package location.");
|
|
3528
|
-
context.powerlinesPath = powerlinesPath;
|
|
3552
|
+
static async createEnvironment(options, config, overriddenConfig, environment) {
|
|
3553
|
+
const context = new PowerlinesEnvironmentContext(options, config, overriddenConfig);
|
|
3554
|
+
await context.setEnvironmentConfig(environment);
|
|
3529
3555
|
return context;
|
|
3530
3556
|
}
|
|
3531
3557
|
/**
|
|
3532
|
-
* The
|
|
3558
|
+
* The configuration options provided by plugins added by the user (and other plugins)
|
|
3533
3559
|
*/
|
|
3534
|
-
|
|
3560
|
+
environmentConfig = {};
|
|
3535
3561
|
/**
|
|
3536
3562
|
* The list of plugins applied to this environment
|
|
3537
3563
|
*/
|
|
3538
3564
|
plugins = [];
|
|
3539
3565
|
/**
|
|
3540
|
-
*
|
|
3566
|
+
* Internal context fields and methods
|
|
3567
|
+
*
|
|
3568
|
+
* @danger
|
|
3569
|
+
* This field is for internal use only and should not be accessed or modified directly. It is unstable and can be changed at anytime.
|
|
3570
|
+
*
|
|
3571
|
+
* @internal
|
|
3541
3572
|
*/
|
|
3542
|
-
get
|
|
3543
|
-
return this
|
|
3573
|
+
get $$internal() {
|
|
3574
|
+
return this.#internal;
|
|
3544
3575
|
}
|
|
3545
3576
|
/**
|
|
3546
|
-
*
|
|
3577
|
+
* Internal context fields and methods
|
|
3578
|
+
*
|
|
3579
|
+
* @danger
|
|
3580
|
+
* This field is for internal use only and should not be accessed or modified directly. It is unstable and can be changed at anytime.
|
|
3581
|
+
*
|
|
3582
|
+
* @internal
|
|
3583
|
+
*/
|
|
3584
|
+
set $$internal(value) {
|
|
3585
|
+
this.#internal = value;
|
|
3586
|
+
}
|
|
3587
|
+
/**
|
|
3588
|
+
* The unique identifier of the environment associated with this context, which can be used for logging and other purposes to distinguish between different environments in the same process.
|
|
3589
|
+
*/
|
|
3590
|
+
get id() {
|
|
3591
|
+
return this.config.environment.id;
|
|
3592
|
+
}
|
|
3593
|
+
/**
|
|
3594
|
+
* The hooks registered by plugins in this environment
|
|
3547
3595
|
*/
|
|
3548
3596
|
get hooks() {
|
|
3549
3597
|
return this.#hooks;
|
|
3550
3598
|
}
|
|
3551
3599
|
/**
|
|
3600
|
+
* A setter function to populate the environment config values provided during execution of the command, such as CLI flags or other parameters that may be relevant to the command being executed. This function can be used to update the context with the environment configuration values, which may be used during the configuration resolution process to ensure that the final configuration reflects both the user configuration and any environment configuration provided during execution.
|
|
3601
|
+
*
|
|
3602
|
+
* @param config - The environment configuration values to set.
|
|
3603
|
+
* @returns A promise that resolves when the environment configuration values have been set.
|
|
3604
|
+
*/
|
|
3605
|
+
async setEnvironmentConfig(config) {
|
|
3606
|
+
this.logger.debug({
|
|
3607
|
+
meta: { category: "config" },
|
|
3608
|
+
message: `Updating environment configuration object: \n${this.logConfig(config)}`
|
|
3609
|
+
});
|
|
3610
|
+
this.environmentConfig = config;
|
|
3611
|
+
await this.resolveConfig();
|
|
3612
|
+
}
|
|
3613
|
+
/**
|
|
3552
3614
|
* Create a new logger instance
|
|
3553
3615
|
*
|
|
3554
3616
|
* @param options - The configuration options to use for the logger instance, which can be used to customize the appearance and behavior of the log messages generated by the logger. This is typically the name of the plugin or module that is creating the logger instance.
|
|
@@ -3558,7 +3620,7 @@ var PowerlinesEnvironmentContext = class PowerlinesEnvironmentContext extends Po
|
|
|
3558
3620
|
createLogger(options, logFn) {
|
|
3559
3621
|
return super.createLogger({
|
|
3560
3622
|
...options,
|
|
3561
|
-
environment: this.environment?.name
|
|
3623
|
+
environment: this.config.environment?.name
|
|
3562
3624
|
}, logFn);
|
|
3563
3625
|
}
|
|
3564
3626
|
/**
|
|
@@ -3570,39 +3632,13 @@ var PowerlinesEnvironmentContext = class PowerlinesEnvironmentContext extends Po
|
|
|
3570
3632
|
extendLogger(options) {
|
|
3571
3633
|
return super.extendLogger({
|
|
3572
3634
|
...options,
|
|
3573
|
-
environment: this.environment?.name
|
|
3635
|
+
environment: this.config.environment?.name
|
|
3574
3636
|
});
|
|
3575
3637
|
}
|
|
3576
|
-
/**
|
|
3577
|
-
* Creates a clone of the current context with the same configuration and workspace settings. This can be useful for running multiple builds in parallel or for creating isolated contexts for different parts of the build process.
|
|
3578
|
-
*
|
|
3579
|
-
* @remarks
|
|
3580
|
-
* The cloned context will have the same configuration and workspace settings as the original context, but will have a different build ID, release ID, and timestamp. The virtual file system and caches will also be separate between the original and cloned contexts.
|
|
3581
|
-
*
|
|
3582
|
-
* @returns A promise that resolves to the cloned context.
|
|
3583
|
-
*/
|
|
3584
|
-
async clone() {
|
|
3585
|
-
const context = await PowerlinesEnvironmentContext.fromConfig(deepClone(this.options), deepClone(this.config), deepClone(this.environment));
|
|
3586
|
-
return this.copyTo(context);
|
|
3587
|
-
}
|
|
3588
|
-
/**
|
|
3589
|
-
* Initialize the context with the provided configuration options
|
|
3590
|
-
*/
|
|
3591
|
-
async setup() {
|
|
3592
|
-
this.resolvedConfig = mergeConfig({
|
|
3593
|
-
name: this.config.name,
|
|
3594
|
-
title: this.config.title
|
|
3595
|
-
}, getConfigProps({
|
|
3596
|
-
...this.environment,
|
|
3597
|
-
root: this.options.root,
|
|
3598
|
-
cwd: this.options.cwd
|
|
3599
|
-
}), this.config);
|
|
3600
|
-
await this.innerSetup();
|
|
3601
|
-
}
|
|
3602
3638
|
async addPlugin(plugin) {
|
|
3603
3639
|
let resolvedPlugin = plugin;
|
|
3604
3640
|
if (isFunction(plugin.applyToEnvironment)) {
|
|
3605
|
-
const result = await Promise.resolve(plugin.applyToEnvironment(this.environment));
|
|
3641
|
+
const result = await Promise.resolve(plugin.applyToEnvironment(this.config.environment));
|
|
3606
3642
|
if (!result || isObject(result) && Object.keys(result).length === 0) return;
|
|
3607
3643
|
if (isPluginConfig(result)) return this.$$internal.addPlugin(result);
|
|
3608
3644
|
resolvedPlugin = isPlugin(result) ? result : plugin;
|
|
@@ -3653,29 +3689,51 @@ var PowerlinesEnvironmentContext = class PowerlinesEnvironmentContext extends Po
|
|
|
3653
3689
|
}
|
|
3654
3690
|
return result;
|
|
3655
3691
|
}
|
|
3656
|
-
constructor(options, config,
|
|
3657
|
-
super(options);
|
|
3658
|
-
this.
|
|
3659
|
-
this.
|
|
3692
|
+
constructor(options, config, overriddenConfig) {
|
|
3693
|
+
super(options, config.initialConfig);
|
|
3694
|
+
this.userConfig = config.userConfig ?? {};
|
|
3695
|
+
this.inlineConfig = config.inlineConfig ?? {};
|
|
3696
|
+
this.pluginConfig = config.pluginConfig ?? {};
|
|
3697
|
+
this.overriddenConfig = overriddenConfig;
|
|
3660
3698
|
}
|
|
3661
3699
|
/**
|
|
3662
|
-
*
|
|
3700
|
+
* A function to merge the various configuration objects (initial, user, inline, and plugin) into a single resolved configuration object that can be used throughout the Powerlines process. This function takes into account the different sources of configuration and their respective priorities, ensuring that the final configuration reflects the intended settings for the project. The merged configuration is then returned as a new object that can be accessed through the `config` property of the context.
|
|
3663
3701
|
*
|
|
3664
|
-
* @
|
|
3665
|
-
* The cloned context will have the same configuration and workspace settings as the original context, but will have a different build ID, release ID, and timestamp. The virtual file system and caches will also be separate between the original and cloned contexts.
|
|
3666
|
-
*
|
|
3667
|
-
* @returns The cloned context.
|
|
3702
|
+
* @returns The merged configuration object that combines the initial, user, inline, and plugin configurations.
|
|
3668
3703
|
*/
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3704
|
+
mergeConfig() {
|
|
3705
|
+
return mergeConfig({
|
|
3706
|
+
...omit(this.environmentConfig ?? {}, [
|
|
3707
|
+
"ssr",
|
|
3708
|
+
"preview",
|
|
3709
|
+
"consumer",
|
|
3710
|
+
"runtime"
|
|
3711
|
+
]),
|
|
3712
|
+
environment: { name: this.environmentConfig?.name || DEFAULT_ENVIRONMENT },
|
|
3713
|
+
environmentConfig: this.environmentConfig ?? {}
|
|
3714
|
+
}, super.mergeConfig());
|
|
3672
3715
|
}
|
|
3673
3716
|
};
|
|
3674
3717
|
|
|
3675
3718
|
//#endregion
|
|
3676
3719
|
//#region src/context/execution-context.ts
|
|
3677
3720
|
var PowerlinesExecutionContext = class PowerlinesExecutionContext extends PowerlinesContext {
|
|
3721
|
+
/**
|
|
3722
|
+
* Internal references storage
|
|
3723
|
+
*
|
|
3724
|
+
* @danger
|
|
3725
|
+
* This field is for internal use only and should not be accessed or modified directly. It is unstable and can be changed at anytime.
|
|
3726
|
+
*
|
|
3727
|
+
* @internal
|
|
3728
|
+
*/
|
|
3729
|
+
#internal = {};
|
|
3730
|
+
/**
|
|
3731
|
+
* A record of all environments by name
|
|
3732
|
+
*/
|
|
3678
3733
|
#environments = {};
|
|
3734
|
+
/**
|
|
3735
|
+
* The plugins added to this execution context, which may be used to track the plugins that have been added to the context and ensure that they are properly registered and executed during the build process. This field is for internal use only and should not be accessed or modified directly. It is unstable and can be changed at anytime.
|
|
3736
|
+
*/
|
|
3679
3737
|
#plugins = [];
|
|
3680
3738
|
/**
|
|
3681
3739
|
* Create a new Storm context from the workspace root and user config.
|
|
@@ -3683,13 +3741,9 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3683
3741
|
* @param options - The options for resolving the context.
|
|
3684
3742
|
* @returns A promise that resolves to the new context.
|
|
3685
3743
|
*/
|
|
3686
|
-
static async
|
|
3687
|
-
const context = new PowerlinesExecutionContext(options);
|
|
3688
|
-
await context.init(
|
|
3689
|
-
const powerlinesPath = await resolvePackage("powerlines");
|
|
3690
|
-
if (!powerlinesPath) throw new Error("Could not resolve `powerlines` package location.");
|
|
3691
|
-
context.powerlinesPath = powerlinesPath;
|
|
3692
|
-
await context.setup();
|
|
3744
|
+
static async fromInitialConfig(options, initialConfig) {
|
|
3745
|
+
const context = new PowerlinesExecutionContext(options, initialConfig);
|
|
3746
|
+
await context.init();
|
|
3693
3747
|
return context;
|
|
3694
3748
|
}
|
|
3695
3749
|
/**
|
|
@@ -3698,19 +3752,10 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3698
3752
|
* @param options - The options for resolving the context.
|
|
3699
3753
|
* @returns A promise that resolves to the new context.
|
|
3700
3754
|
*/
|
|
3701
|
-
static async
|
|
3702
|
-
const context = new PowerlinesExecutionContext(options);
|
|
3703
|
-
await context.init(
|
|
3704
|
-
context.
|
|
3705
|
-
if (context.config.inlineConfig.command === "new") {
|
|
3706
|
-
const workspacePackageJsonPath = joinPaths$1(context.config.cwd, "package.json");
|
|
3707
|
-
if (!existsSync(workspacePackageJsonPath)) throw new Error(`The workspace package.json file could not be found at ${workspacePackageJsonPath}`);
|
|
3708
|
-
context.packageJson = await readJsonFile(workspacePackageJsonPath);
|
|
3709
|
-
}
|
|
3710
|
-
await context.setup();
|
|
3711
|
-
const powerlinesPath = await resolvePackage("powerlines");
|
|
3712
|
-
if (!powerlinesPath) throw new Error("Could not resolve `powerlines` package location.");
|
|
3713
|
-
context.powerlinesPath = powerlinesPath;
|
|
3755
|
+
static async fromInlineConfig(options, initialConfig, inlineConfig) {
|
|
3756
|
+
const context = new PowerlinesExecutionContext(options, initialConfig);
|
|
3757
|
+
await context.init();
|
|
3758
|
+
await context.setInlineConfig(inlineConfig);
|
|
3714
3759
|
return context;
|
|
3715
3760
|
}
|
|
3716
3761
|
/**
|
|
@@ -3722,7 +3767,7 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3722
3767
|
* @internal
|
|
3723
3768
|
*/
|
|
3724
3769
|
get $$internal() {
|
|
3725
|
-
return
|
|
3770
|
+
return this.#internal;
|
|
3726
3771
|
}
|
|
3727
3772
|
/**
|
|
3728
3773
|
* Internal context fields and methods
|
|
@@ -3733,8 +3778,8 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3733
3778
|
* @internal
|
|
3734
3779
|
*/
|
|
3735
3780
|
set $$internal(value) {
|
|
3736
|
-
|
|
3737
|
-
for (const environment of Object.values(this.environments)) environment.$$internal =
|
|
3781
|
+
this.#internal = value;
|
|
3782
|
+
for (const environment of Object.values(this.environments)) environment.$$internal = value;
|
|
3738
3783
|
}
|
|
3739
3784
|
/**
|
|
3740
3785
|
* The unique identifier of the execution context, which can be used for logging and other purposes to distinguish between different executions in the same process.
|
|
@@ -3755,9 +3800,26 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3755
3800
|
* Creates a new instance.
|
|
3756
3801
|
*
|
|
3757
3802
|
* @param options - The options to use for creating the context, including the resolved configuration and workspace settings.
|
|
3803
|
+
* @param initialConfig - The initial configuration options to use for the context, which can be used to provide default values for configuration options that may be overridden by user configuration or inline configuration. This is typically the configuration options provided by the user in a configuration file on disk, and can include any relevant settings such as environment definitions, plugin configurations, and other parameters that may be relevant to the execution of a Powerlines command.
|
|
3804
|
+
*/
|
|
3805
|
+
constructor(options, initialConfig = {}) {
|
|
3806
|
+
super(options, initialConfig);
|
|
3807
|
+
this.initialOptions = options;
|
|
3808
|
+
this.initialConfig = initialConfig;
|
|
3809
|
+
}
|
|
3810
|
+
/**
|
|
3811
|
+
* A setter function to populate the inline config values provided during execution of the command, such as CLI flags or other parameters that may be relevant to the command being executed. This function can be used to update the context with the inline configuration values, which may be used during the configuration resolution process to ensure that the final configuration reflects both the user configuration and any inline configuration provided during execution.
|
|
3812
|
+
*
|
|
3813
|
+
* @param config - The inline configuration values to set.
|
|
3814
|
+
* @returns A promise that resolves when the inline configuration values have been set.
|
|
3758
3815
|
*/
|
|
3759
|
-
|
|
3760
|
-
super(
|
|
3816
|
+
async setInlineConfig(config) {
|
|
3817
|
+
await super.setInlineConfig(config);
|
|
3818
|
+
if (this.inlineConfig.command === "new") {
|
|
3819
|
+
const workspacePackageJsonPath = joinPaths$1(this.config.cwd, "package.json");
|
|
3820
|
+
if (!existsSync(workspacePackageJsonPath)) throw new Error(`The workspace package.json file could not be found at ${workspacePackageJsonPath}`);
|
|
3821
|
+
this.packageJson = await readJsonFile(workspacePackageJsonPath);
|
|
3822
|
+
}
|
|
3761
3823
|
}
|
|
3762
3824
|
/**
|
|
3763
3825
|
* Create a new logger instance
|
|
@@ -3787,31 +3849,20 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3787
3849
|
});
|
|
3788
3850
|
}
|
|
3789
3851
|
/**
|
|
3790
|
-
* Creates a clone of the current context with the same configuration and workspace settings. This can be useful for running multiple builds in parallel or for creating isolated contexts for different parts of the build process.
|
|
3791
|
-
*
|
|
3792
|
-
* @remarks
|
|
3793
|
-
* The cloned context will have the same configuration and workspace settings as the original context, but will have a different build ID, release ID, and timestamp. The virtual file system and caches will also be separate between the original and cloned contexts.
|
|
3794
|
-
*
|
|
3795
|
-
* @returns A promise that resolves to the cloned context.
|
|
3796
|
-
*/
|
|
3797
|
-
async clone() {
|
|
3798
|
-
const clone = await PowerlinesExecutionContext.init(this.options, this.initialConfig);
|
|
3799
|
-
clone.config.userConfig = deepClone(this.config.userConfig);
|
|
3800
|
-
clone.config.initialConfig = deepClone(this.config.initialConfig);
|
|
3801
|
-
clone.config.inlineConfig = deepClone(this.config.inlineConfig);
|
|
3802
|
-
clone.config.pluginConfig = deepClone(this.config.pluginConfig);
|
|
3803
|
-
await clone.setup();
|
|
3804
|
-
clone.$$internal = this.$$internal;
|
|
3805
|
-
return this.copyTo(clone);
|
|
3806
|
-
}
|
|
3807
|
-
/**
|
|
3808
3852
|
* A function to copy the context and update the fields for a specific environment
|
|
3809
3853
|
*
|
|
3810
3854
|
* @param environment - The environment configuration to use.
|
|
3811
3855
|
* @returns A new context instance with the updated environment.
|
|
3812
3856
|
*/
|
|
3813
|
-
async
|
|
3814
|
-
const context =
|
|
3857
|
+
async createEnvironment(environment) {
|
|
3858
|
+
const context = await PowerlinesEnvironmentContext.createEnvironment(deepClone(this.options), deepClone(this.config), deepClone(this.overriddenConfig), deepClone(environment));
|
|
3859
|
+
context.dependencies = deepClone(this.dependencies);
|
|
3860
|
+
context.devDependencies = deepClone(this.devDependencies);
|
|
3861
|
+
context.persistedMeta = deepClone(this.persistedMeta);
|
|
3862
|
+
context.resolvePatterns = deepClone(this.resolvePatterns);
|
|
3863
|
+
context.powerlinesPath ??= this.powerlinesPath;
|
|
3864
|
+
context.resolver ??= this.resolver;
|
|
3865
|
+
context.$$internal = this.$$internal;
|
|
3815
3866
|
context.plugins = [];
|
|
3816
3867
|
for (const plugin of this.plugins) await context.addPlugin(plugin);
|
|
3817
3868
|
return context;
|
|
@@ -3819,10 +3870,10 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3819
3870
|
/**
|
|
3820
3871
|
* Update the context using a new inline configuration options
|
|
3821
3872
|
*/
|
|
3822
|
-
async
|
|
3823
|
-
await super.
|
|
3873
|
+
async resolveConfig() {
|
|
3874
|
+
await super.resolveConfig();
|
|
3824
3875
|
await Promise.all(toArray(this.config.environments && Object.keys(this.config.environments).length > 0 ? Object.keys(this.config.environments).map((name) => createEnvironment(name, this.config)) : createDefaultEnvironment(this.config)).map(async (env) => {
|
|
3825
|
-
this.#environments[env.name] = await this.
|
|
3876
|
+
this.#environments[env.name] = await this.createEnvironment(env);
|
|
3826
3877
|
}));
|
|
3827
3878
|
}
|
|
3828
3879
|
/**
|
|
@@ -3847,12 +3898,20 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3847
3898
|
if (name) environment = this.environments[name];
|
|
3848
3899
|
if (Object.keys(this.environments).length === 1) {
|
|
3849
3900
|
environment = this.environments[Object.keys(this.environments)[0]];
|
|
3850
|
-
this.
|
|
3901
|
+
this.trace({
|
|
3902
|
+
meta: { category: "plugins" },
|
|
3903
|
+
message: `Applying the only configured environment: ${chalk.bold.cyanBright(environment?.config.environment?.name)}`
|
|
3904
|
+
});
|
|
3851
3905
|
}
|
|
3852
3906
|
if (!environment) {
|
|
3853
3907
|
if (name) throw new Error(`Environment "${name}" not found.`);
|
|
3854
|
-
environment = await this.
|
|
3855
|
-
|
|
3908
|
+
environment = await PowerlinesEnvironmentContext.createEnvironment(deepClone(this.options), deepClone(this.config), deepClone(this.overriddenConfig), deepClone(createDefaultEnvironment(this.config)));
|
|
3909
|
+
environment.plugins = [];
|
|
3910
|
+
for (const plugin of this.plugins) await environment.addPlugin(plugin);
|
|
3911
|
+
this.warn({
|
|
3912
|
+
meta: { category: "plugins" },
|
|
3913
|
+
message: `No environment specified, and no default environment found. Using a temporary default environment: ${chalk.bold.cyanBright(environment.config.environment?.name)}`
|
|
3914
|
+
});
|
|
3856
3915
|
}
|
|
3857
3916
|
return environment;
|
|
3858
3917
|
}
|
|
@@ -3880,8 +3939,11 @@ var PowerlinesExecutionContext = class PowerlinesExecutionContext extends Powerl
|
|
|
3880
3939
|
async toEnvironment() {
|
|
3881
3940
|
let environment;
|
|
3882
3941
|
if (Object.keys(this.environments).length > 1) {
|
|
3883
|
-
environment = await this.
|
|
3884
|
-
this.debug(
|
|
3942
|
+
environment = await this.createEnvironment(createEnvironment(GLOBAL_ENVIRONMENT, this.config));
|
|
3943
|
+
this.debug({
|
|
3944
|
+
meta: { category: "plugins" },
|
|
3945
|
+
message: `Combined all ${Object.keys(this.environments).length} environments into a single global context.`
|
|
3946
|
+
});
|
|
3885
3947
|
} else environment = await this.getEnvironment();
|
|
3886
3948
|
return environment;
|
|
3887
3949
|
}
|
|
@@ -4301,11 +4363,11 @@ async function installDependencies(context) {
|
|
|
4301
4363
|
//#endregion
|
|
4302
4364
|
//#region src/_internal/helpers/resolve-tsconfig.ts
|
|
4303
4365
|
function getTsconfigDtsPath(context) {
|
|
4304
|
-
return joinPaths(relativePath(joinPaths(context.
|
|
4366
|
+
return joinPaths(relativePath(joinPaths(context.config.cwd, context.config.root), findFilePath(context.typesPath)), findFileName(context.typesPath));
|
|
4305
4367
|
}
|
|
4306
4368
|
async function resolveTsconfigChanges(context) {
|
|
4307
|
-
const tsconfig = getParsedTypeScriptConfig(context.
|
|
4308
|
-
const tsconfigJson = await readJsonFile(getTsconfigFilePath(context.
|
|
4369
|
+
const tsconfig = getParsedTypeScriptConfig(context.config.cwd, context.config.root, context.config.tsconfig, context.config.tsconfigRaw);
|
|
4370
|
+
const tsconfigJson = await readJsonFile(getTsconfigFilePath(context.config.cwd, context.config.root, context.config.tsconfig));
|
|
4309
4371
|
tsconfigJson.compilerOptions ??= {};
|
|
4310
4372
|
if (context.config.output.dts !== false) {
|
|
4311
4373
|
const dtsRelativePath = getTsconfigDtsPath(context);
|
|
@@ -4395,342 +4457,76 @@ var PowerlinesExecution = class PowerlinesExecution {
|
|
|
4395
4457
|
* The Powerlines context
|
|
4396
4458
|
*/
|
|
4397
4459
|
#context;
|
|
4398
|
-
async #handleBuild(context) {
|
|
4399
|
-
await this.callHook("build", {
|
|
4400
|
-
environment: context,
|
|
4401
|
-
order: "pre"
|
|
4402
|
-
});
|
|
4403
|
-
context.debug("Formatting the generated entry files before the build process starts.");
|
|
4404
|
-
await formatFolder(context, context.entryPath);
|
|
4405
|
-
await this.callHook("build", {
|
|
4406
|
-
environment: context,
|
|
4407
|
-
order: "normal"
|
|
4408
|
-
});
|
|
4409
|
-
if (context.config.output.copy) {
|
|
4410
|
-
context.debug("Copying project's files from build output directory.");
|
|
4411
|
-
const destinationPath = isParentPath(appendPath(context.config.output.path, context.config.cwd), appendPath(context.config.root, context.config.cwd)) ? joinPaths(context.config.output.copy.path, relativePath(appendPath(context.config.root, context.config.cwd), appendPath(context.config.output.path, context.config.cwd))) : joinPaths(context.config.output.copy.path, "dist");
|
|
4412
|
-
const sourcePath = context.config.output.path;
|
|
4413
|
-
if (existsSync(sourcePath) && sourcePath !== destinationPath) {
|
|
4414
|
-
context.debug(`Copying files from project's build output directory (${context.config.output.path}) to the project's copy/publish directory (${destinationPath}).`);
|
|
4415
|
-
await copyFiles(sourcePath, destinationPath);
|
|
4416
|
-
} else context.warn(`The source path for the copy operation ${!existsSync(sourcePath) ? "does not exist" : "is the same as the destination path"}. Source: ${sourcePath}, Destination: ${destinationPath}. Skipping copying of build output files.`);
|
|
4417
|
-
if (context.config.output.copy.assets && Array.isArray(context.config.output.copy.assets)) await Promise.all(context.config.output.copy.assets.map(async (asset) => {
|
|
4418
|
-
context.trace(`Copying asset(s): ${chalk.redBright(context.config.cwd === asset.input ? asset.glob : appendPath(asset.glob, replacePath(asset.input, context.config.cwd)))} -> ${chalk.greenBright(appendPath(asset.glob, replacePath(asset.output, context.config.cwd)))} ${Array.isArray(asset.ignore) && asset.ignore.length > 0 ? ` (ignoring: ${asset.ignore.map((i) => chalk.yellowBright(i)).join(", ")})` : ""}`);
|
|
4419
|
-
await context.fs.copy(asset, asset.output);
|
|
4420
|
-
}));
|
|
4421
|
-
} else context.debug("No copy configuration found for the project output. Skipping the copying of build output files.");
|
|
4422
|
-
await this.callHook("build", {
|
|
4423
|
-
environment: context,
|
|
4424
|
-
order: "post"
|
|
4425
|
-
});
|
|
4426
|
-
}
|
|
4427
4460
|
/**
|
|
4428
|
-
*
|
|
4461
|
+
* Initialize a Powerlines API instance
|
|
4429
4462
|
*
|
|
4430
|
-
* @
|
|
4463
|
+
* @param options - The options to initialize the API with
|
|
4464
|
+
* @returns A new instance of the Powerlines API
|
|
4431
4465
|
*/
|
|
4432
|
-
async
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
}
|
|
4437
|
-
this.context.debug(`Found ${Object.keys(this.context.config.environments).length} configured environment(s) for this Powerlines project.`);
|
|
4438
|
-
return (await Promise.all(Object.entries(this.context.config.environments).map(async ([name, config]) => {
|
|
4439
|
-
if (!await this.context.getEnvironmentSafe(name)) {
|
|
4440
|
-
const resolvedEnvironment = await this.callHook("configEnvironment", { environment: name }, name, config);
|
|
4441
|
-
if (resolvedEnvironment) this.context.environments[name] = await this.context.in(resolvedEnvironment);
|
|
4442
|
-
}
|
|
4443
|
-
return this.context.environments[name];
|
|
4444
|
-
}))).filter((context) => isSet(context));
|
|
4466
|
+
static async from(options, initialConfig) {
|
|
4467
|
+
const api = new PowerlinesExecution(await PowerlinesExecutionContext.fromInitialConfig(options, initialConfig ?? {}));
|
|
4468
|
+
await api.init();
|
|
4469
|
+
return api;
|
|
4445
4470
|
}
|
|
4446
4471
|
/**
|
|
4447
|
-
*
|
|
4448
|
-
*
|
|
4449
|
-
* @param handle - The handler function to execute for each environment
|
|
4472
|
+
* The Powerlines context
|
|
4450
4473
|
*/
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
return Promise.resolve(handle(context));
|
|
4454
|
-
}));
|
|
4474
|
+
get context() {
|
|
4475
|
+
return this.#context;
|
|
4455
4476
|
}
|
|
4456
4477
|
/**
|
|
4457
|
-
*
|
|
4478
|
+
* Generate the Powerlines typescript declaration file
|
|
4458
4479
|
*
|
|
4459
|
-
* @
|
|
4460
|
-
*
|
|
4461
|
-
*
|
|
4480
|
+
* @remarks
|
|
4481
|
+
* This method will only generate the typescript declaration file for the Powerlines project. It is generally recommended to run the full `prepare` command, which will run this method as part of its process.
|
|
4482
|
+
*
|
|
4483
|
+
* @param inlineConfig - The inline configuration for the types command
|
|
4462
4484
|
*/
|
|
4463
|
-
async
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
plugins
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
if (
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
} else if (isFunction(pluginConfig)) plugins = toArray(await Promise.resolve(pluginConfig(pluginOptions)));
|
|
4499
|
-
else if (Array.isArray(pluginConfig) && pluginConfig.every(isPlugin)) plugins = pluginConfig;
|
|
4500
|
-
else if (isPlugin(pluginConfig)) plugins = toArray(pluginConfig);
|
|
4501
|
-
}
|
|
4502
|
-
if (!plugins) throw new Error(`The plugin configuration ${JSON.stringify(awaited)} is invalid. This configuration must point to a valid Powerlines plugin module.`);
|
|
4503
|
-
if (plugins.length > 0 && !plugins.every(isPlugin)) throw new Error(`The plugin option ${JSON.stringify(plugins)} does not export a valid module. This configuration must point to a valid Powerlines plugin module.`);
|
|
4504
|
-
const result = [];
|
|
4505
|
-
for (const plugin of plugins) if (isDuplicate(plugin, this.context.plugins)) this.context.trace(`Duplicate ${chalk.bold.cyanBright(plugin.name)} plugin dependency detected - Skipping initialization.`);
|
|
4506
|
-
else {
|
|
4507
|
-
result.push(plugin);
|
|
4508
|
-
this.context.trace(`Initializing the ${chalk.bold.cyanBright(plugin.name)} plugin...`);
|
|
4509
|
-
}
|
|
4510
|
-
return result;
|
|
4511
|
-
}
|
|
4512
|
-
async #resolvePlugin(pluginPath) {
|
|
4513
|
-
if (pluginPath.startsWith("@") && pluginPath.split("/").filter(Boolean).length > 2) {
|
|
4514
|
-
const splits = pluginPath.split("/").filter(Boolean);
|
|
4515
|
-
pluginPath = `${splits[0]}/${splits[1]}`;
|
|
4516
|
-
}
|
|
4517
|
-
const isInstalled = isPackageExists(pluginPath, { paths: [this.context.config.cwd, this.context.config.root] });
|
|
4518
|
-
if (!isInstalled && this.context.config.autoInstall) {
|
|
4519
|
-
this.#context.warn(`The plugin package "${pluginPath}" is not installed. It will be installed automatically.`);
|
|
4520
|
-
const result = await install(pluginPath, { cwd: this.context.config.root });
|
|
4521
|
-
if (isNumber(result.exitCode) && result.exitCode > 0) {
|
|
4522
|
-
this.#context.error(result.stderr);
|
|
4523
|
-
throw new Error(`An error occurred while installing the build plugin package "${pluginPath}" `);
|
|
4524
|
-
}
|
|
4525
|
-
}
|
|
4526
|
-
try {
|
|
4527
|
-
const module = await this.context.resolver.plugin.import(this.context.resolver.plugin.esmResolve(joinPaths(pluginPath, "plugin")));
|
|
4528
|
-
const result = module.plugin ?? module.default;
|
|
4529
|
-
if (!result) throw new Error(`The plugin package "${pluginPath}" does not export a valid module.`);
|
|
4530
|
-
return result;
|
|
4531
|
-
} catch (error) {
|
|
4532
|
-
try {
|
|
4533
|
-
const module = await this.context.resolver.plugin.import(this.context.resolver.plugin.esmResolve(pluginPath));
|
|
4534
|
-
const result = module.plugin ?? module.default;
|
|
4535
|
-
if (!result) throw new Error(`The plugin package "${pluginPath}" does not export a valid module.`);
|
|
4536
|
-
return result;
|
|
4537
|
-
} catch {
|
|
4538
|
-
if (!isInstalled) throw new Error(`The plugin package "${pluginPath}" is not installed. Please install the package using the command: "npm install ${pluginPath} --save-dev"`);
|
|
4539
|
-
else throw new Error(`An error occurred while importing the build plugin package "${pluginPath}":
|
|
4540
|
-
${isError(error) ? error.message : String(error)}
|
|
4541
|
-
|
|
4542
|
-
Note: Please ensure the plugin package's default export is a class that extends \`Plugin\` with a constructor that excepts a single arguments of type \`PluginOptions\`.`);
|
|
4485
|
+
async types(inlineConfig = { command: "types" }) {
|
|
4486
|
+
this.context.debug(" Aggregating configuration options for the Powerlines project");
|
|
4487
|
+
inlineConfig.command ??= "types";
|
|
4488
|
+
await this.context.setInlineConfig(inlineConfig);
|
|
4489
|
+
await this.executeEnvironments(async (context) => {
|
|
4490
|
+
context.debug(`Initializing the processing options for the Powerlines project.`);
|
|
4491
|
+
await this.callHook("configResolved", {
|
|
4492
|
+
environment: context,
|
|
4493
|
+
order: "pre"
|
|
4494
|
+
});
|
|
4495
|
+
await initializeTsconfig(context);
|
|
4496
|
+
await this.callHook("configResolved", {
|
|
4497
|
+
environment: context,
|
|
4498
|
+
order: "normal"
|
|
4499
|
+
});
|
|
4500
|
+
if (context.entry.length > 0) context.debug(`The configuration provided ${isObject(context.config.input) ? Object.keys(context.config.input).length : toArray(context.config.input).length} entry point(s), Powerlines has found ${context.entry.length} entry files(s) for the ${context.config.title} project${context.entry.length > 0 && context.entry.length < 10 ? `: \n${context.entry.map((entry) => `- ${entry.file}${entry.output ? ` -> ${entry.output}` : ""}`).join(" \n")}` : ""}`);
|
|
4501
|
+
else context.warn(`No entry files were found for the ${context.config.title} project. Please ensure this is correct. Powerlines plugins generally require at least one entry point to function properly.`);
|
|
4502
|
+
await resolveTsconfig(context);
|
|
4503
|
+
await installDependencies(context);
|
|
4504
|
+
await this.callHook("configResolved", {
|
|
4505
|
+
environment: context,
|
|
4506
|
+
order: "post"
|
|
4507
|
+
});
|
|
4508
|
+
context.trace(`Powerlines configuration has been resolved: \n\n${formatLogMessage({
|
|
4509
|
+
...context.config,
|
|
4510
|
+
userConfig: isSetObject(context.config.userConfig) ? omit(context.config.userConfig, ["plugins"]) : void 0,
|
|
4511
|
+
inlineConfig: isSetObject(context.config.inlineConfig) ? omit(context.config.inlineConfig, ["plugins"]) : void 0,
|
|
4512
|
+
plugins: context.plugins.map((plugin) => plugin.plugin.name)
|
|
4513
|
+
})}`);
|
|
4514
|
+
if (!context.fs.existsSync(context.cachePath)) await createDirectory(context.cachePath);
|
|
4515
|
+
if (!context.fs.existsSync(context.dataPath)) await createDirectory(context.dataPath);
|
|
4516
|
+
if (context.config.skipCache === true || context.persistedMeta?.checksum !== context.meta.checksum) context.debug(`Using previously prepared files as the meta checksum has not changed.`);
|
|
4517
|
+
else {
|
|
4518
|
+
context.info(`Running \`prepare\` command as the meta checksum has changed since the last run.`);
|
|
4519
|
+
await this.prepare(defu({ output: { types: false } }, inlineConfig));
|
|
4543
4520
|
}
|
|
4544
|
-
|
|
4521
|
+
await this.handleTypes(context);
|
|
4522
|
+
this.context.debug("Formatting files generated during the types step.");
|
|
4523
|
+
await format(context, context.typesPath, await context.fs.read(context.typesPath) ?? "");
|
|
4524
|
+
await writeMetaFile(context);
|
|
4525
|
+
context.persistedMeta = context.meta;
|
|
4526
|
+
});
|
|
4545
4527
|
}
|
|
4546
4528
|
/**
|
|
4547
|
-
*
|
|
4548
|
-
*
|
|
4549
|
-
* @remarks
|
|
4550
|
-
* This method will generate the TypeScript declaration file for the Powerlines project, including any types provided by plugins.
|
|
4551
|
-
*
|
|
4552
|
-
* @param context - The environment context to use for generating the TypeScript declaration file
|
|
4553
|
-
* @returns A promise that resolves when the TypeScript declaration file has been generated
|
|
4554
|
-
*/
|
|
4555
|
-
async #types(context) {
|
|
4556
|
-
context.debug(`Preparing the TypeScript definitions for the Powerlines project.`);
|
|
4557
|
-
if (context.fs.existsSync(context.typesPath)) await context.fs.remove(context.typesPath);
|
|
4558
|
-
if (!await resolvePackage("typescript")) throw new Error("Could not resolve TypeScript package location. Please ensure TypeScript is installed.");
|
|
4559
|
-
context.debug("Running TypeScript compiler for built-in runtime module files.");
|
|
4560
|
-
let { code, directives } = await emitBuiltinTypes(context, (await context.getBuiltins()).reduce((ret, builtin) => {
|
|
4561
|
-
const formatted = replacePath(builtin.path, context.config.cwd);
|
|
4562
|
-
if (!ret.includes(formatted)) ret.push(formatted);
|
|
4563
|
-
return ret;
|
|
4564
|
-
}, []));
|
|
4565
|
-
context.debug(`Generating TypeScript declaration file ${context.typesPath}.`);
|
|
4566
|
-
const merge = async (currentResult, previousResult) => {
|
|
4567
|
-
if (!isSetString(currentResult) && !isSetObject(currentResult) && !isSetString(previousResult) && !isSetObject(previousResult)) return {
|
|
4568
|
-
code,
|
|
4569
|
-
directives
|
|
4570
|
-
};
|
|
4571
|
-
const previous = (await format(context, context.typesPath, isSetString(previousResult) ? previousResult : isSetObject(previousResult) ? previousResult.code : "")).trim().replace(code, "").trim();
|
|
4572
|
-
const current = (await format(context, context.typesPath, isSetString(currentResult) ? currentResult : isSetObject(currentResult) ? currentResult.code : "")).trim().replace(previous, "").trim().replace(code, "").trim();
|
|
4573
|
-
return {
|
|
4574
|
-
directives: [...isSetObject(currentResult) && currentResult.directives ? currentResult.directives : [], ...isSetObject(previousResult) && previousResult.directives ? previousResult.directives : []],
|
|
4575
|
-
code: await format(context, context.typesPath, `${!previous.includes(getTypescriptFileHeader(context)) && !current.includes(getTypescriptFileHeader(context)) ? `${code}\n` : ""}${previous}\n${current}`.trim())
|
|
4576
|
-
};
|
|
4577
|
-
};
|
|
4578
|
-
const asNextParam = (previousResult) => isObject(previousResult) ? previousResult.code : previousResult;
|
|
4579
|
-
let result = await this.callHook("types", {
|
|
4580
|
-
environment: context,
|
|
4581
|
-
sequential: true,
|
|
4582
|
-
order: "pre",
|
|
4583
|
-
result: "merge",
|
|
4584
|
-
merge,
|
|
4585
|
-
asNextParam
|
|
4586
|
-
}, code);
|
|
4587
|
-
if (result) {
|
|
4588
|
-
if (isSetObject(result)) {
|
|
4589
|
-
code = result.code;
|
|
4590
|
-
if (Array.isArray(result.directives) && result.directives.length > 0) directives = getUnique([...directives, ...result.directives]).filter(Boolean);
|
|
4591
|
-
} else if (isSetString(result)) code = result;
|
|
4592
|
-
}
|
|
4593
|
-
result = await this.callHook("types", {
|
|
4594
|
-
environment: context,
|
|
4595
|
-
sequential: true,
|
|
4596
|
-
order: "normal",
|
|
4597
|
-
result: "merge",
|
|
4598
|
-
merge,
|
|
4599
|
-
asNextParam
|
|
4600
|
-
}, code);
|
|
4601
|
-
if (result) {
|
|
4602
|
-
if (isSetObject(result)) {
|
|
4603
|
-
code = result.code;
|
|
4604
|
-
if (Array.isArray(result.directives) && result.directives.length > 0) directives = getUnique([...directives, ...result.directives]).filter(Boolean);
|
|
4605
|
-
} else if (isSetString(result)) code = result;
|
|
4606
|
-
}
|
|
4607
|
-
result = await this.callHook("types", {
|
|
4608
|
-
environment: context,
|
|
4609
|
-
sequential: true,
|
|
4610
|
-
order: "post",
|
|
4611
|
-
result: "merge",
|
|
4612
|
-
merge,
|
|
4613
|
-
asNextParam
|
|
4614
|
-
}, code);
|
|
4615
|
-
if (result) {
|
|
4616
|
-
if (isSetObject(result)) {
|
|
4617
|
-
code = result.code;
|
|
4618
|
-
if (Array.isArray(result.directives) && result.directives.length > 0) directives = getUnique([...directives, ...result.directives]).filter(Boolean);
|
|
4619
|
-
} else if (isSetString(result)) code = result;
|
|
4620
|
-
}
|
|
4621
|
-
if (isSetString(code?.trim()) || directives.length > 0) await context.fs.write(context.typesPath, `${directives.length > 0 ? `${directives.map((directive) => `/// <reference types="${directive}" />`).join("\n")}
|
|
4622
|
-
|
|
4623
|
-
` : ""}${getTypescriptFileHeader(context, {
|
|
4624
|
-
directive: null,
|
|
4625
|
-
prettierIgnore: false
|
|
4626
|
-
})}
|
|
4627
|
-
|
|
4628
|
-
${formatTypes(code)}
|
|
4629
|
-
`);
|
|
4630
|
-
}
|
|
4631
|
-
/**
|
|
4632
|
-
* Initialize a Powerlines API instance
|
|
4633
|
-
*
|
|
4634
|
-
* @param options - The options to initialize the API with
|
|
4635
|
-
* @returns A new instance of the Powerlines API
|
|
4636
|
-
*/
|
|
4637
|
-
static async init(options, initialConfig) {
|
|
4638
|
-
const api = new PowerlinesExecution(await PowerlinesExecutionContext.init(options, initialConfig ?? {}));
|
|
4639
|
-
api.#context.config.initialConfig = initialConfig ?? {};
|
|
4640
|
-
await api.setup();
|
|
4641
|
-
return api;
|
|
4642
|
-
}
|
|
4643
|
-
/**
|
|
4644
|
-
* The Powerlines context
|
|
4645
|
-
*/
|
|
4646
|
-
get context() {
|
|
4647
|
-
return this.#context;
|
|
4648
|
-
}
|
|
4649
|
-
/**
|
|
4650
|
-
* Initialize the execution API with the provided configuration options
|
|
4651
|
-
*/
|
|
4652
|
-
async setup() {
|
|
4653
|
-
await this.#context.setup();
|
|
4654
|
-
this.#context.$$internal = {
|
|
4655
|
-
api: this,
|
|
4656
|
-
addPlugin: this.addPlugin.bind(this)
|
|
4657
|
-
};
|
|
4658
|
-
const timer = this.#context.timer("Initialization");
|
|
4659
|
-
for (const plugin of this.#context.config.plugins.flatMap((p) => toArray(p)) ?? []) await this.addPlugin(plugin);
|
|
4660
|
-
if (this.#context.plugins.length === 0) this.#context.warn({
|
|
4661
|
-
meta: { category: "plugins" },
|
|
4662
|
-
message: "No Powerlines plugins were specified in the options. Please ensure this is correct, as it is generally not recommended."
|
|
4663
|
-
});
|
|
4664
|
-
else this.#context.info({
|
|
4665
|
-
meta: { category: "plugins" },
|
|
4666
|
-
message: `Loaded ${this.#context.plugins.length} ${titleCase(this.#context.config.framework)} plugin${this.#context.plugins.length > 1 ? "s" : ""}: \n${this.#context.plugins.map((plugin, index) => ` ${index + 1}. ${colorText(plugin.name)}`).join("\n")}`
|
|
4667
|
-
});
|
|
4668
|
-
const pluginConfig = await this.callHook("config", {
|
|
4669
|
-
environment: await this.#context.getEnvironment(),
|
|
4670
|
-
sequential: true,
|
|
4671
|
-
result: "merge",
|
|
4672
|
-
merge: mergeConfigs
|
|
4673
|
-
});
|
|
4674
|
-
if (pluginConfig) {
|
|
4675
|
-
this.#context.config.pluginConfig = pluginConfig;
|
|
4676
|
-
await this.#context.setup();
|
|
4677
|
-
}
|
|
4678
|
-
timer();
|
|
4679
|
-
}
|
|
4680
|
-
/**
|
|
4681
|
-
* Generate the Powerlines typescript declaration file
|
|
4682
|
-
*
|
|
4683
|
-
* @remarks
|
|
4684
|
-
* This method will only generate the typescript declaration file for the Powerlines project. It is generally recommended to run the full `prepare` command, which will run this method as part of its process.
|
|
4685
|
-
*
|
|
4686
|
-
* @param inlineConfig - The inline configuration for the types command
|
|
4687
|
-
*/
|
|
4688
|
-
async types(inlineConfig = { command: "types" }) {
|
|
4689
|
-
this.context.debug(" Aggregating configuration options for the Powerlines project");
|
|
4690
|
-
inlineConfig.command ??= "types";
|
|
4691
|
-
this.context.config.inlineConfig = inlineConfig;
|
|
4692
|
-
await this.setup();
|
|
4693
|
-
await this.#executeEnvironments(async (context) => {
|
|
4694
|
-
context.debug(`Initializing the processing options for the Powerlines project.`);
|
|
4695
|
-
await this.callHook("configResolved", {
|
|
4696
|
-
environment: context,
|
|
4697
|
-
order: "pre"
|
|
4698
|
-
});
|
|
4699
|
-
await initializeTsconfig(context);
|
|
4700
|
-
await this.callHook("configResolved", {
|
|
4701
|
-
environment: context,
|
|
4702
|
-
order: "normal"
|
|
4703
|
-
});
|
|
4704
|
-
if (context.entry.length > 0) context.debug(`The configuration provided ${isObject(context.config.input) ? Object.keys(context.config.input).length : toArray(context.config.input).length} entry point(s), Powerlines has found ${context.entry.length} entry files(s) for the ${context.config.title} project${context.entry.length > 0 && context.entry.length < 10 ? `: \n${context.entry.map((entry) => `- ${entry.file}${entry.output ? ` -> ${entry.output}` : ""}`).join(" \n")}` : ""}`);
|
|
4705
|
-
else context.warn(`No entry files were found for the ${context.config.title} project. Please ensure this is correct. Powerlines plugins generally require at least one entry point to function properly.`);
|
|
4706
|
-
await resolveTsconfig(context);
|
|
4707
|
-
await installDependencies(context);
|
|
4708
|
-
await this.callHook("configResolved", {
|
|
4709
|
-
environment: context,
|
|
4710
|
-
order: "post"
|
|
4711
|
-
});
|
|
4712
|
-
context.trace(`Powerlines configuration has been resolved: \n\n${formatLogMessage({
|
|
4713
|
-
...context.config,
|
|
4714
|
-
userConfig: isSetObject(context.config.userConfig) ? omit(context.config.userConfig, ["plugins"]) : void 0,
|
|
4715
|
-
inlineConfig: isSetObject(context.config.inlineConfig) ? omit(context.config.inlineConfig, ["plugins"]) : void 0,
|
|
4716
|
-
plugins: context.plugins.map((plugin) => plugin.plugin.name)
|
|
4717
|
-
})}`);
|
|
4718
|
-
if (!context.fs.existsSync(context.cachePath)) await createDirectory(context.cachePath);
|
|
4719
|
-
if (!context.fs.existsSync(context.dataPath)) await createDirectory(context.dataPath);
|
|
4720
|
-
if (context.config.skipCache === true || context.persistedMeta?.checksum !== context.meta.checksum) context.debug(`Using previously prepared files as the meta checksum has not changed.`);
|
|
4721
|
-
else {
|
|
4722
|
-
context.info(`Running \`prepare\` command as the meta checksum has changed since the last run.`);
|
|
4723
|
-
await this.prepare(defu({ output: { types: false } }, inlineConfig));
|
|
4724
|
-
}
|
|
4725
|
-
await this.#types(context);
|
|
4726
|
-
this.context.debug("Formatting files generated during the types step.");
|
|
4727
|
-
await format(context, context.typesPath, await context.fs.read(context.typesPath) ?? "");
|
|
4728
|
-
await writeMetaFile(context);
|
|
4729
|
-
context.persistedMeta = context.meta;
|
|
4730
|
-
});
|
|
4731
|
-
}
|
|
4732
|
-
/**
|
|
4733
|
-
* Prepare the Powerlines API
|
|
4529
|
+
* Prepare the Powerlines API
|
|
4734
4530
|
*
|
|
4735
4531
|
* @remarks
|
|
4736
4532
|
* This method will prepare the Powerlines API for use, initializing any necessary resources.
|
|
@@ -4739,9 +4535,8 @@ ${formatTypes(code)}
|
|
|
4739
4535
|
*/
|
|
4740
4536
|
async prepare(inlineConfig = { command: "prepare" }) {
|
|
4741
4537
|
inlineConfig.command ??= "prepare";
|
|
4742
|
-
this.context.
|
|
4743
|
-
await this.
|
|
4744
|
-
await this.#executeEnvironments(async (context) => {
|
|
4538
|
+
await this.context.setInlineConfig(inlineConfig);
|
|
4539
|
+
await this.executeEnvironments(async (context) => {
|
|
4745
4540
|
context.debug(`Initializing the processing options for the Powerlines project.`);
|
|
4746
4541
|
await this.callHook("configResolved", {
|
|
4747
4542
|
environment: context,
|
|
@@ -4791,7 +4586,7 @@ ${formatTypes(code)}
|
|
|
4791
4586
|
environment: context,
|
|
4792
4587
|
order: "post"
|
|
4793
4588
|
});
|
|
4794
|
-
if (context.config.output.types !== false) await this
|
|
4589
|
+
if (context.config.output.types !== false) await this.handleTypes(context);
|
|
4795
4590
|
this.context.debug("Formatting files generated during the prepare step.");
|
|
4796
4591
|
await Promise.all([formatFolder(context, context.builtinsPath), formatFolder(context, context.entryPath)]);
|
|
4797
4592
|
await writeMetaFile(context);
|
|
@@ -4810,7 +4605,7 @@ ${formatTypes(code)}
|
|
|
4810
4605
|
async new(inlineConfig) {
|
|
4811
4606
|
inlineConfig.command ??= "new";
|
|
4812
4607
|
await this.prepare(inlineConfig);
|
|
4813
|
-
await this
|
|
4608
|
+
await this.executeEnvironments(async (context) => {
|
|
4814
4609
|
context.debug("Initializing the processing options for the Powerlines project.");
|
|
4815
4610
|
await this.callHook("new", {
|
|
4816
4611
|
environment: context,
|
|
@@ -4859,7 +4654,7 @@ ${formatTypes(code)}
|
|
|
4859
4654
|
async clean(inlineConfig = { command: "clean" }) {
|
|
4860
4655
|
inlineConfig.command ??= "clean";
|
|
4861
4656
|
await this.prepare(inlineConfig);
|
|
4862
|
-
await this
|
|
4657
|
+
await this.executeEnvironments(async (context) => {
|
|
4863
4658
|
context.debug("Cleaning the project's dist and artifacts directories.");
|
|
4864
4659
|
await context.fs.remove(joinPaths(context.config.cwd, context.config.output.path));
|
|
4865
4660
|
await context.fs.remove(joinPaths(context.config.cwd, context.config.root, context.config.output.artifactsPath));
|
|
@@ -4878,7 +4673,7 @@ ${formatTypes(code)}
|
|
|
4878
4673
|
async lint(inlineConfig = { command: "lint" }) {
|
|
4879
4674
|
inlineConfig.command ??= "lint";
|
|
4880
4675
|
await this.prepare(inlineConfig);
|
|
4881
|
-
await this
|
|
4676
|
+
await this.executeEnvironments(async (context) => {
|
|
4882
4677
|
await this.callHook("lint", {
|
|
4883
4678
|
environment: context,
|
|
4884
4679
|
sequential: false
|
|
@@ -4894,7 +4689,7 @@ ${formatTypes(code)}
|
|
|
4894
4689
|
async test(inlineConfig = { command: "test" }) {
|
|
4895
4690
|
inlineConfig.command ??= "test";
|
|
4896
4691
|
await this.prepare(inlineConfig);
|
|
4897
|
-
await this
|
|
4692
|
+
await this.executeEnvironments(async (context) => {
|
|
4898
4693
|
await this.callHook("test", {
|
|
4899
4694
|
environment: context,
|
|
4900
4695
|
sequential: false
|
|
@@ -4912,17 +4707,15 @@ ${formatTypes(code)}
|
|
|
4912
4707
|
*/
|
|
4913
4708
|
async build(inlineConfig = { command: "build" }) {
|
|
4914
4709
|
inlineConfig.command ??= "build";
|
|
4710
|
+
await this.context.setInlineConfig(inlineConfig);
|
|
4915
4711
|
await this.context.generateChecksum();
|
|
4916
4712
|
if (this.context.meta.checksum !== this.context.persistedMeta?.checksum || this.context.config.skipCache) {
|
|
4917
4713
|
this.context.info(!this.context.persistedMeta?.checksum ? "No previous build cache found. Preparing the project for the initial build." : this.context.meta.checksum !== this.context.persistedMeta.checksum ? "The project has been modified since the last time `prepare` was ran. Re-preparing the project." : "The project is configured to skip cache. Re-preparing the project.");
|
|
4918
4714
|
await this.prepare(inlineConfig);
|
|
4919
|
-
} else {
|
|
4920
|
-
this.context.config.inlineConfig = inlineConfig;
|
|
4921
|
-
await this.context.setup();
|
|
4922
4715
|
}
|
|
4923
|
-
if (this.context.config.singleBuild) await this
|
|
4924
|
-
else await this
|
|
4925
|
-
await this
|
|
4716
|
+
if (this.context.config.singleBuild) await this.handleBuild(await this.#context.toEnvironment());
|
|
4717
|
+
else await this.executeEnvironments(async (context) => {
|
|
4718
|
+
await this.handleBuild(context);
|
|
4926
4719
|
});
|
|
4927
4720
|
}
|
|
4928
4721
|
/**
|
|
@@ -4933,8 +4726,9 @@ ${formatTypes(code)}
|
|
|
4933
4726
|
*/
|
|
4934
4727
|
async docs(inlineConfig = { command: "docs" }) {
|
|
4935
4728
|
inlineConfig.command ??= "docs";
|
|
4729
|
+
await this.context.setInlineConfig(inlineConfig);
|
|
4936
4730
|
await this.prepare(inlineConfig);
|
|
4937
|
-
await this
|
|
4731
|
+
await this.executeEnvironments(async (context) => {
|
|
4938
4732
|
context.debug("Writing documentation for the Powerlines project artifacts.");
|
|
4939
4733
|
await this.callHook("docs", { environment: context });
|
|
4940
4734
|
});
|
|
@@ -4949,8 +4743,9 @@ ${formatTypes(code)}
|
|
|
4949
4743
|
*/
|
|
4950
4744
|
async deploy(inlineConfig = { command: "deploy" }) {
|
|
4951
4745
|
inlineConfig.command ??= "deploy";
|
|
4746
|
+
await this.context.setInlineConfig(inlineConfig);
|
|
4952
4747
|
await this.prepare(inlineConfig);
|
|
4953
|
-
await this
|
|
4748
|
+
await this.executeEnvironments(async (context) => {
|
|
4954
4749
|
await this.callHook("deploy", { environment: context });
|
|
4955
4750
|
});
|
|
4956
4751
|
}
|
|
@@ -4963,7 +4758,7 @@ ${formatTypes(code)}
|
|
|
4963
4758
|
* @returns A promise that resolves when the finalization process has completed
|
|
4964
4759
|
*/
|
|
4965
4760
|
async finalize() {
|
|
4966
|
-
await this
|
|
4761
|
+
await this.executeEnvironments(async (context) => {
|
|
4967
4762
|
await this.callHook("finalize", { environment: context });
|
|
4968
4763
|
await context.fs.dispose();
|
|
4969
4764
|
if (existsSync(context.cachePath) && !(await listFiles(joinPaths(context.cachePath, "**/*")))?.length) await removeDirectory(context.cachePath);
|
|
@@ -4995,13 +4790,40 @@ ${formatTypes(code)}
|
|
|
4995
4790
|
this.#context = context;
|
|
4996
4791
|
}
|
|
4997
4792
|
/**
|
|
4793
|
+
* Initialize the execution API with the provided configuration options
|
|
4794
|
+
*/
|
|
4795
|
+
async init() {
|
|
4796
|
+
this.#context.$$internal = {
|
|
4797
|
+
api: this,
|
|
4798
|
+
addPlugin: this.addPlugin.bind(this)
|
|
4799
|
+
};
|
|
4800
|
+
const timer = this.#context.timer("Initialization");
|
|
4801
|
+
for (const plugin of this.#context.config.plugins.flatMap((p) => toArray(p)) ?? []) await this.addPlugin(plugin);
|
|
4802
|
+
if (this.#context.plugins.length === 0) this.#context.warn({
|
|
4803
|
+
meta: { category: "plugins" },
|
|
4804
|
+
message: "No Powerlines plugins were specified in the options. Please ensure this is correct, as it is generally not recommended."
|
|
4805
|
+
});
|
|
4806
|
+
else this.#context.info({
|
|
4807
|
+
meta: { category: "plugins" },
|
|
4808
|
+
message: `Loaded ${this.#context.plugins.length} ${titleCase(this.#context.config.framework)} plugin${this.#context.plugins.length > 1 ? "s" : ""}: \n${this.#context.plugins.map((plugin, index) => ` ${index + 1}. ${colorText(plugin.name)}`).join("\n")}`
|
|
4809
|
+
});
|
|
4810
|
+
const pluginConfig = await this.callHook("config", {
|
|
4811
|
+
environment: await this.#context.getEnvironment(),
|
|
4812
|
+
sequential: true,
|
|
4813
|
+
result: "merge",
|
|
4814
|
+
merge: mergeConfigs
|
|
4815
|
+
});
|
|
4816
|
+
if (pluginConfig) await this.context.setPluginConfig(pluginConfig);
|
|
4817
|
+
timer();
|
|
4818
|
+
}
|
|
4819
|
+
/**
|
|
4998
4820
|
* Add a Powerlines plugin used in the build process
|
|
4999
4821
|
*
|
|
5000
4822
|
* @param config - The import path of the plugin to add
|
|
5001
4823
|
*/
|
|
5002
4824
|
async addPlugin(config) {
|
|
5003
4825
|
if (config) {
|
|
5004
|
-
const result = await this
|
|
4826
|
+
const result = await this.initPlugin(config);
|
|
5005
4827
|
if (!result) return;
|
|
5006
4828
|
for (const plugin of result) {
|
|
5007
4829
|
this.context.debug({
|
|
@@ -5012,33 +4834,266 @@ ${formatTypes(code)}
|
|
|
5012
4834
|
}
|
|
5013
4835
|
}
|
|
5014
4836
|
}
|
|
4837
|
+
/**
|
|
4838
|
+
* Get the configured environments
|
|
4839
|
+
*
|
|
4840
|
+
* @returns The configured environments
|
|
4841
|
+
*/
|
|
4842
|
+
async getEnvironments() {
|
|
4843
|
+
if (!this.context.config.environments || Object.keys(this.context.config.environments).length <= 1) {
|
|
4844
|
+
this.context.debug("No environments are configured for this Powerlines project. Using the default environment.");
|
|
4845
|
+
return [await this.context.getEnvironment()];
|
|
4846
|
+
}
|
|
4847
|
+
this.context.debug(`Found ${Object.keys(this.context.config.environments).length} configured environment(s) for this Powerlines project.`);
|
|
4848
|
+
return (await Promise.all(Object.entries(this.context.config.environments).map(async ([name, config]) => {
|
|
4849
|
+
if (!await this.context.getEnvironmentSafe(name)) {
|
|
4850
|
+
const resolvedEnvironment = await this.callHook("configEnvironment", { environment: name }, name, config);
|
|
4851
|
+
if (resolvedEnvironment) this.context.environments[name] = await this.context.createEnvironment(resolvedEnvironment);
|
|
4852
|
+
}
|
|
4853
|
+
return this.context.environments[name];
|
|
4854
|
+
}))).filter((context) => isSet(context));
|
|
4855
|
+
}
|
|
4856
|
+
/**
|
|
4857
|
+
* Execute a handler function for each environment
|
|
4858
|
+
*
|
|
4859
|
+
* @param handle - The handler function to execute for each environment
|
|
4860
|
+
*/
|
|
4861
|
+
async executeEnvironments(handle) {
|
|
4862
|
+
await Promise.all((await this.getEnvironments()).map(async (context) => {
|
|
4863
|
+
return Promise.resolve(handle(context));
|
|
4864
|
+
}));
|
|
4865
|
+
}
|
|
4866
|
+
/**
|
|
4867
|
+
* Initialize a Powerlines plugin
|
|
4868
|
+
*
|
|
4869
|
+
* @param config - The configuration for the plugin
|
|
4870
|
+
* @returns The initialized plugin instance, or null if the plugin was a duplicate
|
|
4871
|
+
* @throws Will throw an error if the plugin cannot be found or is invalid
|
|
4872
|
+
*/
|
|
4873
|
+
async initPlugin(config) {
|
|
4874
|
+
let awaited = config;
|
|
4875
|
+
if (isPromiseLike(config)) awaited = await Promise.resolve(config);
|
|
4876
|
+
if (!isPluginConfig(awaited)) {
|
|
4877
|
+
const invalid = findInvalidPluginConfig(awaited);
|
|
4878
|
+
throw new Error(`Invalid ${invalid && invalid.length > 1 ? "plugins" : "plugin"} specified in the configuration - ${invalid && invalid.length > 0 ? JSON.stringify(awaited) : invalid?.join("\n\n")} \n\nPlease ensure the value is one of the following: \n - an instance of \`Plugin\` \n - a plugin name \n - an object with the \`plugin\` and \`options\` properties \n - a tuple array with the plugin and options \n - a factory function that returns a plugin or array of plugins \n - an array of plugins or plugin configurations`);
|
|
4879
|
+
}
|
|
4880
|
+
let plugins;
|
|
4881
|
+
if (isPlugin(awaited)) plugins = [awaited];
|
|
4882
|
+
else if (isFunction(awaited)) plugins = toArray(await Promise.resolve(awaited()));
|
|
4883
|
+
else if (isString(awaited)) {
|
|
4884
|
+
const resolved = await this.resolvePlugin(awaited);
|
|
4885
|
+
if (isFunction(resolved)) plugins = toArray(await Promise.resolve(resolved()));
|
|
4886
|
+
else plugins = toArray(resolved);
|
|
4887
|
+
} else if (Array.isArray(awaited) && awaited.every(isPlugin)) plugins = awaited;
|
|
4888
|
+
else if (Array.isArray(awaited) && awaited.every(isPluginConfig)) {
|
|
4889
|
+
plugins = [];
|
|
4890
|
+
for (const pluginConfig of awaited) {
|
|
4891
|
+
const initialized = await this.initPlugin(pluginConfig);
|
|
4892
|
+
if (initialized) plugins.push(...initialized);
|
|
4893
|
+
}
|
|
4894
|
+
} else if (isPluginConfigTuple(awaited) || isPluginConfigObject(awaited)) {
|
|
4895
|
+
let pluginConfig;
|
|
4896
|
+
let pluginOptions;
|
|
4897
|
+
if (isPluginConfigTuple(awaited)) {
|
|
4898
|
+
pluginConfig = awaited[0];
|
|
4899
|
+
pluginOptions = awaited?.length === 2 ? awaited[1] : void 0;
|
|
4900
|
+
} else {
|
|
4901
|
+
pluginConfig = awaited.plugin;
|
|
4902
|
+
pluginOptions = awaited.options;
|
|
4903
|
+
}
|
|
4904
|
+
if (isSetString(pluginConfig)) {
|
|
4905
|
+
const resolved = await this.resolvePlugin(pluginConfig);
|
|
4906
|
+
if (isFunction(resolved)) plugins = toArray(await Promise.resolve(pluginOptions ? resolved(pluginOptions) : resolved()));
|
|
4907
|
+
else plugins = toArray(resolved);
|
|
4908
|
+
} else if (isFunction(pluginConfig)) plugins = toArray(await Promise.resolve(pluginConfig(pluginOptions)));
|
|
4909
|
+
else if (Array.isArray(pluginConfig) && pluginConfig.every(isPlugin)) plugins = pluginConfig;
|
|
4910
|
+
else if (isPlugin(pluginConfig)) plugins = toArray(pluginConfig);
|
|
4911
|
+
}
|
|
4912
|
+
if (!plugins) throw new Error(`The plugin configuration ${JSON.stringify(awaited)} is invalid. This configuration must point to a valid Powerlines plugin module.`);
|
|
4913
|
+
if (plugins.length > 0 && !plugins.every(isPlugin)) throw new Error(`The plugin option ${JSON.stringify(plugins)} does not export a valid module. This configuration must point to a valid Powerlines plugin module.`);
|
|
4914
|
+
const result = [];
|
|
4915
|
+
for (const plugin of plugins) if (isDuplicate(plugin, this.context.plugins)) this.context.trace(`Duplicate ${chalk.bold.cyanBright(plugin.name)} plugin dependency detected - Skipping initialization.`);
|
|
4916
|
+
else {
|
|
4917
|
+
result.push(plugin);
|
|
4918
|
+
this.context.trace(`Initializing the ${chalk.bold.cyanBright(plugin.name)} plugin...`);
|
|
4919
|
+
}
|
|
4920
|
+
return result;
|
|
4921
|
+
}
|
|
4922
|
+
async resolvePlugin(pluginPath) {
|
|
4923
|
+
if (pluginPath.startsWith("@") && pluginPath.split("/").filter(Boolean).length > 2) {
|
|
4924
|
+
const splits = pluginPath.split("/").filter(Boolean);
|
|
4925
|
+
pluginPath = `${splits[0]}/${splits[1]}`;
|
|
4926
|
+
}
|
|
4927
|
+
const isInstalled = isPackageExists(pluginPath, { paths: [this.context.config.cwd, this.context.config.root] });
|
|
4928
|
+
if (!isInstalled && this.context.config.autoInstall) {
|
|
4929
|
+
this.#context.warn(`The plugin package "${pluginPath}" is not installed. It will be installed automatically.`);
|
|
4930
|
+
const result = await install(pluginPath, { cwd: this.context.config.root });
|
|
4931
|
+
if (isNumber(result.exitCode) && result.exitCode > 0) {
|
|
4932
|
+
this.#context.error(result.stderr);
|
|
4933
|
+
throw new Error(`An error occurred while installing the build plugin package "${pluginPath}" `);
|
|
4934
|
+
}
|
|
4935
|
+
}
|
|
4936
|
+
try {
|
|
4937
|
+
const module = await this.context.resolver.plugin.import(this.context.resolver.plugin.esmResolve(joinPaths(pluginPath, "plugin")));
|
|
4938
|
+
const result = module.plugin ?? module.default;
|
|
4939
|
+
if (!result) throw new Error(`The plugin package "${pluginPath}" does not export a valid module.`);
|
|
4940
|
+
return result;
|
|
4941
|
+
} catch (error) {
|
|
4942
|
+
try {
|
|
4943
|
+
const module = await this.context.resolver.plugin.import(this.context.resolver.plugin.esmResolve(pluginPath));
|
|
4944
|
+
const result = module.plugin ?? module.default;
|
|
4945
|
+
if (!result) throw new Error(`The plugin package "${pluginPath}" does not export a valid module.`);
|
|
4946
|
+
return result;
|
|
4947
|
+
} catch {
|
|
4948
|
+
if (!isInstalled) throw new Error(`The plugin package "${pluginPath}" is not installed. Please install the package using the command: "npm install ${pluginPath} --save-dev"`);
|
|
4949
|
+
else throw new Error(`An error occurred while importing the build plugin package "${pluginPath}":
|
|
4950
|
+
${isError(error) ? error.message : String(error)}
|
|
4951
|
+
|
|
4952
|
+
Note: Please ensure the plugin package's default export is a class that extends \`Plugin\` with a constructor that excepts a single arguments of type \`PluginOptions\`.`);
|
|
4953
|
+
}
|
|
4954
|
+
}
|
|
4955
|
+
}
|
|
4956
|
+
async handleBuild(context) {
|
|
4957
|
+
await this.callHook("build", {
|
|
4958
|
+
environment: context,
|
|
4959
|
+
order: "pre"
|
|
4960
|
+
});
|
|
4961
|
+
context.debug("Formatting the generated entry files before the build process starts.");
|
|
4962
|
+
await formatFolder(context, context.entryPath);
|
|
4963
|
+
await this.callHook("build", {
|
|
4964
|
+
environment: context,
|
|
4965
|
+
order: "normal"
|
|
4966
|
+
});
|
|
4967
|
+
if (context.config.output.copy) {
|
|
4968
|
+
context.debug("Copying project's files from build output directory.");
|
|
4969
|
+
const destinationPath = isParentPath(appendPath(context.config.output.path, context.config.cwd), appendPath(context.config.root, context.config.cwd)) ? joinPaths(context.config.output.copy.path, relativePath(appendPath(context.config.root, context.config.cwd), appendPath(context.config.output.path, context.config.cwd))) : joinPaths(context.config.output.copy.path, "dist");
|
|
4970
|
+
const sourcePath = context.config.output.path;
|
|
4971
|
+
if (existsSync(sourcePath) && sourcePath !== destinationPath) {
|
|
4972
|
+
context.debug(`Copying files from project's build output directory (${context.config.output.path}) to the project's copy/publish directory (${destinationPath}).`);
|
|
4973
|
+
await copyFiles(sourcePath, destinationPath);
|
|
4974
|
+
} else context.warn(`The source path for the copy operation ${!existsSync(sourcePath) ? "does not exist" : "is the same as the destination path"}. Source: ${sourcePath}, Destination: ${destinationPath}. Skipping copying of build output files.`);
|
|
4975
|
+
if (context.config.output.copy.assets && Array.isArray(context.config.output.copy.assets)) await Promise.all(context.config.output.copy.assets.map(async (asset) => {
|
|
4976
|
+
context.trace(`Copying asset(s): ${chalk.redBright(context.config.cwd === asset.input ? asset.glob : appendPath(asset.glob, replacePath(asset.input, context.config.cwd)))} -> ${chalk.greenBright(appendPath(asset.glob, replacePath(asset.output, context.config.cwd)))} ${Array.isArray(asset.ignore) && asset.ignore.length > 0 ? ` (ignoring: ${asset.ignore.map((i) => chalk.yellowBright(i)).join(", ")})` : ""}`);
|
|
4977
|
+
await context.fs.copy(asset, asset.output);
|
|
4978
|
+
}));
|
|
4979
|
+
} else context.debug("No copy configuration found for the project output. Skipping the copying of build output files.");
|
|
4980
|
+
await this.callHook("build", {
|
|
4981
|
+
environment: context,
|
|
4982
|
+
order: "post"
|
|
4983
|
+
});
|
|
4984
|
+
}
|
|
4985
|
+
/**
|
|
4986
|
+
* Generate the Powerlines TypeScript declaration file
|
|
4987
|
+
*
|
|
4988
|
+
* @remarks
|
|
4989
|
+
* This method will generate the TypeScript declaration file for the Powerlines project, including any types provided by plugins.
|
|
4990
|
+
*
|
|
4991
|
+
* @param context - The environment context to use for generating the TypeScript declaration file
|
|
4992
|
+
* @returns A promise that resolves when the TypeScript declaration file has been generated
|
|
4993
|
+
*/
|
|
4994
|
+
async handleTypes(context) {
|
|
4995
|
+
context.debug(`Preparing the TypeScript definitions for the Powerlines project.`);
|
|
4996
|
+
if (context.fs.existsSync(context.typesPath)) await context.fs.remove(context.typesPath);
|
|
4997
|
+
if (!await resolvePackage("typescript")) throw new Error("Could not resolve TypeScript package location. Please ensure TypeScript is installed.");
|
|
4998
|
+
context.debug("Running TypeScript compiler for built-in runtime module files.");
|
|
4999
|
+
let { code, directives } = await emitBuiltinTypes(context, (await context.getBuiltins()).reduce((ret, builtin) => {
|
|
5000
|
+
const formatted = replacePath(builtin.path, context.config.cwd);
|
|
5001
|
+
if (!ret.includes(formatted)) ret.push(formatted);
|
|
5002
|
+
return ret;
|
|
5003
|
+
}, []));
|
|
5004
|
+
context.debug(`Generating TypeScript declaration file ${context.typesPath}.`);
|
|
5005
|
+
const merge = async (currentResult, previousResult) => {
|
|
5006
|
+
if (!isSetString(currentResult) && !isSetObject(currentResult) && !isSetString(previousResult) && !isSetObject(previousResult)) return {
|
|
5007
|
+
code,
|
|
5008
|
+
directives
|
|
5009
|
+
};
|
|
5010
|
+
const previous = (await format(context, context.typesPath, isSetString(previousResult) ? previousResult : isSetObject(previousResult) ? previousResult.code : "")).trim().replace(code, "").trim();
|
|
5011
|
+
const current = (await format(context, context.typesPath, isSetString(currentResult) ? currentResult : isSetObject(currentResult) ? currentResult.code : "")).trim().replace(previous, "").trim().replace(code, "").trim();
|
|
5012
|
+
return {
|
|
5013
|
+
directives: [...isSetObject(currentResult) && currentResult.directives ? currentResult.directives : [], ...isSetObject(previousResult) && previousResult.directives ? previousResult.directives : []],
|
|
5014
|
+
code: await format(context, context.typesPath, `${!previous.includes(getTypescriptFileHeader(context)) && !current.includes(getTypescriptFileHeader(context)) ? `${code}\n` : ""}${previous}\n${current}`.trim())
|
|
5015
|
+
};
|
|
5016
|
+
};
|
|
5017
|
+
const asNextParam = (previousResult) => isObject(previousResult) ? previousResult.code : previousResult;
|
|
5018
|
+
let result = await this.callHook("types", {
|
|
5019
|
+
environment: context,
|
|
5020
|
+
sequential: true,
|
|
5021
|
+
order: "pre",
|
|
5022
|
+
result: "merge",
|
|
5023
|
+
merge,
|
|
5024
|
+
asNextParam
|
|
5025
|
+
}, code);
|
|
5026
|
+
if (result) {
|
|
5027
|
+
if (isSetObject(result)) {
|
|
5028
|
+
code = result.code;
|
|
5029
|
+
if (Array.isArray(result.directives) && result.directives.length > 0) directives = getUnique([...directives, ...result.directives]).filter(Boolean);
|
|
5030
|
+
} else if (isSetString(result)) code = result;
|
|
5031
|
+
}
|
|
5032
|
+
result = await this.callHook("types", {
|
|
5033
|
+
environment: context,
|
|
5034
|
+
sequential: true,
|
|
5035
|
+
order: "normal",
|
|
5036
|
+
result: "merge",
|
|
5037
|
+
merge,
|
|
5038
|
+
asNextParam
|
|
5039
|
+
}, code);
|
|
5040
|
+
if (result) {
|
|
5041
|
+
if (isSetObject(result)) {
|
|
5042
|
+
code = result.code;
|
|
5043
|
+
if (Array.isArray(result.directives) && result.directives.length > 0) directives = getUnique([...directives, ...result.directives]).filter(Boolean);
|
|
5044
|
+
} else if (isSetString(result)) code = result;
|
|
5045
|
+
}
|
|
5046
|
+
result = await this.callHook("types", {
|
|
5047
|
+
environment: context,
|
|
5048
|
+
sequential: true,
|
|
5049
|
+
order: "post",
|
|
5050
|
+
result: "merge",
|
|
5051
|
+
merge,
|
|
5052
|
+
asNextParam
|
|
5053
|
+
}, code);
|
|
5054
|
+
if (result) {
|
|
5055
|
+
if (isSetObject(result)) {
|
|
5056
|
+
code = result.code;
|
|
5057
|
+
if (Array.isArray(result.directives) && result.directives.length > 0) directives = getUnique([...directives, ...result.directives]).filter(Boolean);
|
|
5058
|
+
} else if (isSetString(result)) code = result;
|
|
5059
|
+
}
|
|
5060
|
+
if (isSetString(code?.trim()) || directives.length > 0) await context.fs.write(context.typesPath, `${directives.length > 0 ? `${directives.map((directive) => `/// <reference types="${directive}" />`).join("\n")}
|
|
5061
|
+
|
|
5062
|
+
` : ""}${getTypescriptFileHeader(context, {
|
|
5063
|
+
directive: null,
|
|
5064
|
+
prettierIgnore: false
|
|
5065
|
+
})}
|
|
5066
|
+
|
|
5067
|
+
${formatTypes(code)}
|
|
5068
|
+
`);
|
|
5069
|
+
}
|
|
5015
5070
|
};
|
|
5016
5071
|
|
|
5017
5072
|
//#endregion
|
|
5018
5073
|
//#region src/_internal/worker.ts
|
|
5019
5074
|
async function clean({ options, initialConfig, inlineConfig }) {
|
|
5020
|
-
await (await PowerlinesExecution.
|
|
5075
|
+
await (await PowerlinesExecution.from(options, initialConfig)).clean(inlineConfig);
|
|
5021
5076
|
}
|
|
5022
5077
|
async function prepare({ options, initialConfig, inlineConfig }) {
|
|
5023
|
-
await (await PowerlinesExecution.
|
|
5078
|
+
await (await PowerlinesExecution.from(options, initialConfig)).prepare(inlineConfig);
|
|
5024
5079
|
}
|
|
5025
5080
|
async function types({ options, initialConfig, inlineConfig }) {
|
|
5026
|
-
await (await PowerlinesExecution.
|
|
5081
|
+
await (await PowerlinesExecution.from(options, initialConfig)).types(inlineConfig);
|
|
5027
5082
|
}
|
|
5028
5083
|
async function lint({ options, initialConfig, inlineConfig }) {
|
|
5029
|
-
await (await PowerlinesExecution.
|
|
5084
|
+
await (await PowerlinesExecution.from(options, initialConfig)).lint(inlineConfig);
|
|
5030
5085
|
}
|
|
5031
5086
|
async function test({ options, initialConfig, inlineConfig }) {
|
|
5032
|
-
await (await PowerlinesExecution.
|
|
5087
|
+
await (await PowerlinesExecution.from(options, initialConfig)).test(inlineConfig);
|
|
5033
5088
|
}
|
|
5034
5089
|
async function build({ options, initialConfig, inlineConfig }) {
|
|
5035
|
-
await (await PowerlinesExecution.
|
|
5090
|
+
await (await PowerlinesExecution.from(options, initialConfig)).build(inlineConfig);
|
|
5036
5091
|
}
|
|
5037
5092
|
async function docs({ options, initialConfig, inlineConfig }) {
|
|
5038
|
-
await (await PowerlinesExecution.
|
|
5093
|
+
await (await PowerlinesExecution.from(options, initialConfig)).docs(inlineConfig);
|
|
5039
5094
|
}
|
|
5040
5095
|
async function deploy({ options, initialConfig, inlineConfig }) {
|
|
5041
|
-
await (await PowerlinesExecution.
|
|
5096
|
+
await (await PowerlinesExecution.from(options, initialConfig)).deploy(inlineConfig);
|
|
5042
5097
|
}
|
|
5043
5098
|
|
|
5044
5099
|
//#endregion
|