Skip to content

Commit

Permalink
Merge pull request #961 from nodejs/main
Browse files Browse the repository at this point in the history
Create a new pull request by comparing changes across two branches
  • Loading branch information
GulajavaMinistudio authored Jan 24, 2024
2 parents 18b611a + 26f63be commit 9f89347
Show file tree
Hide file tree
Showing 22 changed files with 408 additions and 33 deletions.
23 changes: 23 additions & 0 deletions doc/api/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -2260,6 +2260,29 @@ process.kill(process.pid, 'SIGHUP');
When `SIGUSR1` is received by a Node.js process, Node.js will start the
debugger. See [Signal Events][].
## `process.loadEnvFile(path)`
<!-- YAML
added: REPLACEME
-->
> Stability: 1.1 - Active development
* `path` {string | URL | Buffer | undefined}. **Default:** `'./.env'`
Loads the `.env` file into `process.env`. Usage of `NODE_OPTIONS`
in the `.env` file will not have any effect on Node.js.
```cjs
const { loadEnvFile } = require('node:process');
loadEnvFile();
```
```mjs
import { loadEnvFile } from 'node:process';
loadEnvFile();
```
## `process.mainModule`
<!-- YAML
Expand Down
30 changes: 30 additions & 0 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -1593,6 +1593,36 @@ $ node negate.js --no-logfile --logfile=test.log --color --no-color
{ logfile: 'test.log', color: false }
```
## `util.parseEnv(content)`
> Stability: 1.1 - Active development
<!-- YAML
added: REPLACEME
-->
* `content` {string}
The raw contents of a `.env` file.
* Returns: {Object}
Given an example `.env` file:
```cjs
const { parseEnv } = require('node:util');

parseEnv('HELLO=world\nHELLO=oh my\n');
// Returns: { HELLO: 'oh my' }
```
```mjs
import { parseEnv } from 'node:util';

parseEnv('HELLO=world\nHELLO=oh my\n');
// Returns: { HELLO: 'oh my' }
```
## `util.promisify(original)`
<!-- YAML
Expand Down
1 change: 1 addition & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ const rawMethods = internalBinding('process_methods');
process._kill = rawMethods._kill;

const wrapped = perThreadSetup.wrapProcessMethods(rawMethods);
process.loadEnvFile = wrapped.loadEnvFile;
process._rawDebug = wrapped._rawDebug;
process.cpuUsage = wrapped.cpuUsage;
process.resourceUsage = wrapped.resourceUsage;
Expand Down
17 changes: 17 additions & 0 deletions lib/internal/process/per_thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const {
validateNumber,
validateObject,
} = require('internal/validators');
const { getValidatedPath } = require('internal/fs/utils');
const { toNamespacedPath } = require('path');
const constants = internalBinding('constants').os.signals;

const kInternal = Symbol('internal properties');
Expand Down Expand Up @@ -100,6 +102,7 @@ function wrapProcessMethods(binding) {
memoryUsage: _memoryUsage,
rss,
resourceUsage: _resourceUsage,
loadEnvFile: _loadEnvFile,
} = binding;

function _rawDebug(...args) {
Expand Down Expand Up @@ -250,6 +253,19 @@ function wrapProcessMethods(binding) {
};
}

/**
* Loads the `.env` file to process.env.
* @param {string | URL | Buffer | undefined} path
*/
function loadEnvFile(path = undefined) { // Provide optional value so that `loadEnvFile.length` returns 0
if (path != null) {
path = getValidatedPath(path);
_loadEnvFile(toNamespacedPath(path));
} else {
_loadEnvFile();
}
}


return {
_rawDebug,
Expand All @@ -258,6 +274,7 @@ function wrapProcessMethods(binding) {
memoryUsage,
kill,
exit,
loadEnvFile,
};
}

Expand Down
6 changes: 5 additions & 1 deletion lib/internal/webstreams/readablestream.js
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,11 @@ class ReadableStream {
const transfer = lazyTransfer();
setupReadableStreamDefaultControllerFromSource(
this,
new transfer.CrossRealmTransformReadableSource(port),
// The MessagePort is set to be referenced when reading.
// After two MessagePorts are closed, there is a problem with
// lingering promise not being properly resolved.
// https://github.com/nodejs/node/issues/51486
new transfer.CrossRealmTransformReadableSource(port, true),
0, () => 1);
}
}
Expand Down
36 changes: 26 additions & 10 deletions lib/internal/webstreams/transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,11 @@ function InternalCloneableDOMException() {
InternalCloneableDOMException[kDeserialize] = () => {};

class CrossRealmTransformReadableSource {
constructor(port) {
constructor(port, unref) {
this[kState] = {
port,
controller: undefined,
unref,
};

port.onmessage = ({ data }) => {
Expand Down Expand Up @@ -143,13 +144,19 @@ class CrossRealmTransformReadableSource {
error);
port.close();
};

port.unref();
}

start(controller) {
this[kState].controller = controller;
}

async pull() {
if (this[kState].unref) {
this[kState].unref = false;
this[kState].port.ref();
}
this[kState].port.postMessage({ type: 'pull' });
}

Expand All @@ -170,11 +177,12 @@ class CrossRealmTransformReadableSource {
}

class CrossRealmTransformWritableSink {
constructor(port) {
constructor(port, unref) {
this[kState] = {
port,
controller: undefined,
backpressurePromise: createDeferredPromise(),
unref,
};

port.onmessage = ({ data }) => {
Expand Down Expand Up @@ -211,13 +219,18 @@ class CrossRealmTransformWritableSink {
port.close();
};

port.unref();
}

start(controller) {
this[kState].controller = controller;
}

async write(chunk) {
if (this[kState].unref) {
this[kState].unref = false;
this[kState].port.ref();
}
if (this[kState].backpressurePromise === undefined) {
this[kState].backpressurePromise = {
promise: PromiseResolve(),
Expand Down Expand Up @@ -262,12 +275,12 @@ class CrossRealmTransformWritableSink {
}

function newCrossRealmReadableStream(writable, port) {
const readable =
new ReadableStream(
new CrossRealmTransformReadableSource(port));
// MessagePort should always be unref.
// There is a problem with the process not terminating.
// https://github.com/nodejs/node/issues/44985
const readable = new ReadableStream(new CrossRealmTransformReadableSource(port, false));

const promise =
readableStreamPipeTo(readable, writable, false, false, false);
const promise = readableStreamPipeTo(readable, writable, false, false, false);

setPromiseHandled(promise);

Expand All @@ -278,12 +291,15 @@ function newCrossRealmReadableStream(writable, port) {
}

function newCrossRealmWritableSink(readable, port) {
const writable =
new WritableStream(
new CrossRealmTransformWritableSink(port));
// MessagePort should always be unref.
// There is a problem with the process not terminating.
// https://github.com/nodejs/node/issues/44985
const writable = new WritableStream(new CrossRealmTransformWritableSink(port, false));

const promise = readableStreamPipeTo(readable, writable, false, false, false);

setPromiseHandled(promise);

return {
writable,
promise,
Expand Down
8 changes: 5 additions & 3 deletions lib/internal/webstreams/writablestream.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,6 @@ class WritableStream {
this[kState].transfer.readable = readable;
this[kState].transfer.promise = promise;

setPromiseHandled(this[kState].transfer.promise);

return {
data: { port: this[kState].transfer.port2 },
deserializeInfo:
Expand All @@ -283,7 +281,11 @@ class WritableStream {
const transfer = lazyTransfer();
setupWritableStreamDefaultControllerFromSink(
this,
new transfer.CrossRealmTransformWritableSink(port),
// The MessagePort is set to be referenced when reading.
// After two MessagePorts are closed, there is a problem with
// lingering promise not being properly resolved.
// https://github.com/nodejs/node/issues/51486
new transfer.CrossRealmTransformWritableSink(port, true),
1,
() => 1);
}
Expand Down
13 changes: 13 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ const { debuglog } = require('internal/util/debuglog');
const {
validateFunction,
validateNumber,
validateString,
} = require('internal/validators');
const { isBuffer } = require('buffer').Buffer;
const types = require('internal/util/types');
const binding = internalBinding('util');

const {
deprecate,
Expand Down Expand Up @@ -371,6 +373,16 @@ function _exceptionWithHostPort(...args) {
return new ExceptionWithHostPort(...args);
}

/**
* Parses the content of a `.env` file.
* @param {string} content
* @returns {Record<string, string>}
*/
function parseEnv(content) {
validateString(content, 'content');
return binding.parseEnv(content);
}

// Keep the `exports =` so that various functions can still be monkeypatched
module.exports = {
_errnoException,
Expand Down Expand Up @@ -465,6 +477,7 @@ module.exports = {
return lazyAbortController().aborted;
},
types,
parseEnv,
};

defineLazyProperties(
Expand Down
5 changes: 0 additions & 5 deletions node.gni
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Copyright 2019 the V8 project authors. All rights reserved.
# Copyright 2023 Microsoft Inc.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This file is used by GN for building, which is NOT the build system used for
# building official binaries.
# Please take a look at node.gyp if you are making changes to build system.
Expand Down
15 changes: 12 additions & 3 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -871,9 +871,18 @@ static ExitCode InitializeNodeWithArgsInternal(
CHECK(!per_process::v8_initialized);

for (const auto& file_path : file_paths) {
bool path_exists = per_process::dotenv_file.ParsePath(file_path);

if (!path_exists) errors->push_back(file_path + ": not found");
switch (per_process::dotenv_file.ParsePath(file_path)) {
case Dotenv::ParseResult::Valid:
break;
case Dotenv::ParseResult::InvalidContent:
errors->push_back(file_path + ": invalid format");
break;
case Dotenv::ParseResult::FileError:
errors->push_back(file_path + ": not found");
break;
default:
UNREACHABLE();
}
}

per_process::dotenv_file.AssignNodeOptionsIfAvailable(&node_options);
Expand Down
Loading

0 comments on commit 9f89347

Please sign in to comment.