nx
Advanced tools
Comparing version 19.4.0-canary.20240626-3a2e8d4 to 19.4.0-canary.20240627-c2c6a13
{ | ||
"name": "nx", | ||
"version": "19.4.0-canary.20240626-3a2e8d4", | ||
"version": "19.4.0-canary.20240627-c2c6a13", | ||
"private": false, | ||
@@ -48,4 +48,4 @@ "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.", | ||
"cliui": "^8.0.1", | ||
"dotenv": "~16.3.1", | ||
"dotenv-expand": "~10.0.0", | ||
"dotenv": "~16.4.5", | ||
"dotenv-expand": "~11.0.6", | ||
"enquirer": "~2.3.6", | ||
@@ -74,3 +74,3 @@ "figures": "3.2.0", | ||
"ora": "5.3.0", | ||
"@nrwl/tao": "19.4.0-canary.20240626-3a2e8d4" | ||
"@nrwl/tao": "19.4.0-canary.20240627-c2c6a13" | ||
}, | ||
@@ -90,12 +90,12 @@ "peerDependencies": { | ||
"optionalDependencies": { | ||
"@nx/nx-darwin-x64": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-darwin-arm64": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-linux-x64-gnu": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-linux-x64-musl": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-win32-x64-msvc": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-linux-arm64-gnu": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-linux-arm64-musl": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-linux-arm-gnueabihf": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-win32-arm64-msvc": "19.4.0-canary.20240626-3a2e8d4", | ||
"@nx/nx-freebsd-x64": "19.4.0-canary.20240626-3a2e8d4" | ||
"@nx/nx-darwin-x64": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-darwin-arm64": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-linux-x64-gnu": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-linux-x64-musl": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-win32-x64-msvc": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-linux-arm64-gnu": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-linux-arm64-musl": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-linux-arm-gnueabihf": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-win32-arm64-msvc": "19.4.0-canary.20240627-c2c6a13", | ||
"@nx/nx-freebsd-x64": "19.4.0-canary.20240627-c2c6a13" | ||
}, | ||
@@ -102,0 +102,0 @@ "nx-migrations": { |
@@ -6,4 +6,4 @@ import { NxJsonConfiguration } from '../../config/nx-json'; | ||
export declare function connectToNxCloudIfExplicitlyAsked(opts: NxArgs): Promise<void>; | ||
export declare function connectToNxCloudCommand(): Promise<boolean>; | ||
export declare function connectToNxCloudCommand(command?: string): Promise<boolean>; | ||
export declare function connectToNxCloudWithPrompt(command: string): Promise<void>; | ||
export declare function connectExistingRepoToNxCloudPrompt(key?: MessageKey): Promise<boolean>; |
@@ -44,34 +44,25 @@ "use strict"; | ||
exports.connectToNxCloudIfExplicitlyAsked = connectToNxCloudIfExplicitlyAsked; | ||
async function connectToNxCloudCommand() { | ||
async function connectToNxCloudCommand(command) { | ||
const nxJson = (0, configuration_1.readNxJson)(); | ||
if ((0, nx_cloud_utils_1.isNxCloudUsed)(nxJson)) { | ||
if (process.env.NX_NEW_CLOUD_ONBOARDING !== 'true') { | ||
output_1.output.log({ | ||
title: '✔ This workspace already has Nx Cloud set up', | ||
bodyLines: [ | ||
'If you have not done so already, connect your workspace to your Nx Cloud account:', | ||
`- Login at ${(0, nx_cloud_utils_1.getNxCloudUrl)(nxJson)} to connect your repository`, | ||
], | ||
}); | ||
const token = process.env.NX_CLOUD_ACCESS_TOKEN || nxJson.nxCloudAccessToken; | ||
if (!token) { | ||
throw new Error(`Unable to authenticate. Either define accessToken in nx.json or set the NX_CLOUD_ACCESS_TOKEN env variable.`); | ||
} | ||
else { | ||
const token = process.env.NX_CLOUD_ACCESS_TOKEN || nxJson.nxCloudAccessToken; | ||
if (!token) { | ||
throw new Error(`Unable to authenticate. Either define accessToken in nx.json or set the NX_CLOUD_ACCESS_TOKEN env variable.`); | ||
} | ||
const connectCloudUrl = await (0, url_shorten_1.shortenedCloudUrl)('nx-connect', token); | ||
output_1.output.log({ | ||
title: '✔ This workspace already has Nx Cloud set up', | ||
bodyLines: [ | ||
'If you have not done so already, connect your workspace to your Nx Cloud account:', | ||
`- Connect with Nx Cloud at: | ||
const connectCloudUrl = await (0, url_shorten_1.shortenedCloudUrl)('nx-connect', token); | ||
output_1.output.log({ | ||
title: '✔ This workspace already has Nx Cloud set up', | ||
bodyLines: [ | ||
'If you have not done so already, connect your workspace to your Nx Cloud account:', | ||
`- Connect with Nx Cloud at: | ||
${connectCloudUrl}`, | ||
], | ||
}); | ||
} | ||
], | ||
}); | ||
return false; | ||
} | ||
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, false, 'connect-to-nx-cloud'); | ||
const callback = await (0, connect_to_nx_cloud_1.connectToNxCloud)(tree, {}); | ||
const callback = await (0, connect_to_nx_cloud_1.connectToNxCloud)(tree, { | ||
installationSource: command ?? 'nx-connect', | ||
}); | ||
tree.lock(); | ||
@@ -85,3 +76,3 @@ (0, tree_1.flushChanges)(workspace_root_1.workspaceRoot, tree.listChanges()); | ||
const setNxCloud = await nxCloudPrompt('setupNxCloud'); | ||
const useCloud = setNxCloud === 'yes' ? await connectToNxCloudCommand() : false; | ||
const useCloud = setNxCloud === 'yes' ? await connectToNxCloudCommand(command) : false; | ||
await (0, ab_testing_1.recordStat)({ | ||
@@ -88,0 +79,0 @@ command, |
@@ -26,2 +26,3 @@ import { ProjectFileMap, ProjectGraphDependency, ProjectGraphProjectNode } from '../../config/project-graph'; | ||
errors?: GraphError[]; | ||
connectedToCloud?: boolean; | ||
} | ||
@@ -28,0 +29,0 @@ export interface TaskGraphClientResponse { |
@@ -31,2 +31,3 @@ "use strict"; | ||
const error_types_1 = require("../../project-graph/error-types"); | ||
const nx_cloud_utils_1 = require("../../utils/nx-cloud-utils"); | ||
// maps file extention to MIME types | ||
@@ -482,2 +483,3 @@ const mimeType = { | ||
let errors; | ||
let connectedToCloud; | ||
try { | ||
@@ -487,2 +489,3 @@ const projectGraphAndSourceMaps = await (0, project_graph_1.createProjectGraphAndSourceMapsAsync)({ exitOnError: false }); | ||
sourceMaps = projectGraphAndSourceMaps.sourceMaps; | ||
connectedToCloud = (0, nx_cloud_utils_1.isNxCloudUsed)((0, configuration_1.readNxJson)()); | ||
} | ||
@@ -515,3 +518,10 @@ catch (e) { | ||
const hasher = (0, crypto_1.createHash)('sha256'); | ||
hasher.update(JSON.stringify({ layout, projects, dependencies, sourceMaps, errors })); | ||
hasher.update(JSON.stringify({ | ||
layout, | ||
projects, | ||
dependencies, | ||
sourceMaps, | ||
errors, | ||
connectedToCloud, | ||
})); | ||
const hash = hasher.digest('hex'); | ||
@@ -532,2 +542,3 @@ perf_hooks_1.performance.mark('project graph response generation:end'); | ||
errors, | ||
connectedToCloud, | ||
}, | ||
@@ -534,0 +545,0 @@ sourceMapResponse: sourceMaps, |
@@ -31,6 +31,7 @@ "use strict"; | ||
handler: async (args) => { | ||
await (0, params_1.handleErrors)(args.verbose ?? process.env.NX_VERBOSE_LOGGING === 'true', async () => { | ||
const exitCode = await (0, params_1.handleErrors)(args.verbose ?? process.env.NX_VERBOSE_LOGGING === 'true', async () => { | ||
return (await Promise.resolve().then(() => require('./run-one'))).runOne(process.cwd(), (0, shared_options_1.withOverrides)(args, 0)); | ||
}); | ||
process.exit(exitCode); | ||
}, | ||
}; |
@@ -116,2 +116,3 @@ import type { NxJsonConfiguration, NxReleaseVersionConfiguration } from './nx-json'; | ||
technologies?: string[]; | ||
nonAtomizedTarget?: string; | ||
} | ||
@@ -118,0 +119,0 @@ export interface TargetDependencyConfig { |
@@ -10,3 +10,4 @@ export declare const isWindows: boolean; | ||
export declare const getForkedProcessOsSocketPath: (id: string) => string; | ||
export declare const getPluginOsSocketPath: (id: string) => string; | ||
export declare function killSocketOrPath(): void; | ||
export declare function serializeResult(error: Error | null, serializedProjectGraph: string | null, serializedSourceMaps: string | null): string | null; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.serializeResult = exports.killSocketOrPath = exports.getForkedProcessOsSocketPath = exports.getFullOsSocketPath = exports.isWindows = void 0; | ||
exports.serializeResult = exports.killSocketOrPath = exports.getPluginOsSocketPath = exports.getForkedProcessOsSocketPath = exports.getFullOsSocketPath = exports.isWindows = void 0; | ||
const fs_1 = require("fs"); | ||
@@ -25,2 +25,7 @@ const os_1 = require("os"); | ||
exports.getForkedProcessOsSocketPath = getForkedProcessOsSocketPath; | ||
const getPluginOsSocketPath = (id) => { | ||
let path = (0, path_1.resolve)((0, path_1.join)((0, tmp_dir_1.getSocketDir)(), 'plugin' + id + '.sock')); | ||
return exports.isWindows ? '\\\\.\\pipe\\nx\\' + (0, path_1.resolve)(path) : (0, path_1.resolve)(path); | ||
}; | ||
exports.getPluginOsSocketPath = getPluginOsSocketPath; | ||
function killSocketOrPath() { | ||
@@ -27,0 +32,0 @@ try { |
@@ -11,15 +11,20 @@ "use strict"; | ||
const exit_codes_1 = require("../../utils/exit-codes"); | ||
const task_env_1 = require("../../tasks-runner/task-env"); | ||
exports.LARGE_BUFFER = 1024 * 1000000; | ||
let pseudoTerminal; | ||
const childProcesses = new Set(); | ||
async function loadEnvVars(path) { | ||
function loadEnvVarsFile(path, env = {}) { | ||
(0, task_env_1.unloadDotEnvFile)(path, env); | ||
const result = (0, task_env_1.loadAndExpandDotEnvFile)(path, env); | ||
if (result.error) { | ||
throw result.error; | ||
} | ||
} | ||
function loadEnvVars(path, env = {}) { | ||
if (path) { | ||
const result = (await Promise.resolve().then(() => require('dotenv'))).config({ path }); | ||
if (result.error) { | ||
throw result.error; | ||
} | ||
loadEnvVarsFile(path, env); | ||
} | ||
else { | ||
try { | ||
(await Promise.resolve().then(() => require('dotenv'))).config(); | ||
loadEnvVarsFile('.env', env); | ||
} | ||
@@ -50,5 +55,2 @@ catch { } | ||
registerProcessListener(); | ||
if (process.env.NX_LOAD_DOT_ENV_FILES !== 'false') { | ||
await loadEnvVars(options.envFile); | ||
} | ||
const normalized = normalizeOptions(options); | ||
@@ -77,3 +79,3 @@ if (normalized.readyWhenStatus.length && !normalized.parallel) { | ||
async function runInParallel(options, context) { | ||
const procs = options.commands.map((c) => createProcess(null, c, options.readyWhenStatus, options.color, calculateCwd(options.cwd, context), options.env ?? {}, true, options.usePty, options.streamOutput, options.tty).then((result) => ({ | ||
const procs = options.commands.map((c) => createProcess(null, c, options.readyWhenStatus, options.color, calculateCwd(options.cwd, context), options.env ?? {}, true, options.usePty, options.streamOutput, options.tty, options.envFile).then((result) => ({ | ||
result, | ||
@@ -168,3 +170,3 @@ command: c.command, | ||
for (const c of options.commands) { | ||
const result = await createProcess(pseudoTerminal, c, [], options.color, calculateCwd(options.cwd, context), options.env ?? {}, false, options.usePty, options.streamOutput, options.tty); | ||
const result = await createProcess(pseudoTerminal, c, [], options.color, calculateCwd(options.cwd, context), options.processEnv ?? options.env ?? {}, false, options.usePty, options.streamOutput, options.tty, options.envFile); | ||
terminalOutput += result.terminalOutput; | ||
@@ -182,4 +184,4 @@ if (!result.success) { | ||
} | ||
async function createProcess(pseudoTerminal, commandConfig, readyWhenStatus = [], color, cwd, env, isParallel, usePty = true, streamOutput = true, tty) { | ||
env = processEnv(color, cwd, env); | ||
async function createProcess(pseudoTerminal, commandConfig, readyWhenStatus = [], color, cwd, env, isParallel, usePty = true, streamOutput = true, tty, envFile) { | ||
env = processEnv(color, cwd, env, envFile); | ||
// The rust runCommand is always a tty, so it will not look nice in parallel and if we need prefixes | ||
@@ -290,3 +292,3 @@ // currently does not work properly in windows | ||
} | ||
function processEnv(color, cwd, env) { | ||
function processEnv(color, cwd, env, envFile) { | ||
const localEnv = (0, npm_run_path_1.env)({ cwd: cwd ?? process.cwd() }); | ||
@@ -298,2 +300,5 @@ const res = { | ||
}; | ||
if (process.env.NX_LOAD_DOT_ENV_FILES !== 'false') { | ||
loadEnvVars(envFile, res); | ||
} | ||
// need to override PATH to make sure we are using the local node_modules | ||
@@ -300,0 +305,0 @@ if (localEnv.PATH) |
@@ -7,4 +7,5 @@ import { Tree } from '../../../generators/tree'; | ||
github?: boolean; | ||
directory?: string; | ||
} | ||
export declare function connectToNxCloud(tree: Tree, schema: ConnectToNxCloudOptions): Promise<() => void>; | ||
export default connectToNxCloud; |
@@ -5,3 +5,2 @@ "use strict"; | ||
const child_process_1 = require("child_process"); | ||
const node_url_1 = require("node:url"); | ||
const output_1 = require("../../../utils/output"); | ||
@@ -12,2 +11,5 @@ const json_1 = require("../../../generators/utils/json"); | ||
const url_shorten_1 = require("../../utilities/url-shorten"); | ||
const git_utils_1 = require("../../../utils/git-utils"); | ||
const ora = require("ora"); | ||
const open = require("open"); | ||
function printCloudConnectionDisabledMessage() { | ||
@@ -62,31 +64,55 @@ output_1.output.error({ | ||
} | ||
async function printSuccessMessage(url, token, installationSource, github) { | ||
if (process.env.NX_NEW_CLOUD_ONBOARDING !== 'true') { | ||
let origin = 'https://nx.app'; | ||
async function printSuccessMessage(url, token, installationSource, usesGithub, directory) { | ||
const connectCloudUrl = await (0, url_shorten_1.shortenedCloudUrl)(installationSource, token, usesGithub); | ||
if (installationSource === 'nx-connect' && usesGithub) { | ||
try { | ||
origin = new node_url_1.URL(url).origin; | ||
const cloudConnectSpinner = ora(`Opening Nx Cloud ${connectCloudUrl} in your browser to connect your workspace.`).start(); | ||
await sleep(2000); | ||
open(connectCloudUrl); | ||
cloudConnectSpinner.succeed(); | ||
} | ||
catch (e) { } | ||
output_1.output.note({ | ||
title: `Your Nx Cloud workspace is public`, | ||
bodyLines: [ | ||
`To restrict access, connect it to your Nx Cloud account:`, | ||
`- Push your changes`, | ||
`- Login at ${origin} to connect your repository`, | ||
], | ||
}); | ||
catch (e) { | ||
output_1.output.note({ | ||
title: `Your Nx Cloud workspace is ready.`, | ||
bodyLines: [ | ||
`To claim it, connect it to your Nx Cloud account:`, | ||
`- Go to the following URL to connect your workspace to Nx Cloud:`, | ||
'', | ||
`${connectCloudUrl}`, | ||
], | ||
}); | ||
} | ||
} | ||
else { | ||
const connectCloudUrl = await (0, url_shorten_1.shortenedCloudUrl)(installationSource, token, github); | ||
output_1.output.note({ | ||
title: `Your Nx Cloud workspace is ready.`, | ||
bodyLines: [ | ||
`To claim it, connect it to your Nx Cloud account:`, | ||
`- Commit and push your changes.`, | ||
`- Create a pull request for the changes.`, | ||
`- Go to the following URL to connect your workspace to Nx Cloud: | ||
${connectCloudUrl}`, | ||
], | ||
}); | ||
if (installationSource === 'create-nx-workspace') { | ||
output_1.output.note({ | ||
title: `Your Nx Cloud workspace is ready.`, | ||
bodyLines: [ | ||
`To claim it, connect it to your Nx Cloud account:`, | ||
`- Push your repository to your git hosting provider.`, | ||
`- Go to the following URL to connect your workspace to Nx Cloud:`, | ||
'', | ||
`${connectCloudUrl}`, | ||
], | ||
}); | ||
(0, git_utils_1.commitChanges)(`feat(nx): Added Nx Cloud token to your nx.json | ||
To connect your workspace to Nx Cloud, push your repository | ||
to your git hosting provider and go to the following URL: | ||
${connectCloudUrl}`, directory); | ||
} | ||
else { | ||
output_1.output.note({ | ||
title: `Your Nx Cloud workspace is ready.`, | ||
bodyLines: [ | ||
`To claim it, connect it to your Nx Cloud account:`, | ||
`- Commit and push your changes.`, | ||
`- Create a pull request for the changes.`, | ||
`- Go to the following URL to connect your workspace to Nx Cloud:`, | ||
'', | ||
`${connectCloudUrl}`, | ||
], | ||
}); | ||
} | ||
} | ||
@@ -114,12 +140,21 @@ } | ||
else { | ||
// TODO: Change to using loading light client when that is enabled by default | ||
const r = await createNxCloudWorkspace(getRootPackageName(tree), schema.installationSource, getNxInitDate()); | ||
addNxCloudOptionsToNxJson(tree, nxJson, r.token); | ||
await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, { | ||
silent: schema.hideFormatLogs, | ||
}); | ||
return async () => await printSuccessMessage(r.url, r.token, schema.installationSource, schema.github); | ||
const usesGithub = await (0, url_shorten_1.repoUsesGithub)(schema.github); | ||
let responseFromCreateNxCloudWorkspace; | ||
// do NOT create Nx Cloud token (createNxCloudWorkspace) | ||
// if user is using github and is running nx-connect | ||
if (!(usesGithub && schema.installationSource === 'nx-connect')) { | ||
responseFromCreateNxCloudWorkspace = await createNxCloudWorkspace(getRootPackageName(tree), schema.installationSource, getNxInitDate()); | ||
addNxCloudOptionsToNxJson(tree, nxJson, responseFromCreateNxCloudWorkspace?.token); | ||
await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, { | ||
silent: schema.hideFormatLogs, | ||
}); | ||
} | ||
const apiUrl = removeTrailingSlash(process.env.NX_CLOUD_API || process.env.NRWL_API || `https://cloud.nx.app`); | ||
return async () => await printSuccessMessage(responseFromCreateNxCloudWorkspace?.url ?? apiUrl, responseFromCreateNxCloudWorkspace?.token, schema.installationSource, usesGithub, schema.directory); | ||
} | ||
} | ||
exports.connectToNxCloud = connectToNxCloud; | ||
function sleep(ms) { | ||
return new Promise((resolve) => setTimeout(resolve, ms)); | ||
} | ||
exports.default = connectToNxCloud; |
@@ -28,2 +28,7 @@ { | ||
"default": false | ||
}, | ||
"directory": { | ||
"type": "string", | ||
"description": "The directory where the workspace is located", | ||
"x-priority": "internal" | ||
} | ||
@@ -30,0 +35,0 @@ }, |
@@ -1,1 +0,2 @@ | ||
export declare function shortenedCloudUrl(installationSource: string, accessToken: string, github?: boolean): Promise<string>; | ||
export declare function shortenedCloudUrl(installationSource: string, accessToken?: string, usesGithub?: boolean): Promise<string>; | ||
export declare function repoUsesGithub(github?: boolean): Promise<boolean>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.shortenedCloudUrl = void 0; | ||
exports.repoUsesGithub = exports.shortenedCloudUrl = void 0; | ||
const devkit_exports_1 = require("../../devkit-exports"); | ||
const git_utils_1 = require("../../utils/git-utils"); | ||
async function shortenedCloudUrl(installationSource, accessToken, github) { | ||
const semver_1 = require("semver"); | ||
async function shortenedCloudUrl(installationSource, accessToken, usesGithub) { | ||
const githubSlug = (0, git_utils_1.getGithubSlugOrNull)(); | ||
const apiUrl = removeTrailingSlash(process.env.NX_CLOUD_API || process.env.NRWL_API || `https://cloud.nx.app`); | ||
const installationSupportsGitHub = await getInstallationSupportsGitHub(apiUrl); | ||
const usesGithub = (githubSlug || github) && | ||
(apiUrl.includes('cloud.nx.app') || | ||
apiUrl.includes('eu.nx.app') || | ||
installationSupportsGitHub); | ||
const version = await getNxCloudVersion(apiUrl); | ||
if (version && (0, semver_1.lt)(truncateToSemver(version), '2406.11.5')) { | ||
return apiUrl; | ||
} | ||
const source = getSource(installationSource); | ||
@@ -30,6 +30,16 @@ try { | ||
${e}`); | ||
return getURLifShortenFailed(usesGithub, githubSlug, apiUrl, accessToken, source); | ||
return getURLifShortenFailed(usesGithub, githubSlug, apiUrl, source, accessToken); | ||
} | ||
} | ||
exports.shortenedCloudUrl = shortenedCloudUrl; | ||
async function repoUsesGithub(github) { | ||
const githubSlug = (0, git_utils_1.getGithubSlugOrNull)(); | ||
const apiUrl = removeTrailingSlash(process.env.NX_CLOUD_API || process.env.NRWL_API || `https://cloud.nx.app`); | ||
const installationSupportsGitHub = await getInstallationSupportsGitHub(apiUrl); | ||
return ((githubSlug || github) && | ||
(apiUrl.includes('cloud.nx.app') || | ||
apiUrl.includes('eu.nx.app') || | ||
installationSupportsGitHub)); | ||
} | ||
exports.repoUsesGithub = repoUsesGithub; | ||
function removeTrailingSlash(apiUrl) { | ||
@@ -52,9 +62,9 @@ return apiUrl[apiUrl.length - 1] === '/' ? apiUrl.slice(0, -1) : apiUrl; | ||
} | ||
function getURLifShortenFailed(usesGithub, githubSlug, apiUrl, accessToken, source) { | ||
function getURLifShortenFailed(usesGithub, githubSlug, apiUrl, source, accessToken) { | ||
if (usesGithub) { | ||
if (githubSlug) { | ||
return `${apiUrl}/setup/connect-workspace/vcs?provider=GITHUB&selectedRepositoryName=${encodeURIComponent(githubSlug)}&source=${source}`; | ||
return `${apiUrl}/setup/connect-workspace/github/connect?name=${encodeURIComponent(githubSlug)}&source=${source}`; | ||
} | ||
else { | ||
return `${apiUrl}/setup/connect-workspace/vcs?provider=GITHUB&source=${source}`; | ||
return `${apiUrl}/setup/connect-workspace/github/select&source=${source}`; | ||
} | ||
@@ -80,1 +90,27 @@ } | ||
} | ||
async function getNxCloudVersion(apiUrl) { | ||
try { | ||
const response = await require('axios').get(`${apiUrl}/version`, { | ||
responseType: 'document', | ||
}); | ||
const version = extractVersion(response.data); | ||
if (!version) { | ||
throw new Error('Failed to extract version from response.'); | ||
} | ||
return version; | ||
} | ||
catch (e) { | ||
devkit_exports_1.logger.verbose(`Failed to get version of Nx Cloud. | ||
${e}`); | ||
} | ||
} | ||
function extractVersion(htmlString) { | ||
// The pattern assumes 'Version' is inside an h1 tag and the version number is the next span's content | ||
const regex = /<h1[^>]*>Version<\/h1>\s*<div[^>]*><div[^>]*><div[^>]*><span[^>]*>([^<]+)<\/span>/; | ||
const match = htmlString.match(regex); | ||
return match ? match[1].trim() : null; | ||
} | ||
function truncateToSemver(versionString) { | ||
// version may be something like 2406.13.5.hotfix2 | ||
return versionString.split(/[\.-]/).slice(0, 3).join('.'); | ||
} |
@@ -8,2 +8,3 @@ "use strict"; | ||
const package_json_1 = require("../../../utils/package-json"); | ||
const package_json_workspaces_1 = require("../../package-json-workspaces"); | ||
// TODO: Remove this one day, this should not need to be done. | ||
@@ -31,4 +32,10 @@ exports.PackageJsonProjectsNextToProjectJsonPlugin = { | ||
const root = (0, path_1.dirname)(projectJsonPath); | ||
const packageJsonPath = (0, path_1.join)(workspaceRoot, root, 'package.json'); | ||
if (!(0, fs_1.existsSync)(packageJsonPath)) { | ||
const relativePackageJsonPath = (0, path_1.join)(root, 'package.json'); | ||
const packageJsonPath = (0, path_1.join)(workspaceRoot, relativePackageJsonPath); | ||
const readJson = (f) => (0, fileutils_1.readJsonFile)((0, path_1.join)(workspaceRoot, f)); | ||
// Do not create projects for package.json files | ||
// that are part of the package manager workspaces | ||
// Those package.json files will be processed later on | ||
const matcher = (0, package_json_workspaces_1.buildPackageJsonWorkspacesMatcher)(workspaceRoot, readJson); | ||
if (!(0, fs_1.existsSync)(packageJsonPath) || matcher(relativePackageJsonPath)) { | ||
return null; | ||
@@ -35,0 +42,0 @@ } |
@@ -20,2 +20,3 @@ import { TargetConfiguration } from '../../config/workspace-json-project-json'; | ||
technologies?: string[]; | ||
nonAtomizedTarget?: string; | ||
}; | ||
@@ -35,2 +36,3 @@ executor?: undefined; | ||
technologies?: string[]; | ||
nonAtomizedTarget?: string; | ||
}; | ||
@@ -49,2 +51,3 @@ command?: undefined; | ||
technologies?: string[]; | ||
nonAtomizedTarget?: string; | ||
}; | ||
@@ -58,2 +61,3 @@ command?: undefined; | ||
technologies?: string[]; | ||
nonAtomizedTarget?: string; | ||
}; | ||
@@ -73,2 +77,3 @@ command?: undefined; | ||
technologies?: string[]; | ||
nonAtomizedTarget?: string; | ||
}; | ||
@@ -75,0 +80,0 @@ command?: undefined; |
@@ -79,3 +79,3 @@ "use strict"; | ||
for (const plugin of plugins) { | ||
const [loadedPluginPromise, cleanup] = loadingMethod(plugin, root); | ||
const [loadedPluginPromise, cleanup] = await loadingMethod(plugin, root); | ||
result.push(loadedPluginPromise); | ||
@@ -82,0 +82,0 @@ cleanupFunctions.push(cleanup); |
import { PluginConfiguration } from '../../../config/nx-json'; | ||
import { LoadedNxPlugin } from '../internal-api'; | ||
export declare function loadNxPluginInIsolation(plugin: PluginConfiguration, root?: string): readonly [Promise<LoadedNxPlugin>, () => void]; | ||
export declare function loadNxPluginInIsolation(plugin: PluginConfiguration, root?: string): Promise<readonly [Promise<LoadedNxPlugin>, () => void]>; |
@@ -6,23 +6,11 @@ "use strict"; | ||
const plugin_pool_1 = require("./plugin-pool"); | ||
/** | ||
* Used to ensure 1 plugin : 1 worker | ||
*/ | ||
const remotePluginCache = new Map(); | ||
function loadNxPluginInIsolation(plugin, root = workspace_root_1.workspaceRoot) { | ||
const cacheKey = JSON.stringify(plugin); | ||
if (remotePluginCache.has(cacheKey)) { | ||
return remotePluginCache.get(cacheKey); | ||
} | ||
const [loadingPlugin, cleanup] = (0, plugin_pool_1.loadRemoteNxPlugin)(plugin, root); | ||
// We clean up plugin workers when Nx process completes. | ||
const val = [ | ||
async function loadNxPluginInIsolation(plugin, root = workspace_root_1.workspaceRoot) { | ||
const [loadingPlugin, cleanup] = await (0, plugin_pool_1.loadRemoteNxPlugin)(plugin, root); | ||
return [ | ||
loadingPlugin, | ||
() => { | ||
cleanup(); | ||
remotePluginCache.delete(cacheKey); | ||
}, | ||
]; | ||
remotePluginCache.set(cacheKey, val); | ||
return val; | ||
} | ||
exports.loadNxPluginInIsolation = loadNxPluginInIsolation; |
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import { ProjectGraph, ProjectGraphProcessorContext } from '../../../config/project-graph'; | ||
import { PluginConfiguration } from '../../../config/nx-json'; | ||
import { CreateDependenciesContext, CreateMetadataContext, CreateNodesContext } from '../public-api'; | ||
import { CreateDependenciesContext, CreateMetadataContext, CreateNodesContextV2 } from '../public-api'; | ||
import { LoadedNxPlugin } from '../internal-api'; | ||
import { Serializable } from 'child_process'; | ||
import { Socket } from 'net'; | ||
export interface PluginWorkerLoadMessage { | ||
@@ -34,3 +36,3 @@ type: 'load'; | ||
configFiles: string[]; | ||
context: CreateNodesContext; | ||
context: CreateNodesContextV2; | ||
tx: string; | ||
@@ -116,3 +118,3 @@ }; | ||
type MessageHandlerReturn<T extends PluginWorkerMessage | PluginWorkerResult> = T extends PluginWorkerResult ? MaybePromise<PluginWorkerMessage | void> : MaybePromise<PluginWorkerResult | void>; | ||
export declare function consumeMessage<T extends PluginWorkerMessage | PluginWorkerResult>(raw: T, handlers: { | ||
export declare function consumeMessage<T extends PluginWorkerMessage | PluginWorkerResult>(socket: Socket, raw: T, handlers: { | ||
[K in T['type']]: (payload: Extract<T, { | ||
@@ -122,2 +124,3 @@ type: K; | ||
}): Promise<void>; | ||
export declare function sendMessageOverSocket(socket: Socket, message: PluginWorkerMessage | PluginWorkerResult): void; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.consumeMessage = exports.isPluginWorkerResult = exports.isPluginWorkerMessage = void 0; | ||
exports.sendMessageOverSocket = exports.consumeMessage = exports.isPluginWorkerResult = exports.isPluginWorkerMessage = void 0; | ||
function isPluginWorkerMessage(message) { | ||
@@ -13,2 +13,3 @@ return (typeof message === 'object' && | ||
'processProjectGraph', | ||
'createMetadata', | ||
].includes(message.type)); | ||
@@ -26,2 +27,3 @@ } | ||
'processProjectGraphResult', | ||
'createMetadataResult', | ||
].includes(message.type)); | ||
@@ -32,3 +34,3 @@ } | ||
// type safe and requires all handlers to be handled | ||
async function consumeMessage(raw, handlers) { | ||
async function consumeMessage(socket, raw, handlers) { | ||
const message = raw; | ||
@@ -39,3 +41,3 @@ const handler = handlers[message.type]; | ||
if (response) { | ||
process.send(response); | ||
sendMessageOverSocket(socket, response); | ||
} | ||
@@ -45,1 +47,5 @@ } | ||
exports.consumeMessage = consumeMessage; | ||
function sendMessageOverSocket(socket, message) { | ||
socket.write(JSON.stringify(message) + String.fromCodePoint(4)); | ||
} | ||
exports.sendMessageOverSocket = sendMessageOverSocket; |
import { PluginConfiguration } from '../../../config/nx-json'; | ||
import { LoadedNxPlugin } from '../internal-api'; | ||
export declare function loadRemoteNxPlugin(plugin: PluginConfiguration, root: string): [Promise<LoadedNxPlugin>, () => void]; | ||
export declare function loadRemoteNxPlugin(plugin: PluginConfiguration, root: string): Promise<[Promise<LoadedNxPlugin>, () => void]>; |
@@ -9,31 +9,16 @@ "use strict"; | ||
const internal_api_1 = require("../internal-api"); | ||
const socket_utils_1 = require("../../../daemon/socket-utils"); | ||
const consume_messages_from_socket_1 = require("../../../utils/consume-messages-from-socket"); | ||
const messaging_1 = require("./messaging"); | ||
const net_1 = require("net"); | ||
const cleanupFunctions = new Set(); | ||
const pluginNames = new Map(); | ||
function loadRemoteNxPlugin(plugin, root) { | ||
// this should only really be true when running unit tests within | ||
// the Nx repo. We still need to start the worker in this case, | ||
// but its typescript. | ||
const isWorkerTypescript = path.extname(__filename) === '.ts'; | ||
const workerPath = path.join(__dirname, 'plugin-worker'); | ||
const env = { | ||
...process.env, | ||
...(isWorkerTypescript | ||
? { | ||
// Ensures that the worker uses the same tsconfig as the main process | ||
TS_NODE_PROJECT: path.join(__dirname, '../../../../tsconfig.lib.json'), | ||
} | ||
: {}), | ||
}; | ||
const worker = (0, child_process_1.fork)(workerPath, [], { | ||
stdio: ['ignore', 'inherit', 'inherit', 'ipc'], | ||
env, | ||
execArgv: [ | ||
...process.execArgv, | ||
// If the worker is typescript, we need to register ts-node | ||
...(isWorkerTypescript ? ['-r', 'ts-node/register'] : []), | ||
], | ||
}); | ||
worker.send({ type: 'load', payload: { plugin, root } }); | ||
// logger.verbose(`[plugin-worker] started worker: ${worker.pid}`); | ||
const MAX_MESSAGE_WAIT = 1000 * 60 * 5; // 5 minutes | ||
const nxPluginWorkerCache = (global['nxPluginWorkerCache'] ??= new Map()); | ||
async function loadRemoteNxPlugin(plugin, root) { | ||
const cacheKey = JSON.stringify({ plugin, root }); | ||
if (nxPluginWorkerCache.has(cacheKey)) { | ||
return [nxPluginWorkerCache.get(cacheKey), () => { }]; | ||
} | ||
const { worker, socket } = await startPluginWorker(); | ||
const pendingPromises = new Map(); | ||
@@ -43,15 +28,24 @@ const exitHandler = createWorkerExitHandler(worker, pendingPromises); | ||
worker.off('exit', exitHandler); | ||
socket.destroy(); | ||
shutdownPluginWorker(worker); | ||
nxPluginWorkerCache.delete(cacheKey); | ||
}; | ||
cleanupFunctions.add(cleanupFunction); | ||
return [ | ||
new Promise((res, rej) => { | ||
worker.on('message', createWorkerHandler(worker, pendingPromises, res, rej)); | ||
worker.on('exit', exitHandler); | ||
}), | ||
() => { | ||
cleanupFunction(); | ||
cleanupFunctions.delete(cleanupFunction); | ||
}, | ||
]; | ||
const pluginPromise = new Promise((res, rej) => { | ||
(0, messaging_1.sendMessageOverSocket)(socket, { | ||
type: 'load', | ||
payload: { plugin, root }, | ||
}); | ||
// logger.verbose(`[plugin-worker] started worker: ${worker.pid}`); | ||
const loadTimeout = setTimeout(() => { | ||
rej(new Error('Plugin worker timed out when loading plugin:' + plugin)); | ||
}, MAX_MESSAGE_WAIT); | ||
socket.on('data', (0, consume_messages_from_socket_1.consumeMessagesFromSocket)(createWorkerHandler(worker, pendingPromises, (val) => { | ||
clearTimeout(loadTimeout); | ||
res(val); | ||
}, rej, socket))); | ||
worker.on('exit', exitHandler); | ||
}); | ||
nxPluginWorkerCache.set(cacheKey, pluginPromise); | ||
return [pluginPromise, cleanupFunction]; | ||
} | ||
@@ -73,9 +67,11 @@ exports.loadRemoteNxPlugin = loadRemoteNxPlugin; | ||
*/ | ||
function createWorkerHandler(worker, pending, onload, onloadError) { | ||
function createWorkerHandler(worker, pending, onload, onloadError, socket) { | ||
let pluginName; | ||
return function (message) { | ||
let txId = 0; | ||
return function (raw) { | ||
const message = JSON.parse(raw); | ||
if (!(0, messaging_1.isPluginWorkerResult)(message)) { | ||
return; | ||
} | ||
return (0, messaging_1.consumeMessage)(message, { | ||
return (0, messaging_1.consumeMessage)(socket, message, { | ||
'load-result': (result) => { | ||
@@ -94,5 +90,5 @@ if (result.success) { | ||
(configFiles, ctx) => { | ||
const tx = pluginName + ':createNodes:' + performance.now(); | ||
const tx = pluginName + worker.pid + ':createNodes:' + txId++; | ||
return registerPendingPromise(tx, pending, () => { | ||
worker.send({ | ||
(0, messaging_1.sendMessageOverSocket)(socket, { | ||
type: 'createNodes', | ||
@@ -107,5 +103,5 @@ payload: { configFiles, context: ctx, tx }, | ||
? (ctx) => { | ||
const tx = pluginName + ':createDependencies:' + performance.now(); | ||
const tx = pluginName + worker.pid + ':createDependencies:' + txId++; | ||
return registerPendingPromise(tx, pending, () => { | ||
worker.send({ | ||
(0, messaging_1.sendMessageOverSocket)(socket, { | ||
type: 'createDependencies', | ||
@@ -119,5 +115,5 @@ payload: { context: ctx, tx }, | ||
? (graph, ctx) => { | ||
const tx = pluginName + ':processProjectGraph:' + performance.now(); | ||
const tx = pluginName + worker.pid + ':processProjectGraph:' + txId++; | ||
return registerPendingPromise(tx, pending, () => { | ||
worker.send({ | ||
(0, messaging_1.sendMessageOverSocket)(socket, { | ||
type: 'processProjectGraph', | ||
@@ -131,5 +127,5 @@ payload: { graph, ctx, tx }, | ||
? (graph, ctx) => { | ||
const tx = pluginName + ':createMetadata:' + performance.now(); | ||
const tx = pluginName + worker.pid + ':createMetadata:' + txId++; | ||
return registerPendingPromise(tx, pending, () => { | ||
worker.send({ | ||
(0, messaging_1.sendMessageOverSocket)(socket, { | ||
type: 'createMetadata', | ||
@@ -193,15 +189,26 @@ payload: { graph, context: ctx, tx }, | ||
} | ||
process.on('exit', () => { | ||
let cleanedUp = false; | ||
const exitHandler = () => { | ||
if (cleanedUp) | ||
return; | ||
for (const fn of cleanupFunctions) { | ||
fn(); | ||
} | ||
}); | ||
cleanedUp = true; | ||
}; | ||
process.on('exit', exitHandler); | ||
process.on('SIGINT', exitHandler); | ||
process.on('SIGTERM', exitHandler); | ||
function registerPendingPromise(tx, pending, callback) { | ||
let resolver, rejector; | ||
let resolver, rejector, timeout; | ||
const promise = new Promise((res, rej) => { | ||
rejector = rej; | ||
resolver = res; | ||
rejector = rej; | ||
timeout = setTimeout(() => { | ||
rej(new Error(`Plugin worker timed out when processing message ${tx}`)); | ||
}, MAX_MESSAGE_WAIT); | ||
callback(); | ||
}).finally(() => { | ||
pending.delete(tx); | ||
clearTimeout(timeout); | ||
}); | ||
@@ -215,1 +222,68 @@ pending.set(tx, { | ||
} | ||
global.nxPluginWorkerCount ??= 0; | ||
async function startPluginWorker() { | ||
// this should only really be true when running unit tests within | ||
// the Nx repo. We still need to start the worker in this case, | ||
// but its typescript. | ||
const isWorkerTypescript = path.extname(__filename) === '.ts'; | ||
const workerPath = path.join(__dirname, 'plugin-worker'); | ||
const env = { | ||
...process.env, | ||
...(isWorkerTypescript | ||
? { | ||
// Ensures that the worker uses the same tsconfig as the main process | ||
TS_NODE_PROJECT: path.join(__dirname, '../../../../tsconfig.lib.json'), | ||
} | ||
: {}), | ||
}; | ||
const ipcPath = (0, socket_utils_1.getPluginOsSocketPath)([process.pid, global.nxPluginWorkerCount++].join('-')); | ||
const worker = (0, child_process_1.fork)(workerPath, [ipcPath], { | ||
stdio: process.stdout.isTTY ? 'inherit' : 'ignore', | ||
env, | ||
execArgv: [ | ||
...process.execArgv, | ||
// If the worker is typescript, we need to register ts-node | ||
...(isWorkerTypescript ? ['-r', 'ts-node/register'] : []), | ||
], | ||
detached: true, | ||
}); | ||
worker.disconnect(); | ||
worker.unref(); | ||
let attempts = 0; | ||
return new Promise((resolve, reject) => { | ||
const id = setInterval(async () => { | ||
const socket = await isServerAvailable(ipcPath); | ||
if (socket) { | ||
socket.unref(); | ||
clearInterval(id); | ||
resolve({ | ||
worker, | ||
socket, | ||
}); | ||
} | ||
else if (attempts > 1000) { | ||
// daemon fails to start, the process probably exited | ||
// we print the logs and exit the client | ||
reject('Failed to start plugin worker.'); | ||
} | ||
else { | ||
attempts++; | ||
} | ||
}, 10); | ||
}); | ||
} | ||
function isServerAvailable(ipcPath) { | ||
return new Promise((resolve) => { | ||
try { | ||
const socket = (0, net_1.connect)(ipcPath, () => { | ||
resolve(socket); | ||
}); | ||
socket.once('error', () => { | ||
resolve(false); | ||
}); | ||
} | ||
catch (err) { | ||
resolve(false); | ||
} | ||
}); | ||
} |
@@ -6,2 +6,5 @@ "use strict"; | ||
const serializable_error_1 = require("../../../utils/serializable-error"); | ||
const net_1 = require("net"); | ||
const consume_messages_from_socket_1 = require("../../../utils/consume-messages-from-socket"); | ||
const fs_1 = require("fs"); | ||
if (process.env.NX_PERF_LOGGING === 'true') { | ||
@@ -12,109 +15,127 @@ require('../../../utils/perf-logging'); | ||
let plugin; | ||
process.on('message', async (message) => { | ||
if (!(0, messaging_1.isPluginWorkerMessage)(message)) { | ||
return; | ||
const socketPath = process.argv[2]; | ||
const server = (0, net_1.createServer)((socket) => { | ||
socket.on('data', (0, consume_messages_from_socket_1.consumeMessagesFromSocket)((raw) => { | ||
const message = JSON.parse(raw.toString()); | ||
if (!(0, messaging_1.isPluginWorkerMessage)(message)) { | ||
return; | ||
} | ||
return (0, messaging_1.consumeMessage)(socket, message, { | ||
load: async ({ plugin: pluginConfiguration, root }) => { | ||
process.chdir(root); | ||
try { | ||
const [promise] = (0, loader_1.loadNxPlugin)(pluginConfiguration, root); | ||
plugin = await promise; | ||
return { | ||
type: 'load-result', | ||
payload: { | ||
name: plugin.name, | ||
include: plugin.include, | ||
exclude: plugin.exclude, | ||
createNodesPattern: plugin.createNodes?.[0], | ||
hasCreateDependencies: 'createDependencies' in plugin && !!plugin.createDependencies, | ||
hasProcessProjectGraph: 'processProjectGraph' in plugin && | ||
!!plugin.processProjectGraph, | ||
hasCreateMetadata: 'createMetadata' in plugin && !!plugin.createMetadata, | ||
success: true, | ||
}, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'load-result', | ||
payload: { | ||
success: false, | ||
error: (0, serializable_error_1.createSerializableError)(e), | ||
}, | ||
}; | ||
} | ||
}, | ||
createNodes: async ({ configFiles, context, tx }) => { | ||
try { | ||
const result = await plugin.createNodes[1](configFiles, context); | ||
return { | ||
type: 'createNodesResult', | ||
payload: { result, success: true, tx }, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'createNodesResult', | ||
payload: { | ||
success: false, | ||
error: (0, serializable_error_1.createSerializableError)(e), | ||
tx, | ||
}, | ||
}; | ||
} | ||
}, | ||
createDependencies: async ({ context, tx }) => { | ||
try { | ||
const result = await plugin.createDependencies(context); | ||
return { | ||
type: 'createDependenciesResult', | ||
payload: { dependencies: result, success: true, tx }, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'createDependenciesResult', | ||
payload: { | ||
success: false, | ||
error: (0, serializable_error_1.createSerializableError)(e), | ||
tx, | ||
}, | ||
}; | ||
} | ||
}, | ||
processProjectGraph: async ({ graph, ctx, tx }) => { | ||
try { | ||
const result = await plugin.processProjectGraph(graph, ctx); | ||
return { | ||
type: 'processProjectGraphResult', | ||
payload: { graph: result, success: true, tx }, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'processProjectGraphResult', | ||
payload: { | ||
success: false, | ||
error: (0, serializable_error_1.createSerializableError)(e), | ||
tx, | ||
}, | ||
}; | ||
} | ||
}, | ||
createMetadata: async ({ graph, context, tx }) => { | ||
try { | ||
const result = await plugin.createMetadata(graph, context); | ||
return { | ||
type: 'createMetadataResult', | ||
payload: { metadata: result, success: true, tx }, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'createMetadataResult', | ||
payload: { success: false, error: e.stack, tx }, | ||
}; | ||
} | ||
}, | ||
}); | ||
})); | ||
}); | ||
server.listen(socketPath); | ||
const exitHandler = (exitCode) => () => { | ||
server.close(); | ||
try { | ||
(0, fs_1.unlinkSync)(socketPath); | ||
} | ||
return (0, messaging_1.consumeMessage)(message, { | ||
load: async ({ plugin: pluginConfiguration, root }) => { | ||
process.chdir(root); | ||
try { | ||
const [promise] = (0, loader_1.loadNxPlugin)(pluginConfiguration, root); | ||
plugin = await promise; | ||
return { | ||
type: 'load-result', | ||
payload: { | ||
name: plugin.name, | ||
include: plugin.include, | ||
exclude: plugin.exclude, | ||
createNodesPattern: plugin.createNodes?.[0], | ||
hasCreateDependencies: 'createDependencies' in plugin && !!plugin.createDependencies, | ||
hasProcessProjectGraph: 'processProjectGraph' in plugin && !!plugin.processProjectGraph, | ||
hasCreateMetadata: 'createMetadata' in plugin && !!plugin.createMetadata, | ||
success: true, | ||
}, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'load-result', | ||
payload: { | ||
success: false, | ||
error: (0, serializable_error_1.createSerializableError)(e), | ||
}, | ||
}; | ||
} | ||
}, | ||
createNodes: async ({ configFiles, context, tx }) => { | ||
try { | ||
const result = await plugin.createNodes[1](configFiles, context); | ||
return { | ||
type: 'createNodesResult', | ||
payload: { result, success: true, tx }, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'createNodesResult', | ||
payload: { | ||
success: false, | ||
error: (0, serializable_error_1.createSerializableError)(e), | ||
tx, | ||
}, | ||
}; | ||
} | ||
}, | ||
createDependencies: async ({ context, tx }) => { | ||
try { | ||
const result = await plugin.createDependencies(context); | ||
return { | ||
type: 'createDependenciesResult', | ||
payload: { dependencies: result, success: true, tx }, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'createDependenciesResult', | ||
payload: { | ||
success: false, | ||
error: (0, serializable_error_1.createSerializableError)(e), | ||
tx, | ||
}, | ||
}; | ||
} | ||
}, | ||
processProjectGraph: async ({ graph, ctx, tx }) => { | ||
try { | ||
const result = await plugin.processProjectGraph(graph, ctx); | ||
return { | ||
type: 'processProjectGraphResult', | ||
payload: { graph: result, success: true, tx }, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'processProjectGraphResult', | ||
payload: { | ||
success: false, | ||
error: (0, serializable_error_1.createSerializableError)(e), | ||
tx, | ||
}, | ||
}; | ||
} | ||
}, | ||
createMetadata: async ({ graph, context, tx }) => { | ||
try { | ||
const result = await plugin.createMetadata(graph, context); | ||
return { | ||
type: 'createMetadataResult', | ||
payload: { metadata: result, success: true, tx }, | ||
}; | ||
} | ||
catch (e) { | ||
return { | ||
type: 'createMetadataResult', | ||
payload: { success: false, error: e.stack, tx }, | ||
}; | ||
} | ||
}, | ||
}); | ||
}); | ||
catch (e) { } | ||
process.exit(exitCode); | ||
}; | ||
const events = ['SIGINT', 'SIGTERM', 'SIGQUIT', 'exit']; | ||
events.forEach((event) => process.once(event, exitHandler(0))); | ||
process.once('uncaughtException', exitHandler(1)); | ||
process.once('unhandledRejection', exitHandler(1)); |
@@ -12,8 +12,8 @@ import { ProjectConfiguration } from '../../config/workspace-json-project-json'; | ||
export declare function retrieveWorkspaceFiles(workspaceRoot: string, projectRootMap: Record<string, string>): Promise<{ | ||
allWorkspaceFiles: import("nx/src/devkit-exports").FileData[]; | ||
allWorkspaceFiles: import("../file-utils").FileData[]; | ||
fileMap: { | ||
projectFileMap: ProjectFiles; | ||
nonProjectFiles: import("nx/src/native").FileData[]; | ||
nonProjectFiles: import("../../native").FileData[]; | ||
}; | ||
rustReferences: import("nx/src/native").NxWorkspaceFilesExternals; | ||
rustReferences: import("../../native").NxWorkspaceFilesExternals; | ||
}>; | ||
@@ -20,0 +20,0 @@ /** |
@@ -9,1 +9,14 @@ /// <reference types="node" /> | ||
}; | ||
/** | ||
* This function loads a .env file and expands the variables in it. | ||
* It is going to override existing environmentVariables. | ||
* @param filename | ||
* @param environmentVariables | ||
*/ | ||
export declare function loadAndExpandDotEnvFile(filename: string, environmentVariables: NodeJS.ProcessEnv, override?: boolean): import("dotenv-expand").DotenvExpandOutput; | ||
/** | ||
* This function unloads a .env file and removes the variables in it from the environmentVariables. | ||
* @param filename | ||
* @param environmentVariables | ||
*/ | ||
export declare function unloadDotEnvFile(filename: string, environmentVariables: NodeJS.ProcessEnv, override?: boolean): void; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getEnvVariablesForTask = exports.getTaskSpecificEnv = exports.getEnvVariablesForBatchProcess = void 0; | ||
exports.unloadDotEnvFile = exports.loadAndExpandDotEnvFile = exports.getEnvVariablesForTask = exports.getTaskSpecificEnv = exports.getEnvVariablesForBatchProcess = void 0; | ||
const dotenv_1 = require("dotenv"); | ||
@@ -78,5 +78,38 @@ const dotenv_expand_1 = require("dotenv-expand"); | ||
} | ||
function loadDotEnvFilesForTask(task, environmentVariables) { | ||
/** | ||
* This function loads a .env file and expands the variables in it. | ||
* It is going to override existing environmentVariables. | ||
* @param filename | ||
* @param environmentVariables | ||
*/ | ||
function loadAndExpandDotEnvFile(filename, environmentVariables, override = false) { | ||
const myEnv = (0, dotenv_1.config)({ | ||
path: filename, | ||
processEnv: environmentVariables, | ||
override, | ||
}); | ||
return (0, dotenv_expand_1.expand)({ | ||
...myEnv, | ||
processEnv: environmentVariables, | ||
}); | ||
} | ||
exports.loadAndExpandDotEnvFile = loadAndExpandDotEnvFile; | ||
/** | ||
* This function unloads a .env file and removes the variables in it from the environmentVariables. | ||
* @param filename | ||
* @param environmentVariables | ||
*/ | ||
function unloadDotEnvFile(filename, environmentVariables, override = false) { | ||
const parsedDotEnvFile = {}; | ||
loadAndExpandDotEnvFile(filename, parsedDotEnvFile, override); | ||
Object.keys(parsedDotEnvFile).forEach((envVarKey) => { | ||
if (environmentVariables[envVarKey] === parsedDotEnvFile[envVarKey]) { | ||
delete environmentVariables[envVarKey]; | ||
} | ||
}); | ||
} | ||
exports.unloadDotEnvFile = unloadDotEnvFile; | ||
function getEnvFilesForTask(task) { | ||
// Collect dot env files that may pertain to a task | ||
const dotEnvFiles = [ | ||
return [ | ||
// Load DotEnv Files for a configuration in the project root | ||
@@ -126,16 +159,7 @@ ...(task.target.configuration | ||
]; | ||
} | ||
function loadDotEnvFilesForTask(task, environmentVariables) { | ||
const dotEnvFiles = getEnvFilesForTask(task); | ||
for (const file of dotEnvFiles) { | ||
const myEnv = (0, dotenv_1.config)({ | ||
path: file, | ||
processEnv: environmentVariables, | ||
// Do not override existing env variables as we load | ||
override: false, | ||
}); | ||
environmentVariables = { | ||
...(0, dotenv_expand_1.expand)({ | ||
...myEnv, | ||
ignoreProcessEnv: true, // Do not override existing env variables as we load | ||
}).parsed, | ||
...environmentVariables, | ||
}; | ||
loadAndExpandDotEnvFile(file, environmentVariables); | ||
} | ||
@@ -145,15 +169,6 @@ return environmentVariables; | ||
function unloadDotEnvFiles(environmentVariables) { | ||
const unloadDotEnvFile = (filename) => { | ||
let parsedDotEnvFile = {}; | ||
(0, dotenv_1.config)({ path: filename, processEnv: parsedDotEnvFile }); | ||
Object.keys(parsedDotEnvFile).forEach((envVarKey) => { | ||
if (environmentVariables[envVarKey] === parsedDotEnvFile[envVarKey]) { | ||
delete environmentVariables[envVarKey]; | ||
} | ||
}); | ||
}; | ||
for (const file of ['.env', '.local.env', '.env.local']) { | ||
unloadDotEnvFile(file); | ||
unloadDotEnvFile(file, environmentVariables); | ||
} | ||
return environmentVariables; | ||
} |
export declare function getGithubSlugOrNull(): string | null; | ||
export declare function extractUserAndRepoFromGitHubUrl(gitRemotes: string): string | null; | ||
export declare function commitChanges(commitMessage: string): string | null; | ||
export declare function commitChanges(commitMessage: string, directory?: string): string | null; | ||
export declare function getLatestCommitSha(): string | null; |
@@ -5,2 +5,3 @@ "use strict"; | ||
const child_process_1 = require("child_process"); | ||
const devkit_exports_1 = require("../devkit-exports"); | ||
function getGithubSlugOrNull() { | ||
@@ -42,3 +43,3 @@ try { | ||
} | ||
function commitChanges(commitMessage) { | ||
function commitChanges(commitMessage, directory) { | ||
try { | ||
@@ -50,6 +51,16 @@ (0, child_process_1.execSync)('git add -A', { encoding: 'utf8', stdio: 'pipe' }); | ||
input: commitMessage, | ||
cwd: directory, | ||
}); | ||
} | ||
catch (err) { | ||
throw new Error(`Error committing changes:\n${err.stderr}`); | ||
if (directory) { | ||
// We don't want to throw during create-nx-workspace | ||
// because maybe there was an error when setting up git | ||
// initially. | ||
devkit_exports_1.logger.verbose(`Git may not be set up correctly for this new workspace. | ||
${err}`); | ||
} | ||
else { | ||
throw new Error(`Error committing changes:\n${err.stderr}`); | ||
} | ||
} | ||
@@ -56,0 +67,0 @@ return getLatestCommitSha(); |
import { NxJsonConfiguration } from '../config/nx-json'; | ||
export declare function isNxCloudUsed(nxJson: NxJsonConfiguration): string | boolean; | ||
export declare function isNxCloudUsed(nxJson: NxJsonConfiguration): boolean; | ||
export declare function getNxCloudUrl(nxJson: NxJsonConfiguration): string; | ||
export declare function getNxCloudToken(nxJson: NxJsonConfiguration): string; |
@@ -5,3 +5,3 @@ "use strict"; | ||
function isNxCloudUsed(nxJson) { | ||
return (process.env.NX_CLOUD_ACCESS_TOKEN || | ||
return (!!process.env.NX_CLOUD_ACCESS_TOKEN || | ||
!!nxJson.nxCloudAccessToken || | ||
@@ -8,0 +8,0 @@ !!Object.values(nxJson.tasksRunnerOptions ?? {}).find((r) => r.runner == '@nrwl/nx-cloud' || r.runner == 'nx-cloud')); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
4246867
48638
377
43
+ Added@nrwl/tao@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-darwin-arm64@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-darwin-x64@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-freebsd-x64@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-linux-arm-gnueabihf@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-linux-arm64-gnu@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-linux-arm64-musl@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-linux-x64-gnu@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-linux-x64-musl@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-win32-arm64-msvc@19.4.0-canary.20240627-c2c6a13(transitive)
+ Added@nx/nx-win32-x64-msvc@19.4.0-canary.20240627-c2c6a13(transitive)
+ Addeddotenv@16.4.5(transitive)
+ Addeddotenv-expand@11.0.6(transitive)
- Removed@nrwl/tao@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-darwin-arm64@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-darwin-x64@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-freebsd-x64@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-linux-arm-gnueabihf@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-linux-arm64-gnu@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-linux-arm64-musl@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-linux-x64-gnu@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-linux-x64-musl@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-win32-arm64-msvc@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removed@nx/nx-win32-x64-msvc@19.4.0-canary.20240626-3a2e8d4(transitive)
- Removeddotenv@16.3.2(transitive)
- Removeddotenv-expand@10.0.0(transitive)
Updateddotenv@~16.4.5
Updateddotenv-expand@~11.0.6