Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions HOWTO.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ Node.js event emitters take strings as event names and don't check listener sign

If you provide an instance of `Event<T>` abstract string type where an event name is expected in any `EventEmitter` method, then the listener type will be unified with `T` and thus provide type checking and inference for the listener function.

We provide [@:enum abstract types](http://haxe.org/manual/types-abstract-enum.html) that enumerate possible event names for a given event emitter. They are implicitly castable to `Event<T>` and can be used for type-checking listener functions as described above. For each `EventEmitter` subclass, an `@:enum abstract` type must be created with a `Event` postfix in its name. For example, if we have a `Process` class which is an `EventEmitter`, it should have a pairing `ProcessEvent` type in its module, i.e.:
We provide [enum abstract types](https://haxe.org/manual/types-abstract-enum.html) that enumerate possible event names for a given event emitter. They are implicitly castable to `Event<T>` and can be used for type-checking listener functions as described above. For each `EventEmitter` subclass, an `enum abstract` type must be created with a `Event` postfix in its name. For example, if we have a `Process` class which is an `EventEmitter`, it should have a pairing `ProcessEvent` type in its module, i.e.:

```haxe
extern class Process extends EventEmitter {
// ...
}

@:enum abstract ProcessEvent<T:haxe.Constraints.Function>(Event<T>) to Event<T> {
enum abstract ProcessEvent<T:haxe.Constraints.Function>(Event<T>) to Event<T> {
var Exit : ProcessEvent<Int->Void> = "exit";
}
```
Expand All @@ -96,7 +96,7 @@ TODO (describe the difference of overloading/optional argument concepts and advi

The whole idea of haxe externs is provide a fully type-checked access to external API. Considering that, we must avoid the need for use `Dynamic` type or `cast` and think of a way to properly express type restrictions.

On the other hand, we want developers to be able to copy-paste node.js code into haxe with minimal modification and have it compiling. For that reason we have to weaken some typing restrictions, for example adding implicit cast `from String` for our `@:enum abstract` types.
On the other hand, we want developers to be able to copy-paste node.js code into haxe with minimal modification and have it compiling. For that reason we have to weaken some typing restrictions, for example adding implicit cast `from String` for our `enum abstract` types.

### Multiple inheritance

Expand Down Expand Up @@ -147,12 +147,12 @@ If a type can be of 3 and more types, nested `EitherType` can be used.

### Constant enumeration

If there's a finite set of posible values for a function argument or object field, [@:enum abstract types](http://haxe.org/manual/types-abstract-enum.html) are used to enumerate those values.
If there's a finite set of posible values for a function argument or object field, [enum abstract types](https://haxe.org/manual/types-abstract-enum.html) are used to enumerate those values.

Example:

```haxe
@:enum abstract SymlinkType(String) from String to String {
enum abstract SymlinkType(String) from String to String {
var File = "file";
var Dir = "dir";
var Junction = "junction";
Expand All @@ -164,10 +164,10 @@ The `to` and `from` implicit cast must be added so user can use both enumeration
Constant names are `UpperCamelCase` and their values are actual values expected by native API.


Note that combined with `haxe.EitherType` (described above), `@:enum abstract`s can handle even complicated cases where a value can be of different types, e.g.
Note that combined with `haxe.EitherType` (described above), `enum abstract`s can handle even complicated cases where a value can be of different types, e.g.

```haxe
@:enum abstract ListeningEventAddressType(haxe.EitherType<Int,String>) to haxe.EitherType<Int,String> {
enum abstract ListeningEventAddressType(haxe.EitherType<Int,String>) to haxe.EitherType<Int,String> {
var TCPv4 = 4;
var TCPv6 = 6;
var Unix = -1;
Expand Down Expand Up @@ -213,4 +213,4 @@ extern class NotSoDeprecated {

## Tricks and hints

TODO (dealing with keywords, `untyped __js__`, inline methods and properties on extern classes)
TODO (dealing with keywords, `js.Syntax.code`, inline methods and properties on extern classes)
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[![Haxelib License](https://badgen.net/haxelib/license/hxnodejs)](LICENSE.md)

Extern type definitions for Node.JS. Haxe **4.0** or newer is required.
Targeted at **Node.js 24** Active LTS APIs (bindings may lag behind edge cases).

Haxe-generated API documentation is available at http://haxefoundation.github.io/hxnodejs/js/Node.html.

Expand Down
2 changes: 1 addition & 1 deletion haxelib.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Extern definitions for node.js",
"license": "MIT",
"version": "12.2.0",
"releasenote": "Update some API, fix some deprecation warnings.",
"releasenote": "Node.js 24 Active LTS audit ongoing; Haxe 4.0+ only.",
"classPath": "src",
"contributors": ["nadako", "Simn", "Gama11", "HaxeFoundation"],
"tags": ["js", "nodejs", "async", "net", "web", "extern"]
Expand Down
40 changes: 1 addition & 39 deletions src/js/Node.hx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ package js;

import haxe.Constraints.Function;
import haxe.extern.Rest;
import js.Syntax.code;
import js.node.Module;
import js.node.Process;
import js.node.Timers.Immediate;
import js.node.Timers.Timeout;
import js.node.console.Console;
import js.node.perf_hooks.Performance;
#if haxe4
import js.Syntax.code;
#end

/**
Node.js globals
Expand All @@ -45,11 +43,7 @@ extern class Node {
static var __dirname(get, never):String;

private static inline function get___dirname():String {
#if haxe4
return code("__dirname");
#else
return untyped __js__("__dirname");
#end
}

/**
Expand All @@ -58,11 +52,7 @@ extern class Node {
static var __filename(get, never):String;

private static inline function get___filename():String {
#if haxe4
return code("__filename");
#else
return untyped __js__("__filename");
#end
}

/**
Expand All @@ -86,11 +76,7 @@ extern class Node {
static var console(get, never):Console;

private static inline function get_console():Console {
#if haxe4
return code("console");
#else
return untyped __js__("console");
#end
}

/**
Expand All @@ -99,11 +85,7 @@ extern class Node {
static var exports(get, never):Dynamic<Dynamic>;

private static inline function get_exports():Dynamic<Dynamic> {
#if haxe4
return code("exports");
#else
return untyped __js__("exports");
#end
}

/**
Expand All @@ -124,11 +106,7 @@ extern class Node {
static var globalThis(get, never):Dynamic<Dynamic>;

private static inline function get_globalThis():Dynamic<Dynamic> {
#if haxe4
return code("globalThis");
#else
return untyped __js__("globalThis");
#end
}

/**
Expand All @@ -137,11 +115,7 @@ extern class Node {
static var module(get, never):Module;

private static inline function get_module():Module {
#if haxe4
return code("module");
#else
return untyped __js__("module");
#end
}

/**
Expand All @@ -150,11 +124,7 @@ extern class Node {
static var process(get, never):Process;

private static inline function get_process():Process {
#if haxe4
return code("process");
#else
return untyped __js__("process");
#end
}

/**
Expand All @@ -167,11 +137,7 @@ extern class Node {
static var performance(get, never):Performance;

private static inline function get_performance():Performance {
#if haxe4
return code("performance");
#else
return untyped __js__("performance");
#end
}

/**
Expand All @@ -188,11 +154,7 @@ extern class Node {
This variable may appear to be global but is not. See [require()](https://nodejs.org/api/modules.html#modules_require_id).
**/
static inline function require(module:String):Dynamic {
#if haxe4
return code("require({0})", module);
#else
return untyped __js__("require({0})", module);
#end
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/js/node/Constants.hx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@

package js.node;

/**
Constants exported by Node.js core modules (legacy aggregate module).

Prefer module-specific constants (e.g. `fs.constants`, `os.constants`, `crypto.constants`)
over `require('constants')`. This extern only mirrors a subset historically used by
crypto engine/padding callers.

@see https://nodejs.org/api/crypto.html#crypto-constants
**/
@:jsRequire("constants")
extern class Constants {
static var ENGINE_METHOD_RSA(default, null):Int;
Expand Down
Loading
Loading