Merge branch 'dev' into translation-zhcn

This commit is contained in:
Nick O'Leary 2023-03-03 15:22:34 +00:00 committed by GitHub
commit 307fbef5b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
346 changed files with 47588 additions and 9901 deletions

View File

@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16]
node-version: [16, 18]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
@ -30,7 +30,7 @@ jobs:
run: |
npm run test
- name: Publish to coveralls.io
if: ${{ matrix.node-version == 14 }}
if: ${{ matrix.node-version == 16 }}
uses: coverallsapp/github-action@v1.1.2
with:
github-token: ${{ github.token }}

View File

@ -15,5 +15,5 @@
"shadow": true, // allow variable shadowing (re-use of names...)
"sub": true, // don't warn that foo['bar'] should be written as foo.bar
"proto": true, // allow setting of __proto__ in node < v0.12,
"esversion": 6 // allow es6
"esversion": 11 // allow es11(ES2020)
}

View File

@ -1,3 +1,94 @@
#### 3.1.0-beta.1: Beta Release
Editor
- NEW: Locking Flows (#3938) @knolleary
- NEW: Improve UX around hiding flows via context menu (#3930) @knolleary
- NEW: Add support for inline image in markdown editor by drag and drop of an image file (#4006) @HiroyasuNishiyama
- NEW: Add support for mermaid diagram to markdown editor (#4007) @HiroyasuNishiyama
- NEW: Support uri fragments for nodes and groups including edit support (#3870) @knolleary
- NEW: Add global environment variable feature (#3941) @HiroyasuNishiyama
- Remember compact/pretty flow export user choice (#3974) @Steve-Mcl
- fix .red-ui-notification class (#4035) @xiaobinqt
- Fix border radius on Modules list header (#4038) @bonanitech
- fix workspace reference error in case of empty tabs (#4029) @HiroyasuNishiyama
- Disable delete tab menu when single tab exists (#4030) @HiroyasuNishiyama
- Disable hide all menu if all tabs hidden (#4031) @HiroyasuNishiyama
- fix hide subflow tooltip (#4033) @HiroyasuNishiyama
- Fix disabled menu items in project feature (#4027) @kazuhitoyokoi
- Let themes change radialMenu text colors (#3995) @bonanitech
- Add Japanese translations for v3.0.3 (#4012) @kazuhitoyokoi
- Add Japanese translation for v3.1.0-beta.0 (#3997) @kazuhitoyokoi
- Add Japanese translation for v3.1.0-beta.0 (#3916) @kazuhitoyokoi
- Hide subflow category after deleting subflow (#3980) @kazuhitoyokoi
- Prevent dbl-click opening node edit dialog with text selected (#3970) @knolleary
- Handle replacing unknown node inside group or subflow (#3921) @knolleary
- Fix #3939, red border red-ui-typedInput-container (#3949) @Steveorevo
- i18n item URL copy notification & add Japanese message (#3946) @HiroyasuNishiyama
- add Japanese message for item url copy actions (#3947) @HiroyasuNishiyama
- Fix autocomplete entry for responseUrl (#3884) @knolleary
- Fix Japanese translation for JSONata editor (#3872) @HiroyasuNishiyama
- Fix search type with spaces (#3841) @Steve-Mcl
- Fix error hanndling of JSONata expression editor for extended functions (#3871) @HiroyasuNishiyama
- Add button type to the adding SSH key button (#3866) @kazuhitoyokoi
- Check radio button as default in project dialog (#3879) @kazuhitoyokoi
- Add $clone as supported function (#3874) @HiroyasuNishiyama
- Env var jsonata (#3807) @HiroyasuNishiyama
- Add Japanese translation for v3.0.2 (#3852) @kazuhitoyokoi
Runtime
- Force IPv4 name resolution to have priority (#4019) @dceejay
- Fix async loading of modules containing both nodes and plugins (#3999) @knolleary
- Use main branch as default in project feature (#4036) @kazuhitoyokoi
- Rename package var to avoid strict mode error (#4020) @knolleary
- Fix typos in settings.js (#4013) @ypid
- Ensure credentials object is removed before returning node in getFlow request (#3971) @knolleary
- Ignore commit error in project feature (#3987) @kazuhitoyokoi
- Update dependencies (#3969) @knolleary
- Add check that node sends object rather than primitive type (#3909) @knolleary
- Ensure key_path is quoted in GIT_SSH_COMMAND in case of spaces in pathname (#3912) @knolleary
- Fix nodesDir scan when node package has js/html in sub dir to package.json (#3867) @Steve-Mcl
- Fix file permissions (#3917) @kazuhitoyokoi
- ci: add minimum GitHub token permissions for workflows (#3907) @boahc077
Nodes
- Catch: fix typo in catch.html (#3965) @we11adam
- Change: Fix change node overwriting msg with itself (#3899) @dceejay
- Comment node: Clarify where the text will appear (#4004) @dirkjanfaber
- CSV: change replace to replaceAll (#3990) @dceejay
- CSV node: check header properties for ' and " (#3920) @dceejay
- CSV: Fix for CSV undefined property (#3906) @dceejay
- Delay: let delay node handle both flush then reset (#3898) @dceejay
- Function: Limit number of ports in function node (#3886) @kazuhitoyokoi
- Function: Remove dot from variable name for external module in function node (#3880) @kazuhitoyokoi
- Function: add function node monaco types util and promisify (#3868) @Steve-Mcl
- HTTP In: Ensure msg.req.headers is enumerable (#3908) @knolleary
- HTTP Request: Support form-data arrays (#3991) @hardillb
- HTTP Request: Fix httprequest tests to be more lenient on error message (#3922) @knolleary
- HTTP Request: Add missing property to node object HTTPRequest (#3842) @hardillb
- HTTP Request/Response: Support sortable list on property UI of http request and http response nodes (#3857) @kazuhitoyokoi
- HTTP Response: Ensure statusCode is a number (#3894) @hardillb
- Inject: Allow Inject node to work with async context stores (#4021) @knolleary
- Join/Batch: Add count to join and batch node labels (#4028) @dceejay
- MQTT: Fix birth topic handling in MQTT node (#3905) @Steve-Mcl
- MQTT: Fix pull-down menus of MQTT configuration node (#3890) @kazuhitoyokoi
- MQTT: Prevent invalid mqtt birth topic crashing node-red (#3869) @Steve-Mcl
- MQTT: ensure sessionExpiry(Interval) is applied (#3840) @Steve-Mcl
- MQTT: Fix mqtt nodes not reconnecting on modified-flows deploy (#3992) @knolleary
- MQTT: fix single subscription mqtt node status (#3966) @Steve-Mcl
- Range: Add drop mode to range node (#3935) @dceejay
- Remove done from describe (#3873) @HiroyasuNishiyama
- Split node: avoid duplicate done call for buffer split (#4000) @knolleary
- Status: Fix typo in 25-status.html (#3981) @kazuhitoyokoi
- TCP Node: ensure newline substitution applies to whole message (#4009) @dceejay
- Template: Add information about environment variable to template node (#3882) @kazuhitoyokoi
- Trigger: Hide trigger node repeat send option if sending nothing (#4023) @dceejay
- Watch: fix watch node test on MacOS/ARM (#3942) @HiroyasuNishiyama
#### 3.0.2: Maintenance Release
Editor

View File

@ -151,6 +151,7 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/font-awesome.js",
"packages/node_modules/@node-red/editor-client/src/js/history.js",
"packages/node_modules/@node-red/editor-client/src/js/validators.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/mermaid.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/utils.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js",
@ -169,6 +170,7 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/ui/diagnostics.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/diff.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/env-var.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/view.js",
@ -224,7 +226,7 @@ module.exports = function(grunt) {
"node_modules/jsonata/jsonata-es5.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js",
"packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js",
"packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js",
"packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js"
],
// "packages/node_modules/@node-red/editor-client/public/vendor/vendor.css": [
// // TODO: resolve relative resource paths in
@ -233,6 +235,9 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/public/vendor/ace/worker-jsonata.js": [
"node_modules/jsonata/jsonata-es5.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js"
],
"packages/node_modules/@node-red/editor-client/public/vendor/mermaid/mermaid.min.js": [
"node_modules/mermaid/dist/mermaid.min.js"
]
}
}
@ -403,7 +408,7 @@ module.exports = function(grunt) {
{
cwd: 'packages/node_modules/@node-red/editor-client/src',
src: [
'types/node/*.ts',
'types/node/**/*.ts',
'types/node-red/*.ts',
],
expand: true,

View File

@ -1,6 +1,6 @@
{
"name": "node-red",
"version": "3.0.2",
"version": "3.1.0-beta.1",
"description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
@ -26,30 +26,30 @@
}
],
"dependencies": {
"acorn": "8.7.1",
"acorn": "8.8.2",
"acorn-walk": "8.2.0",
"ajv": "8.11.0",
"async-mutex": "0.3.2",
"ajv": "8.12.0",
"async-mutex": "0.4.0",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"body-parser": "1.20.0",
"body-parser": "1.20.2",
"cheerio": "1.0.0-rc.10",
"clone": "2.1.2",
"content-type": "1.0.4",
"content-type": "1.0.5",
"cookie": "0.5.0",
"cookie-parser": "1.4.6",
"cors": "2.8.5",
"cronosjs": "1.7.1",
"denque": "2.1.0",
"express": "4.18.1",
"express": "4.18.2",
"express-session": "1.17.3",
"form-data": "4.0.0",
"fs-extra": "10.1.0",
"got": "11.8.5",
"got": "11.8.6",
"hash-sum": "2.0.0",
"hpagent": "1.0.0",
"hpagent": "1.2.0",
"https-proxy-agent": "5.0.1",
"i18next": "21.8.16",
"i18next": "21.10.0",
"iconv-lite": "0.6.3",
"is-utf8": "0.2.1",
"js-yaml": "4.1.0",
@ -60,7 +60,7 @@
"memorystore": "1.6.7",
"mime": "3.0.0",
"moment": "2.29.4",
"moment-timezone": "0.5.34",
"moment-timezone": "0.5.41",
"mqtt": "4.3.7",
"multer": "1.4.5-lts.1",
"mustache": "4.2.0",
@ -72,21 +72,21 @@
"passport": "0.6.0",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"raw-body": "2.5.1",
"semver": "7.3.7",
"tar": "6.1.11",
"tough-cookie": "4.0.0",
"uglify-js": "3.16.3",
"uuid": "8.3.2",
"raw-body": "2.5.2",
"semver": "7.3.8",
"tar": "6.1.13",
"tough-cookie": "4.1.2",
"uglify-js": "3.17.4",
"uuid": "9.0.0",
"ws": "7.5.6",
"xml2js": "0.4.23"
},
"optionalDependencies": {
"bcrypt": "5.0.1"
"bcrypt": "5.1.0"
},
"devDependencies": {
"dompurify": "2.3.10",
"grunt": "1.5.3",
"dompurify": "2.4.1",
"grunt": "1.6.1",
"grunt-chmod": "~1.1.1",
"grunt-cli": "~1.4.3",
"grunt-concurrent": "3.0.0",
@ -108,17 +108,18 @@
"i18next-http-backend": "1.4.1",
"jquery-i18next": "1.2.1",
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
"marked": "4.0.18",
"marked": "4.2.12",
"mermaid": "^9.3.0",
"minami": "1.2.3",
"mocha": "9.2.2",
"node-red-node-test-helper": "^0.3.0",
"nodemon": "2.0.19",
"nodemon": "2.0.20",
"proxy": "^1.0.2",
"sass": "1.54.2",
"sass": "1.58.3",
"should": "13.2.3",
"sinon": "11.1.2",
"stoppable": "^1.1.0",
"supertest": "6.2.4"
"supertest": "6.3.3"
},
"engines": {
"node": ">=14"

View File

@ -1,6 +1,6 @@
{
"name": "@node-red/editor-api",
"version": "3.0.2",
"version": "3.1.0-beta.1",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@ -16,14 +16,14 @@
}
],
"dependencies": {
"@node-red/util": "3.0.2",
"@node-red/editor-client": "3.0.2",
"@node-red/util": "3.1.0-beta.1",
"@node-red/editor-client": "3.1.0-beta.1",
"bcryptjs": "2.4.3",
"body-parser": "1.20.0",
"body-parser": "1.20.2",
"clone": "2.1.2",
"cors": "2.8.5",
"express-session": "1.17.3",
"express": "4.18.1",
"express": "4.18.2",
"memorystore": "1.6.7",
"mime": "3.0.0",
"multer": "1.4.5-lts.1",
@ -35,6 +35,6 @@
"ws": "7.5.6"
},
"optionalDependencies": {
"bcrypt": "5.0.1"
"bcrypt": "5.1.0"
}
}

View File

@ -1175,8 +1175,10 @@
"languages": {
"de": "Deutsch",
"en-US": "Englisch",
"fr": "Französisch",
"ja": "Japanisch",
"ko": "Koreanisch",
"pt-BR":"Portugiesisch",
"ru": "Russisch",
"zh-CN": "Chinesisch (Vereinfacht)",
"zh-TW": "Chinesisch (Traditionell)"

View File

View File

View File

@ -23,7 +23,11 @@
"position": "Position",
"enable": "Enable",
"disable": "Disable",
"upload": "Upload"
"upload": "Upload",
"lock": "Lock",
"unlock": "Unlock",
"locked": "Locked",
"unlocked": "Unlocked"
},
"type": {
"string": "string",
@ -53,22 +57,30 @@
"confirmDelete": "Confirm delete",
"delete": "Are you sure you want to delete '__label__'?",
"dropFlowHere": "Drop the flow here",
"dropImageHere": "Drop the image here",
"addFlow": "Add flow",
"addFlowToRight": "Add flow to the right",
"closeFlow": "Close flow",
"hideFlow": "Hide flow",
"hideOtherFlows": "Hide other flows",
"showAllFlows": "Show all flows",
"showAllFlows": "Show all flows (__count__ hidden)",
"hideAllFlows": "Hide all flows",
"hiddenFlows": "List __count__ hidden flow",
"hiddenFlows_plural": "List __count__ hidden flows",
"showLastHiddenFlow": "Show last hidden flow",
"showLastHiddenFlow": "Reopen hidden flow",
"listFlows": "List flows",
"listSubflows": "List subflows",
"status": "Status",
"enabled": "Enabled",
"disabled": "Disabled",
"info": "Description",
"selectNodes": "Click nodes to select"
"selectNodes": "Click nodes to select",
"enableFlow": "Enable flow",
"disableFlow": "Disable flow",
"lockFlow": "Lock flow",
"unlockFlow": "Unlock flow",
"moveToStart": "Move flow to start",
"moveToEnd": "Move flow to end"
},
"menu": {
"label": {
@ -101,6 +113,7 @@
"displayStatus": "Show node status",
"displayConfig": "Configuration nodes",
"import": "Import",
"importExample": "Import Example Flow",
"export": "Export",
"search": "Search flows",
"searchInput": "search your flows",
@ -497,6 +510,7 @@
"addRemoveNode": "Add/remove node from selection",
"editSelected": "Edit selected node",
"deleteSelected": "Delete selected nodes or link",
"deleteReconnect": "Delete and Reconnect",
"importNode": "Import nodes",
"exportNode": "Export nodes",
"nudgeNode": "Move selected nodes (1px)",
@ -683,7 +697,11 @@
"empty": "empty",
"globalConfig": "Global Configuration Nodes",
"triggerAction": "Trigger action",
"find": "Find in workspace"
"find": "Find in workspace",
"copyItemUrl": "Copy item url",
"copyURL2Clipboard": "Copied url to clipboard",
"showFlow": "Show",
"hideFlow": "Hide"
},
"help": {
"name": "Help",
@ -984,7 +1002,10 @@
"quote": "Quote",
"link": "Link",
"horizontal-rule": "Horizontal rule",
"toggle-preview": "Toggle preview"
"toggle-preview": "Toggle preview",
"mermaid": {
"summary": "Mermaid Diagram"
}
},
"bufferEditor": {
"title": "Buffer editor",
@ -1179,8 +1200,10 @@
"languages": {
"de": "German",
"en-US": "English",
"fr": "French",
"ja": "Japanese",
"ko": "Korean",
"pt-BR":"Portuguese",
"ru": "Russian",
"zh-CN": "Chinese(Simplified)",
"zh-TW": "Chinese(Traditional)"
@ -1206,5 +1229,10 @@
"node": "Node",
"junction": "Junction",
"linkNodes": "Link Nodes"
},
"env-var": {
"environment": "Environment",
"header": "Global Environment Variables",
"revert": "Revert"
}
}

View File

View File

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
{
"info": {
"tip0": "Vous pouvez supprimer les noeuds ou les liens sélectionnés avec {{core:delete-selection}}",
"tip1": "Rechercher des noeuds à l'aide de {{core:search}}",
"tip2": "{{core:toggle-sidebar}} basculera l'affichage de cette barre latérale",
"tip3": "Vous pouvez gérer votre palette de noeuds avec {{core:manage-palette}}",
"tip4": "Vos noeuds de configuration de flux sont répertoriés dans le panneau de la barre latérale. Ils sont accessibles depuis le menu ou avec {{core:show-config-tab}}",
"tip5": "Activer ou désactiver ces conseils à partir de l'option dans les paramètres",
"tip6": "Déplacer les noeuds sélectionnés à l'aide des touches [gauche] [haut] [bas] et [droite]. Maintenir la touche [shift] enfoncée pour les pousser plus loin",
"tip7": "Faire glisser un noeud sur un fil le raccordera au lien",
"tip8": "Exporter les noeuds sélectionnés, ou l'onglet actuel avec {{core:show-export-dialog}}",
"tip9": "Importer un flux en faisant glisser son JSON dans l'éditeur, ou avec {{core:show-import-dialog}}",
"tip10": "[majuscule] [clic] et faites glisser sur un port de noeud pour déplacer tous les fils attachés ou seulement celui sélectionné",
"tip11": "Afficher l'onglet Infos avec {{core:show-info-tab}} ou l'onglet Débogage avec {{core:show-debug-tab}}",
"tip12": "[ctrl] [clic] dans l'espace de travail pour ouvrir la boîte de dialogue d'ajout rapide",
"tip13": "Maintenir la touche [ctrl] enfoncée lorsque vous [cliquez] sur un port de noeud pour activer le câblage rapide",
"tip14": "Maintenir la touche [shift] enfoncée lorsque vous [cliquez] sur un noeud pour sélectionner également tous ses noeuds connectés",
"tip15": "Maintenir la touche [ctrl] enfoncée lorsque vous [cliquez] sur un noeud pour l'ajouter ou le supprimer de la sélection actuelle",
"tip16": "Changer d'onglet de flux avec {{core:show-previous-tab}} et {{core:show-next-tab}}",
"tip17": "Vous pouvez confirmer vos modifications dans le panneau d'édition du noeud avec {{core:confirm-edit-tray}} ou les annuler avec {{core:cancel-edit-tray}}",
"tip18": "Appuyer sur {{core:edit-selected-node}} modifiera le premier noeud de la sélection actuelle"
}
}

View File

@ -0,0 +1,274 @@
{
"$string": {
"args": "arg[, prettify]",
"desc": "Convertit le paramètre `arg` en une chaîne de caractères en utilisant les règles de typage suivantes :\n\n - Les chaînes de caractères sont inchangées\n - Les fonctions sont converties en une chaîne vide\n - L'infini numérique et NaN renvoient une erreur car ils ne peuvent pas être représentés comme un Numéro JSON\n - Toutes les autres valeurs sont converties en une chaîne JSON à l'aide de la fonction `JSON.stringify`. Si `prettify` est vrai, alors le JSON \"prettified\" est produit. c'est-à-dire une ligne par champ et les lignes seront en retrait en fonction de la profondeur du champ."
},
"$length": {
"args": "str",
"desc": "Renvoie le nombre de caractères dans la chaîne `str`. Une erreur est renvoyée si `str` n'est pas une chaîne de caractères."
},
"$substring": {
"args": "str, start[, length]",
"desc": "Renvoie une chaîne contenant les caractères du premier paramètre `str` commençant à la position `start` (pas de décalage). Si `length` est spécifié, alors la sous-chaîne contiendra un maximum de caractères `length`. Si `start` est négatif alors il indique le nombre de caractères à partir de la fin de `str`."
},
"$substringBefore": {
"args": "str, chars",
"desc": "Renvoie la sous-chaîne avant la première occurrence de la séquence de caractères `chars` dans `str`. Si `str` ne contient pas `chars`, alors il renvoie `str`."
},
"$substringAfter": {
"args": "str, chars",
"desc": "Renvoie la sous-chaîne après la première occurrence de la séquence de caractères `chars` dans `str`. Si `str` ne contient pas `chars`, alors il renvoie `str`."
},
"$uppercase": {
"args": "str",
"desc": "Renvoie une chaîne avec tous les caractères de `str` convertis en majuscules."
},
"$lowercase": {
"args": "str",
"desc": "Renvoie une chaîne avec tous les caractères de `str` convertis en minuscules."
},
"$trim": {
"args": "str",
"desc": "Normalise et supprime tous les caractères d'espacement dans `str` en appliquant les étapes suivantes :\n\n - Toutes les tabulations, retours à la ligne et sauts de ligne sont remplacés par des espaces.\n- Les séquences contiguës d'espaces sont réduites à un seul espace.\n- Les espaces de fin et de début sont supprimés.\n\n Si `str` n'est pas spécifié (c'est-à-dire que cette fonction est invoquée sans argument), alors la valeur de contexte est utilisée comme valeur de `str`. Une erreur est renvoyée si `str` n'est pas une chaîne."
},
"$contains": {
"args": "str, pattern",
"desc": "Renvoie `true` si `str` correspond à `pattern`, sinon il renvoie `false`. Si `str` n'est pas spécifié (c'est-à-dire que cette fonction est invoquée avec un argument), alors la valeur de contexte est utilisée comme valeur de `str`. Le paramètre `pattern` peut être une chaîne ou une expression régulière."
},
"$split": {
"args": "str[, separator][, limit]",
"desc": "Divise le paramètre `str` en un tableau de sous-chaînes. C'est une erreur si `str` n'est pas une chaîne. Le paramètre facultatif `separator` spécifie les caractères à l'intérieur de `str` à propos desquels il doit être divisé en chaîne ou en expression régulière. Si `separator` n'est pas spécifié, la chaîne vide est supposée et `str` sera divisé en un tableau de caractères uniques. C'est une erreur si `separator` n'est pas une chaîne. Le paramètre facultatif `limit` est un nombre qui spécifie le nombre maximum de sous-chaînes à inclure dans le tableau résultant. Toutes les sous-chaînes supplémentaires sont ignorées. Si `limit` n'est pas spécifié, alors `str` est entièrement divisé sans limite à la taille du tableau résultant. C'est une erreur si `limit` n'est pas un nombre non négatif."
},
"$join": {
"args": "array[, separator]",
"desc": "Joint un tableau de chaînes de composants en une seule chaîne concaténée, chaque chaîne de composants étant séparée par le paramètre facultatif `separator`. C'est une erreur si l'entrée `array` contient un élément qui n'est pas une chaîne. Si `séparateur` n'est pas spécifié, il est supposé être la chaîne vide, c'est-à-dire qu'il n'y a pas de `séparateur` entre les chaînes de composants. C'est une erreur si `separator` n'est pas une chaîne."
},
"$match": {
"args": "str, pattern [, limit]",
"desc": "Applique la chaîne `str` à l'expression régulière `pattern` et renvoie un tableau d'objets, chaque objet contenant des informations sur chaque occurrence d'une correspondance dans `str`."
},
"$replace": {
"args": "str, pattern, replacement [, limit]",
"desc": "Trouve les occurrences de `pattern` dans `str` et les remplace par `replacement`.\n\nLe paramètre facultatif `limit` est le nombre maximum de remplacements."
},
"$now": {
"args": "$[picture [, timezone]]",
"desc": "Génère un horodatage au format compatible ISO 8601 et le renvoie sous forme de chaîne. Si les paramètres optionnels d'image et de fuseau horaire sont fournis, alors l'horodatage actuel est formaté comme décrit par la fonction `$fromMillis()`"
},
"$base64encode": {
"args": "string",
"desc": "Convertit une chaîne ASCII en une représentation en base 64. Chaque caractère de la chaîne est traité comme un octet de données binaires. Cela nécessite que tous les caractères de la chaîne se trouvent dans la plage 0x00 à 0xFF, qui inclut tous les caractères des chaînes encodées en URI. Les caractères Unicode en dehors de cette plage ne sont pas pris en charge."
},
"$base64decode": {
"args": "string",
"desc": "Convertit les octets encodés en base 64 en une chaîne, à l'aide d'une page de codes Unicode UTF-8."
},
"$number": {
"args": "arg",
"desc": "Convertit le paramètre `arg` en un nombre en utilisant les règles de conversion suivantes :\n\n - Les nombres sont inchangés\n - Les chaînes qui contiennent une séquence de caractères représentant un nombre JSON légal sont converties en ce nombre\n - Toutes les autres valeurs provoquer l'envoi d'une erreur."
},
"$abs": {
"args": "number",
"desc": "Renvoie la valeur absolue du paramètre `nombre`."
},
"$floor": {
"args": "number",
"desc": "Renvoie la valeur de `number` arrondie à l'entier le plus proche inférieur ou égal à `number`."
},
"$ceil": {
"args": "number",
"desc": "Renvoie la valeur de `number` arrondie à l'entier le plus proche supérieur ou égal à `number`."
},
"$round": {
"args": "number [, precision]",
"desc": "Renvoie la valeur du paramètre `number` arrondie au nombre de décimales spécifié par le paramètre facultatif `precision`."
},
"$power": {
"args": "base, exponent",
"desc": "Renvoie la valeur de `base` élevée à la puissance de `exponent`."
},
"$sqrt": {
"args": "number",
"desc": "Renvoie la racine carrée de la valeur du paramètre `number`."
},
"$random": {
"args": "",
"desc": "Renvoie un nombre pseudo-aléatoire supérieur ou égal à zéro et inférieur à un."
},
"$millis": {
"args": "",
"desc": "Renvoie le nombre de millisecondes depuis l'époque Unix (1er janvier 1970 UTC) sous forme de nombre. Tous les appels de `$millis()` dans une évaluation d'une expression renverront toutes la même valeur."
},
"$sum": {
"args": "array",
"desc": "Renvoie la somme arithmétique d'un `tableau` de nombres. C'est une erreur si l'entrée `array` contient un élément qui n'est pas un nombre."
},
"$max": {
"args": "array",
"desc": "Renvoie le nombre maximal dans un `tableau` de nombres. C'est une erreur si l'entrée `array` contient un élément qui n'est pas un nombre."
},
"$min": {
"args": "array",
"desc": "Renvoie le nombre minimum dans un `tableau` de nombres. C'est une erreur si l'entrée `array` contient un élément qui n'est pas un nombre."
},
"$average": {
"args": "array",
"desc": "Renvoie la valeur moyenne d'un `tableau` de nombres. C'est une erreur si l'entrée `array` contient un élément qui n'est pas un nombre."
},
"$boolean": {
"args": "arg",
"desc": "Transforme l'argument en booléen en utilisant les règles suivantes :\n\n - `Boolean` : inchangé\n - `string` : vide : `false`\n - `string` : non vide : `true`\n - `number` : `0` : `false`\n - `number` : non nul : `true`\n - `null` : `false`\n - `array` : vide : `false`\n - `array` : contient un membre qui convertit en `true` : `true`\n - `array` : tous les membres sont transformés en `false` : `false`\n - `object` : vide : `false`\n - `object` : non vide : `true`\n - `function` : `false`"
},
"$not": {
"args": "arg",
"desc": "Renvoie un booléen résultat de la négation logique de l'argument"
},
"$exists": {
"args": "arg",
"desc": "Renvoie la valeur booléenne `true` si l'expression `arg` est évaluée à une valeur, ou `false` si l'expression ne correspond à rien (par exemple, un chemin vers une référence de champ inexistante)."
},
"$count": {
"args": "array",
"desc": "Renvoie le nombre d'éléments du tableau"
},
"$append": {
"args": "array, array",
"desc": "Combine deux tableaux"
},
"$sort": {
"args": "array [, function]",
"desc": "Renvoie un tableau contenant toutes les valeurs du paramètre `array`, mais triées dans l'ordre.\n\nSi un comparateur `function` est fourni, alors il doit s'agir d'une fonction qui prend deux paramètres :\n\n`function(left , droite)`\n\nCette fonction est invoquée par l'algorithme de tri pour comparer deux valeurs à gauche et à droite. Si la valeur de left doit être placée après la valeur de right dans l'ordre de tri souhaité, la fonction doit renvoyer un booléen `true` pour indiquer un échange. Sinon, il doit renvoyer `false`."
},
"$reverse": {
"args": "array",
"desc": "Renvoie un tableau contenant toutes les valeurs du paramètre `array`, mais dans l'ordre inverse."
},
"$shuffle": {
"args": "array",
"desc": "Renvoie un tableau contenant toutes les valeurs du paramètre `array`, mais mélangées dans un ordre aléatoire."
},
"$zip": {
"args": "array, ...",
"desc": "Renvoie un tableau convolué (zippé) contenant des tableaux groupés de valeurs des arguments `array1`...`arrayN` d'index 0, 1, 2...."
},
"$keys": {
"args": "object",
"desc": "Renvoie un tableau contenant les clés de l'objet. Si l'argument est un tableau d'objets, le tableau renvoyé contient une liste dédupliquée de toutes les clés de tous les objets."
},
"$lookup": {
"args": "object, key",
"desc": "Renvoie la valeur associée à la clé dans l'objet. Si le premier argument est un tableau d'objets, tous les objets du tableau sont recherchés et les valeurs associées à toutes les occurrences de key sont renvoyées."
},
"$spread": {
"args": "object",
"desc": "Divise un objet contenant des paires clé/valeur en un tableau d'objets, chacun ayant une seule paire clé/valeur de l'objet d'entrée. Si le paramètre est un tableau d'objets, alors le tableau résultant contient un objet pour chaque paire clé/valeur dans chaque objet du tableau fourni."
},
"$merge": {
"args": "array&lt;object&gt;",
"desc": "Fusionne un tableau d'`objets` en un seul `objet` contenant toutes les paires clé/valeur de chacun des objets du tableau d'entrée. Si l'un des objets d'entrée contient la même clé, alors l'`objet` renvoyé contiendra la valeur du dernier dans le tableau. C'est une erreur si le tableau d'entrée contient un élément qui n'est pas un objet."
},
"$sift": {
"args": "object, function",
"desc": "Renvoie un objet qui contient uniquement les paires clé/valeur du paramètre `object` qui satisfont le prédicat `function` transmis comme second paramètre.\n\nLa `function` qui est fournie comme second paramètre doit avoir la signature suivante :\n\n`fonction(valeur [, clé [, objet]])`"
},
"$each": {
"args": "object, function",
"desc": "Renvoie un tableau contenant les valeurs renvoyées par la `fonction` lorsqu'elle est appliquée à chaque paire clé/valeur dans l'`objet`."
},
"$map": {
"args": "array, function",
"desc": "Renvoie un tableau contenant les résultats de l'application du paramètre `function` à chaque valeur du paramètre `array`.\n\nLa `function` fournie comme second paramètre doit avoir la signature suivante :\n\n`function( valeur [, indice [, tableau]])`"
},
"$filter": {
"args": "array, function",
"desc": "Renvoie un tableau contenant uniquement les valeurs du paramètre `array` qui satisfont le prédicat `function`.\n\nLa `function` fournie comme second paramètre doit avoir la signature suivante :\n\n`function(value [ , indice [, tableau]])`"
},
"$reduce": {
"args": "array, function [, init]",
"desc": "Renvoie une valeur agrégée dérivée de l'application successive du paramètre `function` à chaque valeur de `array` en combinaison avec le résultat de l'application précédente de la fonction.\n\nLa fonction doit accepter deux arguments et se comporte comme un opérateur infixe entre chaque valeur dans le `tableau`. La signature de `function` doit être de la forme : `myfunc($accumulator, $value[, $index[, $array]])`\n\nLe paramètre facultatif `init` est utilisé comme valeur initiale dans l'agrégation ."
},
"$flowContext": {
"args": "string[, string]",
"desc": "Récupère une propriété de contexte de flux.\n\nCeci est une fonction définie par Node-RED."
},
"$globalContext": {
"args": "string[, string]",
"desc": "Récupère une propriété de contexte globale.\n\nCeci est une fonction définie par Node-RED."
},
"$pad": {
"args": "string, width [, char]",
"desc": "Renvoie une copie de la `chaîne` avec un rembourrage supplémentaire, si nécessaire, de sorte que son nombre total de caractères corresponde au moins à la valeur absolue du paramètre `width`.\n\nSi `width` est un nombre positif, alors la chaîne est rembourré à droite; s'il est négatif, il est rempli vers la gauche.\n\nL'argument optionnel `char` spécifie le(s) caractère(s) de remplissage à utiliser. S'il n'est pas spécifié, la valeur par défaut est le caractère espace."
},
"$fromMillis": {
"args": "number, [, picture [, timezone]]",
"desc": "Convertisser le « nombre » représentant les millisecondes depuis l'époque Unix (1er janvier 1970 UTC) en une représentation sous forme de chaîne formatée de l'horodatage tel que spécifié par la chaîne d'image.\n\nSi le paramètre facultatif « image » est omis, l'horodatage est formaté au format ISO 8601.\n\nSi la chaîne facultative `image` est fournie, l'horodatage est formaté selon la représentation spécifiée dans cette chaîne. Le comportement de cette fonction est cohérent avec la version à deux arguments de la fonction XPath/XQuery `format-dateTime` telle que définie dans la spécification XPath F&O 3.1. Le paramètre de chaîne d'image définit la façon dont l'horodatage est formaté et a la même syntaxe que `format-dateTime`.\n\nSi la chaîne facultative `timezone` est fournie, alors l'horodatage formaté sera dans ce fuseau horaire. La chaîne `timezone` doit être au format '±HHMM', où ± est le signe plus ou moins et HHMM est le décalage en heures et minutes par rapport à UTC. Décalage positif pour les fuseaux horaires à l'est de UTC, décalage négatif pour les fuseaux horaires à l'ouest de UTC."
},
"$formatNumber": {
"args": "number, picture [, options]",
"desc": "Convertit le `number` en une chaîne et le formate en une représentation décimale comme spécifié par la chaîne `picture`.\n\n Le comportement de cette fonction est cohérent avec la fonction XPath/XQuery fn:format-number telle que définie dans le Spécification XPath F&O 3.1. Le paramètre de chaîne d'image définit la façon dont le nombre est formaté et a la même syntaxe que fn:format-number.\n\nLe troisième argument facultatif `options` est utilisé pour remplacer les caractères de formatage spécifiques aux paramètres régionaux par défaut, tels que le séparateur décimal. S'il est fourni, cet argument doit être un objet contenant des paires nom/valeur spécifiées dans la section de format décimal de la spécification XPath F&O 3.1."
},
"$formatBase": {
"args": "number [, radix]",
"desc": "Convertit le `number` en une chaîne et le formate en un entier représenté dans la base numérique spécifiée par l'argument `radix`. Si `radix` n'est pas spécifié, la valeur par défaut est la base 10. `radix` peut être compris entre 2 et 36, sinon une erreur est renvoyée."
},
"$toMillis": {
"args": "timestamp",
"desc": "Convertit une chaîne `timestamp` au format ISO 8601 en nombre de millisecondes depuis l'époque Unix (1er janvier 1970 UTC) sous forme de nombre. Une erreur est renvoyée si la chaîne n'est pas au format correct."
},
"$env": {
"args": "arg",
"desc": "Renvoie la valeur d'une variable d'environnement.\n\nCeci est une fonction définie par Node-RED."
},
"$eval": {
"args": "expr [, context]",
"desc": "Analyse et évalue la chaîne `expr` qui contient un JSON littéral ou une expression JSONata en utilisant le contexte actuel comme contexte d'évaluation."
},
"$formatInteger": {
"args": "number, picture",
"desc": "Transforme le `nombre` en une chaîne et le formate en une représentation entière comme spécifié par la chaîne `image`. Le paramètre de chaîne d'image définit la façon dont le nombre est formaté et a la même syntaxe que `fn:format-integer` de la spécification XPath F&O 3.1."
},
"$parseInteger": {
"args": "string, picture",
"desc": "Analyse le contenu du paramètre `string` en un entier (comme un nombre JSON) en utilisant le format spécifié par la chaîne `picture`. Le paramètre de chaîne `picture` a le même format que `$formatInteger`."
},
"$error": {
"args": "[str]",
"desc": "Génère une erreur avec un message. Le `str` facultatif remplacera le message par défaut de la fonction `$error() évaluée`"
},
"$assert": {
"args": "arg, str",
"desc": "Si `arg` est vrai, la fonction renvoie undefined. Si `arg` est faux, une exception est lancée avec `str` comme message de l'exception."
},
"$single": {
"args": "array, function",
"desc": "Renvoie la seule et unique valeur du paramètre `array` qui satisfait le prédicat `function` (c'est-à-dire que la `function` renvoie la valeur booléenne `true` lorsqu'elle est transmise à la valeur). Lève une exception si le nombre de valeurs correspondantes n'est pas exactement un.\n\nLa fonction doit être fournie dans la signature suivante : `function(value [, index [, array]])` où value est chaque entrée du tableau, index est la position de cette valeur et le tableau entier est passé comme troisième argument"
},
"$encodeUrlComponent": {
"args": "str",
"desc": "Encode un composant URL (Uniform Resource Locator) en remplaçant chaque instance de certains caractères par une, deux, trois ou quatre séquences d'échappement représentant l'encodage UTF-8 du caractère.\n\nExemple : `$encodeUrlComponent(\"?x =test\")` => `\"%3Fx%3Dtest\"`"
},
"$encodeUrl": {
"args": "str",
"desc": "Encode une URL (Uniform Resource Locator) en remplaçant chaque instance de certains caractères par une, deux, trois ou quatre séquences d'échappement représentant l'encodage UTF-8 du caractère. \n\nExemple : `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0% B5%D0%BB%D0%BB%D1%8B\"`"
},
"$decodeUrlComponent": {
"args": "str",
"desc": "Décode un composant URL (Uniform Resource Locator) précédemment créé par encodeUrlComponent. \n\nExemple : `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
},
"$decodeUrl": {
"args": "str",
"desc": "Décode une URL (Uniform Resource Locator) précédemment créée par encodeUrl. \n\nExemple : `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
},
"$distinct": {
"args": "array",
"desc": "Renvoie un tableau avec les valeurs en double supprimées de `array`"
},
"$type": {
"args": "value",
"desc": "Renvoie le type de `value` sous forme de chaîne. Si `value` n'est pas défini, cela renverra `undefined`"
},
"$moment": {
"args": "[str]",
"desc": "Obtient un objet de date à l'aide de la bibliothèque Moment."
}
}

View File

@ -23,7 +23,11 @@
"position": "配置",
"enable": "有効",
"disable": "無効",
"upload": "アップロード"
"upload": "アップロード",
"lock": "固定",
"unlock": "固定を解除",
"locked": "固定済み",
"unlocked": "固定なし"
},
"type": {
"string": "文字列",
@ -53,8 +57,10 @@
"confirmDelete": "削除の確認",
"delete": "本当に '__label__' を削除しますか?",
"dropFlowHere": "ここにフローをドロップしてください",
"dropImageHere": "ここに画像ファイルをドロップしてください",
"addFlow": "フローの追加",
"addFlowToRight": "右側にフローを追加",
"closeFlow": "フローを閉じる",
"hideFlow": "フローを非表示",
"hideOtherFlows": "他のフローを非表示",
"showAllFlows": "全てのフローを表示",
@ -68,7 +74,13 @@
"enabled": "有効",
"disabled": "無効",
"info": "詳細",
"selectNodes": "ノードをクリックして選択"
"selectNodes": "ノードをクリックして選択",
"enableFlow": "フローを有効化",
"disableFlow": "フローを無効化",
"lockFlow": "フローを固定",
"unlockFlow": "フローの固定を解除",
"moveToStart": "フローを先頭へ移動",
"moveToEnd": "フローを最後へ移動"
},
"menu": {
"label": {
@ -101,6 +113,7 @@
"displayStatus": "ノードのステータスを表示",
"displayConfig": "設定ノード",
"import": "読み込み",
"importExample": "フロー例を読み込み",
"export": "書き出し",
"search": "ノードを検索",
"searchInput": "ノードを検索",
@ -497,6 +510,7 @@
"addRemoveNode": "ノードの選択、選択解除",
"editSelected": "選択したノードを編集",
"deleteSelected": "選択したノードや接続を削除",
"deleteReconnect": "削除と再接続",
"importNode": "フローの読み込み",
"exportNode": "フローの書き出し",
"nudgeNode": "選択したノードを移動(移動量小)",
@ -683,7 +697,11 @@
"empty": "空",
"globalConfig": "グローバル設定ノード",
"triggerAction": "アクションを実行",
"find": "ワークスペース内を検索"
"find": "ワークスペース内を検索",
"copyItemUrl": "要素のURLをコピー",
"copyURL2Clipboard": "URLをクリップボードにコピーしました",
"showFlow": "表示",
"hideFlow": "非表示"
},
"help": {
"name": "ヘルプ",
@ -984,7 +1002,10 @@
"quote": "引用",
"link": "リンク",
"horizontal-rule": "区切り線",
"toggle-preview": "プレビュー表示切替え"
"toggle-preview": "プレビュー表示切替え",
"mermaid": {
"summary": "Mermaid図"
}
},
"bufferEditor": {
"title": "バッファエディタ",
@ -1179,8 +1200,10 @@
"languages": {
"de": "ドイツ語",
"en-US": "英語",
"fr": "フランス語",
"ja": "日本語",
"ko": "韓国語",
"pt-BR":"ポルトガル語",
"ru": "ロシア語",
"zh-CN": "中国語(簡体)",
"zh-TW": "中国語(繁体)"
@ -1207,6 +1230,11 @@
"junction": "分岐点",
"linkNodes": "Linkード"
},
"env-var": {
"environment": "環境変数",
"header": "大域環境変数",
"revert": "破棄"
},
"action-list": {
"toggle-show-tips": "ヒント表示切替",
"show-about": "Node-REDの説明を表示",
@ -1291,6 +1319,7 @@
"distribute-selection-vertically": "選択を上下に整列",
"wire-series-of-nodes": "ノードを一続きに接続",
"wire-node-to-multiple": "ノードを複数に接続",
"wire-multiple-to-node": "複数からノードへ接続",
"split-wire-with-link-nodes": "ワイヤーをlinkードで分割",
"generate-node-names": "ノード名を生成",
"show-user-settings": "ユーザ設定を表示",
@ -1350,6 +1379,14 @@
"show-project-settings": "プロジェクト設定を表示",
"show-version-control-tab": "バージョンコントロールタブを表示",
"start-flows": "フローを開始",
"stop-flows": "フローを停止"
"stop-flows": "フローを停止",
"copy-item-url": "要素のURLをコピー",
"copy-item-edit-url": "要素の編集URLをコピー",
"move-flow-to-start": "フローを先頭に移動",
"move-flow-to-end": "フローを末尾に移動",
"show-global-env": "大域環境変数を表示",
"lock-flow": "フローを固定",
"unlock-flow": "フローの固定を解除",
"show-node-help": "ノードのヘルプを表示"
}
}

View File

View File

View File

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
{
"info": {
"tip0": "Você pode remover os nós ou links selecionados com {{core:delete-selection}}",
"tip1": "Procure por nós usando {{core:search}}",
"tip2": "{{core:toggle-sidebar}} irá alternar a visualização desta barra lateral",
"tip3": "Você pode gerenciar sua paleta de nós com {{core:manage-palette}}",
"tip4": "Seus nós de configuração de fluxo são listados no painel da barra lateral. Pode ser acessado a partir do menu ou com{{core:show-config-tab}}",
"tip5": "Habilite ou desabilite essas dicas na opção nas configurações",
"tip6": "Mova os nós selecionados usando o [left] [up] [down] e [right] chaves. Segure [shift] para empurrá-los ainda mais",
"tip7": "Arrastar um nó para um fio o unirá no link",
"tip8": "Exporte os nós selecionados ou a guia atual com {{core:show-export-dialog}}",
"tip9": "Importe um fluxo arrastando seu JSON para o editor ou com {{core:show-import-dialog}}",
"tip10": "[shift] [click] e arraste em uma porta de nó para mover todos os fios conectados ou apenas o selecionado",
"tip11": "Mostre a guia Informações com {{core:show-info-tab}} ou a guia Depurar com {{core:show-debug-tab}}",
"tip12": "[ctrl] [click] na área de trabalho para abrir a caixa de diálogo de adição rápida",
"tip13": "Mantenha pressionado [ctrl] enquanto você [click] em uma porta de nó para habilitar a ligação rápida",
"tip14": "Mantenha pressionado [shift] enquanto você [click] em um nó para também selecionar todos os seus nós conectados",
"tip15": "Mantenha pressionado [ctrl] enquanto você [click] em um nó para adicioná-lo ou removê-lo da seleção atual",
"tip16": "Alternar guias de fluxo com {{core:show-previous-tab}} e {{core:show-next-tab}}",
"tip17": "Você pode confirmar suas alterações na bandeja de edição do nó com {{core:confirm-edit-tray}} ou cancele-os com {{core:cancel-edit-tray}}",
"tip18": "Pressionando {{core:edit-selected-node}} irá editar o primeiro nó na seleção atual"
}
}

View File

@ -0,0 +1,274 @@
{
"$string": {
"args": "arg[, prettify]",
"desc": "Converte o tipo do parâmetro `arg` em uma cadeia de caracteres usando as seguintes regras de conversão de tipo:\n\n - Cadeia de caracteres não são alteradas\n - As funções são convertidas para uma cadeia de caracteres vazia\n - os tipos numérico infinito e NaN geram um erro porque não podem ser representados como um número JSON\n - Todos os outros valores são convertidos para uma cadeia de caracteres JSON usando a função `JSON.stringify`. Se `prettify` for verdadeira, então o JSON \"prettified\" é produzido. Isto é, uma linha por campo e as linhas serão indentadas com base na profundidade do campo."
},
"$length": {
"args": "str",
"desc": "Retorna o número de caracteres na cadeia de caracteres `str`. Um erro é gerado se `str` não for uma cadeia de caracteres."
},
"$substring": {
"args": "str, start[, length]",
"desc": "Retorna uma cadeia de caracteres contendo os caracteres no primeiro parâmetro `str` começando na posição `start` (deslocamento zero). Se` length` for especificado, então a sub cadeia de caracteres conterá o máximo `length` de caracteres. Se` start` for negativo isso indica o número de caracteres a partir do fim de `str`."
},
"$substringBefore": {
"args": "str, chars",
"desc": "Retorna a sub cadeia de caracteres antes da primeira ocorrência da sequência de caracteres `chars` em `string`. Se` string` não contiver `chars`, então retorna `str`. "
},
"$substringAfter": {
"args": "str, chars",
"desc": "Retorna a sub cadeia de caracteres após a primeira ocorrência da sequência de caracteres `chars` em `string`. Se `string` não contiver `chars`, então retorna `str`. "
},
"$uppercase": {
"args": "str",
"desc": "Retorna uma cadeia de caracteres com todos os caracteres de `string` convertidos em maiúsculas. "
},
"$lowercase": {
"args": "str",
"desc": "Retorna uma cadeia de caracteres com todos os caracteres de `string` convertidos em minúsculas. "
},
"$trim": {
"args": "str",
"desc": "Normaliza e retira todos os caracteres de espaço em branco em `str` aplicando as seguintes etapas:\n\n - Todas as tabulações, retornos de carro e avanços de linha são substituídos por espaços.\n- Sequências contíguas de espaços são reduzidas a um único espaço.\n- Espaços à direita e à esquerda são removidos.\n\n Se `str` não for especificado (isto é, esta função é chamada sem argumentos), então o valor do contexto é usado como o valor de `str`. Um erro é gerado se `str` não for uma cadeia de caracteres."
},
"$contains": {
"args": "str, pattern",
"desc": "Retorna `true` se `str` tiver correspondente em `pattern`, caso contrário, retorna `false`. Se `str` não for especificado (isto é, esta função é chamada com um argumento), então o valor do contexto é usado como o valor de `str`. O parâmetro `pattern` pode ser uma cadeia de caracteres ou uma expressão regular. "
},
"$split": {
"args": "str[, separator][, limit]",
"desc": "Divide o parâmetro `str` em uma matriz de sub cadeia de caracteres. É um erro se `str` não for uma cadeia de caracteres. O parâmetro opcional `separator` especifica os caracteres dentro de `str` sobre os quais devem ser divididos como uma cadeia de caracteres ou expressão regular. Se `separator` não for especificado, a cadeia de caracteres vazia será assumida e `str` será dividido em uma matriz de caracteres únicos. É um erro se `separador` não for uma cadeia de caracteres. O parâmetro opcional `limit` é um número que especifica o número máximo de sub cadeia de caracteres a serem incluídas na matriz resultante. Quaisquer sub cadeia de caracteres adicionais são descartadas. Se `limit` não for especificado, então `str` será totalmente dividido sem limite para o tamanho da matriz resultante . É um erro se `limit` não for um número não negativo."
},
"$join": {
"args": "array[, separator]",
"desc": "Une uma matriz de cadeias de caracteres de componentes em uma única cadeia de caracteres concatenada com cada cadeia de caracteres de componente separada pelo parâmetro opcional `separator`. É um erro se a `matriz` de entrada contiver um item que não seja uma cadeia de caracteres. Se `separator` for não especificado, assume-se que é uma cadeia de caracteres vazia, ou seja, nenhum `separator` entre as cadeias de caracteres do componente. É um erro se `separator` não for uma cadeia de caracteres. "
},
"$match": {
"args": "str, pattern [, limit]",
"desc": "Aplica a cadeia de caracteres `str` à expressão regular `pattern` e retorna uma matriz de objetos, com cada objeto contendo informações sobre cada ocorrência de uma correspondência dentro de `str`. "
},
"$replace": {
"args": "str, pattern, replacement [, limit]",
"desc": "Encontra ocorrências de `pattern` dentro de `str` e as substitui por `replacement`.\n\nO parâmetro opcional `limit` é o número máximo de substituições."
},
"$now": {
"args":"$[picture [, timezone]]",
"desc":"Gera um carimbo de data/hora em formato compatível com ISO 8601 e o retorna como uma cadeia de caracteres. Se os parâmetros opcionais de imagem e fuso horário forem fornecidos, o carimbo de data/hora atual é formatado conforme descrito pela função `$ fromMillis ()`"
},
"$base64encode": {
"args":"string",
"desc":"Converte uma cadeia de caracteres ASCII em uma representação de base 64. Cada caractere na cadeia de caracteres é tratado como um byte de dados binários. Isso requer que todos os caracteres na cadeia de caracteres estejam no intervalo de 0x00 a 0xFF, o que inclui todos os caracteres em cadeias de caracteres codificadas em URI. Caracteres Unicode fora desse intervalo não são suportados."
},
"$base64decode": {
"args":"string",
"desc":"Converte bytes codificados de base 64 em uma cadeia de caracteres, usando uma página de código UTF-8 Unicode."
},
"$number": {
"args": "arg",
"desc": "Converte o parâmetro `arg` em um número usando as seguintes regras de conversão:\n\n - Os números permanecem inalterados\n - Cadeias de caracteres que contêm uma sequência de caracteres que representam um número JSON válido são convertidos para esse número\n - Todos os outros valores causam a geração de um erro."
},
"$abs": {
"args":"number",
"desc":"Retorna o valor absoluto do parâmetro `number`."
},
"$floor": {
"args":"number",
"desc":"Retorna o valor de `number` arredondado para baixo para o inteiro mais próximo que seja menor ou igual a `number`."
},
"$ceil": {
"args":"number",
"desc":"Retorna o valor de `number` arredondado para o número inteiro mais próximo que é maior ou igual a `number`."
},
"$round": {
"args":"number [, precision]",
"desc":"Retorna o valor do parâmetro `number` arredondado para o número de casas decimais especificado pelo parâmetro opcional `precision`."
},
"$power": {
"args":"base, exponent",
"desc":"Retorna o valor de `base` elevado à potência de `exponent`."
},
"$sqrt": {
"args":"number",
"desc":"Retorna a raiz quadrada do valor do parâmetro `number`."
},
"$random": {
"args":"",
"desc":"Retorna um número pseudoaleatório maior ou igual a zero e menor que um."
},
"$millis": {
"args":"",
"desc":"Retorna o número de milissegundos desde o Unix Epoch (1º de janeiro de 1970 UTC) como um número. Todas as invocações de `$ millis ()` dentro de uma avaliação de uma expressão retornarão todas o mesmo valor."
},
"$sum": {
"args": "array",
"desc": "Retorna a soma aritmética de uma `array` de números. É um erro se o `array` de entrada contiver um item que não seja um número."
},
"$max": {
"args": "array",
"desc": "Retorna o número máximo em uma `array` de números. É um erro se o `array` de entrada contiver um item que não seja um número."
},
"$min": {
"args": "array",
"desc": "Retorna o número mínimo em uma `array` de números. É um erro se o `array` de entrada contiver um item que não seja um número."
},
"$average": {
"args": "array",
"desc": "Retorna o valor médio de uma `array` de números. É um erro se o `array` de entrada contiver um item que não seja um número."
},
"$boolean": {
"args": "arg",
"desc": "Converte o argumento em um booliano usando as seguintes regras:\n\n - `Boolean` : inalterado\n - `string`: vazio : `false`\n - `string`: não-vazio : `true`\n - `number`: `0` : `false`\n - `number`: não-zero : `true`\n - `null` : `false`\n - `array`: vazio : `false`\n - `array`: contém um membro que converte de tipo para `true` : `true`\n - `array`: todos os membros convertidos de tipo para `false` : `false`\n - `object`: vazio : `false`\n - `object`: não-vazio : `true`\n - `function` : `false`"
},
"$not": {
"args": "arg",
"desc": "Retorna booliano NOT no argumento. `Arg` é convertido de tipo primeiro para um booliano "
},
"$exists": {
"args": "arg",
"desc": "Retorna booliano `true` se a expressão `arg` for avaliada como um valor, ou `false` se a expressão não corresponder a nada (por exemplo, um caminho para uma referência de campo inexistente)."
},
"$count": {
"args": "array",
"desc": "Retorna o número de itens na matriz"
},
"$append": {
"args": "array, array",
"desc": "Anexa duas matrizes"
},
"$sort": {
"args":"array [, function]",
"desc":"Retorna uma matriz contendo todos os valores no parâmetro `array`, mas classificados em ordem.\n\nSe um comparador `function` for fornecido, então deve ser uma função que leva dois parâmetros:\n\n`function(left, right)`\n\nEsta função é invocada pelo algoritmo de classificação para comparar dois valores à esquerda e à direita. Se o valor de esquerda deve ser colocado após o valor de direita na ordem de classificação desejada, a função deve retornar o booliano `true` para indicar uma troca. Caso contrário, deve retornar `false`."
},
"$reverse": {
"args":"array",
"desc":"Retorna uma matriz contendo todos os valores do parâmetro `array`, mas na ordem reversa. "
},
"$shuffle": {
"args":"array",
"desc":"Retorna uma matriz contendo todos os valores do parâmetro `array`, mas misturados em ordem aleatória. "
},
"$zip": {
"args":"array, ...",
"desc":"Retorna uma matriz convolucional (compactada) contendo matrizes agrupadas de valores dos argumentos `array1`… `arrayN` do índice 0, 1, 2 ...."
},
"$keys": {
"args": "object",
"desc": "Retorna uma matriz contendo as chaves do objeto. Se o argumento for uma matriz de objetos, então a matriz retornada contém uma lista não duplicada de todas as chaves em todos os objetos."
},
"$lookup": {
"args": "object, key",
"desc": "Retorna o valor associado à chave no objeto. Se o primeiro argumento for uma matriz de objetos, todos os objetos na matriz são pesquisados e os valores associados a todas as ocorrências da chave são retornados."
},
"$spread": {
"args": "object",
"desc": "Divide um objeto que contém pares de chave/valor em uma matriz de objetos, cada um com um único par de chave/valor do objeto de entrada. Se o parâmetro for uma matriz de objetos, a matriz resultante conterá um objeto para cada par de chave/valor em todo objeto na matriz fornecida. "
},
"$merge": {
"args": "array&lt;object&gt;",
"desc": "Mescla uma matriz de `objects` em um único `object` contendo todos os pares de chave/valor de cada um dos objetos na matriz de entrada. Se qualquer um dos objetos de entrada contiver a mesma chave, então o `object` retornado conterá o valor do último na matriz. É um erro se a matriz de entrada contiver um item que não seja um objeto."
},
"$sift": {
"args":"object, function",
"desc": "Retorna um objeto que contém apenas os pares de chave/valor do parâmetro `object` que satisfazem o predicado `function` passado como o segundo parâmetro.\n\nA `function` que é fornecida como o segundo parâmetro deve ter o seguinte assinatura:\n\n`function(value [, key [, object]])`"
},
"$each": {
"args":"object, function",
"desc":"Retorna uma matriz contendo os valores retornados por `function` quando aplicado a cada par chave/valor no `object`."
},
"$map": {
"args":"array, function",
"desc":"Retorna uma matriz contendo os resultados da aplicação do parâmetro `function` a cada valor no parâmetro `array`.\n\nA `function` que é fornecido como o segundo parâmetro deve ter a seguinte assinatura:\n\n`function(value [, index [, array]])`"
},
"$filter": {
"args":"array, function",
"desc":"Retorna uma matriz contendo apenas os valores no parâmetro `array` que satisfazem o predicado `function`.\n\nThe `function` que é fornecido como o segundo parâmetro deve ter a seguinte assinatura:\n\n`function(value [, index [, array]])`"
},
"$reduce": {
"args":"array, function [, init]",
"desc":"Retorna um valor agregado derivado da aplicação do parâmetro `function` sucessivamente a cada valor em `array` em combinação com o resultado da aplicação anterior da função.\n\nA função deve aceitar dois argumentos e se comportar como um operador inserido entre cada valor dentro de `array`. A assinatura da `function` deve estar no formato: `myfunc($accumulator, $value[, $index[, $array]])`\n\nO parâmetro opcional `init` é usado como o valor inicial na agregação."
},
"$flowContext": {
"args": "string[, string]",
"desc": "Recupera uma propriedade de contexto de fluxo.\n\nEsta é uma função definida pelo Node-RED. "
},
"$globalContext": {
"args": "string[, string]",
"desc": "Recupera uma propriedade de contexto global.\n\nEsta é uma função definida pelo Node-RED. "
},
"$pad": {
"args": "string, width [, char]",
"desc": "Retorna uma cópia da `string` com preenchimento extra, se necessário, de forma que seu número total de caracteres seja pelo menos o valor absoluto do parâmetro `width`.\n\nSe `width` for um número positivo, a cadeia de caracteres será preenchida à direita; se negativo, é preenchida à esquerda.\n\nO argumento opcional `char` especifica os caracteres de preenchimento a serem usados. Se não for especificado, o padrão é o caractere de espaço. "
},
"$fromMillis": {
"args": "number, [, picture [, timezone]]",
"desc": "Converta o `number` que representa os milissegundos desde a época do Unix (1 January, 1970 UTC) em uma representação de cadeia de caracteres formatada do carimbo de data/hora conforme especificado pela cadeia de caracteres de imagem.\n\nSe o parâmetro opcional `image` for omitido, o carimbo de data/hora será formatado no formato ISO 8601.\n\nSe a cadeia de caracteresopcional `picture` for fornecida, o carimbo de data/hora é formatado de acordo com a representação especificada nessa cadeia de caracteres. O comportamento desta função é consistente com a versão de dois argumentos da função XPath/XQuery `format-dateTime` conforme definido na especificação XPath F&O 3.1. O parâmetro de cadeia de caracteres de imagem define como o carimbo de data/hora é formatado e tem a mesma sintaxe de `format-dateTime`.\n\nSe a cadeia de caracteres opcional `timezone` for fornecida, o carimbo de data/hora formatado estará nesse fuso horário. A cadeia de caracteres `timezone` deve estar no formato '± HHMM', onde ± é o sinal de mais ou menos e HHMM é o deslocamento em horas e minutos do UTC. Deslocamento positivo para fusos horários a leste do UTC, deslocamento negativo para fusos horários a oeste do UTC. "
},
"$formatNumber": {
"args": "number, picture [, options]",
"desc": "Converte o tipo de `number` em uma cadeia de caracteres e o formata em uma representação decimal conforme especificado pela cadeia de caracteres `picture`.\n\n O comportamento desta função é consistente com a função XPath/XQuery fn: format-number conforme definido na especificação XPath F&O 3.1. O parâmetro de cadeia de caracteres de imagem define como o número é formatado e tem a mesma sintaxe de fn: format-number.\n\nO terceiro argumento opcional `options` é usado para substituir os caracteres de formatação específicos da localidade padrão, como o separador decimal. Se fornecido, este argumento deve ser um objeto contendo pares de nome/valor especificados na seção de formato decimal da especificação XPath F&O 3.1."
},
"$formatBase": {
"args": "number [, radix]",
"desc": "Converte o `number` em uma cadeia de caracteres e o formata em um inteiro representado na base do número especificada pelo argumento `radix`. Se `radix` não for especificado, o padrão é a base 10. `radix` pode estar entre 2 e 36, caso contrário, um erro será gerado. "
},
"$toMillis": {
"args": "timestamp",
"desc": "Converta o tipo de uma cadeia de caracteres `timestamp` no formato ISO 8601 para o número de milissegundos desde a época do Unix (1 January, 1970 UTC) como um número. Um erro é gerado se a cadeia de caracteres não estiver no formato correto. "
},
"$env": {
"args": "arg",
"desc": "Retorna o valor de uma variável de ambiente.\n\nEsta é uma função definida pelo Node-RED."
},
"$eval": {
"args": "expr [, context]",
"desc": "Analisa e avalia a cadeia de caracteres `expr` que contém um JSON literal ou uma expressão JSONata usando o contexto atual como o contexto para avaliação. "
},
"$formatInteger": {
"args": "number, picture",
"desc": "Converte o tipo de `number` em uma cadeia de caracteres e o formata em uma representação inteira conforme especificado pela cadeia de caracteres `picture`. O parâmetro da cadeia de caracteres de imagem define como o número é formatado e tem a mesma sintaxe de `fn: format-integer` do Especificação XPath F&O 3.1. "
},
"$parseInteger": {
"args": "string, picture",
"desc": "Examina e troca o conteúdo do parâmetro `string` para um inteiro (como um número JSON) usando o formato especificado pela cadeia de caracteres `picture`. O parâmetro da cadeia de caracteres `picture` tem o mesmo formato que `$ formatInteger`."
},
"$error": {
"args": "[str]",
"desc": "Gera um erro com uma mensagem. O (parâmetro) opcional `str` substituirá a mensagem padrão de `$error() function evaluated`"
},
"$assert": {
"args": "arg, str",
"desc": "Se `arg` for verdadeiro, a função retorna indefinido. Se `arg` for falso, uma exceção é gerada com `str` como a mensagem da exceção. "
},
"$single": {
"args": "array, function",
"desc": "Retorna o único valor no parâmetro `array` que satisfaz o predicado `function` (isto é, O (parâmetro) `function` retorna o booliano `true` quando passado o valor). Gera uma exceção se o número de valores correspondentes não for exatamente um .\n\nA função deve ser fornecida na seguinte assinatura: `function(value [, index [, array]])` onde 'value' é cada entrada da matriz, 'index' é a posição desse valor e toda a matriz é passada como o terceiro argumento"
},
"$encodeUrlComponent": {
"args": "str",
"desc": "Codifica um componente Localizador Uniforme de Recursos (URL) substituindo cada instância de certos caracteres por uma, duas, três ou quatro sequências de escape que representam a codificação UTF-8 do caractere.\n\nExemplo: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
},
"$encodeUrl": {
"args": "str",
"desc": "Codifica um Localizador Uniforme de Recursos (URL) substituindo cada instância de certos caracteres por uma, duas, três ou quatro sequências de escape que representam a codificação UTF-8 do caractere. \n\nExemplo: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
},
"$decodeUrlComponent": {
"args": "str",
"desc": "Decodifica um componente Localizador Uniforme de Recursos (URL) criado anteriormente por encodeUrlComponent. \n\nExemplo: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
},
"$decodeUrl": {
"args": "str",
"desc": "Decodifica um Localizador Uniforme de Recursos (URL) criado anteriormente por encodeUrl. \n\nExemplo: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
},
"$distinct": {
"args": "array",
"desc": "Retorna uma matriz com valores duplicados removidos da `array` "
},
"$type": {
"args": "value",
"desc": "Retorna o tipo de `value` como uma cadeia de caracteres. Se `value` for indefinido, retornará `undefined` "
},
"$moment": {
"args": "[str]",
"desc": "Obtém um objeto de dados usando a biblioteca 'Moment'."
}
}

View File

@ -1133,8 +1133,10 @@
"languages" : {
"de": "Немецкий",
"en-US": "Английский",
"fr": "Французский",
"ja": "Японский",
"ko": "Корейский",
"pt-BR":"португальский",
"ru": "Русский",
"zh-CN": "Китайский (упрощенный)",
"zh-TW": "Китайский (традиционный)"

View File

View File

View File

@ -1147,6 +1147,17 @@
"create": "创建分支",
"current": "当前的"
},
"languages": {
"de": "德语",
"en-US": "英文",
"fr": "法语",
"ja": "日语",
"ko": "韩文",
"pt-BR":"葡萄牙语",
"ru":"俄語",
"zh-CN": "简体中文",
"zh-TW": "繁体中文"
},
"create-default-file-set": {
"no-active": "没有活动项目就无法创建默认文件集",
"no-empty": "无法在非空项目上创建默认文件集",

View File

@ -1088,8 +1088,11 @@
"languages": {
"de": "德語",
"en-US": "英語",
"fr": "法語",
"ja": "日語",
"ko": "韓語",
"pt-BR":"葡萄牙语",
"ru":"俄語",
"zh-CN": "簡體中文",
"zh-TW": "繁體中文"
}

View File

@ -1,6 +1,6 @@
{
"name": "@node-red/editor-client",
"version": "3.0.2",
"version": "3.1.0-beta.1",
"license": "Apache-2.0",
"repository": {
"type": "git",

View File

@ -14,7 +14,7 @@
* limitations under the License.
**/
/**
/**
* An API for undo / redo history buffer
* @namespace RED.history
*/
@ -378,7 +378,8 @@ RED.history = (function() {
if (ev.addToGroup) {
RED.group.removeFromGroup(ev.addToGroup,ev.nodes.map(function(n) { return n.n }),false);
inverseEv.removeFromGroup = ev.addToGroup;
} else if (ev.removeFromGroup) {
}
if (ev.removeFromGroup) {
RED.group.addToGroup(ev.removeFromGroup,ev.nodes.map(function(n) { return n.n }));
inverseEv.addToGroup = ev.removeFromGroup;
}
@ -421,6 +422,9 @@ RED.history = (function() {
ev.node[i] = ev.changes[i];
}
}
ev.node.dirty = true;
ev.node.changed = ev.changed;
var eventType;
switch(ev.node.type) {
case 'tab': eventType = "flows"; break;
@ -434,7 +438,9 @@ RED.history = (function() {
if (ev.node.type === 'tab' && ev.changes.hasOwnProperty('disabled')) {
$("#red-ui-tab-"+(ev.node.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!ev.node.disabled);
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!ev.node.disabled);
}
if (ev.node.type === 'tab' && ev.changes.hasOwnProperty('locked')) {
$("#red-ui-tab-"+(ev.node.id.replace(".","-"))).toggleClass('red-ui-workspace-locked',!!ev.node.locked);
}
if (ev.subflow) {
inverseEv.subflow = {};
@ -509,8 +515,6 @@ RED.history = (function() {
inverseEv.links.push(ev.createdLinks[i]);
}
}
ev.node.dirty = true;
ev.node.changed = ev.changed;
} else if (ev.t == "createSubflow") {
inverseEv = {
t: "deleteSubflow",
@ -646,6 +650,12 @@ RED.history = (function() {
ev.groups[i].nodes = [];
RED.nodes.addGroup(ev.groups[i]);
RED.group.addToGroup(ev.groups[i],nodes);
if (ev.groups[i].g) {
const parentGroup = RED.nodes.group(ev.groups[i].g)
if (parentGroup) {
RED.group.addToGroup(parentGroup, ev.groups[i])
}
}
}
}
} else if (ev.t == "addToGroup") {

View File

@ -19,7 +19,6 @@
* @namespace RED.nodes
*/
RED.nodes = (function() {
var PORT_TYPE_INPUT = 1;
var PORT_TYPE_OUTPUT = 0;
@ -47,6 +46,9 @@ RED.nodes = (function() {
function setDirty(d) {
dirty = d;
if (!d) {
allNodes.clearState()
}
RED.events.emit("workspace:dirty",{dirty:dirty});
}
@ -63,12 +65,12 @@ RED.nodes = (function() {
defaults: {
label: {value:""},
disabled: {value: false},
locked: {value: false},
info: {value: ""},
env: {value: []}
}
};
var exports = {
setModulePendingUpdated: function(module,version) {
moduleList[module].pending_version = version;
@ -238,22 +240,72 @@ RED.nodes = (function() {
// allNodes holds information about the Flow nodes.
var allNodes = (function() {
// Map node.id -> node
var nodes = {};
// Map tab.id -> Array of nodes on that tab
var tabMap = {};
// Map tab.id -> Set of dirty object ids on that tab
var tabDirtyMap = {};
// Map tab.id -> Set of object ids of things deleted from the tab that weren't otherwise dirty
var tabDeletedNodesMap = {};
// Set of object ids of things added to a tab after initial import
var addedDirtyObjects = new Set()
function changeCollectionDepth(tabNodes, toMove, direction, singleStep) {
const result = []
const moved = new Set();
const startIndex = direction ? tabNodes.length - 1 : 0
const endIndex = direction ? -1 : tabNodes.length
const step = direction ? -1 : 1
let target = startIndex // Only used for all-the-way moves
for (let i = startIndex; i != endIndex; i += step) {
if (toMove.size === 0) {
break;
}
const n = tabNodes[i]
if (toMove.has(n)) {
if (singleStep) {
if (i !== startIndex && !moved.has(tabNodes[i - step])) {
tabNodes.splice(i, 1)
tabNodes.splice(i - step, 0, n)
n._reordered = true
result.push(n)
}
} else {
if (i !== target) {
tabNodes.splice(i, 1)
tabNodes.splice(target, 0, n)
n._reordered = true
result.push(n)
}
target += step
}
toMove.delete(n);
moved.add(n);
}
}
return result
}
var api = {
addTab: function(id) {
tabMap[id] = [];
tabDirtyMap[id] = new Set();
tabDeletedNodesMap[id] = new Set();
},
hasTab: function(z) {
return tabMap.hasOwnProperty(z)
},
removeTab: function(id) {
delete tabMap[id];
delete tabDirtyMap[id];
delete tabDeletedNodesMap[id];
},
addNode: function(n) {
nodes[n.id] = n;
if (tabMap.hasOwnProperty(n.z)) {
tabMap[n.z].push(n);
api.addObjectToWorkspace(n.z, n.id, n.changed || n.moved)
} else {
console.warn("Node added to unknown tab/subflow:",n);
tabMap["_"] = tabMap["_"] || [];
@ -267,8 +319,37 @@ RED.nodes = (function() {
if (i > -1) {
tabMap[n.z].splice(i,1);
}
api.removeObjectFromWorkspace(n.z, n.id)
}
},
/**
* Add an object to our dirty/clean tracking state
* @param {String} z
* @param {String} id
* @param {Boolean} isDirty
*/
addObjectToWorkspace: function (z, id, isDirty) {
if (isDirty) {
addedDirtyObjects.add(id)
}
if (tabDeletedNodesMap[z].has(id)) {
tabDeletedNodesMap[z].delete(id)
}
api.markNodeDirty(z, id, isDirty)
},
/**
* Remove an object from our dirty/clean tracking state
* @param {String} z
* @param {String} id
*/
removeObjectFromWorkspace: function (z, id) {
if (!addedDirtyObjects.has(id)) {
tabDeletedNodesMap[z].add(id)
} else {
addedDirtyObjects.delete(id)
}
api.markNodeDirty(z, id, false)
},
hasNode: function(id) {
return nodes.hasOwnProperty(id);
},
@ -280,152 +361,54 @@ RED.nodes = (function() {
n.z = newZ;
api.addNode(n)
},
moveNodesForwards: function(nodes) {
var result = [];
/**
* @param {array} nodes
* @param {boolean} direction true:forwards false:back
* @param {boolean} singleStep true:single-step false:all-the-way
*/
changeDepth: function(nodes, direction, singleStep) {
if (!Array.isArray(nodes)) {
nodes = [nodes]
}
// Can only do this for nodes on the same tab.
// Use nodes[0] to get the z
var tabNodes = tabMap[nodes[0].z];
var toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
var moved = new Set();
for (var i = tabNodes.length-1; i >= 0; i--) {
if (toMove.size === 0) {
break;
}
var n = tabNodes[i];
if (toMove.has(n)) {
// This is a node to move.
if (i < tabNodes.length-1 && !moved.has(tabNodes[i+1])) {
// Remove from current position
tabNodes.splice(i,1);
// Add it back one position higher
tabNodes.splice(i+1,0,n);
n._reordered = true;
result.push(n);
}
toMove.delete(n);
moved.add(n);
let result = []
const tabNodes = tabMap[nodes[0].z];
const toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
if (toMove.size > 0) {
result = result.concat(changeCollectionDepth(tabNodes, toMove, direction, singleStep))
if (result.length > 0) {
RED.events.emit('nodes:reorder',{
z: nodes[0].z,
nodes: result
});
}
}
if (result.length > 0) {
RED.events.emit('nodes:reorder',{
z: nodes[0].z,
nodes: result
});
const groupNodes = groupsByZ[nodes[0].z] || []
const groupsToMove = new Set(nodes.filter(function(n) { return n.type === 'group'}))
if (groupsToMove.size > 0) {
const groupResult = changeCollectionDepth(groupNodes, groupsToMove, direction, singleStep)
if (groupResult.length > 0) {
result = result.concat(groupResult)
RED.events.emit('groups:reorder',{
z: nodes[0].z,
nodes: groupResult
});
}
}
return result;
RED.view.redraw(true)
return result
},
moveNodesForwards: function(nodes) {
return api.changeDepth(nodes, true, true)
},
moveNodesBackwards: function(nodes) {
var result = [];
if (!Array.isArray(nodes)) {
nodes = [nodes]
}
// Can only do this for nodes on the same tab.
// Use nodes[0] to get the z
var tabNodes = tabMap[nodes[0].z];
var toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
var moved = new Set();
for (var i = 0; i < tabNodes.length; i++) {
if (toMove.size === 0) {
break;
}
var n = tabNodes[i];
if (toMove.has(n)) {
// This is a node to move.
if (i > 0 && !moved.has(tabNodes[i-1])) {
// Remove from current position
tabNodes.splice(i,1);
// Add it back one position lower
tabNodes.splice(i-1,0,n);
n._reordered = true;
result.push(n);
}
toMove.delete(n);
moved.add(n);
}
}
if (result.length > 0) {
RED.events.emit('nodes:reorder',{
z: nodes[0].z,
nodes: result
});
}
return result;
return api.changeDepth(nodes, false, true)
},
moveNodesToFront: function(nodes) {
var result = [];
if (!Array.isArray(nodes)) {
nodes = [nodes]
}
// Can only do this for nodes on the same tab.
// Use nodes[0] to get the z
var tabNodes = tabMap[nodes[0].z];
var toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
var target = tabNodes.length-1;
for (var i = tabNodes.length-1; i >= 0; i--) {
if (toMove.size === 0) {
break;
}
var n = tabNodes[i];
if (toMove.has(n)) {
// This is a node to move.
if (i < target) {
// Remove from current position
tabNodes.splice(i,1);
tabNodes.splice(target,0,n);
n._reordered = true;
result.push(n);
}
target--;
toMove.delete(n);
}
}
if (result.length > 0) {
RED.events.emit('nodes:reorder',{
z: nodes[0].z,
nodes: result
});
}
return result;
return api.changeDepth(nodes, true, false)
},
moveNodesToBack: function(nodes) {
var result = [];
if (!Array.isArray(nodes)) {
nodes = [nodes]
}
// Can only do this for nodes on the same tab.
// Use nodes[0] to get the z
var tabNodes = tabMap[nodes[0].z];
var toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
var target = 0;
for (var i = 0; i < tabNodes.length; i++) {
if (toMove.size === 0) {
break;
}
var n = tabNodes[i];
if (toMove.has(n)) {
// This is a node to move.
if (i > target) {
// Remove from current position
tabNodes.splice(i,1);
// Add it back one position lower
tabNodes.splice(target,0,n);
n._reordered = true;
result.push(n);
}
target++;
toMove.delete(n);
}
}
if (result.length > 0) {
RED.events.emit('nodes:reorder',{
z: nodes[0].z,
nodes: result
});
}
return result;
return api.changeDepth(nodes, false, false)
},
getNodes: function(z) {
return tabMap[z];
@ -433,6 +416,33 @@ RED.nodes = (function() {
clear: function() {
nodes = {};
tabMap = {};
tabDirtyMap = {};
tabDeletedNodesMap = {};
addedDirtyObjects = new Set();
},
/**
* Clear all internal state on what is dirty.
*/
clearState: function () {
// Called when a deploy happens, we can forget about added/remove
// items as they have now been deployed.
addedDirtyObjects = new Set()
const flowsToCheck = new Set()
for (const [z, set] of Object.entries(tabDeletedNodesMap)) {
if (set.size > 0) {
set.clear()
flowsToCheck.add(z)
}
}
for (const [z, set] of Object.entries(tabDirtyMap)) {
if (set.size > 0) {
set.clear()
flowsToCheck.add(z)
}
}
for (const z of flowsToCheck) {
api.checkTabState(z)
}
},
eachNode: function(cb) {
var nodeList,i,j;
@ -498,7 +508,7 @@ RED.nodes = (function() {
return result;
},
getNodeOrder: function(z) {
return tabMap[z].map(function(n) { return n.id })
return (groupsByZ[z] || []).concat(tabMap[z]).map(n => n.id)
},
setNodeOrder: function(z, order) {
var orderMap = {};
@ -510,6 +520,41 @@ RED.nodes = (function() {
B._reordered = true;
return orderMap[A.id] - orderMap[B.id];
})
if (groupsByZ[z]) {
groupsByZ[z].sort(function(A,B) {
return orderMap[A.id] - orderMap[B.id];
})
}
},
/**
* Update our records if an object is dirty or not
* @param {String} z tab id
* @param {String} id object id
* @param {Boolean} dirty whether the object is dirty or not
*/
markNodeDirty: function(z, id, dirty) {
if (tabDirtyMap[z]) {
if (dirty) {
tabDirtyMap[z].add(id)
} else {
tabDirtyMap[z].delete(id)
}
api.checkTabState(z)
}
},
/**
* Check if a tab should update its contentsChange flag
* @param {String} z tab id
*/
checkTabState: function (z) {
const ws = workspaces[z]
if (ws) {
const contentsChanged = tabDirtyMap[z].size > 0 || tabDeletedNodesMap[z].size > 0
if (Boolean(ws.contentsChanged) !== contentsChanged) {
ws.contentsChanged = contentsChanged
RED.events.emit("flows:change", ws);
}
}
}
}
return api;
@ -575,15 +620,53 @@ RED.nodes = (function() {
}
}
const nodeProxyHandler = {
get(node, prop) {
if (prop === '__isProxy__') {
return true
} else if (prop == '__node__') {
return node
}
return node[prop]
},
set(node, prop, value) {
if (node.z && (RED.nodes.workspace(node.z)?.locked || RED.nodes.subflow(node.z)?.locked)) {
if (
node._def.defaults[prop] ||
prop === 'z' ||
prop === 'l' ||
prop === 'd' ||
(prop === 'changed' && (!!node.changed) !== (!!value)) || // jshint ignore:line
((prop === 'x' || prop === 'y') && !node.resize && node.type !== 'group')
) {
throw new Error(`Cannot modified property '${prop}' of locked object '${node.type}:${node.id}'`)
}
}
if (node.z && (prop === 'changed' || prop === 'moved')) {
setTimeout(() => {
allNodes.markNodeDirty(node.z, node.id, node.changed || node.moved)
}, 0)
}
node[prop] = value;
return true
}
}
function addNode(n) {
let newNode
if (!n.__isProxy__) {
newNode = new Proxy(n, nodeProxyHandler)
} else {
newNode = n
}
if (n.type.indexOf("subflow") !== 0) {
n["_"] = n._def._;
} else {
var subflowId = n.type.substring(8);
var sf = RED.nodes.subflow(subflowId);
if (sf) {
sf.instances.push(sf);
sf.instances.push(newNode);
}
n["_"] = RED._;
}
@ -600,12 +683,13 @@ RED.nodes = (function() {
});
n.i = nextId+1;
}
allNodes.addNode(n);
allNodes.addNode(newNode);
if (!nodeLinks[n.id]) {
nodeLinks[n.id] = {in:[],out:[]};
}
}
RED.events.emit('nodes:add',n);
RED.events.emit('nodes:add',newNode);
return newNode
}
function addLink(l) {
if (nodeLinks[l.source.id]) {
@ -632,10 +716,16 @@ RED.nodes = (function() {
}
if (l.source.z === l.target.z && linkTabMap[l.source.z]) {
linkTabMap[l.source.z].push(l);
allNodes.addObjectToWorkspace(l.source.z, getLinkId(l), true)
}
RED.events.emit("links:add",l);
}
function getLinkId(link) {
return link.source.id + ':' + link.sourcePort + ':' + link.target.id
}
function getNode(id) {
if (id in configNodes) {
return configNodes[id];
@ -830,6 +920,7 @@ RED.nodes = (function() {
if (index !== -1) {
linkTabMap[l.source.z].splice(index,1)
}
allNodes.removeObjectFromWorkspace(l.source.z, getLinkId(l))
}
}
RED.events.emit("links:remove",l);
@ -999,6 +1090,11 @@ RED.nodes = (function() {
return false;
}
function getDownstreamNodes(node) {
const downstreamLinks = nodeLinks[node.id].out
const downstreamNodes = new Set(downstreamLinks.map(l => l.target))
return Array.from(downstreamNodes)
}
function getAllDownstreamNodes(node) {
return getAllFlowNodes(node,'down').filter(function(n) { return n !== node });
}
@ -1046,6 +1142,9 @@ RED.nodes = (function() {
node.type = n.type;
for (var d in n._def.defaults) {
if (n._def.defaults.hasOwnProperty(d)) {
if (d === 'locked' && !n.locked) {
continue
}
node[d] = n[d];
}
}
@ -1651,6 +1750,7 @@ RED.nodes = (function() {
* Options:
* - generateIds - whether to replace all node ids
* - addFlow - whether to import nodes to a new tab
* - markChanged - whether to set changed=true on all newly imported objects
* - reimport - if node has a .z property, dont overwrite it
* Only applicible when `generateIds` is false
* - importMap - how to resolve any conflicts.
@ -1659,7 +1759,7 @@ RED.nodes = (function() {
* - id:replace - import over the top of existing
*/
function importNodes(newNodesObj,options) { // createNewIds,createMissingWorkspace) {
const defOpts = { generateIds: false, addFlow: false, reimport: false, importMap: {} }
const defOpts = { generateIds: false, addFlow: false, markChanged: false, reimport: false, importMap: {} }
options = Object.assign({}, defOpts, options)
options.importMap = options.importMap || {}
const createNewIds = options.generateIds;
@ -1685,7 +1785,7 @@ RED.nodes = (function() {
newNodes = newNodesObj;
}
if (!$.isArray(newNodes)) {
if (!Array.isArray(newNodes)) {
newNodes = [newNodes];
}
@ -1965,7 +2065,7 @@ RED.nodes = (function() {
}
}
} else {
const keepNodesCurrentZ = reimport && n.z && RED.workspaces.contains(n.z)
const keepNodesCurrentZ = reimport && n.z && (RED.workspaces.contains(n.z) || RED.nodes.subflow(n.z))
if (!keepNodesCurrentZ && n.z && !workspace_map[n.z] && !subflow_map[n.z]) {
n.z = activeWorkspace;
}
@ -1983,6 +2083,9 @@ RED.nodes = (function() {
if (!n.z) {
delete configNode.z;
}
if (options.markChanged) {
configNode.changed = true
}
if (n.hasOwnProperty('d')) {
configNode.d = n.d;
}
@ -2045,6 +2148,9 @@ RED.nodes = (function() {
if (n.hasOwnProperty('g')) {
node.g = n.g;
}
if (options.markChanged) {
node.changed = true
}
if (createNewIds || options.importMap[n.id] === "copy") {
if (subflow_denylist[n.z]) {
continue;
@ -2067,7 +2173,7 @@ RED.nodes = (function() {
node.id = getID();
} else {
node.id = n.id;
const keepNodesCurrentZ = reimport && node.z && RED.workspaces.contains(node.z)
const keepNodesCurrentZ = reimport && node.z && (RED.workspaces.contains(node.z) || RED.nodes.subflow(node.z))
if (!keepNodesCurrentZ && (node.z == null || (!workspace_map[node.z] && !subflow_map[node.z]))) {
if (createMissingWorkspace) {
if (missingWorkspace === null) {
@ -2265,7 +2371,7 @@ RED.nodes = (function() {
// get added
if (activeSubflow && /^link /.test(n.type) && n.links) {
n.links = n.links.filter(function(id) {
var otherNode = RED.nodes.node(id);
const otherNode = node_map[id] || RED.nodes.node(id);
return (otherNode && otherNode.z === activeWorkspace)
});
}
@ -2315,19 +2421,6 @@ RED.nodes = (function() {
if (n.g && !new_group_set.has(n.g)) {
delete n.g;
}
n.nodes = n.nodes.map(function(id) {
return node_map[id];
})
// Just in case the group references a node that doesn't exist for some reason
n.nodes = n.nodes.filter(function(v) {
if (v) {
// Repair any nodes that have forgotten they are in this group
if (v.g !== n.id) {
v.g = n.id;
}
}
return !!v
});
if (!n.g) {
groupDepthMap[n.id] = 0;
}
@ -2350,21 +2443,22 @@ RED.nodes = (function() {
return groupDepthMap[A.id] - groupDepthMap[B.id];
});
for (i=0;i<new_groups.length;i++) {
n = new_groups[i];
addGroup(n);
new_groups[i] = addGroup(new_groups[i]);
node_map[new_groups[i].id] = new_groups[i]
}
for (i=0;i<new_junctions.length;i++) {
var junction = new_junctions[i];
addJunction(junction);
new_junctions[i] = addJunction(new_junctions[i]);
node_map[new_junctions[i].id] = new_junctions[i]
}
// Now the nodes have been fully updated, add them.
for (i=0;i<new_nodes.length;i++) {
var node = new_nodes[i];
addNode(node);
new_nodes[i] = addNode(new_nodes[i])
node_map[new_nodes[i].id] = new_nodes[i]
}
// Finally validate them all.
// This has to be done after everything is added so that any checks for
// dependent config nodes will pass
@ -2372,6 +2466,39 @@ RED.nodes = (function() {
var node = new_nodes[i];
RED.editor.validateNode(node);
}
const lookupNode = (id) => {
const mappedNode = node_map[id]
if (!mappedNode) {
return null
}
if (mappedNode.__isProxy__) {
return mappedNode
} else {
return node_map[mappedNode.id]
}
}
// Update groups to reference proxy node objects
for (i=0;i<new_groups.length;i++) {
n = new_groups[i];
// bypass the proxy in case the flow is locked
n.__node__.nodes = n.nodes.map(lookupNode)
// Just in case the group references a node that doesn't exist for some reason
n.__node__.nodes = n.nodes.filter(function(v) {
if (v) {
// Repair any nodes that have forgotten they are in this group
if (v.g !== n.id) {
v.g = n.id;
}
}
return !!v
});
}
// Update links to use proxy node objects
for (i=0;i<new_links.length;i++) {
new_links[i].source = lookupNode(new_links[i].source.id) || new_links[i].source
new_links[i].target = lookupNode(new_links[i].target.id) || new_links[i].target
}
RED.workspaces.refresh();
@ -2500,11 +2627,17 @@ RED.nodes = (function() {
junctions = {};
junctionsByZ = {};
var workspaceIds = Object.keys(workspaces);
// Ensure all workspaces are unlocked so we don't get any edit-protection
// preventing removal
workspaceIds.forEach(function(id) {
workspaces[id].locked = false
});
var subflowIds = Object.keys(subflows);
subflowIds.forEach(function(id) {
RED.subflow.removeSubflow(id)
});
var workspaceIds = Object.keys(workspaces);
workspaceIds.forEach(function(id) {
RED.workspaces.remove(workspaces[id]);
});
@ -2525,10 +2658,15 @@ RED.nodes = (function() {
}
function addGroup(group) {
if (!group.__isProxy__) {
group = new Proxy(group, nodeProxyHandler)
}
groupsByZ[group.z] = groupsByZ[group.z] || [];
groupsByZ[group.z].push(group);
groups[group.id] = group;
allNodes.addObjectToWorkspace(group.z, group.id, group.changed || group.moved)
RED.events.emit("groups:add",group);
return group
}
function removeGroup(group) {
var i = groupsByZ[group.z].indexOf(group);
@ -2543,19 +2681,28 @@ RED.nodes = (function() {
}
}
RED.group.markDirty(group);
allNodes.removeObjectFromWorkspace(group.z, group.id)
delete groups[group.id];
RED.events.emit("groups:remove",group);
}
function getGroupOrder(z) {
const groups = groupsByZ[z]
return groups.map(g => g.id)
}
function addJunction(junction) {
if (!junction.__isProxy__) {
junction = new Proxy(junction, nodeProxyHandler)
}
junctionsByZ[junction.z] = junctionsByZ[junction.z] || []
junctionsByZ[junction.z].push(junction)
junctions[junction.id] = junction;
if (!nodeLinks[junction.id]) {
nodeLinks[junction.id] = {in:[],out:[]};
}
allNodes.addObjectToWorkspace(junction.z, junction.id, junction.changed || junction.moved)
RED.events.emit("junctions:add", junction)
return junction
}
function removeJunction(junction) {
var i = junctionsByZ[junction.z].indexOf(junction)
@ -2565,6 +2712,7 @@ RED.nodes = (function() {
}
delete junctions[junction.id]
delete nodeLinks[junction.id];
allNodes.removeObjectFromWorkspace(junction.z, junction.id)
RED.events.emit("junctions:remove", junction)
var removedLinks = links.filter(function(l) { return (l.source === junction) || (l.target === junction); });
@ -2740,6 +2888,7 @@ RED.nodes = (function() {
}
});
const nodeGroupMap = {}
var replaceNodeIds = Object.keys(replaceNodes);
if (replaceNodeIds.length > 0) {
var reimportList = [];
@ -2750,6 +2899,12 @@ RED.nodes = (function() {
} else {
allNodes.removeNode(n);
}
if (n.g) {
// reimporting a node *without* including its group object
// will cause the g property to be cleared. Cache it
// here so we can restore it
nodeGroupMap[n.id] = n.g
}
reimportList.push(convertNode(n));
RED.events.emit('nodes:remove',n);
});
@ -2771,6 +2926,18 @@ RED.nodes = (function() {
var newNodeMap = {};
result.nodes.forEach(function(n) {
newNodeMap[n.id] = n;
if (nodeGroupMap[n.id]) {
// This node is in a group - need to substitute the
// node reference inside the group
n.g = nodeGroupMap[n.id]
const group = RED.nodes.group(n.g)
if (group) {
var index = group.nodes.findIndex(gn => gn.id === n.id)
if (index > -1) {
group.nodes[index] = n
}
}
}
});
RED.nodes.eachLink(function(l) {
if (newNodeMap.hasOwnProperty(l.source.id)) {
@ -2783,6 +2950,9 @@ RED.nodes = (function() {
RED.view.redraw(true);
}
});
RED.events.on('deploy', function () {
allNodes.clearState()
})
},
registry:registry,
setNodeList: registry.setNodeList,
@ -2831,7 +3001,7 @@ RED.nodes = (function() {
},
addWorkspace: addWorkspace,
removeWorkspace: removeWorkspace,
getWorkspaceOrder: function() { return workspacesOrder },
getWorkspaceOrder: function() { return [...workspacesOrder] },
setWorkspaceOrder: function(order) { workspacesOrder = order; },
workspace: getWorkspace,
@ -2885,6 +3055,20 @@ RED.nodes = (function() {
}
}
},
eachGroup: function(cb) {
for (var group of Object.values(groups)) {
if (cb(group) === false) {
break
}
}
},
eachJunction: function(cb) {
for (var junction of Object.values(junctions)) {
if (cb(junction) === false) {
break
}
}
},
node: getNode,
@ -2907,6 +3091,7 @@ RED.nodes = (function() {
getAllFlowNodes: getAllFlowNodes,
getAllUpstreamNodes: getAllUpstreamNodes,
getAllDownstreamNodes: getAllDownstreamNodes,
getDownstreamNodes: getDownstreamNodes,
getNodeIslands: getNodeIslands,
createExportableNodeSet: createExportableNodeSet,
createCompleteNodeSet: createCompleteNodeSet,

View File

@ -249,8 +249,35 @@ var RED = (function() {
RED.nodes.import(nodes.flows);
RED.nodes.dirty(false);
RED.view.redraw(true);
if (/^#flow\/.+$/.test(currentHash)) {
RED.workspaces.show(currentHash.substring(6),true);
if (/^#(flow|node|group)\/.+$/.test(currentHash)) {
const hashParts = currentHash.split('/')
const showEditDialog = hashParts.length > 2 && hashParts[2] === 'edit'
if (hashParts[0] === '#flow') {
RED.workspaces.show(hashParts[1], true);
if (showEditDialog) {
RED.workspaces.edit()
}
} else if (hashParts[0] === '#node') {
const nodeToShow = RED.nodes.node(hashParts[1])
if (nodeToShow) {
setTimeout(() => {
RED.view.reveal(nodeToShow.id)
window.location.hash = currentHash
if (showEditDialog) {
RED.editor.edit(nodeToShow)
}
}, 50)
}
} else if (hashParts[0] === '#group') {
const nodeToShow = RED.nodes.group(hashParts[1])
if (nodeToShow) {
RED.view.reveal(nodeToShow.id)
window.location.hash = currentHash
if (showEditDialog) {
RED.editor.editGroup(nodeToShow)
}
}
}
}
if (RED.workspaces.count() > 0) {
const hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
@ -321,6 +348,8 @@ var RED = (function() {
loader.end()
RED.notify($("<p>").text(message));
RED.sidebar.info.refresh()
RED.menu.setDisabled('menu-item-projects-open',false);
RED.menu.setDisabled('menu-item-projects-settings',false);
});
});
return;
@ -641,11 +670,6 @@ var RED = (function() {
]});
menuOptions.push({id:"menu-item-arrange-menu", label:RED._("menu.label.arrange"), options: [
{id: "menu-item-view-tools-move-to-back", label:RED._("menu.label.moveToBack"), disabled: true, onselect: "core:move-selection-to-back"},
{id: "menu-item-view-tools-move-to-front", label:RED._("menu.label.moveToFront"), disabled: true, onselect: "core:move-selection-to-front"},
{id: "menu-item-view-tools-move-backwards", label:RED._("menu.label.moveBackwards"), disabled: true, onselect: "core:move-selection-backwards"},
{id: "menu-item-view-tools-move-forwards", label:RED._("menu.label.moveForwards"), disabled: true, onselect: "core:move-selection-forwards"},
null,
{id: "menu-item-view-tools-align-left", label:RED._("menu.label.alignLeft"), disabled: true, onselect: "core:align-selection-to-left"},
{id: "menu-item-view-tools-align-center", label:RED._("menu.label.alignCenter"), disabled: true, onselect: "core:align-selection-to-center"},
{id: "menu-item-view-tools-align-right", label:RED._("menu.label.alignRight"), disabled: true, onselect: "core:align-selection-to-right"},
@ -655,7 +679,12 @@ var RED = (function() {
{id: "menu-item-view-tools-align-bottom", label:RED._("menu.label.alignBottom"), disabled: true, onselect: "core:align-selection-to-bottom"},
null,
{id: "menu-item-view-tools-distribute-horizontally", label:RED._("menu.label.distributeHorizontally"), disabled: true, onselect: "core:distribute-selection-horizontally"},
{id: "menu-item-view-tools-distribute-veritcally", label:RED._("menu.label.distributeVertically"), disabled: true, onselect: "core:distribute-selection-vertically"}
{id: "menu-item-view-tools-distribute-veritcally", label:RED._("menu.label.distributeVertically"), disabled: true, onselect: "core:distribute-selection-vertically"},
null,
{id: "menu-item-view-tools-move-to-back", label:RED._("menu.label.moveToBack"), disabled: true, onselect: "core:move-selection-to-back"},
{id: "menu-item-view-tools-move-to-front", label:RED._("menu.label.moveToFront"), disabled: true, onselect: "core:move-selection-to-front"},
{id: "menu-item-view-tools-move-backwards", label:RED._("menu.label.moveBackwards"), disabled: true, onselect: "core:move-selection-backwards"},
{id: "menu-item-view-tools-move-forwards", label:RED._("menu.label.moveForwards"), disabled: true, onselect: "core:move-selection-forwards"}
]});
menuOptions.push(null);
@ -748,6 +777,7 @@ var RED = (function() {
RED.deploy.init(RED.settings.theme("deployButton",null));
RED.keyboard.init(buildMainMenu);
RED.envVar.init();
RED.nodes.init();
RED.runtime.init()

View File

@ -423,11 +423,10 @@ RED.clipboard = (function() {
}
}
function showImportNodes(mode) {
function showImportNodes(library = 'clipboard') {
if (disabled) {
return;
}
mode = mode || "clipboard";
dialogContainer.empty();
dialogContainer.append($(importNodesDialog));
@ -504,7 +503,7 @@ RED.clipboard = (function() {
$("#red-ui-clipboard-dialog-import-text").on("keyup", validateImport);
$("#red-ui-clipboard-dialog-import-text").on('paste',function() { setTimeout(validateImport,10)});
if (RED.workspaces.active() === 0) {
if (RED.workspaces.active() === 0 || RED.workspaces.isLocked()) {
$("#red-ui-clipboard-dialog-import-opt-current").addClass('disabled').removeClass("selected");
$("#red-ui-clipboard-dialog-import-opt-new").addClass("selected");
} else {
@ -533,8 +532,8 @@ RED.clipboard = (function() {
$("#red-ui-clipboard-dialog-import-file-upload").trigger("click");
})
tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+mode);
if (mode === 'clipboard') {
tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+library);
if (library === 'clipboard') {
setTimeout(function() {
$("#red-ui-clipboard-dialog-import-text").trigger("focus");
},100)
@ -558,13 +557,16 @@ RED.clipboard = (function() {
});
}
function showExportNodes(mode) {
/**
* Show the export dialog
* @params library which export destination to show
* @params mode whether to default to 'auto' (default) or 'flow'
**/
function showExportNodes(library = 'clipboard', mode = 'auto' ) {
if (disabled) {
return;
}
mode = mode || "clipboard";
dialogContainer.empty();
dialogContainer.append($(exportNodesDialog));
@ -654,7 +656,12 @@ RED.clipboard = (function() {
$("#red-ui-clipboard-dialog-tab-library-name").val("flows.json").select();
dialogContainer.i18n();
var format = RED.settings.flowFilePretty ? "red-ui-clipboard-dialog-export-fmt-full" : "red-ui-clipboard-dialog-export-fmt-mini";
const userFormat = RED.settings.get("editor.dialog.export.pretty")
if (userFormat === false || userFormat === true) {
format = userFormat ? "red-ui-clipboard-dialog-export-fmt-full" : "red-ui-clipboard-dialog-export-fmt-mini";
}
$("#red-ui-clipboard-dialog-export-fmt-group > a").on("click", function(evt) {
evt.preventDefault();
@ -670,7 +677,8 @@ RED.clipboard = (function() {
var nodes = JSON.parse(flow);
format = $(this).attr('id');
if (format === 'red-ui-clipboard-dialog-export-fmt-full') {
const pretty = format === "red-ui-clipboard-dialog-export-fmt-full";
if (pretty) {
flow = JSON.stringify(nodes,null,4);
} else {
flow = JSON.stringify(nodes);
@ -679,6 +687,7 @@ RED.clipboard = (function() {
setTimeout(function() { $("#red-ui-clipboard-dialog-export-text").scrollTop(0); },50);
$("#red-ui-clipboard-dialog-export-text").trigger("focus");
RED.settings.set("editor.dialog.export.pretty", pretty)
}
});
@ -766,12 +775,15 @@ RED.clipboard = (function() {
}
}
}
if (mode === 'flow' && !$("#red-ui-clipboard-dialog-export-rng-flow").hasClass('disabled')) {
$("#red-ui-clipboard-dialog-export-rng-flow").trigger("click");
}
if (format === "red-ui-clipboard-dialog-export-fmt-full") {
$("#red-ui-clipboard-dialog-export-fmt-full").trigger("click");
} else {
$("#red-ui-clipboard-dialog-export-fmt-mini").trigger("click");
}
tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode);
tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+library);
var dialogHeight = 400;
var winHeight = $(window).height();
@ -1266,15 +1278,17 @@ RED.clipboard = (function() {
RED.keyboard.add("#red-ui-drop-target", "escape" ,hideDropTarget);
$('#red-ui-workspace-chart').on("dragenter",function(event) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 ||
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
if (!RED.workspaces.isLocked() && (
$.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 ||
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1)) {
$("#red-ui-drop-target").css({display:'table'}).focus();
}
});
$('#red-ui-drop-target').on("dragover",function(event) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 ||
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1 ||
RED.workspaces.isLocked()) {
event.preventDefault();
}
})
@ -1282,27 +1296,29 @@ RED.clipboard = (function() {
hideDropTarget();
})
.on("drop",function(event) {
try {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
var data = event.originalEvent.dataTransfer.getData("text/plain");
data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1);
importNodes(data);
} else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
var files = event.originalEvent.dataTransfer.files;
if (files.length === 1) {
var file = files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
importNodes(e.target.result);
};
})(file);
reader.readAsText(file);
if (!RED.workspaces.isLocked()) {
try {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
var data = event.originalEvent.dataTransfer.getData("text/plain");
data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1);
importNodes(data);
} else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
var files = event.originalEvent.dataTransfer.files;
if (files.length === 1) {
var file = files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
importNodes(e.target.result);
};
})(file);
reader.readAsText(file);
}
}
} catch(err) {
// Ensure any errors throw above doesn't stop the drop target from
// being hidden.
}
} catch(err) {
// Ensure any errors throw above doesn't stop the drop target from
// being hidden.
}
hideDropTarget();
event.preventDefault();

View File

@ -417,6 +417,9 @@
} else {
return null;
}
},
cancel: function() {
this.element.sortable("cancel");
}
});
})(jQuery);

View File

@ -94,8 +94,8 @@ RED.menu = (function() {
var link = $(linkContent).appendTo(item);
opt.link = link;
if (typeof opt.onselect === 'string') {
var shortcut = RED.keyboard.getShortcut(opt.onselect);
if (typeof opt.onselect === 'string' || opt.shortcut) {
var shortcut = opt.shortcut || RED.keyboard.getShortcut(opt.onselect);
if (shortcut && shortcut.key) {
opt.shortcutSpan = $('<span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span>').appendTo(link.find(".red-ui-menu-label"));
}

View File

@ -141,7 +141,29 @@ RED.tabs = (function() {
})
}
if (options.contextmenu) {
wrapper.on('contextmenu', function(evt) {
let clickedTab
let target = evt.target
while(target.nodeName !== 'A' && target.nodeName !== 'UL' && target.nodeName !== 'BODY') {
target = target.parentNode
}
if (target.nodeName === 'A') {
const href = target.getAttribute('href')
if (href) {
clickedTab = tabs[href.slice(1)]
}
}
evt.preventDefault()
evt.stopPropagation()
RED.contextMenu.show({
x:evt.clientX-5,
y:evt.clientY-5,
options: options.contextmenu(clickedTab)
})
return false
})
}
var scrollLeft;
var scrollRight;
@ -161,7 +183,7 @@ RED.tabs = (function() {
// Assume this is wheel event which might not trigger
// the scroll event, so do things manually
var sl = scrollContainer.scrollLeft();
sl -= evt.originalEvent.deltaY;
sl += evt.originalEvent.deltaY;
scrollContainer.scrollLeft(sl);
}
})
@ -807,23 +829,22 @@ RED.tabs = (function() {
event.preventDefault();
removeTab(tab.id);
});
RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
}
if (tab.hideable) {
li.addClass("red-ui-tabs-closeable")
var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close red-ui-tab-hide"}).appendTo(li);
closeLink.append('<i class="fa fa-eye" />');
closeLink.append('<i class="fa fa-eye-slash" />');
closeLink.on("click",function(event) {
event.preventDefault();
hideTab(tab.id);
});
RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
RED.popover.tooltip(closeLink,RED._("workspace.closeFlow"));
}
// if (tab.hideable) {
// li.addClass("red-ui-tabs-closeable")
// var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close red-ui-tab-hide"}).appendTo(li);
// closeLink.append('<i class="fa fa-eye" />');
// closeLink.append('<i class="fa fa-eye-slash" />');
// closeLink.on("click",function(event) {
// event.preventDefault();
// hideTab(tab.id);
// });
// RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
// }
var badges = $('<span class="red-ui-tabs-badges"></span>').appendTo(li);
if (options.onselect) {
$('<i class="red-ui-tabs-badge-changed fa fa-circle"></i>').appendTo(badges);
$('<i class="red-ui-tabs-badge-selected fa fa-check-circle"></i>').appendTo(badges);
}
@ -938,6 +959,9 @@ RED.tabs = (function() {
activeIndex: function() {
return ul.find("li.active").index()
},
getTabIndex: function (id) {
return ul.find("a[href='#"+id+"']").parent().index()
},
contains: function(id) {
return ul.find("a[href='#"+id+"']").length > 0;
},

View File

@ -1,21 +1,6 @@
RED.contextMenu = (function () {
let menu;
function createMenu() {
// menu = RED.popover.menu({
// options: [
// {
// label: 'delete selection',
// onselect: function() {
// RED.actions.invoke('core:delete-selection')
// RED.view.focus()
// }
// },
// { label: 'world' }
// ],
// width: 200,
// })
}
function disposeMenu() {
$(document).off("mousedown.red-ui-workspace-context-menu");
@ -28,114 +13,172 @@ RED.contextMenu = (function () {
if (menu) {
menu.remove()
}
let menuItems = []
if (options.options) {
menuItems = options.options
} else if (options.type === 'workspace') {
const selection = RED.view.selection()
const noSelection = !selection || Object.keys(selection).length === 0
const hasSelection = (selection.nodes && selection.nodes.length > 0);
const hasMultipleSelection = hasSelection && selection.nodes.length > 1;
const virtulLinks = (selection.links && selection.links.filter(e => !!e.link)) || [];
const wireLinks = (selection.links && selection.links.filter(e => !e.link)) || [];
const hasLinks = wireLinks.length > 0;
const isSingleLink = !hasSelection && hasLinks && wireLinks.length === 1
const isMultipleLinks = !hasSelection && hasLinks && wireLinks.length > 1
const canDelete = hasSelection || hasLinks
const isGroup = hasSelection && selection.nodes.length === 1 && selection.nodes[0].type === 'group'
const canEdit = !RED.workspaces.isLocked()
const canRemoveFromGroup = hasSelection && !!selection.nodes[0].g
const isAllGroups = hasSelection && selection.nodes.filter(n => n.type !== 'group').length === 0
const hasGroup = hasSelection && selection.nodes.filter(n => n.type === 'group' ).length > 0
const offset = $("#red-ui-workspace-chart").offset()
const selection = RED.view.selection()
const noSelection = !selection || Object.keys(selection).length === 0
const hasSelection = (selection.nodes && selection.nodes.length > 0);
const hasMultipleSelection = hasSelection && selection.nodes.length > 1;
const virtulLinks = (selection.links && selection.links.filter(e => !!e.link)) || [];
const wireLinks = (selection.links && selection.links.filter(e => !e.link)) || [];
const hasLinks = wireLinks.length > 0;
const isSingleLink = !hasSelection && hasLinks && wireLinks.length === 1
const isMultipleLinks = !hasSelection && hasLinks && wireLinks.length > 1
const canDelete = hasSelection || hasLinks
const isGroup = hasSelection && selection.nodes.length === 1 && selection.nodes[0].type === 'group'
const canRemoveFromGroup = hasSelection && !!selection.nodes[0].g
const offset = $("#red-ui-workspace-chart").offset()
// addX/addY must be the position in the workspace accounting for both scroll and scale
// The +5 is because we display the contextMenu -5,-5 to actual click position
let addX = (options.x + 5 - offset.left + $("#red-ui-workspace-chart").scrollLeft()) / RED.view.scale()
let addY = (options.y + 5 - offset.top + $("#red-ui-workspace-chart").scrollTop()) / RED.view.scale()
const menuItems = [
{ onselect: 'core:show-action-list', onpostselect: function () { } },
{
label: RED._("contextMenu.insert"),
options: [
{
label: RED._("contextMenu.node"),
onselect: function () {
RED.view.showQuickAddDialog({
position: [addX, addY],
touchTrigger: true,
splice: isSingleLink ? selection.links[0] : undefined,
// spliceMultiple: isMultipleLinks
})
},
onpostselect: function() {
// ensure quick add dialog search input has focus
$('#red-ui-type-search-input').trigger('focus')
}
},
(hasLinks) ? { // has least 1 wire selected
label: RED._("contextMenu.junction"),
onselect: 'core:split-wires-with-junctions',
disabled: !hasLinks
} : {
label: RED._("contextMenu.junction"),
onselect: function () {
const nn = {
_def: { defaults: {} },
type: 'junction',
z: RED.workspaces.active(),
id: RED.nodes.id(),
x: addX,
y: addY,
w: 0, h: 0,
outputs: 1,
inputs: 1,
dirty: true
}
const historyEvent = {
dirty: RED.nodes.dirty(),
t: 'add',
junctions: [nn]
}
RED.nodes.addJunction(nn);
RED.history.push(historyEvent);
RED.nodes.dirty(true);
RED.view.select({nodes: [nn] });
RED.view.redraw(true)
}
},
{
label: RED._("contextMenu.linkNodes"),
onselect: 'core:split-wire-with-link-nodes',
disabled: !hasLinks
}
]
let addX = options.x - offset.left + $("#red-ui-workspace-chart").scrollLeft()
let addY = options.y - offset.top + $("#red-ui-workspace-chart").scrollTop()
if (RED.view.snapGrid) {
const gridSize = RED.view.gridSize()
addX = gridSize * Math.floor(addX / gridSize)
addY = gridSize * Math.floor(addY / gridSize)
}
menuItems.push(
{ onselect: 'core:show-action-list', onpostselect: function () { } }
)
const insertOptions = []
menuItems.push({ label: RED._("contextMenu.insert"), options: insertOptions })
insertOptions.push(
{
label: RED._("contextMenu.node"),
onselect: function () {
RED.view.showQuickAddDialog({
position: [addX, addY],
touchTrigger: true,
splice: isSingleLink ? selection.links[0] : undefined,
// spliceMultiple: isMultipleLinks
})
},
disabled: !canEdit
},
(hasLinks) ? { // has least 1 wire selected
label: RED._("contextMenu.junction"),
onselect: 'core:split-wires-with-junctions',
disabled: !canEdit || !hasLinks
} : {
label: RED._("contextMenu.junction"),
onselect: function () {
const nn = {
_def: { defaults: {} },
type: 'junction',
z: RED.workspaces.active(),
id: RED.nodes.id(),
x: addX,
y: addY,
w: 0, h: 0,
outputs: 1,
inputs: 1,
dirty: true,
moved: true
}
const junction = RED.nodes.addJunction(nn);
const historyEvent = {
dirty: RED.nodes.dirty(),
t: 'add',
junctions: [junction]
}
RED.history.push(historyEvent);
RED.nodes.dirty(true);
RED.view.select({nodes: [junction] });
RED.view.redraw(true)
},
disabled: !canEdit
},
{
label: RED._("contextMenu.linkNodes"),
onselect: 'core:split-wire-with-link-nodes',
disabled: !canEdit || !hasLinks
},
null,
{ onselect: 'core:show-import-dialog', label: RED._('common.label.import')},
{ onselect: 'core:show-examples-import-dialog', label: RED._('menu.label.importExample') }
)
if (hasSelection && canEdit) {
const nodeOptions = []
if (!hasMultipleSelection && !isGroup) {
nodeOptions.push(
{ onselect: 'core:show-node-help' },
null
)
}
nodeOptions.push(
{ onselect: 'core:enable-selected-nodes' },
{ onselect: 'core:disable-selected-nodes' },
null,
{ onselect: 'core:show-selected-node-labels' },
{ onselect: 'core:hide-selected-node-labels' }
)
menuItems.push({
label: RED._('sidebar.info.node'),
options: nodeOptions
})
menuItems.push({
label: RED._('sidebar.info.group'),
options: [
{ onselect: 'core:group-selection' },
{ onselect: 'core:ungroup-selection', disabled: !hasGroup },
]
})
if (hasGroup) {
menuItems[menuItems.length - 1].options.push(
{ onselect: 'core:merge-selection-to-group', label: RED._("menu.label.groupMergeSelection") }
)
}
if (canRemoveFromGroup) {
menuItems[menuItems.length - 1].options.push(
{ onselect: 'core:remove-selection-from-group', label: RED._("menu.label.groupRemoveSelection") }
)
}
menuItems[menuItems.length - 1].options.push(
null,
{ onselect: 'core:copy-group-style', disabled: !hasGroup },
{ onselect: 'core:paste-group-style', disabled: !hasGroup}
)
}
if (canEdit && hasMultipleSelection) {
menuItems.push({
label: RED._('menu.label.arrange'),
options: [
{ label:RED._("menu.label.alignLeft"), onselect: "core:align-selection-to-left"},
{ label:RED._("menu.label.alignCenter"), onselect: "core:align-selection-to-center"},
{ label:RED._("menu.label.alignRight"), onselect: "core:align-selection-to-right"},
null,
{ label:RED._("menu.label.alignTop"), onselect: "core:align-selection-to-top"},
{ label:RED._("menu.label.alignMiddle"), onselect: "core:align-selection-to-middle"},
{ label:RED._("menu.label.alignBottom"), onselect: "core:align-selection-to-bottom"},
null,
{ label:RED._("menu.label.distributeHorizontally"), onselect: "core:distribute-selection-horizontally"},
{ label:RED._("menu.label.distributeVertically"), onselect: "core:distribute-selection-vertically"}
]
})
}
]
menuItems.push(
null,
{ onselect: 'core:undo', disabled: RED.history.list().length === 0 },
{ onselect: 'core:redo', disabled: RED.history.listRedo().length === 0 },
null,
{ onselect: 'core:cut-selection-to-internal-clipboard', label: RED._("keyboard.cutNode"), disabled: !hasSelection },
{ onselect: 'core:copy-selection-to-internal-clipboard', label: RED._("keyboard.copyNode"), disabled: !hasSelection },
{ onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !RED.view.clipboard() },
{ onselect: 'core:delete-selection', disabled: !canDelete },
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
{ onselect: 'core:select-all-nodes' }
)
if (hasSelection) {
menuItems.push(
null,
isGroup ?
{ onselect: 'core:ungroup-selection', disabled: !isGroup }
: { onselect: 'core:group-selection', disabled: !hasSelection }
{ onselect: 'core:undo', disabled: RED.history.list().length === 0 },
{ onselect: 'core:redo', disabled: RED.history.listRedo().length === 0 },
null,
{ onselect: 'core:cut-selection-to-internal-clipboard', label: RED._("keyboard.cutNode"), disabled: !canEdit || !hasSelection },
{ onselect: 'core:copy-selection-to-internal-clipboard', label: RED._("keyboard.copyNode"), disabled: !hasSelection },
{ onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !canEdit || !RED.view.clipboard() },
{ onselect: 'core:delete-selection', disabled: !canEdit || !canDelete },
{ onselect: 'core:delete-selection-and-reconnect', label: RED._('keyboard.deleteReconnect'), disabled: !canEdit || !canDelete },
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
{ onselect: 'core:select-all-nodes' },
)
if (canRemoveFromGroup) {
menuItems.push({ onselect: 'core:remove-selection-from-group', label: RED._("menu.label.groupRemoveSelection") })
}
}
var direction = "right";

View File

@ -557,7 +557,17 @@ RED.deploy = (function() {
} else {
RED.notify('<p>' + RED._("deploy.successfulDeploy") + '</p>', "success");
}
const flowsToLock = new Set()
function ensureUnlocked(id) {
const flow = id && (RED.nodes.workspace(id) || RED.nodes.subflow(id) || null);
const isLocked = flow ? flow.locked : false;
if (flow && isLocked) {
flow.locked = false;
flowsToLock.add(flow)
}
}
RED.nodes.eachNode(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
@ -570,7 +580,32 @@ RED.deploy = (function() {
delete node.credentials;
}
});
RED.nodes.eachGroup(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if (node.moved) {
node.dirty = true;
node.moved = false;
}
})
RED.nodes.eachJunction(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if (node.moved) {
node.dirty = true;
node.moved = false;
}
})
RED.nodes.eachConfig(function (confNode) {
if (confNode.z) {
ensureUnlocked(confNode.z)
}
confNode.changed = false;
if (confNode.credentials) {
delete confNode.credentials;
@ -580,8 +615,16 @@ RED.deploy = (function() {
subflow.changed = false;
});
RED.nodes.eachWorkspace(function (ws) {
ws.changed = false;
if (ws.changed || ws.added) {
ensureUnlocked(ws.z)
ws.changed = false;
delete ws.added
RED.events.emit("flows:change", ws)
}
});
flowsToLock.forEach(flow => {
flow.locked = true
})
// Once deployed, cannot undo back to a clean state
RED.history.markAllDirty();
RED.view.redraw();

View File

@ -238,6 +238,7 @@ RED.editor = (function() {
var valid = validateNodeProperty(node, defaults, property,value);
if (((typeof valid) === "string") || !valid) {
input.addClass("input-error");
input.next(".red-ui-typedInput-container").addClass("input-error");
if ((typeof valid) === "string") {
var tooltip = input.data("tooltip");
if (tooltip) {
@ -250,6 +251,7 @@ RED.editor = (function() {
}
} else {
input.removeClass("input-error");
input.next(".red-ui-typedInput-container").removeClass("input-error");
var tooltip = input.data("tooltip");
if (tooltip) {
input.data("tooltip", null);
@ -858,6 +860,7 @@ RED.editor = (function() {
function showEditDialog(node, defaultTab) {
if (buildingEditDialog) { return }
buildingEditDialog = true;
if (node.z && RED.workspaces.isLocked(node.z)) { return }
var editing_node = node;
var removeInfoEditorOnClose = false;
var skipInfoRefreshOnClose = false;
@ -1043,6 +1046,13 @@ RED.editor = (function() {
var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter)
var helpButton = $('<button type="button" class="red-ui-button"><i class="fa fa-book"></button>').on("click", function(evt) {
evt.preventDefault();
evt.stopPropagation();
RED.sidebar.help.show(editing_node.type);
}).appendTo(trayFooterLeft);
RED.popover.tooltip(helpButton, RED._("sidebar.help.showHelp"));
$('<input id="node-input-node-disabled" type="checkbox">').prop("checked",!!node.d).appendTo(trayFooterLeft).toggleButton({
enabledIcon: "fa-circle-thin",
disabledIcon: "fa-ban",
@ -1146,6 +1156,8 @@ RED.editor = (function() {
var editing_config_node = RED.nodes.node(id);
var activeEditPanes = [];
if (editing_config_node && editing_config_node.z && RED.workspaces.isLocked(editing_config_node.z)) { return }
var configNodeScope = ""; // default to global
var activeSubflow = RED.nodes.subflow(RED.workspaces.active());
if (activeSubflow) {
@ -1188,6 +1200,13 @@ RED.editor = (function() {
var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter)
var helpButton = $('<button type="button" class="red-ui-button"><i class="fa fa-book"></button>').on("click", function(evt) {
evt.preventDefault();
evt.stopPropagation();
RED.sidebar.help.show(editing_config_node.type);
}).appendTo(trayFooterLeft);
RED.popover.tooltip(helpButton, RED._("sidebar.help.showHelp"));
$('<input id="node-config-input-node-disabled" type="checkbox">').prop("checked",!!editing_config_node.d).appendTo(trayFooterLeft).toggleButton({
enabledIcon: "fa-circle-thin",
disabledIcon: "fa-ban",
@ -1692,6 +1711,7 @@ RED.editor = (function() {
function showEditGroupDialog(group, defaultTab) {
if (buildingEditDialog) { return }
buildingEditDialog = true;
if (group.z && RED.workspaces.isLocked(group.z)) { return }
var editing_node = group;
editStack.push(group);
RED.view.state(RED.state.EDITING);
@ -1851,11 +1871,15 @@ RED.editor = (function() {
workspace.disabled = disabled;
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
if (workspace.id === RED.workspaces.active()) {
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
}
}
var locked = $("#node-input-locked").prop("checked");
if (workspace.locked !== locked) {
editState.changes.locked = workspace.locked;
editState.changed = true;
workspace.locked = locked;
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-locked',!!workspace.locked);
}
if (editState.changed) {
var historyEvent = {
t: "edit",
@ -1896,6 +1920,7 @@ RED.editor = (function() {
var trayBody = tray.find('.red-ui-tray-body');
trayBody.parent().css('overflow','hidden');
var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter)
var trayFooterRight = $('<div class="red-ui-tray-footer-right"></div>').appendTo(trayFooter)
var nodeEditPanes = [
'editor-tab-flow-properties',
@ -1910,6 +1935,18 @@ RED.editor = (function() {
disabledIcon: "fa-ban",
invertState: true
})
if (!workspace.hasOwnProperty("locked")) {
workspace.locked = false;
}
$('<input id="node-input-locked" type="checkbox">').prop("checked",workspace.locked).appendTo(trayFooterRight).toggleButton({
enabledLabel: RED._("common.label.unlocked"),
enabledIcon: "fa-unlock-alt",
disabledLabel: RED._("common.label.locked"),
disabledIcon: "fa-lock",
invertState: true
})
prepareEditDialog(trayBody, nodeEditPanes, workspace, {}, "node-input", defaultTab, function(_activeEditPanes) {
activeEditPanes = _activeEditPanes;
trayBody.i18n();

View File

@ -45,6 +45,9 @@
selectedCodeEditor = RED.editor.codeEditor[defaultEditor];
initialised = selectedCodeEditor.init();
}
$('<div id="red-ui-image-drop-target"><div data-i18n="[append]workspace.dropImageHere"><i class="fa fa-download"></i><br></div></div>').appendTo('#red-ui-editor');
$("#red-ui-image-drop-target").hide();
}
function create(options) {
@ -64,6 +67,7 @@
options = {};
}
var editor = null;
if (this.editor.type === MONACO) {
// compatibility (see above note)
if (!options.element && !options.id) {
@ -74,10 +78,14 @@
console.warn("createEditor() options.element or options.id is not valid", options);
$("#dialog-form").append('<div id="' + options.id + '" style="display: none;" />');
}
return this.editor.create(options);
editor = this.editor.create(options);
} else {
return this.editor.create(options);//fallback to ACE
editor = this.editor.create(options);//fallback to ACE
}
if (options.mode === "ace/mode/markdown") {
RED.editor.customEditTypes['_markdown'].postInit(editor, options);
}
return editor;
}
return {

View File

@ -59,18 +59,21 @@ RED.editor.codeEditor.monaco = (function() {
//TODO: get from externalModules.js For now this is enough for feature parity with ACE (and then some).
const knownModules = {
"assert": {package: "node", module: "assert", path: "node/assert.d.ts" },
"assert/strict": {package: "node", module: "assert/strict", path: "node/assert/strict.d.ts" },
"async_hooks": {package: "node", module: "async_hooks", path: "node/async_hooks.d.ts" },
"buffer": {package: "node", module: "buffer", path: "node/buffer.d.ts" },
"child_process": {package: "node", module: "child_process", path: "node/child_process.d.ts" },
"cluster": {package: "node", module: "cluster", path: "node/cluster.d.ts" },
"console": {package: "node", module: "console", path: "node/console.d.ts" },
"constants": {package: "node", module: "constants", path: "node/constants.d.ts" },
"crypto": {package: "node", module: "crypto", path: "node/crypto.d.ts" },
"dgram": {package: "node", module: "dgram", path: "node/dgram.d.ts" },
"diagnostics_channel.d": {package: "node", module: "diagnostics_channel", path: "node/diagnostics_channel.d.ts" },
"dns": {package: "node", module: "dns", path: "node/dns.d.ts" },
"dns/promises": {package: "node", module: "dns/promises", path: "node/dns/promises.d.ts" },
"domain": {package: "node", module: "domain", path: "node/domain.d.ts" },
"events": {package: "node", module: "events", path: "node/events.d.ts" },
"fs": {package: "node", module: "fs", path: "node/fs.d.ts" },
"fs/promises": {package: "node", module: "fs/promises", path: "node/fs/promises.d.ts" },
"globals": {package: "node", module: "globals", path: "node/globals.d.ts" },
"http": {package: "node", module: "http", path: "node/http.d.ts" },
"http2": {package: "node", module: "http2", path: "node/http2.d.ts" },
@ -84,8 +87,13 @@ RED.editor.codeEditor.monaco = (function() {
"querystring": {package: "node", module: "querystring", path: "node/querystring.d.ts" },
"readline": {package: "node", module: "readline", path: "node/readline.d.ts" },
"stream": {package: "node", module: "stream", path: "node/stream.d.ts" },
"stream/consumers": {package: "node", module: "stream/consumers", path: "node/stream/consumers.d.ts" },
"stream/promises": {package: "node", module: "stream/promises", path: "node/stream/promises.d.ts" },
"stream/web": {package: "node", module: "stream/web", path: "node/stream/web.d.ts" },
"string_decoder": {package: "node", module: "string_decoder", path: "node/string_decoder.d.ts" },
"test": {package: "node", module: "test", path: "node/test.d.ts" },
"timers": {package: "node", module: "timers", path: "node/timers.d.ts" },
"timers/promises": {package: "node", module: "timers/promises", path: "node/timers/promises.d.ts" },
"tls": {package: "node", module: "tls", path: "node/tls.d.ts" },
"trace_events": {package: "node", module: "trace_events", path: "node/trace_events.d.ts" },
"tty": {package: "node", module: "tty", path: "node/tty.d.ts" },

View File

@ -2,7 +2,7 @@ RED.editor.envVarList = (function() {
var currentLocale = 'en-US';
var DEFAULT_ENV_TYPE_LIST = ['str','num','bool','json','bin','env'];
var DEFAULT_ENV_TYPE_LIST_INC_CRED = ['str','num','bool','json','bin','env','cred'];
var DEFAULT_ENV_TYPE_LIST_INC_CRED = ['str','num','bool','json','bin','env','cred','jsonata'];
/**
* Create env var edit interface

View File

@ -294,32 +294,37 @@
}
try {
var result = expr.evaluate(legacyMode?{msg:parsedData}:parsedData);
if (usesContext) {
testResultEditor.setValue(RED._("expressionEditor.errors.context-unsupported"),-1);
return;
}
if (usesEnv) {
testResultEditor.setValue(RED._("expressionEditor.errors.env-unsupported"),-1);
return;
}
if (usesMoment) {
testResultEditor.setValue(RED._("expressionEditor.errors.moment-unsupported"),-1);
return;
}
if (usesClone) {
testResultEditor.setValue(RED._("expressionEditor.errors.clone-unsupported"),-1);
return;
}
var formattedResult;
if (result !== undefined) {
formattedResult = JSON.stringify(result,null,4);
} else {
formattedResult = RED._("expressionEditor.noMatch");
}
testResultEditor.setValue(formattedResult,-1);
} catch(err) {
expr.evaluate(legacyMode?{msg:parsedData}:parsedData, (err, result) => {
if (err) {
testResultEditor.setValue(RED._("expressionEditor.errors.eval",{message:err.message}),-1);
} else {
if (usesContext) {
testResultEditor.setValue(RED._("expressionEditor.errors.context-unsupported"),-1);
return;
}
if (usesEnv) {
testResultEditor.setValue(RED._("expressionEditor.errors.env-unsupported"),-1);
return;
}
if (usesMoment) {
testResultEditor.setValue(RED._("expressionEditor.errors.moment-unsupported"),-1);
return;
}
if (usesClone) {
testResultEditor.setValue(RED._("expressionEditor.errors.clone-unsupported"),-1);
return;
}
var formattedResult;
if (result !== undefined) {
formattedResult = JSON.stringify(result,null,4);
} else {
formattedResult = RED._("expressionEditor.noMatch");
}
testResultEditor.setValue(formattedResult,-1);
}
});
} catch(err) {
testResultEditor.setValue(RED._("expressionEditor.errors.eval",{message:err.message}),-1);
}
}

View File

@ -14,6 +14,61 @@
* limitations under the License.
**/
(function() {
/**
* Converts dropped image file to date URL
*/
function file2base64Image(file, cb) {
var reader = new FileReader();
reader.onload = (function (fd) {
return function (e) {
cb(e.target.result);
};
})(file);
reader.readAsDataURL(file);
}
var initialized = false;
var currentEditor = null;
/**
* Initialize handler for image file drag events
*/
function initImageDrag(elem, editor) {
$(elem).on("dragenter", function (ev) {
ev.preventDefault();
$("#red-ui-image-drop-target").css({display:'table'}).focus();
currentEditor = editor;
});
if (!initialized) {
initialized = true;
$("#red-ui-image-drop-target").on("dragover", function (ev) {
ev.preventDefault();
}).on("dragleave", function (ev) {
$("#red-ui-image-drop-target").hide();
}).on("drop", function (ev) {
ev.preventDefault();
if ($.inArray("Files",ev.originalEvent.dataTransfer.types) != -1) {
var files = ev.originalEvent.dataTransfer.files;
if (files.length === 1) {
var file = files[0];
var name = file.name.toLowerCase();
if (name.match(/\.(apng|avif|gif|jpeg|png|svg|webp)$/)) {
file2base64Image(file, function (image) {
var session = currentEditor.getSession();
var img = `<img src="${image}"/>\n`;
var pos = session.getCursorPosition();
session.insert(pos, img);
$("#red-ui-image-drop-target").hide();
});
return;
}
}
}
$("#red-ui-image-drop-target").hide();
});
}
}
var toolbarTemplate = '<div style="margin-bottom: 5px">'+
'<span class="button-group">'+
@ -114,6 +169,7 @@
var currentScrollTop = $(".red-ui-editor-type-markdown-panel-preview").scrollTop();
$(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
$(".red-ui-editor-type-markdown-panel-preview").scrollTop(currentScrollTop);
mermaid.init();
},200);
})
if (options.header) {
@ -122,6 +178,7 @@
if (value) {
$(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
mermaid.init();
}
panels = RED.panels.create({
id:"red-ui-editor-type-markdown-panels",
@ -148,10 +205,14 @@
});
RED.popover.tooltip($("#node-btn-markdown-preview"), RED._("markdownEditor.toggle-preview"));
if (options.cursor && !expressionEditor._initState) {
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
}
if(!expressionEditor._initState) {
if (options.cursor) {
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
}
else {
expressionEditor.gotoLine(0, 0, false);
}
}
dialogForm.i18n();
},
close: function() {
@ -215,7 +276,11 @@
}
})
return toolbar;
}
},
postInit: function (editor, options) {
var elem = $("#"+options.id);
initImageDrag(elem, editor);
}
}
RED.editor.registerTypeEditor("_markdown", definition);
})();

View File

@ -52,8 +52,6 @@
node.info = info;
}
$("#red-ui-tab-"+(node.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!node.disabled);
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!node.disabled);
}
}
});

View File

@ -0,0 +1,179 @@
RED.envVar = (function() {
function saveEnvList(list) {
const items = list.editableList("items")
const new_env = [];
items.each(function (i,el) {
var data = el.data('data');
var item;
if (data.nameField && data.valueField) {
item = {
name: data.nameField.val(),
value: data.valueField.typedInput("value"),
type: data.valueField.typedInput("type")
};
new_env.push(item);
}
});
return new_env;
}
function getGlobalConf(create) {
var gconf = null;
RED.nodes.eachConfig(function (conf) {
if (conf.type === "global-config") {
gconf = conf;
}
});
if ((gconf === null) && create) {
var cred = {
_ : {},
map: {}
};
gconf = {
id: RED.nodes.id(),
type: "global-config",
env: [],
name: "global-config",
label: "",
hasUsers: false,
users: [],
credentials: cred,
_def: RED.nodes.getType("global-config"),
};
RED.nodes.add(gconf);
}
return gconf;
}
function applyChanges(list) {
var gconf = getGlobalConf(false);
var new_env = [];
var items = list.editableList('items');
var credentials = gconf ? gconf.credentials : null;
if (!credentials) {
credentials = {
_ : {},
map: {}
};
}
items.each(function (i,el) {
var data = el.data('data');
if (data.nameField && data.valueField) {
var item = {
name: data.nameField.val(),
value: data.valueField.typedInput("value"),
type: data.valueField.typedInput("type")
};
if (item.name.trim() !== "") {
new_env.push(item);
if ((item.type === "cred") && (item.value !== "__PWRD__")) {
credentials.map[item.name] = item.value;
credentials.map["has_"+item.name] = (item.value !== "");
item.value = "__PWRD__";
}
}
}
});
if (gconf === null) {
gconf = getGlobalConf(true);
}
if ((JSON.stringify(new_env) !== JSON.stringify(gconf.env)) ||
(JSON.stringify(credentials) !== JSON.stringify(gconf.credentials))) {
gconf.env = new_env;
gconf.credentials = credentials;
RED.nodes.dirty(true);
}
}
function getSettingsPane() {
var gconf = getGlobalConf(false);
var env = gconf ? gconf.env : [];
var cred = gconf ? gconf.credentials : null;
if (!cred) {
cred = {
_ : {},
map: {}
};
}
var pane = $("<div/>", {
id: "red-ui-settings-tab-envvar",
class: "form-horizontal"
});
var content = $("<div/>", {
class: "form-row node-input-env-container-row"
}).css({
"margin": "10px"
}).appendTo(pane);
var label = $("<label></label>").css({
width: "100%"
}).appendTo(content);
$("<i/>", {
class: "fa fa-list"
}).appendTo(label);
$("<span/>").text(" "+RED._("env-var.header")).appendTo(label);
var list = $("<ol/>", {
id: "node-input-env-container"
}).appendTo(content);
var node = {
type: "",
env: env,
credentials: cred.map,
};
RED.editor.envVarList.create(list, node);
var buttons = $("<div/>").css({
"text-align": "right",
}).appendTo(content);
var revertButton = $("<button/>", {
class: "red-ui-button"
}).css({
}).text(RED._("env-var.revert")).appendTo(buttons);
var items = saveEnvList(list);
revertButton.on("click", function (ev) {
list.editableList("empty");
list.editableList("addItems", items);
});
return pane;
}
function init(done) {
if (!RED.user.hasPermission("settings.write")) {
RED.notify(RED._("user.errors.settings"),"error");
return;
}
RED.userSettings.add({
id:'envvar',
title: RED._("env-var.environment"),
get: getSettingsPane,
focus: function() {
var height = $("#red-ui-settings-tab-envvar").parent().height();
$("#node-input-env-container").editableList("height", (height -100));
},
close: function() {
var list = $("#node-input-env-container");
try {
applyChanges(list);
}
catch (e) {
console.log(e);
console.log(e.stack);
}
}
});
RED.actions.add("core:show-global-env", function() {
RED.userSettings.show('envvar');
});
}
return {
init: init,
};
})();

View File

@ -188,6 +188,8 @@ RED.group = (function() {
var activateMerge = false;
var activateRemove = false;
var singleGroupSelected = false;
var locked = RED.workspaces.isLocked()
if (activateGroup) {
singleGroupSelected = selection.nodes.length === 1 && selection.nodes[0].type === 'group';
selection.nodes.forEach(function (n) {
@ -202,12 +204,12 @@ RED.group = (function() {
activateMerge = (selection.nodes.length > 1);
}
}
RED.menu.setDisabled("menu-item-group-group", !activateGroup);
RED.menu.setDisabled("menu-item-group-ungroup", !activateUngroup);
RED.menu.setDisabled("menu-item-group-merge", !activateMerge);
RED.menu.setDisabled("menu-item-group-remove", !activateRemove);
RED.menu.setDisabled("menu-item-group-group", locked || !activateGroup);
RED.menu.setDisabled("menu-item-group-ungroup", locked || !activateUngroup);
RED.menu.setDisabled("menu-item-group-merge", locked || !activateMerge);
RED.menu.setDisabled("menu-item-group-remove", locked || !activateRemove);
RED.menu.setDisabled("menu-item-edit-copy-group-style", !singleGroupSelected);
RED.menu.setDisabled("menu-item-edit-paste-group-style", !activateUngroup);
RED.menu.setDisabled("menu-item-edit-paste-group-style", locked || !activateUngroup);
});
RED.actions.add("core:group-selection", function() { groupSelection() })
@ -264,6 +266,7 @@ RED.group = (function() {
}
}
function pasteGroupStyle() {
if (RED.workspaces.isLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
if (groupStyleClipboard) {
var selection = RED.view.selection();
@ -298,6 +301,7 @@ RED.group = (function() {
}
function groupSelection() {
if (RED.workspaces.isLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
var selection = RED.view.selection();
if (selection.nodes) {
@ -316,11 +320,12 @@ RED.group = (function() {
}
}
function ungroupSelection() {
if (RED.workspaces.isLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
var selection = RED.view.selection();
if (selection.nodes) {
var newSelection = [];
groups = selection.nodes.filter(function(n) { return n.type === "group" });
let groups = selection.nodes.filter(function(n) { return n.type === "group" });
var historyEvent = {
t:"ungroup",
@ -339,6 +344,7 @@ RED.group = (function() {
}
function ungroup(g) {
if (RED.workspaces.isLocked()) { return }
var nodes = [];
var parentGroup = RED.nodes.group(g.g);
g.nodes.forEach(function(n) {
@ -365,6 +371,7 @@ RED.group = (function() {
}
function mergeSelection() {
if (RED.workspaces.isLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
var selection = RED.view.selection();
if (selection.nodes) {
@ -434,6 +441,7 @@ RED.group = (function() {
}
function removeSelection() {
if (RED.workspaces.isLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
var selection = RED.view.selection();
if (selection.nodes) {
@ -461,12 +469,21 @@ RED.group = (function() {
}
}
function createGroup(nodes) {
if (RED.workspaces.isLocked()) { return }
if (nodes.length === 0) {
return;
}
if (nodes.filter(function(n) { return n.type === "subflow" }).length > 0) {
RED.notify(RED._("group.errors.cannotAddSubflowPorts"),"error");
return;
const existingGroup = nodes[0].g
for (let i = 0; i < nodes.length; i++) {
const n = nodes[i]
if (n.type === 'subflow') {
RED.notify(RED._("group.errors.cannotAddSubflowPorts"),"error");
return;
}
if (n.g !== existingGroup) {
console.warn("Cannot add nooes with different z properties")
return
}
}
// nodes is an array
// each node must be on the same tab (z)
@ -479,11 +496,16 @@ RED.group = (function() {
y: Number.POSITIVE_INFINITY,
w: 0,
h: 0,
_def: RED.group.def
_def: RED.group.def,
changed: true
}
group.z = nodes[0].z;
RED.nodes.addGroup(group);
group = RED.nodes.addGroup(group);
if (existingGroup) {
addToGroup(RED.nodes.group(existingGroup), group)
}
try {
addToGroup(group,nodes);
@ -508,7 +530,7 @@ RED.group = (function() {
if (!z) {
z = n.z;
} else if (z !== n.z) {
throw new Error("Cannot add nooes with different z properties")
throw new Error("Cannot add nodes with different z properties")
}
if (n.g) {
// This is already in a group.
@ -525,14 +547,10 @@ RED.group = (function() {
throw new Error(RED._("group.errors.cannotCreateDiffGroups"))
}
}
// The nodes are already in a group. The assumption is they should be
// wrapped in the newly provided group, and that group added to in their
// place to the existing containing group.
// The nodes are already in a group - so we need to remove them first
if (g) {
g = RED.nodes.group(g);
g.nodes.push(group);
g.dirty = true;
group.g = g.id;
}
// Second pass - add them to the group
for (i=0;i<nodes.length;i++) {
@ -566,6 +584,7 @@ RED.group = (function() {
markDirty(group);
}
function removeFromGroup(group, nodes, reparent) {
if (RED.workspaces.isLocked()) { return }
if (!Array.isArray(nodes)) {
nodes = [nodes];
}
@ -583,7 +602,7 @@ RED.group = (function() {
n.dirty = true;
var index = group.nodes.indexOf(n);
group.nodes.splice(index,1);
if (reparent && group.g) {
if (reparent && parentGroup) {
n.g = group.g
parentGroup.nodes.push(n);
} else {

0
packages/node_modules/@node-red/editor-client/src/js/ui/library.js vendored Executable file → Normal file
View File

View File

@ -0,0 +1,46 @@
// Mermaid diagram stub library for on-demand dynamic loading
// Will be overwritten after script loading by $.getScript
var mermaid = (function () {
var enabled /* = undefined */;
var initializing = false;
var initCalled = false;
function initialize(opt) {
if (enabled === undefined) {
if (RED.settings.markdownEditor &&
RED.settings.markdownEditor.mermaid) {
enabled = RED.settings.markdownEditor.mermaid.enabled;
}
else {
enabled = true;
}
}
if (enabled) {
initializing = true;
$.getScript("vendor/mermaid/mermaid.min.js",
function (data, stat, jqxhr) {
$(".mermaid").show();
// invoke loaded mermaid API
initializing = false;
mermaid.initialize(opt);
if (initCalled) {
mermaid.init();
initCalled = false;
}
});
}
}
function init() {
if (initializing) {
$(".mermaid").hide();
initCalled = true;
}
}
return {
initialize: initialize,
init: init,
};
})();

166
packages/node_modules/@node-red/editor-client/src/js/ui/palette.js vendored Executable file → Normal file
View File

@ -292,6 +292,7 @@ RED.palette = (function() {
var hoverGroup;
var paletteWidth;
var paletteTop;
var dropEnabled;
$(d).draggable({
helper: 'clone',
appendTo: '#red-ui-editor',
@ -299,6 +300,7 @@ RED.palette = (function() {
revertDuration: 200,
containment:'#red-ui-main-container',
start: function() {
dropEnabled = !(RED.nodes.workspace(RED.workspaces.active())?.locked);
paletteWidth = $("#red-ui-palette").width();
paletteTop = $("#red-ui-palette").parent().position().top + $("#red-ui-palette-container").position().top;
hoverGroup = null;
@ -309,96 +311,100 @@ RED.palette = (function() {
RED.view.focus();
},
stop: function() {
d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
if (hoverGroup) {
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
if (dropEnabled) {
d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
if (hoverGroup) {
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
}
if (activeGroup) {
document.getElementById("group_select_"+activeGroup.id).classList.remove("red-ui-flow-group-active-hovered");
}
if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null; }
if (groupTimer) { clearTimeout(groupTimer); groupTimer = null; }
}
if (activeGroup) {
document.getElementById("group_select_"+activeGroup.id).classList.remove("red-ui-flow-group-active-hovered");
}
if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null; }
if (groupTimer) { clearTimeout(groupTimer); groupTimer = null; }
},
drag: function(e,ui) {
var paletteNode = getPaletteNode(nt);
ui.originalPosition.left = paletteNode.offset().left;
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop() + 10;
if (!groupTimer) {
groupTimer = setTimeout(function() {
var mx = mouseX / RED.view.scale();
var my = mouseY / RED.view.scale();
var group = RED.view.getGroupAtPoint(mx,my);
if (group !== hoverGroup) {
if (hoverGroup) {
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
}
if (group) {
document.getElementById("group_select_"+group.id).classList.add("red-ui-flow-group-hovered");
}
hoverGroup = group;
if (hoverGroup) {
$(ui.helper).data('group',hoverGroup);
} else {
$(ui.helper).removeData('group');
}
}
groupTimer = null;
},200)
}
if (def.inputs > 0 && def.outputs > 0) {
if (!spliceTimer) {
spliceTimer = setTimeout(function() {
var nodes = [];
var bestDistance = Infinity;
var bestLink = null;
if (chartSVG.getIntersectionList) {
var svgRect = chartSVG.createSVGRect();
svgRect.x = mouseX;
svgRect.y = mouseY;
svgRect.width = 1;
svgRect.height = 1;
nodes = chartSVG.getIntersectionList(svgRect,chartSVG);
} else {
// Firefox doesn't do getIntersectionList and that
// makes us sad
nodes = RED.view.getLinksAtPoint(mouseX,mouseY);
}
if (dropEnabled) {
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop() + 10;
if (!groupTimer) {
groupTimer = setTimeout(function() {
var mx = mouseX / RED.view.scale();
var my = mouseY / RED.view.scale();
for (var i=0;i<nodes.length;i++) {
var node = d3.select(nodes[i]);
if (node.classed('red-ui-flow-link-background') && !node.classed('red-ui-flow-link-link')) {
var length = nodes[i].getTotalLength();
for (var j=0;j<length;j+=10) {
var p = nodes[i].getPointAtLength(j);
var d2 = ((p.x-mx)*(p.x-mx))+((p.y-my)*(p.y-my));
if (d2 < 200 && d2 < bestDistance) {
bestDistance = d2;
bestLink = nodes[i];
var group = RED.view.getGroupAtPoint(mx,my);
if (group !== hoverGroup) {
if (hoverGroup) {
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
}
if (group) {
document.getElementById("group_select_"+group.id).classList.add("red-ui-flow-group-hovered");
}
hoverGroup = group;
if (hoverGroup) {
$(ui.helper).data('group',hoverGroup);
} else {
$(ui.helper).removeData('group');
}
}
groupTimer = null;
},200)
}
if (def.inputs > 0 && def.outputs > 0) {
if (!spliceTimer) {
spliceTimer = setTimeout(function() {
var nodes = [];
var bestDistance = Infinity;
var bestLink = null;
if (chartSVG.getIntersectionList) {
var svgRect = chartSVG.createSVGRect();
svgRect.x = mouseX;
svgRect.y = mouseY;
svgRect.width = 1;
svgRect.height = 1;
nodes = chartSVG.getIntersectionList(svgRect,chartSVG);
} else {
// Firefox doesn't do getIntersectionList and that
// makes us sad
nodes = RED.view.getLinksAtPoint(mouseX,mouseY);
}
var mx = mouseX / RED.view.scale();
var my = mouseY / RED.view.scale();
for (var i=0;i<nodes.length;i++) {
var node = d3.select(nodes[i]);
if (node.classed('red-ui-flow-link-background') && !node.classed('red-ui-flow-link-link')) {
var length = nodes[i].getTotalLength();
for (var j=0;j<length;j+=10) {
var p = nodes[i].getPointAtLength(j);
var d2 = ((p.x-mx)*(p.x-mx))+((p.y-my)*(p.y-my));
if (d2 < 200 && d2 < bestDistance) {
bestDistance = d2;
bestLink = nodes[i];
}
}
}
}
}
if (activeSpliceLink && activeSpliceLink !== bestLink) {
d3.select(activeSpliceLink.parentNode).classed('red-ui-flow-link-splice',false);
}
if (bestLink) {
d3.select(bestLink.parentNode).classed('red-ui-flow-link-splice',true)
} else {
d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
}
if (activeSpliceLink !== bestLink) {
if (bestLink) {
$(ui.helper).data('splice',d3.select(bestLink).data()[0]);
} else {
$(ui.helper).removeData('splice');
if (activeSpliceLink && activeSpliceLink !== bestLink) {
d3.select(activeSpliceLink.parentNode).classed('red-ui-flow-link-splice',false);
}
}
activeSpliceLink = bestLink;
spliceTimer = null;
},200);
if (bestLink) {
d3.select(bestLink.parentNode).classed('red-ui-flow-link-splice',true)
} else {
d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
}
if (activeSpliceLink !== bestLink) {
if (bestLink) {
$(ui.helper).data('splice',d3.select(bestLink).data()[0]);
} else {
$(ui.helper).removeData('splice');
}
}
activeSpliceLink = bestLink;
spliceTimer = null;
},200);
}
}
}
}
@ -432,6 +438,7 @@ RED.palette = (function() {
categoryNode.find(".red-ui-palette-content").slideToggle();
categoryNode.find("i").toggleClass("expanded");
}
categoryNode.hide();
}
}
@ -510,6 +517,7 @@ RED.palette = (function() {
currentCategoryNode.find(".red-ui-palette-content").slideToggle();
currentCategoryNode.find("i").toggleClass("expanded");
}
currentCategoryNode.hide();
}
}

View File

@ -165,6 +165,9 @@ RED.projects.settings = (function() {
}
var description = addTargetToExternalLinks($('<span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(desc)+'">'+desc+'</span>')).appendTo(container);
description.find(".red-ui-text-bidi-aware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" );
setTimeout(function () {
mermaid.init();
}, 200);
}
function editSummary(activeProject, summary, container, version, versionContainer) {

View File

View File

@ -273,6 +273,11 @@ RED.subflow = (function() {
var subflowInstances = [];
if (activeSubflow) {
RED.nodes.filterNodes({type:"subflow:"+activeSubflow.id}).forEach(function(n) {
const parentFlow = RED.nodes.workspace(n.z)
const wasLocked = parentFlow && parentFlow.locked
if (wasLocked) {
parentFlow.locked = false
}
subflowInstances.push({
id: n.id,
changed: n.changed
@ -285,6 +290,9 @@ RED.subflow = (function() {
n.resize = true;
n.dirty = true;
RED.editor.updateNodeProperties(n);
if (wasLocked) {
parentFlow.locked = true
}
});
RED.editor.validateNode(activeSubflow);
return {
@ -431,44 +439,7 @@ RED.subflow = (function() {
$("#red-ui-subflow-delete").on("click", function(event) {
event.preventDefault();
var subflow = RED.nodes.subflow(RED.workspaces.active());
if (subflow.instances.length > 0) {
var msg = $('<div>')
$('<p>').text(RED._("subflow.subflowInstances",{count: subflow.instances.length})).appendTo(msg);
$('<p>').text(RED._("subflow.confirmDelete")).appendTo(msg);
var confirmDeleteNotification = RED.notify(msg, {
modal: true,
fixed: true,
buttons: [
{
text: RED._('common.label.cancel'),
click: function() {
confirmDeleteNotification.close();
}
},
{
text: RED._('workspace.confirmDelete'),
class: "primary",
click: function() {
confirmDeleteNotification.close();
completeDelete();
}
}
]
});
return;
} else {
completeDelete();
}
function completeDelete() {
var startDirty = RED.nodes.dirty();
var historyEvent = removeSubflow(RED.workspaces.active());
historyEvent.t = 'delete';
historyEvent.dirty = startDirty;
RED.history.push(historyEvent);
}
RED.subflow.delete(RED.workspaces.active())
});
refreshToolbar(activeSubflow);
@ -481,7 +452,51 @@ RED.subflow = (function() {
$("#red-ui-workspace-toolbar").hide().empty();
$("#red-ui-workspace-chart").css({"margin-top": "0"});
}
function deleteSubflow(id) {
const subflow = RED.nodes.subflow(id || RED.workspaces.active());
if (!subflow) {
return
}
if (subflow.instances.length > 0) {
if (subflow.instances.some(sf => { const ws = RED.nodes.workspace(sf.z); return ws?ws.locked:false })) {
return
}
const msg = $('<div>')
$('<p>').text(RED._("subflow.subflowInstances",{count: subflow.instances.length})).appendTo(msg);
$('<p>').text(RED._("subflow.confirmDelete")).appendTo(msg);
const confirmDeleteNotification = RED.notify(msg, {
modal: true,
fixed: true,
buttons: [
{
text: RED._('common.label.cancel'),
click: function() {
confirmDeleteNotification.close();
}
},
{
text: RED._('workspace.confirmDelete'),
class: "primary",
click: function() {
confirmDeleteNotification.close();
completeDelete();
}
}
]
});
return;
} else {
completeDelete();
}
function completeDelete() {
const startDirty = RED.nodes.dirty();
const historyEvent = removeSubflow(subflow.id);
historyEvent.t = 'delete';
historyEvent.dirty = startDirty;
RED.history.push(historyEvent);
}
}
function removeSubflow(id, keepInstanceNodes) {
// TODO: A lot of this logic is common with RED.nodes.removeWorkspace
var removedNodes = [];
@ -558,7 +573,7 @@ RED.subflow = (function() {
}
});
RED.events.on("view:selection-changed",function(selection) {
if (!selection.nodes) {
if (!selection.nodes || RED.workspaces.isLocked()) {
RED.menu.setDisabled("menu-item-subflow-convert",true);
} else {
RED.menu.setDisabled("menu-item-subflow-convert",false);
@ -621,6 +636,9 @@ RED.subflow = (function() {
}
function convertToSubflow() {
if (RED.workspaces.isLocked()) {
return
}
var selection = RED.view.selection();
if (!selection.nodes) {
RED.notify(RED._("subflow.errors.noNodesSelected"),"error");
@ -776,7 +794,7 @@ RED.subflow = (function() {
}
subflowInstance._def = RED.nodes.getType(subflowInstance.type);
RED.editor.validateNode(subflowInstance);
RED.nodes.add(subflowInstance);
subflowInstance = RED.nodes.add(subflowInstance);
if (containingGroup) {
RED.group.addToGroup(containingGroup, subflowInstance);
@ -1330,7 +1348,10 @@ RED.subflow = (function() {
init: init,
createSubflow: createSubflow,
convertToSubflow: convertToSubflow,
// removeSubflow: Internal function to remove subflow
removeSubflow: removeSubflow,
// delete: Prompt user for confirmation
delete: deleteSubflow,
refresh: refresh,
removeInput: removeSubflowInput,
removeOutput: removeSubflowOutput,

View File

@ -43,12 +43,15 @@ RED.sidebar.config = (function() {
var categories = {};
function getOrCreateCategory(name,parent,label) {
function getOrCreateCategory(name,parent,label,isLocked) {
name = name.replace(/\./i,"-");
if (!categories[name]) {
var container = $('<div class="red-ui-palette-category red-ui-sidebar-config-category" id="red-ui-sidebar-config-category-'+name+'"></div>').appendTo(parent);
var header = $('<div class="red-ui-sidebar-config-tray-header red-ui-palette-header"><i class="fa fa-angle-down expanded"></i></div>').appendTo(container);
let lockIcon
if (label) {
lockIcon = $('<span style="margin-right: 5px"><i class="fa fa-lock"/></span>').appendTo(header)
lockIcon.toggle(!!isLocked)
$('<span class="red-ui-palette-node-config-label"/>').text(label).appendTo(header);
} else {
$('<span class="red-ui-palette-node-config-label" data-i18n="sidebar.config.'+name+'">').appendTo(header);
@ -62,6 +65,7 @@ RED.sidebar.config = (function() {
var icon = header.find("i");
var result = {
label: label,
lockIcon,
list: category,
size: function() {
return result.list.find("li:not(.red-ui-palette-node-config-none)").length
@ -100,6 +104,9 @@ RED.sidebar.config = (function() {
});
categories[name] = result;
} else {
if (isLocked !== undefined && categories[name].lockIcon) {
categories[name].lockIcon.toggle(!!isLocked)
}
if (categories[name].label !== label) {
categories[name].list.parent().find('.red-ui-palette-node-config-label').text(label);
categories[name].label = label;
@ -138,17 +145,19 @@ RED.sidebar.config = (function() {
} else {
var currentType = "";
nodes.forEach(function(node) {
var label = RED.utils.getNodeLabel(node,node.id);
var labelText = RED.utils.getNodeLabel(node,node.id);
if (node.type != currentType) {
$('<li class="red-ui-palette-node-config-type">'+node.type+'</li>').appendTo(list);
currentType = node.type;
}
if (node.changed) {
labelText += "!!"
}
var entry = $('<li class="red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list);
var nodeDiv = $('<div class="red-ui-palette-node-config red-ui-palette-node"></div>').appendTo(entry);
entry.data('node',node.id);
nodeDiv.data('node',node.id);
var label = $('<div class="red-ui-palette-label"></div>').text(label).appendTo(nodeDiv);
var label = $('<div class="red-ui-palette-label"></div>').text(labelText).appendTo(nodeDiv);
if (node.d) {
nodeDiv.addClass("red-ui-palette-node-config-disabled");
$('<i class="fa fa-ban"></i>').prependTo(label);
@ -216,7 +225,7 @@ RED.sidebar.config = (function() {
RED.nodes.eachWorkspace(function(ws) {
validList[ws.id.replace(/\./g,"-")] = true;
getOrCreateCategory(ws.id,flowCategories,ws.label);
getOrCreateCategory(ws.id,flowCategories,ws.label, ws.locked);
})
RED.nodes.eachSubflow(function(sf) {
validList[sf.id.replace(/\./g,"-")] = true;
@ -274,6 +283,15 @@ RED.sidebar.config = (function() {
changes: {},
dirty: RED.nodes.dirty()
}
for (let i = 0; i < selectedNodes.length; i++) {
let node = RED.nodes.node(selectedNodes[i])
if (node.z) {
let ws = RED.nodes.workspace(node.z)
if (ws && ws.locked) {
return
}
}
}
selectedNodes.forEach(function(id) {
var node = RED.nodes.node(id);
try {

View File

@ -141,7 +141,8 @@ RED.sidebar.help = (function() {
RED.events.on('registry:node-type-removed', queueRefresh);
RED.events.on('subflows:change', refreshSubflow);
RED.actions.add("core:show-help-tab",show);
RED.actions.add("core:show-help-tab", show);
RED.actions.add("core:show-node-help", showNodeHelp)
}
@ -338,6 +339,19 @@ RED.sidebar.help = (function() {
resizeStack();
}
function showNodeHelp(node) {
if (!node) {
const selection = RED.view.selection()
if (selection.nodes && selection.nodes.length > 0) {
node = selection.nodes.find(n => n.type !== 'group' && n.type !== 'junction')
}
}
if (node) {
show(node.type, true)
}
}
// TODO: DRY - projects.js
function addTargetToExternalLinks(el) {
$(el).find("a").each(function(el) {

View File

@ -135,6 +135,10 @@ RED.sidebar.info.outliner = (function() {
RED.workspaces.show(n.id, null, true);
}
});
RED.popover.tooltip(toggleVisibleButton, function () {
var isHidden = !div.hasClass("red-ui-info-outline-item-hidden");
return RED._("sidebar.info." + (isHidden ? "hideFlow" : "showFlow"));
});
}
if (n.type !== 'subflow') {
var toggleButton = $('<button type="button" class="red-ui-info-outline-item-control-disable red-ui-button red-ui-button-small"><i class="fa fa-circle-thin"></i><i class="fa fa-ban"></i></button>').appendTo(controls).on("click",function(evt) {
@ -221,6 +225,22 @@ RED.sidebar.info.outliner = (function() {
} else {
$('<div class="red-ui-info-outline-item-control-spacer">').appendTo(controls)
}
if (n.type === 'tab') {
var lockToggleButton = $('<button type="button" class="red-ui-info-outline-item-control-lock red-ui-button red-ui-button-small"><i class="fa fa-unlock-alt"></i><i class="fa fa-lock"></i></button>').appendTo(controls).on("click",function(evt) {
evt.preventDefault();
evt.stopPropagation();
if (n.locked) {
RED.workspaces.unlock(n.id)
} else {
RED.workspaces.lock(n.id)
}
})
RED.popover.tooltip(lockToggleButton,function() {
return RED._("common.label."+(n.locked?"unlock":"lock"));
});
} else {
$('<div class="red-ui-info-outline-item-control-spacer">').appendTo(controls)
}
controls.find("button").on("dblclick", function(evt) {
evt.preventDefault();
evt.stopPropagation();
@ -364,6 +384,8 @@ RED.sidebar.info.outliner = (function() {
flowList.treeList.addChild(objects[ws.id])
objects[ws.id].element.toggleClass("red-ui-info-outline-item-disabled", !!ws.disabled)
objects[ws.id].treeList.container.toggleClass("red-ui-info-outline-item-disabled", !!ws.disabled)
objects[ws.id].element.toggleClass("red-ui-info-outline-item-locked", !!ws.locked)
objects[ws.id].treeList.container.toggleClass("red-ui-info-outline-item-locked", !!ws.locked)
updateSearch();
}
@ -378,6 +400,8 @@ RED.sidebar.info.outliner = (function() {
existingObject.element.find(".red-ui-info-outline-item-label").text(label);
existingObject.element.toggleClass("red-ui-info-outline-item-disabled", !!n.disabled)
existingObject.treeList.container.toggleClass("red-ui-info-outline-item-disabled", !!n.disabled)
existingObject.element.toggleClass("red-ui-info-outline-item-locked", !!n.locked)
existingObject.treeList.container.toggleClass("red-ui-info-outline-item-locked", !!n.locked)
updateSearch();
}
function onFlowsReorder(order) {
@ -613,6 +637,9 @@ RED.sidebar.info.outliner = (function() {
objects[n.id].children = missingParents[n.id];
delete missingParents[n.id]
}
if (objects[n.id].children.length === 0) {
objects[n.id].children.push(getEmptyItem(n.id));
}
}
var parent = n.g||n.z||"__global__";

View File

@ -25,6 +25,7 @@ RED.sidebar.info = (function() {
var propertiesPanelHeaderLabel;
var propertiesPanelHeaderReveal;
var propertiesPanelHeaderHelp;
var propertiesPanelHeaderCopyLink;
var selectedObject;
@ -67,10 +68,20 @@ RED.sidebar.info = (function() {
propertiesPanelHeaderIcon = $("<span>").appendTo(propertiesPanelHeader);
propertiesPanelHeaderLabel = $("<span>").appendTo(propertiesPanelHeader);
propertiesPanelHeaderHelp = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-book"></button>').css({
propertiesPanelHeaderCopyLink = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-link"></button>').css({
position: 'absolute',
top: '12px',
right: '32px'
}).on("click", function(evt) {
RED.actions.invoke('core:copy-item-url',selectedObject)
}).appendTo(propertiesPanelHeader);
RED.popover.tooltip(propertiesPanelHeaderCopyLink,RED._("sidebar.info.copyItemUrl"));
propertiesPanelHeaderHelp = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-book"></button>').css({
position: 'absolute',
top: '12px',
right: '56px'
}).on("click", function(evt) {
evt.preventDefault();
evt.stopPropagation();
@ -80,8 +91,7 @@ RED.sidebar.info = (function() {
}).appendTo(propertiesPanelHeader);
RED.popover.tooltip(propertiesPanelHeaderHelp,RED._("sidebar.help.showHelp"));
propertiesPanelHeaderReveal = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-search"></button>').css({
propertiesPanelHeaderReveal = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-search"></button>').css({
position: 'absolute',
top: '12px',
right: '8px'
@ -185,6 +195,7 @@ RED.sidebar.info = (function() {
propertiesPanelHeaderLabel.text("");
propertiesPanelHeaderReveal.hide();
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.hide();
return;
} else if (Array.isArray(node)) {
// Multiple things selected
@ -196,6 +207,7 @@ RED.sidebar.info = (function() {
propertiesPanelHeaderLabel.text("Selection");
propertiesPanelHeaderReveal.hide();
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.hide();
selectedObject = null;
var types = {
@ -277,9 +289,11 @@ RED.sidebar.info = (function() {
if (node.type === "tab" || node.type === "subflow") {
// If nothing is selected, but we're on a flow or subflow tab.
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.show();
} else if (node.type === "group") {
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.show();
propRow = $('<tr class="red-ui-help-info-row"><td>&nbsp;</td><td></td></tr>').appendTo(tableBody);
@ -304,8 +318,10 @@ RED.sidebar.info = (function() {
}
} else if (node.type === 'junction') {
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.hide();
} else {
propertiesPanelHeaderHelp.show();
propertiesPanelHeaderCopyLink.show();
if (!subflowRegex) {
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.type")+'</td><td></td></tr>').appendTo(tableBody);
@ -447,7 +463,8 @@ RED.sidebar.info = (function() {
el = el.next();
}
$(this).toggleClass('expanded',!isExpanded);
})
});
mermaid.init();
}
var tips = (function() {

View File

@ -435,10 +435,15 @@ RED.tourGuide = (function() {
function listTour() {
return [
{
id: "3_1",
label: "3.1",
path: "./tours/welcome.js"
},
{
id: "3_0",
label: "3.0",
path: "./tours/welcome.js"
path: "./tours/3.0/welcome.js"
},
{
id: "2_2",

View File

@ -96,6 +96,37 @@ RED.utils = (function() {
}
}
var mermaidIsInitialized = false;
var mermaidIsEnabled /* = undefined */;
renderer.code = function (code, lang) {
if(lang === "mermaid") {
// mermaid diagram rendering
if (mermaidIsEnabled === undefined) {
if (RED.settings.markdownEditor &&
RED.settings.markdownEditor.mermaid) {
mermaidIsEnabled = RED.settings.markdownEditor.mermaid.enabled;
}
else {
mermaidIsEnabled = true;
}
}
if (mermaidIsEnabled) {
if (!mermaidIsInitialized) {
mermaidIsInitialized = true;
mermaid.initialize({startOnLoad:false});
}
return `<pre class='mermaid'>${code}</pre>`;
}
else {
return `<details><summary>${RED._("markdownEditor.mermaid.summary")}</summary><pre><code>${code}</code></pre></details>`;
}
}
else {
return "<pre><code>" +code +"</code></pre>";
}
};
window._marked.setOptions({
renderer: renderer,
gfm: true,

View File

@ -15,7 +15,7 @@
**/
RED.view.tools = (function() {
'use strict';
function selectConnected(type) {
var selection = RED.view.selection();
var visited = new Set();
@ -39,6 +39,9 @@ RED.view.tools = (function() {
}
function alignToGrid() {
if (RED.workspaces.isLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
var changedNodes = [];
@ -87,6 +90,9 @@ RED.view.tools = (function() {
}
function moveSelection(dx,dy) {
if (RED.workspaces.isLocked()) {
return
}
if (moving_set === null) {
moving_set = [];
var selection = RED.view.selection();
@ -153,6 +159,9 @@ RED.view.tools = (function() {
}
function setSelectedNodeLabelState(labelShown) {
if (RED.workspaces.isLocked()) {
return
}
var selection = RED.view.selection();
var historyEvents = [];
var nodes = [];
@ -439,6 +448,9 @@ RED.view.tools = (function() {
}
function alignSelectionToEdge(direction) {
if (RED.workspaces.isLocked()) {
return;
}
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length > 1) {
@ -539,8 +551,10 @@ RED.view.tools = (function() {
}
}
function distributeSelection(direction) {
if (RED.workspaces.isLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length > 2) {
@ -699,14 +713,16 @@ RED.view.tools = (function() {
}
function reorderSelection(dir) {
if (RED.workspaces.isLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
var nodesToMove = [];
selection.nodes.forEach(function(n) {
if (n.type === "group") {
nodesToMove = nodesToMove.concat(RED.group.getNodes(n, true).filter(function(n) {
return n.type !== "group";
}))
nodesToMove.push(n)
nodesToMove = nodesToMove.concat(RED.group.getNodes(n, true))
} else if (n.type !== "subflow"){
nodesToMove.push(n);
}
@ -734,8 +750,10 @@ RED.view.tools = (function() {
}
}
function wireSeriesOfNodes() {
if (RED.workspaces.isLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
if (selection.nodes.length > 1) {
@ -776,6 +794,9 @@ RED.view.tools = (function() {
}
function wireNodeToMultiple() {
if (RED.workspaces.isLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
if (selection.nodes.length > 1) {
@ -818,11 +839,72 @@ RED.view.tools = (function() {
}
}
function wireMultipleToNode() {
if (RED.workspaces.isLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
if (selection.nodes.length > 1) {
var targetNode = selection.nodes[selection.nodes.length - 1];
if (targetNode.inputs === 0) {
return;
}
var i = 0;
var newLinks = [];
for (i = 0; i < selection.nodes.length - 1; i++) {
var sourceNode = selection.nodes[i];
if (sourceNode.outputs > 0) {
// Wire the first output to the target that has no link to the target yet.
// This allows for connecting all combinations of inputs/outputs.
// The user may then delete links quickly that aren't needed.
var sourceConnectedOutports = RED.nodes.filterLinks({
source: sourceNode,
target: targetNode
});
// Get outport indices that have no link yet
var sourceOutportIndices = Array.from({ length: sourceNode.outputs }, (_, i) => i);
var sourceConnectedOutportIndices = sourceConnectedOutports.map( x => x.sourcePort );
var sourceFreeOutportIndices = sourceOutportIndices.filter(x => !sourceConnectedOutportIndices.includes(x));
// Does an unconnected source port exist?
if (sourceFreeOutportIndices.length == 0) {
continue;
}
// Connect the first free outport to the target
var newLink = {
source: sourceNode,
target: targetNode,
sourcePort: sourceFreeOutportIndices[0]
}
RED.nodes.addLink(newLink);
newLinks.push(newLink);
}
}
if (newLinks.length > 0) {
RED.history.push({
t: 'add',
links: newLinks,
dirty: RED.nodes.dirty()
})
RED.nodes.dirty(true);
RED.view.redraw(true);
}
}
}
}
/**
* Splits selected wires and re-joins them with link-out+link-in
* @param {Object || Object[]} wires The wire(s) to split and replace with link-out, link-in nodes.
*/
function splitWiresWithLinkNodes(wires) {
if (RED.workspaces.isLocked()) {
return
}
let wiresToSplit = wires || (RED.view.selection().links && RED.view.selection().links.filter(e => !e.link));
if (!wiresToSplit) {
return
@ -877,7 +959,6 @@ RED.view.tools = (function() {
if(!nnLinkOut) {
const nLinkOut = RED.view.createNode("link out"); //create link node
nnLinkOut = nLinkOut.node;
nodeSrcMap[linkOutMapId] = nnLinkOut;
let yOffset = 0;
if(nSrc.outputs > 1) {
@ -892,7 +973,8 @@ RED.view.tools = (function() {
updateNewNodePosXY(nSrc, nnLinkOut, false, RED.view.snapGrid, yOffset);
}
//add created node
RED.nodes.add(nnLinkOut);
nnLinkOut = RED.nodes.add(nnLinkOut);
nodeSrcMap[linkOutMapId] = nnLinkOut;
RED.editor.validateNode(nnLinkOut);
history.events.push(nLinkOut.historyEvent);
//connect node to link node
@ -913,10 +995,10 @@ RED.view.tools = (function() {
if(!nnLinkIn) {
const nLinkIn = RED.view.createNode("link in"); //create link node
nnLinkIn = nLinkIn.node;
nodeTrgMap[nTrg.id] = nnLinkIn;
updateNewNodePosXY(nTrg, nnLinkIn, true, RED.view.snapGrid, 0);
//add created node
RED.nodes.add(nnLinkIn);
nnLinkIn = RED.nodes.add(nnLinkIn);
nodeTrgMap[nTrg.id] = nnLinkIn;
RED.editor.validateNode(nnLinkIn);
history.events.push(nLinkIn.historyEvent);
//connect node to link node
@ -991,6 +1073,9 @@ RED.view.tools = (function() {
* @param {{ renameBlank: boolean, renameClash: boolean, generateHistory: boolean }} options Possible options are `renameBlank`, `renameClash` and `generateHistory`
*/
function generateNodeNames(node, options) {
if (RED.workspaces.isLocked()) {
return
}
options = Object.assign({
renameBlank: true,
renameClash: true,
@ -1061,6 +1146,9 @@ RED.view.tools = (function() {
}
function addJunctionsToWires(wires) {
if (RED.workspaces.isLocked()) {
return
}
let wiresToSplit = wires || (RED.view.selection().links && RED.view.selection().links.filter(e => !e.link));
if (!wiresToSplit) {
return
@ -1102,7 +1190,8 @@ RED.view.tools = (function() {
w: 0, h: 0,
outputs: 1,
inputs: 1,
dirty: true
dirty: true,
moved: true
}
links = links.filter(function(l) { return !removedLinks.has(l) })
if (links.length === 0) {
@ -1131,7 +1220,7 @@ RED.view.tools = (function() {
var nodeGroups = new Set()
RED.nodes.addJunction(junction)
junction = RED.nodes.addJunction(junction)
addedJunctions.push(junction)
let newLink
if (gid === links[0].source.id+":"+links[0].sourcePort) {
@ -1192,6 +1281,30 @@ RED.view.tools = (function() {
RED.view.redraw(true);
}
function copyItemUrl(node, isEdit) {
if (!node) {
const selection = RED.view.selection();
if (selection.nodes && selection.nodes.length > 0) {
node = selection.nodes[0]
}
}
if (node) {
let thingType = 'node'
if (node.type === 'group') {
thingType = 'group'
} else if (node.type === 'tab' || node.type === 'subflow') {
thingType = 'flow'
}
let url = `${window.location.origin}${window.location.pathname}#${thingType}/${node.id}`
if (isEdit) {
url += '/edit'
}
if (RED.clipboard.copyText(url)) {
RED.notify(RED._("sidebar.info.copyURL2Clipboard"), { timeout: 2000 })
}
}
}
return {
init: function() {
RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); })
@ -1252,12 +1365,16 @@ RED.view.tools = (function() {
RED.actions.add("core:wire-series-of-nodes", function() { wireSeriesOfNodes() })
RED.actions.add("core:wire-node-to-multiple", function() { wireNodeToMultiple() })
RED.actions.add("core:wire-multiple-to-node", function() { wireMultipleToNode() })
RED.actions.add("core:split-wire-with-link-nodes", function () { splitWiresWithLinkNodes() });
RED.actions.add("core:split-wires-with-junctions", function () { addJunctionsToWires() });
RED.actions.add("core:generate-node-names", generateNodeNames )
RED.actions.add("core:copy-item-url", function (node) { copyItemUrl(node) })
RED.actions.add("core:copy-item-edit-url", function (node) { copyItemUrl(node, true) })
// RED.actions.add("core:add-node", function() { addNode() })
},
/**

1448
packages/node_modules/@node-red/editor-client/src/js/ui/view.js vendored Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@ -58,6 +58,9 @@ RED.workspaces = (function() {
if (!ws.closeable) {
ws.hideable = true;
}
if (!ws.hasOwnProperty('locked')) {
ws.locked = false
}
workspace_tabs.addTab(ws,targetIndex);
var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
@ -75,11 +78,15 @@ RED.workspaces = (function() {
type: "tab",
id: tabId,
disabled: false,
locked: false,
info: "",
label: RED._('workspace.defaultName',{number:workspaceIndex}),
env: [],
hideable: true
hideable: true,
};
if (!skipHistoryEntry) {
ws.added = true
}
RED.nodes.addWorkspace(ws,targetIndex);
workspace_tabs.addTab(ws,targetIndex);
@ -89,8 +96,7 @@ RED.workspaces = (function() {
RED.nodes.dirty(true);
}
}
$("#red-ui-tab-"+(ws.id.replace(".","-"))).attr("flowname",ws.label)
$("#red-ui-tab-"+(ws.id.replace(".","-"))).attr("flowname",ws.label).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
RED.view.focus();
return ws;
}
@ -99,6 +105,9 @@ RED.workspaces = (function() {
if (workspaceTabCount === 1) {
return;
}
if (ws.locked) {
return
}
var workspaceOrder = RED.nodes.getWorkspaceOrder();
ws._index = workspaceOrder.indexOf(ws.id);
removeWorkspace(ws);
@ -119,13 +128,206 @@ RED.workspaces = (function() {
RED.editor.editSubflow(subflow);
}
} else {
RED.editor.editFlow(workspace);
if (!workspace.locked) {
RED.editor.editFlow(workspace);
}
}
}
var workspace_tabs;
var workspaceTabCount = 0;
function getMenuItems(isMenuButton, tab) {
let hiddenFlows = new Set()
for (let i = 0; i < hideStack.length; i++) {
let ids = hideStack[i]
if (!Array.isArray(ids)) {
ids = [ids]
}
ids.forEach(id => {
if (RED.nodes.workspace(id)) {
hiddenFlows.add(id)
}
})
}
const hiddenflowCount = hiddenFlows.size;
let activeWorkspace = tab || RED.nodes.workspace(RED.workspaces.active()) || RED.nodes.subflow(RED.workspaces.active())
let isFlowDisabled = activeWorkspace ? activeWorkspace.disabled : false
const currentTabs = workspace_tabs.listTabs();
let flowCount = 0;
currentTabs.forEach(tab => {
if (RED.nodes.workspace(tab)) {
flowCount++;
}
});
let isCurrentLocked = RED.workspaces.isLocked()
if (tab) {
isCurrentLocked = tab.locked
}
var menuItems = []
if (isMenuButton) {
menuItems.push({
id:"red-ui-tabs-menu-option-search-flows",
label: RED._("workspace.listFlows"),
onselect: "core:list-flows"
},
{
id:"red-ui-tabs-menu-option-search-subflows",
label: RED._("workspace.listSubflows"),
onselect: "core:list-subflows"
},
null)
}
menuItems.push(
{
id:"red-ui-tabs-menu-option-add-flow",
label: RED._("workspace.addFlow"),
onselect: "core:add-flow"
}
)
if (isMenuButton || !!tab) {
menuItems.push(
{
id:"red-ui-tabs-menu-option-add-flow-right",
label: RED._("workspace.addFlowToRight"),
shortcut: RED.keyboard.getShortcut("core:add-flow-to-right"),
onselect: function() {
RED.actions.invoke("core:add-flow-to-right", tab)
}
},
null
)
if (activeWorkspace && activeWorkspace.type === 'tab') {
menuItems.push(
isFlowDisabled ? {
label: RED._("workspace.enableFlow"),
shortcut: RED.keyboard.getShortcut("core:enable-flow"),
onselect: function() {
RED.actions.invoke("core:enable-flow", tab?tab.id:undefined)
},
disabled: isCurrentLocked
} : {
label: RED._("workspace.disableFlow"),
shortcut: RED.keyboard.getShortcut("core:disable-flow"),
onselect: function() {
RED.actions.invoke("core:disable-flow", tab?tab.id:undefined)
},
disabled: isCurrentLocked
},
isCurrentLocked? {
label: RED._("workspace.unlockFlow"),
shortcut: RED.keyboard.getShortcut("core:unlock-flow"),
onselect: function() {
RED.actions.invoke('core:unlock-flow', tab?tab.id:undefined)
}
} : {
label: RED._("workspace.lockFlow"),
shortcut: RED.keyboard.getShortcut("core:lock-flow"),
onselect: function() {
RED.actions.invoke('core:lock-flow', tab?tab.id:undefined)
}
},
null
)
}
const activeIndex = currentTabs.findIndex(id => (activeWorkspace && (id === activeWorkspace.id)));
menuItems.push(
{
label: RED._("workspace.moveToStart"),
shortcut: RED.keyboard.getShortcut("core:move-flow-to-start"),
onselect: function() {
RED.actions.invoke("core:move-flow-to-start", tab?tab.id:undefined)
},
disabled: activeIndex === 0
},
{
label: RED._("workspace.moveToEnd"),
shortcut: RED.keyboard.getShortcut("core:move-flow-to-end"),
onselect: function() {
RED.actions.invoke("core:move-flow-to-end", tab?tab.id:undefined)
},
disabled: activeIndex === currentTabs.length - 1
}
)
}
menuItems.push(null)
if (isMenuButton || !!tab) {
menuItems.push(
{
id:"red-ui-tabs-menu-option-add-hide-flows",
label: RED._("workspace.hideFlow"),
shortcut: RED.keyboard.getShortcut("core:hide-flow"),
onselect: function() {
RED.actions.invoke("core:hide-flow", tab)
}
},
{
id:"red-ui-tabs-menu-option-add-hide-other-flows",
label: RED._("workspace.hideOtherFlows"),
shortcut: RED.keyboard.getShortcut("core:hide-other-flows"),
onselect: function() {
RED.actions.invoke("core:hide-other-flows", tab)
}
}
)
}
menuItems.push(
{
id:"red-ui-tabs-menu-option-add-hide-all-flows",
label: RED._("workspace.hideAllFlows"),
onselect: "core:hide-all-flows",
disabled: (hiddenflowCount === flowCount)
},
{
id:"red-ui-tabs-menu-option-add-show-all-flows",
disabled: hiddenflowCount === 0,
label: RED._("workspace.showAllFlows", { count: hiddenflowCount }),
onselect: "core:show-all-flows"
},
{
id:"red-ui-tabs-menu-option-add-show-last-flow",
disabled: hideStack.length === 0,
label: RED._("workspace.showLastHiddenFlow"),
onselect: "core:show-last-hidden-flow"
}
)
if (tab) {
menuItems.push(
null,
{
label: RED._("common.label.delete"),
onselect: function() {
if (tab.type === 'tab') {
RED.workspaces.delete(tab)
} else if (tab.type === 'subflow') {
RED.subflow.delete(tab.id)
}
},
disabled: isCurrentLocked || (workspaceTabCount === 1)
},
{
label: RED._("menu.label.export"),
shortcut: RED.keyboard.getShortcut("core:show-export-dialog"),
onselect: function() {
RED.workspaces.show(tab.id)
RED.actions.invoke('core:show-export-dialog', null, 'flow')
}
}
)
}
// if (isMenuButton && hiddenflowCount > 0) {
// menuItems.unshift({
// label: RED._("workspace.hiddenFlows",{count: hiddenflowCount}),
// onselect: "core:list-hidden-flows"
// })
// }
return menuItems;
}
function createWorkspaceTabs() {
workspace_tabs = RED.tabs.create({
id: "red-ui-workspace-tabs",
@ -137,8 +339,9 @@ RED.workspaces = (function() {
$("#red-ui-workspace-chart").show();
activeWorkspace = tab.id;
window.location.hash = 'flow/'+tab.id;
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!tab.disabled);
} else {
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled", !!tab.disabled);
$("#red-ui-workspace").toggleClass("red-ui-workspace-locked", !!tab.locked);
} else {
$("#red-ui-workspace-chart").hide();
activeWorkspace = 0;
window.location.hash = '';
@ -169,6 +372,18 @@ RED.workspaces = (function() {
if (tab.disabled) {
$("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('red-ui-workspace-disabled');
}
$('<span class="red-ui-workspace-locked-icon"><i class="fa fa-lock"></i> </span>').prependTo("#red-ui-tab-"+(tab.id.replace(".","-"))+" .red-ui-tab-label");
if (tab.locked) {
$("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('red-ui-workspace-locked');
}
const changeBadgeContainer = $('<svg class="red-ui-flow-tab-changed red-ui-flow-node-changed" width="10" height="10" viewBox="-1 -1 12 12"></svg>').appendTo("#red-ui-tab-"+(tab.id.replace(".","-")))
const changeBadge = document.createElementNS("http://www.w3.org/2000/svg","circle");
changeBadge.setAttribute("cx",5);
changeBadge.setAttribute("cy",5);
changeBadge.setAttribute("r",5);
changeBadgeContainer.append(changeBadge)
RED.menu.setDisabled("menu-item-workspace-delete",activeWorkspace === 0 || workspaceTabCount <= 1);
if (workspaceTabCount === 1) {
showWorkspace();
@ -189,13 +404,19 @@ RED.workspaces = (function() {
RED.history.push({
t:'reorder',
workspaces: {
from:oldOrder,
to:newOrder
from: oldOrder,
to: newOrder
},
dirty:RED.nodes.dirty()
});
RED.nodes.dirty(true);
setWorkspaceOrder(newOrder);
// Only mark flows dirty if flow-order has changed (excluding subflows)
const filteredOldOrder = oldOrder.filter(id => !!RED.nodes.workspace(id))
const filteredNewOrder = newOrder.filter(id => !!RED.nodes.workspace(id))
if (JSON.stringify(filteredOldOrder) !== JSON.stringify(filteredNewOrder)) {
RED.nodes.dirty(true);
setWorkspaceOrder(newOrder);
}
},
onselect: function(selectedTabs) {
RED.view.select(false)
@ -214,12 +435,12 @@ RED.workspaces = (function() {
},
onhide: function(tab) {
hideStack.push(tab.id);
var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
hiddenTabs[tab.id] = true;
RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
RED.events.emit("workspace:hide",{workspace: tab.id})
if (tab.type === "tab") {
var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
hiddenTabs[tab.id] = true;
RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
RED.events.emit("workspace:hide",{workspace: tab.id})
}
},
onshow: function(tab) {
removeFromHideStack(tab.id);
@ -234,77 +455,8 @@ RED.workspaces = (function() {
scrollable: true,
addButton: "core:add-flow",
addButtonCaption: RED._("workspace.addFlow"),
menu: function() {
var menuItems = [
{
id:"red-ui-tabs-menu-option-search-flows",
label: RED._("workspace.listFlows"),
onselect: "core:list-flows"
},
{
id:"red-ui-tabs-menu-option-search-subflows",
label: RED._("workspace.listSubflows"),
onselect: "core:list-subflows"
},
null,
{
id:"red-ui-tabs-menu-option-add-flow",
label: RED._("workspace.addFlow"),
onselect: "core:add-flow"
},
{
id:"red-ui-tabs-menu-option-add-flow-right",
label: RED._("workspace.addFlowToRight"),
onselect: "core:add-flow-to-right"
},
null,
{
id:"red-ui-tabs-menu-option-add-hide-flows",
label: RED._("workspace.hideFlow"),
onselect: "core:hide-flow"
},
{
id:"red-ui-tabs-menu-option-add-hide-other-flows",
label: RED._("workspace.hideOtherFlows"),
onselect: "core:hide-other-flows"
},
{
id:"red-ui-tabs-menu-option-add-show-all-flows",
label: RED._("workspace.showAllFlows"),
onselect: "core:show-all-flows"
},
{
id:"red-ui-tabs-menu-option-add-hide-all-flows",
label: RED._("workspace.hideAllFlows"),
onselect: "core:hide-all-flows"
},
{
id:"red-ui-tabs-menu-option-add-show-last-flow",
label: RED._("workspace.showLastHiddenFlow"),
onselect: "core:show-last-hidden-flow"
}
]
let hiddenFlows = new Set()
for (let i = 0; i < hideStack.length; i++) {
let ids = hideStack[i]
if (!Array.isArray(ids)) {
ids = [ids]
}
ids.forEach(id => {
if (RED.nodes.workspace(id)) {
hiddenFlows.add(id)
}
})
}
const flowCount = hiddenFlows.size;
if (flowCount > 0) {
menuItems.unshift({
label: RED._("workspace.hiddenFlows",{count: flowCount}),
onselect: "core:list-hidden-flows"
})
}
return menuItems;
}
menu: function() { return getMenuItems(true) },
contextmenu: function(tab) { return getMenuItems(false, tab) }
});
workspaceTabCount = 0;
}
@ -355,16 +507,33 @@ RED.workspaces = (function() {
});
RED.actions.add("core:add-flow",function(opts) { addWorkspace(undefined,undefined,opts?opts.index:undefined)});
RED.actions.add("core:add-flow-to-right",function(opts) { addWorkspace(undefined,undefined,workspace_tabs.activeIndex()+1)});
RED.actions.add("core:add-flow-to-right",function(workspace) {
let index
if (workspace) {
index = workspace_tabs.getTabIndex(workspace.id)+1
} else {
index = workspace_tabs.activeIndex()+1
}
addWorkspace(undefined,undefined,index)
});
RED.actions.add("core:edit-flow",editWorkspace);
RED.actions.add("core:remove-flow",removeWorkspace);
RED.actions.add("core:enable-flow",enableWorkspace);
RED.actions.add("core:disable-flow",disableWorkspace);
RED.actions.add("core:lock-flow",lockWorkspace);
RED.actions.add("core:unlock-flow",unlockWorkspace);
RED.actions.add("core:move-flow-to-start", function(id) { moveWorkspace(id, 'start') });
RED.actions.add("core:move-flow-to-end", function(id) { moveWorkspace(id, 'end') });
RED.actions.add("core:hide-flow", function() {
var selection = workspace_tabs.selection();
if (selection.length === 0) {
selection = [{id:activeWorkspace}]
RED.actions.add("core:hide-flow", function(workspace) {
let selection
if (workspace) {
selection = [workspace]
} else {
selection = workspace_tabs.selection();
if (selection.length === 0) {
selection = [{id:activeWorkspace}]
}
}
var hiddenTabs = [];
selection.forEach(function(ws) {
@ -378,10 +547,15 @@ RED.workspaces = (function() {
workspace_tabs.clearSelection();
})
RED.actions.add("core:hide-other-flows", function() {
var selection = workspace_tabs.selection();
if (selection.length === 0) {
selection = [{id:activeWorkspace}]
RED.actions.add("core:hide-other-flows", function(workspace) {
let selection
if (workspace) {
selection = [workspace]
} else {
selection = workspace_tabs.selection();
if (selection.length === 0) {
selection = [{id:activeWorkspace}]
}
}
var selected = new Set(selection.map(function(ws) { return ws.id }))
@ -471,6 +645,11 @@ RED.workspaces = (function() {
RED.workspaces.show(viewStack[++viewStackPos],true);
}
})
RED.events.on("flows:change", (ws) => {
$("#red-ui-tab-"+(ws.id.replace(".","-"))).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
})
hideWorkspace();
}
@ -486,7 +665,7 @@ RED.workspaces = (function() {
}
function setWorkspaceState(id,disabled) {
var workspace = RED.nodes.workspace(id||activeWorkspace);
if (!workspace) {
if (!workspace || workspace.locked) {
return;
}
if (workspace.disabled !== disabled) {
@ -521,11 +700,47 @@ RED.workspaces = (function() {
}
}
}
function lockWorkspace(id) {
setWorkspaceLockState(id,true);
}
function unlockWorkspace(id) {
setWorkspaceLockState(id,false);
}
function setWorkspaceLockState(id,locked) {
var workspace = RED.nodes.workspace(id||activeWorkspace);
if (!workspace) {
return;
}
if (workspace.locked !== locked) {
var changes = { locked: workspace.locked };
workspace.locked = locked;
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-locked',!!workspace.locked);
if (!id || (id === activeWorkspace)) {
$("#red-ui-workspace").toggleClass("red-ui-workspace-locked",!!workspace.locked);
}
var historyEvent = {
t: "edit",
changes:changes,
node: workspace,
dirty: RED.nodes.dirty()
}
workspace.changed = true;
RED.history.push(historyEvent);
RED.events.emit("flows:change",workspace);
RED.nodes.dirty(true);
RED.nodes.filterNodes({z:workspace.id}).forEach(n => n.dirty = true)
RED.view.redraw(true);
}
}
function removeWorkspace(ws) {
if (!ws) {
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
ws = RED.nodes.workspace(activeWorkspace)
if (ws && !ws.locked) {
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
}
} else {
if (ws.locked) { return }
if (workspace_tabs.contains(ws.id)) {
workspace_tabs.removeTab(ws.id);
}
@ -535,16 +750,46 @@ RED.workspaces = (function() {
}
}
function moveWorkspace(id, direction) {
const workspace = RED.nodes.workspace(id||activeWorkspace) || RED.nodes.subflow(id||activeWorkspace);
if (!workspace) {
return;
}
const currentOrder = workspace_tabs.listTabs()
const oldOrder = [...currentOrder]
const currentIndex = currentOrder.findIndex(id => id === workspace.id)
currentOrder.splice(currentIndex, 1)
if (direction === 'start') {
currentOrder.unshift(workspace.id)
} else if (direction === 'end') {
currentOrder.push(workspace.id)
}
const newOrder = setWorkspaceOrder(currentOrder)
if (JSON.stringify(newOrder) !== JSON.stringify(oldOrder)) {
RED.history.push({
t:'reorder',
workspaces: {
from:oldOrder,
to:newOrder
},
dirty:RED.nodes.dirty()
});
const filteredOldOrder = oldOrder.filter(id => !!RED.nodes.workspace(id))
const filteredNewOrder = newOrder.filter(id => !!RED.nodes.workspace(id))
if (JSON.stringify(filteredOldOrder) !== JSON.stringify(filteredNewOrder)) {
RED.nodes.dirty(true);
}
}
}
function setWorkspaceOrder(order) {
var newOrder = order.filter(function(id) {
return RED.nodes.workspace(id) !== undefined;
})
var newOrder = order.filter(id => !!RED.nodes.workspace(id))
var currentOrder = RED.nodes.getWorkspaceOrder();
if (JSON.stringify(newOrder) !== JSON.stringify(currentOrder)) {
RED.nodes.setWorkspaceOrder(newOrder);
RED.events.emit("flows:reorder",newOrder);
}
workspace_tabs.order(order);
return newOrder
}
function flashTab(tabId) {
@ -590,6 +835,11 @@ RED.workspaces = (function() {
active: function() {
return activeWorkspace
},
isLocked: function(id) {
id = id || activeWorkspace
var ws = RED.nodes.workspace(id) || RED.nodes.subflow(id)
return ws && ws.locked
},
selection: function() {
return workspace_tabs.selection();
},
@ -646,6 +896,8 @@ RED.workspaces = (function() {
workspace_tabs.resize();
},
enable: enableWorkspace,
disable: disableWorkspace
disable: disableWorkspace,
lock: lockWorkspace,
unlock: unlockWorkspace
}
})();

View File

@ -37,3 +37,27 @@
}
}
}
#red-ui-image-drop-target {
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
background: var(--red-ui-dnd-background);
display:table;
width: 100%;
height: 100%;
display: none;
z-index:100;
div {
pointer-events: none;
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 40px;
color: var(--red-ui-dnd-color);
i {
pointer-events: none;
font-size: 80px;
}
}
}

View File

@ -87,16 +87,18 @@
padding: 0px 8px;
height: 26px;
line-height: 26px;
&.toggle:not(.selected) {
&.toggle.selected {
color: var(--red-ui-workspace-button-color-selected) !important;
background: var(--red-ui-workspace-button-background-active);
background: var(--red-ui-workspace-button-background) !important;
}
}
.red-ui-tray-footer-left {
display:inline-block;
margin-right: 20px;
float:left;
& :not(:first-child) {
margin-left: 5px
}
}
.red-ui-tray-footer-right {
float: right;

View File

@ -68,6 +68,9 @@
stroke: var(--red-ui-node-border);
cursor: move;
stroke-width: 1;
.red-ui-workspace-locked & {
cursor: pointer;
}
}
.red-ui-workspace-select-mode {
g.red-ui-flow-node.red-ui-flow-node-hovered * {
@ -88,10 +91,13 @@
.red-ui-flow-group {
&.red-ui-flow-group-hovered {
.red-ui-flow-group-outline-select {
.red-ui-flow-group-outline-select-line {
stroke-opacity: 0.8 !important;
stroke-dasharray: 10 4 !important;
}
.red-ui-flow-group-outline-select-outline {
stroke-opacity: 0.8 !important;
}
}
&.red-ui-flow-group-active-hovered:not(.red-ui-flow-group-hovered) {
.red-ui-flow-group-outline-select {
@ -110,15 +116,35 @@
.red-ui-flow-group-outline-select {
fill: none;
stroke: var(--red-ui-node-selected-color);
pointer-events: stroke;
pointer-events: none;
stroke-opacity: 0;
stroke-width: 3;
stroke-width: 2;
&.red-ui-flow-group-outline-select-background {
&.red-ui-flow-group-outline-select-outline {
stroke: var(--red-ui-view-background);
stroke-width: 6;
stroke-width: 4;
}
&.red-ui-flow-group-outline-select-background {
fill: white;
fill-opacity: 0;
pointer-events: stroke;
stroke-width: 16;
}
}
svg:not(.red-ui-workspace-lasso-active) {
.red-ui-flow-group:not(.red-ui-flow-group-selected) {
.red-ui-flow-group-outline-select.red-ui-flow-group-outline-select-background:hover {
~ .red-ui-flow-group-outline-select {
stroke-opacity: 0.4 !important;
}
~ .red-ui-flow-group-outline-select-line {
stroke-dasharray: 10 4 !important;
}
}
}
}
.red-ui-flow-group-body {
pointer-events: none;
fill: var(--red-ui-group-default-fill);
@ -287,9 +313,11 @@ g.red-ui-flow-node-selected {
text-anchor:start;
}
.red-ui-flow-port-hovered {
stroke: var(--red-ui-port-selected-color);
fill: var(--red-ui-port-selected-color);
#red-ui-workspace:not(.red-ui-workspace-locked) {
.red-ui-flow-port-hovered {
stroke: var(--red-ui-port-selected-color);
fill: var(--red-ui-port-selected-color);
}
}
.red-ui-flow-subflow-port {

View File

@ -32,7 +32,8 @@
color: var(--red-ui-primary-text-color);
border: 1px solid var(--red-ui-notification-border-default);
border-left-width: 16px;
overflow: hidden;
overflow: auto;
max-height: 80vh;
.ui-dialog-buttonset {
margin-top: 20px;
margin-bottom: 10px;

View File

@ -41,6 +41,7 @@
height: 50px;
background: var(--red-ui-secondary-background);
border: 2px solid var(--red-ui-primary-border-color);
color: var(--red-ui-primary-text-color);
text-align: center;
line-height:50px;
@ -51,7 +52,7 @@
.red-ui-editor-radial-menu-opt-disabled {
border-color: var(--red-ui-tertiary-border-color);
color: var(--red-ui-tertiary-border-color);
color: var(--red-ui-secondary-text-color-disabled);
}
.red-ui-editor-radial-menu-opt-active {
background: var(--red-ui-secondary-background-hover);

View File

@ -467,6 +467,9 @@ div.red-ui-info-table {
.fa-eye {
display: none;
}
.fa-unlock-alt {
display: none;
}
}
.red-ui-info-outline-item-control-reveal,
.red-ui-info-outline-item-control-action {
@ -500,6 +503,25 @@ div.red-ui-info-table {
display: none;
}
}
.fa-lock {
display: none;
}
.red-ui-info-outline-item.red-ui-info-outline-item-locked & {
.fa-lock {
display: inline-block;
}
.fa-unlock-alt {
display: none;
}
}
// If the parent is locked, do not show the display/action buttons when
// hovering in the outline
.red-ui-info-outline-item-locked .red-ui-info-outline-item & {
.red-ui-info-outline-item-control-disable,
.red-ui-info-outline-item-control-action {
display: none;
}
}
button {
margin-right: 3px
}
@ -517,8 +539,6 @@ div.red-ui-info-table {
}
}
.red-ui-icons {
display: inline-block;
width: 18px;

View File

@ -105,7 +105,38 @@
}
}
}
.red-ui-tab:not(.red-ui-workspace-changed) .red-ui-flow-tab-changed {
display: none;
}
.red-ui-tab.red-ui-workspace-changed .red-ui-flow-tab-changed {
display: inline-block;
position: absolute;
top: 1px;
right: 1px;
}
.red-ui-workspace-locked-icon {
display: none;
}
.red-ui-workspace-locked {
&.red-ui-tab {
// border-top-style: dashed;
// border-left-style: dashed;
// border-right-style: dashed;
// a {
// font-style: italic;
// color: var(--red-ui-tab-text-color-disabled-inactive) !important;
// }
// &.active a {
// font-weight: normal;
// color: var(--red-ui-tab-text-color-disabled-active) !important;
// }
.red-ui-workspace-locked-icon {
display: inline;
}
}
}
#red-ui-navigator-canvas {
position: absolute;

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,155 @@
export default {
version: "3.0.0",
steps: [
{
titleIcon: "fa fa-map-o",
title: {
"en-US": "Welcome to Node-RED 3.0!",
"ja": "Node-RED 3.0へようこそ!"
},
description: {
"en-US": "<p>Let's take a moment to discover the new features in this release.</p>",
"ja": "<p>本リリースの新機能を見つけてみましょう。</p>"
}
},
{
title: {
"en-US": "Context Menu",
"ja": "コンテキストメニュー"
},
image: '3.0/images/context-menu.png',
description: {
"en-US": `<p>The editor now has its own context menu when you
right-click in the workspace.</p>
<p>This makes many of the built-in actions much easier
to access.</p>`,
"ja": `<p>ワークスペースで右クリックすると、エディタに独自のコンテキストメニューが表示されるようになりました。</p>
<p>これによって多くの組み込み動作をより簡単に利用できます</p>`
}
},
{
title: {
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
},
image: '3.0/images/junction-slice.gif',
description: {
"en-US": `<p>To make it easier to route wires around your flows,
it is now possible to add junction nodes that give
you more control.</p>
<p>Junctions can be added to wires by holding both the Alt key and the Shift key
then click and drag the mouse across the wires.</p>`,
"ja": `<p>フローのワイヤーの経路をより制御しやすくするために、分岐点ノードを追加できるようになりました。</p>
<p>Altキーとシフトキーを押しながらマウスをクリックしワイヤーを横切るようにドラッグすることで分岐点を追加できます</p>`
},
},
{
title: {
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
},
image: '3.0/images/junction-quick-add.png',
description: {
"en-US": `<p>Junctions can also be added using the quick-add dialog.</p>
<p>The dialog is opened by holding the Ctrl (or Cmd) key when
clicking in the workspace.</p>`,
"ja": `<p>クイック追加ダイアログを用いて、分岐点を追加することもできます。</p>
<p>本ダイアログを開くにはCtrl(またはCmd)キーを押しながらワークスペース上でクリックします</p>`
},
},
{
title: {
"en-US": "Debug Path Tooltip",
"ja": "デバッグパスのツールチップ"
},
image: '3.0/images/debug-path-tooltip.png',
description: {
"en-US": `<p>When hovering over a node name in the Debug sidebar, a
new tooltip shows the full location of the node.</p>
<p>This is useful when working with subflows, making it
much easier to identify exactly which node generated
the message.</p>
<p>Clicking on any item in the list will reveal it in
the workspace.</p>`,
"ja": `<p>デバックサイドバー内のノード名の上にマウスカーソルを乗せると、新たにツールチップが表示され、ノードの場所が分かるようになっています。</p>
<p>これはサブフローを用いる時に役立つ機能でありメッセージがどのノードから出力されたかを正確に特定することが遥かに簡単になります</p>
<p>本リスト内の要素をクリックするとワークスペース内にその要素が表示されます</p>`
},
},
{
title: {
"en-US": "Continuous Search",
"ja": "連続した検索"
},
image: '3.0/images/continuous-search.png',
description: {
"en-US": `<p>When searching for things in the editor, a new toolbar in
the workspace provides options to quickly jump between
the search results.</p>`,
"ja": `<p>ワークスペース内の新しいツールバーにあるオプションによって、エディタ内を検索する際に、検索結果の間を素早く移動できます。</p>`
},
},
{
title: {
"en-US": "New wiring actions",
"ja": "新しいワイヤー操作"
},
image: "3.0/images/split-wire-with-links.gif",
description: {
"en-US": `<p>A new action has been added that will replace a wire with a pair of connected Link nodes:</p>
<ul>
<li><b><code>Split Wire With Link Nodes</code></b></li>
</ul>
<p>Actions can be accessed from the Action List in the main menu.</p>`,
"ja": `<p>ワイヤーを、接続されたLinkードのペアに置き換える動作が新たに追加されました:</p>
<ul>
<li><b><code>ワイヤーをlinkードで分割</code></b></li>
</ul>
<p>本アクションはメインメニュー内の動作一覧から呼び出せます</p>`,
},
},
{
title: {
"en-US": "Default node names",
"ja": "標準ノードの名前"
},
// image: "images/",
description: {
"en-US": `<p>Some nodes have been updated to generate a unique name when
new instances are added to the workspace. This applies to
<code>Debug</code>, <code>Function</code> and <code>Link</code> nodes.</p>
<p>A new action has also been added to generate default names for the selected
nodes:</p>
<ul>
<li><b><code>Generate Node Names</code></b></li>
</ul><p>Actions can be accessed from the Action List in the main menu.</p>
`,
"ja": `<p>一部のノードは、ワークスペース上に新インスタンスとして追加した際に、一意の名前を付けるよう変更されました。この変更は、<code>Debug</code>、<code>Function</code>、<code>Link</code>ノードに適用されています。</p>
<p>選択したノードに対して標準の名前を生成する動作も新たに追加されました:</p>
<ul>
<li><b><code>ノード名を生成</code></b></li>
</ul><p></p>
`
}
},
{
title: {
"en-US": "Node Updates",
"ja": "ノードの更新"
},
// image: "images/",
description: {
"en-US": `<ul>
<li>The Debug node can be configured to count messages it receives</li>
<li>The Link Call node can use a message property to dynamically target the link it should call</li>
<li>The HTTP Request node can be preconfigured with HTTP headers</li>
</ul>`,
"ja": `<ul>
<li>Debugードは受信したメッセージの数をカウントするよう設定できるようになりました</li>
<li>Link Callードはメッセージのプロパティによって呼び出し対象のlinkを動的に指定できるようになりました</li>
<li>HTTP RequestードはHTTPヘッダを事前設定できるようになりました</li>
</ul>`
}
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

View File

@ -1,137 +1,105 @@
export default {
version: "3.0.0",
version: "3.1.0-beta.1",
steps: [
{
titleIcon: "fa fa-map-o",
title: {
"en-US": "Welcome to Node-RED 3.0!",
"ja": "Node-RED 3.0へようこそ!"
"en-US": "Welcome to Node-RED 3.1 Beta 1!",
"ja": "Node-RED 3.1 ベータ1へようこそ!"
},
description: {
"en-US": "<p>Let's take a moment to discover the new features in this release.</p>",
"ja": "<p>本リリースの新機能を見つけてみましょう。</p>"
"en-US": "<p>This is the first beta release for 3.1.0 and we have a few new features to tell you about.</p>",
"ja": "<p>これは3.1.0の最初のベータリリースです。いくつかの新機能について説明します。</p>"
}
},
{
title: {
"en-US": "Context Menu",
"ja": "コンテキストメニュー"
"en-US": "Improved Context Menu",
"ja": "コンテキストメニューの改善"
},
image: 'images/context-menu.png',
description: {
"en-US": `<p>The editor now has its own context menu when you
right-click in the workspace.</p>
<p>This makes many of the built-in actions much easier
to access.</p>`,
"ja": `<p>ワークスペースで右クリックすると、エディタに独自のコンテキストメニューが表示されるようになりました。</p>
<p>これによって多くの組み込み動作をより簡単に利用できます</p>`
"en-US": `<p>The editor's context menu has been expanded to make lots more of
the built-in actions available.</p>
<p>Adding nodes, working with groups and plenty
of other useful tools are now just a click away.</p>
<p>The flow tab bar also has its own context menu to make working
with your flows much easier.</p>`,
"ja": `<p>より多くの組み込み動作を利用できるように、エディタのコンテキストメニューが拡張されました。</p>
<p>ノードの追加グループの操作その他の便利なツールをクリックするだけで実行できるようになりました</p>
<p>フローのタブバーにはフローの操作をより簡単にする独自のコンテキストメニューもあります</p>`
}
},
{
title: {
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
"en-US": "Hiding Flows",
"ja": "フローを非表示"
},
image: 'images/junction-slice.gif',
image: 'images/hiding-flows.png',
description: {
"en-US": `<p>To make it easier to route wires around your flows,
it is now possible to add junction nodes that give
you more control.</p>
<p>Junctions can be added to wires by holding both the Alt key and the Shift key
then click and drag the mouse across the wires.</p>`,
"ja": `<p>フローのワイヤーの経路をより制御しやすくするために、分岐点ノードを追加できるようになりました。</p>
<p>Altキーとシフトキーを押しながらマウスをクリックしワイヤーを横切るようにドラッグすることで分岐点を追加できます</p>`
"en-US": `<p>Hiding flows is now done through the flow context menu.</p>
<p>The 'hide' button in previous releases has been removed from the tabs
as they were being clicked accidentally too often.</p>`,
"ja": `<p>フローを非表示にする機能は、フローのコンテキストメニューから実行するようになりました。</p>
<p>これまでのリリースでタブに存在していた非表示ボタンはよく誤ってクリックされていたため削除されました</p>`
},
},
{
title: {
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
"en-US": "Locking Flows",
"ja": "フローを固定"
},
image: 'images/junction-quick-add.png',
image: 'images/locking-flows.png',
description: {
"en-US": `<p>Junctions can also be added using the quick-add dialog.</p>
<p>The dialog is opened by holding the Ctrl (or Cmd) key when
clicking in the workspace.</p>`,
"ja": `<p>クイック追加ダイアログを用いて、分岐点を追加することもできます。</p>
<p>本ダイアログを開くにはCtrl(またはCmd)キーを押しながらワークスペース上でクリックします</p>`
"en-US": `<p>Flows can now be locked to prevent accidental changes being made.</p>
<p>When locked you cannot modify the nodes in any way.</p>
<p>The flow context menu provides the options to lock and unlock flows,
as well as in the Info sidebar explorer.</p>`,
"ja": `<p>誤ってフローに変更が加えられてしまうのを防ぐために、フローを固定できるようになりました。</p>
<p>固定されている時はノードを修正することはできません</p>
<p>フローのコンテキストメニューと情報サイドバーのエクスプローラにはフローの固定や解除をするためのオプションが用意されています</p>`
},
},
{
title: {
"en-US": "Debug Path Tooltip",
"ja": "デバッグパスのツールチップ"
"en-US": "Adding Images to node/flow descriptions",
"ja": "ノードやフローの説明へ画像を追加"
},
image: 'images/debug-path-tooltip.png',
// image: 'images/debug-path-tooltip.png',
description: {
"en-US": `<p>When hovering over a node name in the Debug sidebar, a
new tooltip shows the full location of the node.</p>
<p>This is useful when working with subflows, making it
much easier to identify exactly which node generated
the message.</p>
<p>Clicking on any item in the list will reveal it in
the workspace.</p>`,
"ja": `<p>デバックサイドバー内のノード名の上にマウスカーソルを乗せると、新たにツールチップが表示され、ノードの場所が分かるようになっています。</p>
<p>これはサブフローを用いる時に役立つ機能でありメッセージがどのノードから出力されたかを正確に特定することが遥かに簡単になります</p>
<p>本リスト内の要素をクリックするとワークスペース内にその要素が表示されます</p>`
"en-US": `<p>You can now add images to a node's or flows's description.</p>
<p>Simply drag the image into the text editor and it will get added inline.</p>
<p>When the description is shown in the Info sidebar, the image will be displayed.</p>`,
"ja": `<p>ノードまたはフローの説明に、画像を追加できるようになりました。</p>
<p>画像をテキストエディタにドラッグするだけで行内に埋め込まれます</p>
<p>情報サイドバーの説明を開くとその画像が表示されます</p>`
},
},
{
title: {
"en-US": "Continuous Search",
"ja": "連続した検索"
"en-US": "Adding Mermaid Diagrams",
"ja": "Mermaidの図を追加"
},
image: 'images/continuous-search.png',
image: 'images/mermaid.png',
description: {
"en-US": `<p>When searching for things in the editor, a new toolbar in
the workspace provides options to quickly jump between
the search results.</p>`,
"ja": `<p>ワークスペース内の新しいツールバーにあるオプションによって、エディタ内を検索する際に、検索結果の間を素早く移動できます。</p>`
"en-US": `<p>You can also add <a href="https://github.com/mermaid-js/mermaid">Mermaid</a> diagrams directly into your node or flow descriptions.</p>
<p>This gives you much richer options for documenting your flows.</p>`,
"ja": `<p>ノードやフローの説明に、<a href="https://github.com/mermaid-js/mermaid">Mermaid</a>の図を直接追加することもできます。</p>
<p>これによってフローを説明する文書作成の選択肢がより多くなります</p>`
},
},
{
title: {
"en-US": "New wiring actions",
"ja": "新しいワイヤー操作"
"en-US": "Managing Global Environment Variables",
"ja": "グローバル環境変数の管理"
},
image: "images/split-wire-with-links.gif",
image: 'images/global-env-vars.png',
description: {
"en-US": `<p>A new action has been added that will replace a wire with a pair of connected Link nodes:</p>
<ul>
<li><b><code>Split Wire With Link Nodes</code></b></li>
</ul>
<p>Actions can be accessed from the Action List in the main menu.</p>`,
"ja": `<p>ワイヤーを、接続されたLinkードのペアに置き換える動作が新たに追加されました:</p>
<ul>
<li><b><code>ワイヤーをlinkードで分割</code></b></li>
</ul>
<p>本アクションはメインメニュー内の動作一覧から呼び出せます</p>`,
"en-US": `<p>You can set environment variables that apply to all nodes and flows in the new
'Global Environment Variables' section of User Settings.</p>`,
"ja": `<p>ユーザ設定に新しく追加された「大域環境変数」のセクションで、全てのノードとフローに適用される環境変数を登録できます。</p>`
},
},
{
title: {
"en-US": "Default node names",
"ja": "標準ノードの名前"
},
// image: "images/",
description: {
"en-US": `<p>Some nodes have been updated to generate a unique name when
new instances are added to the workspace. This applies to
<code>Debug</code>, <code>Function</code> and <code>Link</code> nodes.</p>
<p>A new action has also been added to generate default names for the selected
nodes:</p>
<ul>
<li><b><code>Generate Node Names</code></b></li>
</ul><p>Actions can be accessed from the Action List in the main menu.</p>
`,
"ja": `<p>一部のノードは、ワークスペース上に新インスタンスとして追加した際に、一意の名前を付けるよう変更されました。この変更は、<code>Debug</code>、<code>Function</code>、<code>Link</code>ノードに適用されています。</p>
<p>選択したノードに対して標準の名前を生成する動作も新たに追加されました:</p>
<ul>
<li><b><code>ノード名を生成</code></b></li>
</ul><p></p>
`
}
},
{
title: {
"en-US": "Node Updates",
@ -139,16 +107,9 @@ export default {
},
// image: "images/",
description: {
"en-US": `<ul>
<li>The Debug node can be configured to count messages it receives</li>
<li>The Link Call node can use a message property to dynamically target the link it should call</li>
<li>The HTTP Request node can be preconfigured with HTTP headers</li>
</ul>`,
"ja": `<ul>
<li>Debugードは受信したメッセージの数をカウントするよう設定できるようになりました</li>
<li>Link Callードはメッセージのプロパティによって呼び出し対象のlinkを動的に指定できるようになりました</li>
<li>HTTP RequestードはHTTPヘッダを事前設定できるようになりました</li>
</ul>`
"en-US": `<p>The core nodes have received lots of minor fixes, documentation updates and
small enhancements. Check the full changelog in the Help sidebar for a full list.</p>`,
"ja": `<p>コアノードにマイナーな修正、ドキュメント更新、小規模な拡張が数多く追加されています。全ての一覧は、ヘルプサイドバーの全ての更新履歴を確認してください。</p>`
}
}
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
declare module 'assert/strict' {
import { strict } from 'node:assert';
export = strict;
}
declare module 'node:assert/strict' {
import { strict } from 'node:assert';
export = strict;
}

View File

@ -2,18 +2,49 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* Async Hooks module: https://nodejs.org/api/async_hooks.html
* The `async_hooks` module provides an API to track asynchronous resources. It
* can be accessed using:
*
* ```js
* import async_hooks from 'async_hooks';
* ```
* @experimental
* @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/async_hooks.js)
*/
declare module 'async_hooks' {
/**
* Returns the asyncId of the current execution context.
* ```js
* import { executionAsyncId } from 'async_hooks';
*
* console.log(executionAsyncId()); // 1 - bootstrap
* fs.open(path, 'r', (err, fd) => {
* console.log(executionAsyncId()); // 6 - open()
* });
* ```
*
* The ID returned from `executionAsyncId()` is related to execution timing, not
* causality (which is covered by `triggerAsyncId()`):
*
* ```js
* const server = net.createServer((conn) => {
* // Returns the ID of the server, not of the new connection, because the
* // callback runs in the execution scope of the server's MakeCallback().
* async_hooks.executionAsyncId();
*
* }).listen(port, () => {
* // Returns the ID of a TickObject (process.nextTick()) because all
* // callbacks passed to .listen() are wrapped in a nextTick().
* async_hooks.executionAsyncId();
* });
* ```
*
* Promise contexts may not get precise `executionAsyncIds` by default.
* See the section on `promise execution tracking`.
* @since v8.1.0
* @return The `asyncId` of the current execution context. Useful to track when something calls.
*/
function executionAsyncId(): number;
/**
* The resource representing the current execution.
* Useful to store data within the resource.
*
* Resource objects returned by `executionAsyncResource()` are most often internal
* Node.js handle objects with undocumented APIs. Using any functions or properties
* on the object is likely to crash your application and should be avoided.
@ -21,14 +52,70 @@ declare module 'async_hooks' {
* Using `executionAsyncResource()` in the top-level execution context will
* return an empty object as there is no handle or request object to use,
* but having an object representing the top-level can be helpful.
*
* ```js
* import { open } from 'fs';
* import { executionAsyncId, executionAsyncResource } from 'async_hooks';
*
* console.log(executionAsyncId(), executionAsyncResource()); // 1 {}
* open(new URL(import.meta.url), 'r', (err, fd) => {
* console.log(executionAsyncId(), executionAsyncResource()); // 7 FSReqWrap
* });
* ```
*
* This can be used to implement continuation local storage without the
* use of a tracking `Map` to store the metadata:
*
* ```js
* import { createServer } from 'http';
* import {
* executionAsyncId,
* executionAsyncResource,
* createHook
* } from 'async_hooks';
* const sym = Symbol('state'); // Private symbol to avoid pollution
*
* createHook({
* init(asyncId, type, triggerAsyncId, resource) {
* const cr = executionAsyncResource();
* if (cr) {
* resource[sym] = cr[sym];
* }
* }
* }).enable();
*
* const server = createServer((req, res) => {
* executionAsyncResource()[sym] = { state: req.url };
* setTimeout(function() {
* res.end(JSON.stringify(executionAsyncResource()[sym]));
* }, 100);
* }).listen(3000);
* ```
* @since v13.9.0, v12.17.0
* @return The resource representing the current execution. Useful to store data within the resource.
*/
function executionAsyncResource(): object;
/**
* Returns the ID of the resource responsible for calling the callback that is currently being executed.
* ```js
* const server = net.createServer((conn) => {
* // The resource that caused (or triggered) this callback to be called
* // was that of the new connection. Thus the return value of triggerAsyncId()
* // is the asyncId of "conn".
* async_hooks.triggerAsyncId();
*
* }).listen(port, () => {
* // Even though all callbacks passed to .listen() are wrapped in a nextTick()
* // the callback itself exists because the call to the server's .listen()
* // was made. So the return value would be the ID of the server.
* async_hooks.triggerAsyncId();
* });
* ```
*
* Promise contexts may not get valid `triggerAsyncId`s by default. See
* the section on `promise execution tracking`.
* @return The ID of the resource responsible for calling the callback that is currently being executed.
*/
function triggerAsyncId(): number;
interface HookCallbacks {
/**
* Called when a class is constructed that has the possibility to emit an asynchronous event.
@ -38,73 +125,133 @@ declare module 'async_hooks' {
* @param resource reference to the resource representing the async operation, needs to be released during destroy
*/
init?(asyncId: number, type: string, triggerAsyncId: number, resource: object): void;
/**
* When an asynchronous operation is initiated or completes a callback is called to notify the user.
* The before callback is called just before said callback is executed.
* @param asyncId the unique identifier assigned to the resource about to execute the callback.
*/
before?(asyncId: number): void;
/**
* Called immediately after the callback specified in before is completed.
* @param asyncId the unique identifier assigned to the resource which has executed the callback.
*/
after?(asyncId: number): void;
/**
* Called when a promise has resolve() called. This may not be in the same execution id
* as the promise itself.
* @param asyncId the unique id for the promise that was resolve()d.
*/
promiseResolve?(asyncId: number): void;
/**
* Called after the resource corresponding to asyncId is destroyed
* @param asyncId a unique ID for the async resource
*/
destroy?(asyncId: number): void;
}
interface AsyncHook {
/**
* Enable the callbacks for a given AsyncHook instance. If no callbacks are provided enabling is a noop.
*/
enable(): this;
/**
* Disable the callbacks for a given AsyncHook instance from the global pool of AsyncHook callbacks to be executed. Once a hook has been disabled it will not be called again until enabled.
*/
disable(): this;
}
/**
* Registers functions to be called for different lifetime events of each async operation.
* @param options the callbacks to register
* @return an AsyncHooks instance used for disabling and enabling hooks
* Registers functions to be called for different lifetime events of each async
* operation.
*
* The callbacks `init()`/`before()`/`after()`/`destroy()` are called for the
* respective asynchronous event during a resource's lifetime.
*
* All callbacks are optional. For example, if only resource cleanup needs to
* be tracked, then only the `destroy` callback needs to be passed. The
* specifics of all functions that can be passed to `callbacks` is in the `Hook Callbacks` section.
*
* ```js
* import { createHook } from 'async_hooks';
*
* const asyncHook = createHook({
* init(asyncId, type, triggerAsyncId, resource) { },
* destroy(asyncId) { }
* });
* ```
*
* The callbacks will be inherited via the prototype chain:
*
* ```js
* class MyAsyncCallbacks {
* init(asyncId, type, triggerAsyncId, resource) { }
* destroy(asyncId) {}
* }
*
* class MyAddedCallbacks extends MyAsyncCallbacks {
* before(asyncId) { }
* after(asyncId) { }
* }
*
* const asyncHook = async_hooks.createHook(new MyAddedCallbacks());
* ```
*
* Because promises are asynchronous resources whose lifecycle is tracked
* via the async hooks mechanism, the `init()`, `before()`, `after()`, and`destroy()` callbacks _must not_ be async functions that return promises.
* @since v8.1.0
* @param callbacks The `Hook Callbacks` to register
* @return Instance used for disabling and enabling hooks
*/
function createHook(options: HookCallbacks): AsyncHook;
function createHook(callbacks: HookCallbacks): AsyncHook;
interface AsyncResourceOptions {
/**
* The ID of the execution context that created this async event.
* @default executionAsyncId()
*/
triggerAsyncId?: number | undefined;
/**
* Disables automatic `emitDestroy` when the object is garbage collected.
* This usually does not need to be set (even if `emitDestroy` is called
* manually), unless the resource's `asyncId` is retrieved and the
* sensitive API's `emitDestroy` is called with it.
* @default false
*/
requireManualDestroy?: boolean | undefined;
/**
* The ID of the execution context that created this async event.
* @default executionAsyncId()
*/
triggerAsyncId?: number | undefined;
/**
* Disables automatic `emitDestroy` when the object is garbage collected.
* This usually does not need to be set (even if `emitDestroy` is called
* manually), unless the resource's `asyncId` is retrieved and the
* sensitive API's `emitDestroy` is called with it.
* @default false
*/
requireManualDestroy?: boolean | undefined;
}
/**
* The class AsyncResource was designed to be extended by the embedder's async resources.
* Using this users can easily trigger the lifetime events of their own resources.
* The class `AsyncResource` is designed to be extended by the embedder's async
* resources. Using this, users can easily trigger the lifetime events of their
* own resources.
*
* The `init` hook will trigger when an `AsyncResource` is instantiated.
*
* The following is an overview of the `AsyncResource` API.
*
* ```js
* import { AsyncResource, executionAsyncId } from 'async_hooks';
*
* // AsyncResource() is meant to be extended. Instantiating a
* // new AsyncResource() also triggers init. If triggerAsyncId is omitted then
* // async_hook.executionAsyncId() is used.
* const asyncResource = new AsyncResource(
* type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false }
* );
*
* // Run a function in the execution context of the resource. This will
* // * establish the context of the resource
* // * trigger the AsyncHooks before callbacks
* // * call the provided function `fn` with the supplied arguments
* // * trigger the AsyncHooks after callbacks
* // * restore the original execution context
* asyncResource.runInAsyncScope(fn, thisArg, ...args);
*
* // Call AsyncHooks destroy callbacks.
* asyncResource.emitDestroy();
*
* // Return the unique ID assigned to the AsyncResource instance.
* asyncResource.asyncId();
*
* // Return the trigger ID for the AsyncResource instance.
* asyncResource.triggerAsyncId();
* ```
*/
class AsyncResource {
/**
@ -114,115 +261,236 @@ declare module 'async_hooks' {
* @param type The type of async event.
* @param triggerAsyncId The ID of the execution context that created
* this async event (default: `executionAsyncId()`), or an
* AsyncResourceOptions object (since 9.3)
* AsyncResourceOptions object (since v9.3.0)
*/
constructor(type: string, triggerAsyncId?: number|AsyncResourceOptions);
constructor(type: string, triggerAsyncId?: number | AsyncResourceOptions);
/**
* Binds the given function to the current execution context.
*
* The returned function will have an `asyncResource` property referencing
* the `AsyncResource` to which the function is bound.
* @since v14.8.0, v12.19.0
* @param fn The function to bind to the current execution context.
* @param type An optional name to associate with the underlying `AsyncResource`.
*/
static bind<Func extends (...args: any[]) => any>(fn: Func, type?: string): Func & { asyncResource: AsyncResource };
static bind<Func extends (this: ThisArg, ...args: any[]) => any, ThisArg>(
fn: Func,
type?: string,
thisArg?: ThisArg
): Func & {
asyncResource: AsyncResource;
};
/**
* Binds the given function to execute to this `AsyncResource`'s scope.
*
* The returned function will have an `asyncResource` property referencing
* the `AsyncResource` to which the function is bound.
* @since v14.8.0, v12.19.0
* @param fn The function to bind to the current `AsyncResource`.
*/
bind<Func extends (...args: any[]) => any>(fn: Func): Func & { asyncResource: AsyncResource };
bind<Func extends (...args: any[]) => any>(
fn: Func
): Func & {
asyncResource: AsyncResource;
};
/**
* Call the provided function with the provided arguments in the
* execution context of the async resource. This will establish the
* context, trigger the AsyncHooks before callbacks, call the function,
* trigger the AsyncHooks after callbacks, and then restore the original
* execution context.
* @param fn The function to call in the execution context of this
* async resource.
* Call the provided function with the provided arguments in the execution context
* of the async resource. This will establish the context, trigger the AsyncHooks
* before callbacks, call the function, trigger the AsyncHooks after callbacks, and
* then restore the original execution context.
* @since v9.6.0
* @param fn The function to call in the execution context of this async resource.
* @param thisArg The receiver to be used for the function call.
* @param args Optional arguments to pass to the function.
*/
runInAsyncScope<This, Result>(fn: (this: This, ...args: any[]) => Result, thisArg?: This, ...args: any[]): Result;
/**
* Call AsyncHooks destroy callbacks.
* Call all `destroy` hooks. This should only ever be called once. An error will
* be thrown if it is called more than once. This **must** be manually called. If
* the resource is left to be collected by the GC then the `destroy` hooks will
* never be called.
* @return A reference to `asyncResource`.
*/
emitDestroy(): this;
/**
* @return the unique ID assigned to this AsyncResource instance.
* @return The unique `asyncId` assigned to the resource.
*/
asyncId(): number;
/**
* @return the trigger ID for this AsyncResource instance.
*
* @return The same `triggerAsyncId` that is passed to the `AsyncResource` constructor.
*/
triggerAsyncId(): number;
}
/**
* When having multiple instances of `AsyncLocalStorage`, they are independent
* from each other. It is safe to instantiate this class multiple times.
* This class creates stores that stay coherent through asynchronous operations.
*
* While you can create your own implementation on top of the `async_hooks` module,`AsyncLocalStorage` should be preferred as it is a performant and memory safe
* implementation that involves significant optimizations that are non-obvious to
* implement.
*
* The following example uses `AsyncLocalStorage` to build a simple logger
* that assigns IDs to incoming HTTP requests and includes them in messages
* logged within each request.
*
* ```js
* import http from 'http';
* import { AsyncLocalStorage } from 'async_hooks';
*
* const asyncLocalStorage = new AsyncLocalStorage();
*
* function logWithId(msg) {
* const id = asyncLocalStorage.getStore();
* console.log(`${id !== undefined ? id : '-'}:`, msg);
* }
*
* let idSeq = 0;
* http.createServer((req, res) => {
* asyncLocalStorage.run(idSeq++, () => {
* logWithId('start');
* // Imagine any chain of async operations here
* setImmediate(() => {
* logWithId('finish');
* res.end();
* });
* });
* }).listen(8080);
*
* http.get('http://localhost:8080');
* http.get('http://localhost:8080');
* // Prints:
* // 0: start
* // 1: start
* // 0: finish
* // 1: finish
* ```
*
* Each instance of `AsyncLocalStorage` maintains an independent storage context.
* Multiple instances can safely exist simultaneously without risk of interfering
* with each other data.
* @since v13.10.0, v12.17.0
*/
class AsyncLocalStorage<T> {
/**
* This method disables the instance of `AsyncLocalStorage`. All subsequent calls
* to `asyncLocalStorage.getStore()` will return `undefined` until
* `asyncLocalStorage.run()` is called again.
* Disables the instance of `AsyncLocalStorage`. All subsequent calls
* to `asyncLocalStorage.getStore()` will return `undefined` until`asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()` is called again.
*
* When calling `asyncLocalStorage.disable()`, all current contexts linked to the
* instance will be exited.
*
* Calling `asyncLocalStorage.disable()` is required before the
* `asyncLocalStorage` can be garbage collected. This does not apply to stores
* Calling `asyncLocalStorage.disable()` is required before the`asyncLocalStorage` can be garbage collected. This does not apply to stores
* provided by the `asyncLocalStorage`, as those objects are garbage collected
* along with the corresponding async resources.
*
* This method is to be used when the `asyncLocalStorage` is not in use anymore
* Use this method when the `asyncLocalStorage` is not in use anymore
* in the current process.
* @since v13.10.0, v12.17.0
* @experimental
*/
disable(): void;
/**
* This method returns the current store. If this method is called outside of an
* asynchronous context initialized by calling `asyncLocalStorage.run`, it will
* return `undefined`.
* Returns the current store.
* If called outside of an asynchronous context initialized by
* calling `asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()`, it
* returns `undefined`.
* @since v13.10.0, v12.17.0
*/
getStore(): T | undefined;
/**
* This methods runs a function synchronously within a context and return its
* Runs a function synchronously within a context and returns its
* return value. The store is not accessible outside of the callback function or
* the asynchronous operations created within the callback.
*
* Optionally, arguments can be passed to the function. They will be passed to the
* callback function.
* The optional `args` are passed to the callback function.
*
* I the callback function throws an error, it will be thrown by `run` too. The
* stacktrace will not be impacted by this call and the context will be exited.
* If the callback function throws an error, the error is thrown by `run()` too.
* The stacktrace is not impacted by this call and the context is exited.
*
* Example:
*
* ```js
* const store = { id: 2 };
* try {
* asyncLocalStorage.run(store, () => {
* asyncLocalStorage.getStore(); // Returns the store object
* throw new Error();
* });
* } catch (e) {
* asyncLocalStorage.getStore(); // Returns undefined
* // The error will be caught here
* }
* ```
* @since v13.10.0, v12.17.0
*/
// TODO: Apply generic vararg once available
run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R;
run<R, TArgs extends any[]>(store: T, callback: (...args: TArgs) => R, ...args: TArgs): R;
/**
* This methods runs a function synchronously outside of a context and return its
* return value. The store is not accessible within the callback function or the
* asynchronous operations created within the callback.
* Runs a function synchronously outside of a context and returns its
* return value. The store is not accessible within the callback function or
* the asynchronous operations created within the callback. Any `getStore()`call done within the callback function will always return `undefined`.
*
* Optionally, arguments can be passed to the function. They will be passed to the
* callback function.
* The optional `args` are passed to the callback function.
*
* If the callback function throws an error, it will be thrown by `exit` too. The
* stacktrace will not be impacted by this call and the context will be
* re-entered.
* If the callback function throws an error, the error is thrown by `exit()` too.
* The stacktrace is not impacted by this call and the context is re-entered.
*
* Example:
*
* ```js
* // Within a call to run
* try {
* asyncLocalStorage.getStore(); // Returns the store object or value
* asyncLocalStorage.exit(() => {
* asyncLocalStorage.getStore(); // Returns undefined
* throw new Error();
* });
* } catch (e) {
* asyncLocalStorage.getStore(); // Returns the same object or value
* // The error will be caught here
* }
* ```
* @since v13.10.0, v12.17.0
* @experimental
*/
// TODO: Apply generic vararg once available
exit<R>(callback: (...args: any[]) => R, ...args: any[]): R;
exit<R, TArgs extends any[]>(callback: (...args: TArgs) => R, ...args: TArgs): R;
/**
* Calling `asyncLocalStorage.enterWith(store)` will transition into the context
* for the remainder of the current synchronous execution and will persist
* through any following asynchronous calls.
* Transitions into the context for the remainder of the current
* synchronous execution and then persists the store through any following
* asynchronous calls.
*
* Example:
*
* ```js
* const store = { id: 1 };
* // Replaces previous store with the given store object
* asyncLocalStorage.enterWith(store);
* asyncLocalStorage.getStore(); // Returns the store object
* someAsyncOperation(() => {
* asyncLocalStorage.getStore(); // Returns the same object
* });
* ```
*
* This transition will continue for the _entire_ synchronous execution.
* This means that if, for example, the context is entered within an event
* handler subsequent event handlers will also run within that context unless
* specifically bound to another context with an `AsyncResource`. That is why`run()` should be preferred over `enterWith()` unless there are strong reasons
* to use the latter method.
*
* ```js
* const store = { id: 1 };
*
* emitter.on('my-event', () => {
* asyncLocalStorage.enterWith(store);
* });
* emitter.on('my-event', () => {
* asyncLocalStorage.getStore(); // Returns the same object
* });
*
* asyncLocalStorage.getStore(); // Returns undefined
* emitter.emit('my-event');
* asyncLocalStorage.getStore(); // Returns the same object
* ```
* @since v13.11.0, v12.17.0
* @experimental
*/
enterWith(store: T): void;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,64 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* A single instance of Node.js runs in a single thread. To take advantage of
* multi-core systems, the user will sometimes want to launch a cluster of Node.js
* processes to handle the load.
*
* The cluster module allows easy creation of child processes that all share
* server ports.
*
* ```js
* import cluster from 'cluster';
* import http from 'http';
* import { cpus } from 'os';
* import process from 'process';
*
* const numCPUs = cpus().length;
*
* if (cluster.isPrimary) {
* console.log(`Primary ${process.pid} is running`);
*
* // Fork workers.
* for (let i = 0; i < numCPUs; i++) {
* cluster.fork();
* }
*
* cluster.on('exit', (worker, code, signal) => {
* console.log(`worker ${worker.process.pid} died`);
* });
* } else {
* // Workers can share any TCP connection
* // In this case it is an HTTP server
* http.createServer((req, res) => {
* res.writeHead(200);
* res.end('hello world\n');
* }).listen(8000);
*
* console.log(`Worker ${process.pid} started`);
* }
* ```
*
* Running Node.js will now share port 8000 between the workers:
*
* ```console
* $ node server.js
* Primary 3596 is running
* Worker 4324 started
* Worker 4520 started
* Worker 6056 started
* Worker 5644 started
* ```
*
* On Windows, it is not yet possible to set up a named pipe server in a worker.
* @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/cluster.js)
*/
declare module 'cluster' {
import * as child from 'child_process';
import EventEmitter = require('events');
import * as net from 'net';
// interfaces
interface ClusterSettings {
import * as child from 'node:child_process';
import EventEmitter = require('node:events');
import * as net from 'node:net';
export interface ClusterSettings {
execArgv?: string[] | undefined; // default: process.execArgv
exec?: string | undefined;
args?: string[] | undefined;
@ -17,24 +68,214 @@ declare module 'cluster' {
gid?: number | undefined;
inspectPort?: number | (() => number) | undefined;
}
interface Address {
export interface Address {
address: string;
port: number;
addressType: number | "udp4" | "udp6"; // 4, 6, -1, "udp4", "udp6"
addressType: number | 'udp4' | 'udp6'; // 4, 6, -1, "udp4", "udp6"
}
class Worker extends EventEmitter {
/**
* A `Worker` object contains all public information and method about a worker.
* In the primary it can be obtained using `cluster.workers`. In a worker
* it can be obtained using `cluster.worker`.
* @since v0.7.0
*/
export class Worker extends EventEmitter {
/**
* Each new worker is given its own unique id, this id is stored in the`id`.
*
* While a worker is alive, this is the key that indexes it in`cluster.workers`.
* @since v0.8.0
*/
id: number;
/**
* All workers are created using `child_process.fork()`, the returned object
* from this function is stored as `.process`. In a worker, the global `process`is stored.
*
* See: `Child Process module`.
*
* Workers will call `process.exit(0)` if the `'disconnect'` event occurs
* on `process` and `.exitedAfterDisconnect` is not `true`. This protects against
* accidental disconnection.
* @since v0.7.0
*/
process: child.ChildProcess;
send(message: child.Serializable, sendHandle?: child.SendHandle, callback?: (error: Error | null) => void): boolean;
/**
* Send a message to a worker or primary, optionally with a handle.
*
* In the primary this sends a message to a specific worker. It is identical to `ChildProcess.send()`.
*
* In a worker this sends a message to the primary. It is identical to`process.send()`.
*
* This example will echo back all messages from the primary:
*
* ```js
* if (cluster.isPrimary) {
* const worker = cluster.fork();
* worker.send('hi there');
*
* } else if (cluster.isWorker) {
* process.on('message', (msg) => {
* process.send(msg);
* });
* }
* ```
* @since v0.7.0
* @param options The `options` argument, if present, is an object used to parameterize the sending of certain types of handles. `options` supports the following properties:
*/
send(message: child.Serializable, callback?: (error: Error | null) => void): boolean;
send(message: child.Serializable, sendHandle: child.SendHandle, callback?: (error: Error | null) => void): boolean;
send(message: child.Serializable, sendHandle: child.SendHandle, options?: child.MessageOptions, callback?: (error: Error | null) => void): boolean;
/**
* This function will kill the worker. In the primary, it does this
* by disconnecting the `worker.process`, and once disconnected, killing
* with `signal`. In the worker, it does it by disconnecting the channel,
* and then exiting with code `0`.
*
* Because `kill()` attempts to gracefully disconnect the worker process, it is
* susceptible to waiting indefinitely for the disconnect to complete. For example,
* if the worker enters an infinite loop, a graceful disconnect will never occur.
* If the graceful disconnect behavior is not needed, use `worker.process.kill()`.
*
* Causes `.exitedAfterDisconnect` to be set.
*
* This method is aliased as `worker.destroy()` for backward compatibility.
*
* In a worker, `process.kill()` exists, but it is not this function;
* it is `kill()`.
* @since v0.9.12
* @param [signal='SIGTERM'] Name of the kill signal to send to the worker process.
*/
kill(signal?: string): void;
destroy(signal?: string): void;
/**
* In a worker, this function will close all servers, wait for the `'close'` event
* on those servers, and then disconnect the IPC channel.
*
* In the primary, an internal message is sent to the worker causing it to call`.disconnect()` on itself.
*
* Causes `.exitedAfterDisconnect` to be set.
*
* After a server is closed, it will no longer accept new connections,
* but connections may be accepted by any other listening worker. Existing
* connections will be allowed to close as usual. When no more connections exist,
* see `server.close()`, the IPC channel to the worker will close allowing it
* to die gracefully.
*
* The above applies _only_ to server connections, client connections are not
* automatically closed by workers, and disconnect does not wait for them to close
* before exiting.
*
* In a worker, `process.disconnect` exists, but it is not this function;
* it is `disconnect()`.
*
* Because long living server connections may block workers from disconnecting, it
* may be useful to send a message, so application specific actions may be taken to
* close them. It also may be useful to implement a timeout, killing a worker if
* the `'disconnect'` event has not been emitted after some time.
*
* ```js
* if (cluster.isPrimary) {
* const worker = cluster.fork();
* let timeout;
*
* worker.on('listening', (address) => {
* worker.send('shutdown');
* worker.disconnect();
* timeout = setTimeout(() => {
* worker.kill();
* }, 2000);
* });
*
* worker.on('disconnect', () => {
* clearTimeout(timeout);
* });
*
* } else if (cluster.isWorker) {
* const net = require('net');
* const server = net.createServer((socket) => {
* // Connections never end
* });
*
* server.listen(8000);
*
* process.on('message', (msg) => {
* if (msg === 'shutdown') {
* // Initiate graceful close of any connections to server
* }
* });
* }
* ```
* @since v0.7.7
* @return A reference to `worker`.
*/
disconnect(): void;
/**
* This function returns `true` if the worker is connected to its primary via its
* IPC channel, `false` otherwise. A worker is connected to its primary after it
* has been created. It is disconnected after the `'disconnect'` event is emitted.
* @since v0.11.14
*/
isConnected(): boolean;
/**
* This function returns `true` if the worker's process has terminated (either
* because of exiting or being signaled). Otherwise, it returns `false`.
*
* ```js
* import cluster from 'cluster';
* import http from 'http';
* import { cpus } from 'os';
* import process from 'process';
*
* const numCPUs = cpus().length;
*
* if (cluster.isPrimary) {
* console.log(`Primary ${process.pid} is running`);
*
* // Fork workers.
* for (let i = 0; i < numCPUs; i++) {
* cluster.fork();
* }
*
* cluster.on('fork', (worker) => {
* console.log('worker is dead:', worker.isDead());
* });
*
* cluster.on('exit', (worker, code, signal) => {
* console.log('worker is dead:', worker.isDead());
* });
* } else {
* // Workers can share any TCP connection. In this case, it is an HTTP server.
* http.createServer((req, res) => {
* res.writeHead(200);
* res.end(`Current process\n ${process.pid}`);
* process.kill(process.pid);
* }).listen(8000);
* }
* ```
* @since v0.11.14
*/
isDead(): boolean;
/**
* This property is `true` if the worker exited due to `.kill()` or`.disconnect()`. If the worker exited any other way, it is `false`. If the
* worker has not exited, it is `undefined`.
*
* The boolean `worker.exitedAfterDisconnect` allows distinguishing between
* voluntary and accidental exit, the primary may choose not to respawn a worker
* based on this value.
*
* ```js
* cluster.on('exit', (worker, code, signal) => {
* if (worker.exitedAfterDisconnect === true) {
* console.log('Oh, it was just voluntary no need to worry');
* }
* });
*
* // kill worker
* worker.kill();
* ```
* @since v6.0.0
*/
exitedAfterDisconnect: boolean;
/**
* events.EventEmitter
* 1. disconnect
@ -45,69 +286,67 @@ declare module 'cluster' {
* 6. online
*/
addListener(event: string, listener: (...args: any[]) => void): this;
addListener(event: "disconnect", listener: () => void): this;
addListener(event: "error", listener: (error: Error) => void): this;
addListener(event: "exit", listener: (code: number, signal: string) => void): this;
addListener(event: "listening", listener: (address: Address) => void): this;
addListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
addListener(event: "online", listener: () => void): this;
addListener(event: 'disconnect', listener: () => void): this;
addListener(event: 'error', listener: (error: Error) => void): this;
addListener(event: 'exit', listener: (code: number, signal: string) => void): this;
addListener(event: 'listening', listener: (address: Address) => void): this;
addListener(event: 'message', listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
addListener(event: 'online', listener: () => void): this;
emit(event: string | symbol, ...args: any[]): boolean;
emit(event: "disconnect"): boolean;
emit(event: "error", error: Error): boolean;
emit(event: "exit", code: number, signal: string): boolean;
emit(event: "listening", address: Address): boolean;
emit(event: "message", message: any, handle: net.Socket | net.Server): boolean;
emit(event: "online"): boolean;
emit(event: 'disconnect'): boolean;
emit(event: 'error', error: Error): boolean;
emit(event: 'exit', code: number, signal: string): boolean;
emit(event: 'listening', address: Address): boolean;
emit(event: 'message', message: any, handle: net.Socket | net.Server): boolean;
emit(event: 'online'): boolean;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "disconnect", listener: () => void): this;
on(event: "error", listener: (error: Error) => void): this;
on(event: "exit", listener: (code: number, signal: string) => void): this;
on(event: "listening", listener: (address: Address) => void): this;
on(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
on(event: "online", listener: () => void): this;
on(event: 'disconnect', listener: () => void): this;
on(event: 'error', listener: (error: Error) => void): this;
on(event: 'exit', listener: (code: number, signal: string) => void): this;
on(event: 'listening', listener: (address: Address) => void): this;
on(event: 'message', listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
on(event: 'online', listener: () => void): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "disconnect", listener: () => void): this;
once(event: "error", listener: (error: Error) => void): this;
once(event: "exit", listener: (code: number, signal: string) => void): this;
once(event: "listening", listener: (address: Address) => void): this;
once(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
once(event: "online", listener: () => void): this;
once(event: 'disconnect', listener: () => void): this;
once(event: 'error', listener: (error: Error) => void): this;
once(event: 'exit', listener: (code: number, signal: string) => void): this;
once(event: 'listening', listener: (address: Address) => void): this;
once(event: 'message', listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
once(event: 'online', listener: () => void): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "disconnect", listener: () => void): this;
prependListener(event: "error", listener: (error: Error) => void): this;
prependListener(event: "exit", listener: (code: number, signal: string) => void): this;
prependListener(event: "listening", listener: (address: Address) => void): this;
prependListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
prependListener(event: "online", listener: () => void): this;
prependListener(event: 'disconnect', listener: () => void): this;
prependListener(event: 'error', listener: (error: Error) => void): this;
prependListener(event: 'exit', listener: (code: number, signal: string) => void): this;
prependListener(event: 'listening', listener: (address: Address) => void): this;
prependListener(event: 'message', listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
prependListener(event: 'online', listener: () => void): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "disconnect", listener: () => void): this;
prependOnceListener(event: "error", listener: (error: Error) => void): this;
prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this;
prependOnceListener(event: "listening", listener: (address: Address) => void): this;
prependOnceListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
prependOnceListener(event: "online", listener: () => void): this;
prependOnceListener(event: 'disconnect', listener: () => void): this;
prependOnceListener(event: 'error', listener: (error: Error) => void): this;
prependOnceListener(event: 'exit', listener: (code: number, signal: string) => void): this;
prependOnceListener(event: 'listening', listener: (address: Address) => void): this;
prependOnceListener(event: 'message', listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
prependOnceListener(event: 'online', listener: () => void): this;
}
interface Cluster extends EventEmitter {
Worker: Worker;
export interface Cluster extends EventEmitter {
disconnect(callback?: () => void): void;
fork(env?: any): Worker;
isMaster: boolean;
isWorker: boolean;
/** @deprecated since v16.0.0 - use isPrimary. */
readonly isMaster: boolean;
readonly isPrimary: boolean;
readonly isWorker: boolean;
schedulingPolicy: number;
settings: ClusterSettings;
readonly settings: ClusterSettings;
/** @deprecated since v16.0.0 - use setupPrimary. */
setupMaster(settings?: ClusterSettings): void;
worker?: Worker | undefined;
workers?: NodeJS.Dict<Worker> | undefined;
/**
* `setupPrimary` is used to change the default 'fork' behavior. Once called, the settings will be present in cluster.settings.
*/
setupPrimary(settings?: ClusterSettings): void;
readonly worker?: Worker | undefined;
readonly workers?: NodeJS.Dict<Worker> | undefined;
readonly SCHED_NONE: number;
readonly SCHED_RR: number;
/**
* events.EventEmitter
* 1. disconnect
@ -119,150 +358,60 @@ declare module 'cluster' {
* 7. setup
*/
addListener(event: string, listener: (...args: any[]) => void): this;
addListener(event: "disconnect", listener: (worker: Worker) => void): this;
addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
addListener(event: "fork", listener: (worker: Worker) => void): this;
addListener(event: "listening", listener: (worker: Worker, address: Address) => void): this;
addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
addListener(event: "online", listener: (worker: Worker) => void): this;
addListener(event: "setup", listener: (settings: ClusterSettings) => void): this;
addListener(event: 'disconnect', listener: (worker: Worker) => void): this;
addListener(event: 'exit', listener: (worker: Worker, code: number, signal: string) => void): this;
addListener(event: 'fork', listener: (worker: Worker) => void): this;
addListener(event: 'listening', listener: (worker: Worker, address: Address) => void): this;
addListener(event: 'message', listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
addListener(event: 'online', listener: (worker: Worker) => void): this;
addListener(event: 'setup', listener: (settings: ClusterSettings) => void): this;
emit(event: string | symbol, ...args: any[]): boolean;
emit(event: "disconnect", worker: Worker): boolean;
emit(event: "exit", worker: Worker, code: number, signal: string): boolean;
emit(event: "fork", worker: Worker): boolean;
emit(event: "listening", worker: Worker, address: Address): boolean;
emit(event: "message", worker: Worker, message: any, handle: net.Socket | net.Server): boolean;
emit(event: "online", worker: Worker): boolean;
emit(event: "setup", settings: ClusterSettings): boolean;
emit(event: 'disconnect', worker: Worker): boolean;
emit(event: 'exit', worker: Worker, code: number, signal: string): boolean;
emit(event: 'fork', worker: Worker): boolean;
emit(event: 'listening', worker: Worker, address: Address): boolean;
emit(event: 'message', worker: Worker, message: any, handle: net.Socket | net.Server): boolean;
emit(event: 'online', worker: Worker): boolean;
emit(event: 'setup', settings: ClusterSettings): boolean;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "disconnect", listener: (worker: Worker) => void): this;
on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
on(event: "fork", listener: (worker: Worker) => void): this;
on(event: "listening", listener: (worker: Worker, address: Address) => void): this;
on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
on(event: "online", listener: (worker: Worker) => void): this;
on(event: "setup", listener: (settings: ClusterSettings) => void): this;
on(event: 'disconnect', listener: (worker: Worker) => void): this;
on(event: 'exit', listener: (worker: Worker, code: number, signal: string) => void): this;
on(event: 'fork', listener: (worker: Worker) => void): this;
on(event: 'listening', listener: (worker: Worker, address: Address) => void): this;
on(event: 'message', listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
on(event: 'online', listener: (worker: Worker) => void): this;
on(event: 'setup', listener: (settings: ClusterSettings) => void): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "disconnect", listener: (worker: Worker) => void): this;
once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
once(event: "fork", listener: (worker: Worker) => void): this;
once(event: "listening", listener: (worker: Worker, address: Address) => void): this;
once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
once(event: "online", listener: (worker: Worker) => void): this;
once(event: "setup", listener: (settings: ClusterSettings) => void): this;
once(event: 'disconnect', listener: (worker: Worker) => void): this;
once(event: 'exit', listener: (worker: Worker, code: number, signal: string) => void): this;
once(event: 'fork', listener: (worker: Worker) => void): this;
once(event: 'listening', listener: (worker: Worker, address: Address) => void): this;
once(event: 'message', listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
once(event: 'online', listener: (worker: Worker) => void): this;
once(event: 'setup', listener: (settings: ClusterSettings) => void): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "disconnect", listener: (worker: Worker) => void): this;
prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
prependListener(event: "fork", listener: (worker: Worker) => void): this;
prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): this;
prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
prependListener(event: "online", listener: (worker: Worker) => void): this;
prependListener(event: "setup", listener: (settings: ClusterSettings) => void): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): this;
prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
prependOnceListener(event: "fork", listener: (worker: Worker) => void): this;
prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): this;
prependListener(event: 'disconnect', listener: (worker: Worker) => void): this;
prependListener(event: 'exit', listener: (worker: Worker, code: number, signal: string) => void): this;
prependListener(event: 'fork', listener: (worker: Worker) => void): this;
prependListener(event: 'listening', listener: (worker: Worker, address: Address) => void): this;
// the handle is a net.Socket or net.Server object, or undefined.
prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this;
prependOnceListener(event: "online", listener: (worker: Worker) => void): this;
prependOnceListener(event: "setup", listener: (settings: ClusterSettings) => void): this;
prependListener(event: 'message', listener: (worker: Worker, message: any, handle?: net.Socket | net.Server) => void): this;
prependListener(event: 'online', listener: (worker: Worker) => void): this;
prependListener(event: 'setup', listener: (settings: ClusterSettings) => void): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: 'disconnect', listener: (worker: Worker) => void): this;
prependOnceListener(event: 'exit', listener: (worker: Worker, code: number, signal: string) => void): this;
prependOnceListener(event: 'fork', listener: (worker: Worker) => void): this;
prependOnceListener(event: 'listening', listener: (worker: Worker, address: Address) => void): this;
// the handle is a net.Socket or net.Server object, or undefined.
prependOnceListener(event: 'message', listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this;
prependOnceListener(event: 'online', listener: (worker: Worker) => void): this;
prependOnceListener(event: 'setup', listener: (settings: ClusterSettings) => void): this;
}
const SCHED_NONE: number;
const SCHED_RR: number;
function disconnect(callback?: () => void): void;
function fork(env?: any): Worker;
const isMaster: boolean;
const isWorker: boolean;
let schedulingPolicy: number;
const settings: ClusterSettings;
function setupMaster(settings?: ClusterSettings): void;
const worker: Worker;
const workers: NodeJS.Dict<Worker>;
/**
* events.EventEmitter
* 1. disconnect
* 2. exit
* 3. fork
* 4. listening
* 5. message
* 6. online
* 7. setup
*/
function addListener(event: string, listener: (...args: any[]) => void): Cluster;
function addListener(event: "disconnect", listener: (worker: Worker) => void): Cluster;
function addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster;
function addListener(event: "fork", listener: (worker: Worker) => void): Cluster;
function addListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster;
// the handle is a net.Socket or net.Server object, or undefined.
function addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster;
function addListener(event: "online", listener: (worker: Worker) => void): Cluster;
function addListener(event: "setup", listener: (settings: ClusterSettings) => void): Cluster;
function emit(event: string | symbol, ...args: any[]): boolean;
function emit(event: "disconnect", worker: Worker): boolean;
function emit(event: "exit", worker: Worker, code: number, signal: string): boolean;
function emit(event: "fork", worker: Worker): boolean;
function emit(event: "listening", worker: Worker, address: Address): boolean;
function emit(event: "message", worker: Worker, message: any, handle: net.Socket | net.Server): boolean;
function emit(event: "online", worker: Worker): boolean;
function emit(event: "setup", settings: ClusterSettings): boolean;
function on(event: string, listener: (...args: any[]) => void): Cluster;
function on(event: "disconnect", listener: (worker: Worker) => void): Cluster;
function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster;
function on(event: "fork", listener: (worker: Worker) => void): Cluster;
function on(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster;
function on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined.
function on(event: "online", listener: (worker: Worker) => void): Cluster;
function on(event: "setup", listener: (settings: ClusterSettings) => void): Cluster;
function once(event: string, listener: (...args: any[]) => void): Cluster;
function once(event: "disconnect", listener: (worker: Worker) => void): Cluster;
function once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster;
function once(event: "fork", listener: (worker: Worker) => void): Cluster;
function once(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster;
function once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined.
function once(event: "online", listener: (worker: Worker) => void): Cluster;
function once(event: "setup", listener: (settings: ClusterSettings) => void): Cluster;
function removeListener(event: string, listener: (...args: any[]) => void): Cluster;
function removeAllListeners(event?: string): Cluster;
function setMaxListeners(n: number): Cluster;
function getMaxListeners(): number;
function listeners(event: string): Function[];
function listenerCount(type: string): number;
function prependListener(event: string, listener: (...args: any[]) => void): Cluster;
function prependListener(event: "disconnect", listener: (worker: Worker) => void): Cluster;
function prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster;
function prependListener(event: "fork", listener: (worker: Worker) => void): Cluster;
function prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster;
// the handle is a net.Socket or net.Server object, or undefined.
function prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster;
function prependListener(event: "online", listener: (worker: Worker) => void): Cluster;
function prependListener(event: "setup", listener: (settings: ClusterSettings) => void): Cluster;
function prependOnceListener(event: string, listener: (...args: any[]) => void): Cluster;
function prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): Cluster;
function prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster;
function prependOnceListener(event: "fork", listener: (worker: Worker) => void): Cluster;
function prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster;
// the handle is a net.Socket or net.Server object, or undefined.
function prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster;
function prependOnceListener(event: "online", listener: (worker: Worker) => void): Cluster;
function prependOnceListener(event: "setup", listener: (settings: ClusterSettings) => void): Cluster;
function eventNames(): string[];
const cluster: Cluster;
export default cluster;
}
declare module 'node:cluster' {
export * from 'cluster';
export { default as default } from 'cluster';
}

View File

@ -1,100 +1,321 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* The `console` module provides a simple debugging console that is similar to the
* JavaScript console mechanism provided by web browsers.
*
* The module exports two specific components:
*
* * A `Console` class with methods such as `console.log()`, `console.error()` and`console.warn()` that can be used to write to any Node.js stream.
* * A global `console` instance configured to write to `process.stdout` and `process.stderr`. The global `console` can be used without calling`require('console')`.
*
* _**Warning**_: The global console object's methods are neither consistently
* synchronous like the browser APIs they resemble, nor are they consistently
* asynchronous like all other Node.js streams. See the `note on process I/O` for
* more information.
*
* Example using the global `console`:
*
* ```js
* console.log('hello world');
* // Prints: hello world, to stdout
* console.log('hello %s', 'world');
* // Prints: hello world, to stdout
* console.error(new Error('Whoops, something bad happened'));
* // Prints error message and stack trace to stderr:
* // Error: Whoops, something bad happened
* // at [eval]:5:15
* // at Script.runInThisContext (node:vm:132:18)
* // at Object.runInThisContext (node:vm:309:38)
* // at node:internal/process/execution:77:19
* // at [eval]-wrapper:6:22
* // at evalScript (node:internal/process/execution:76:60)
* // at node:internal/main/eval_string:23:3
*
* const name = 'Will Robinson';
* console.warn(`Danger ${name}! Danger!`);
* // Prints: Danger Will Robinson! Danger!, to stderr
* ```
*
* Example using the `Console` class:
*
* ```js
* const out = getStreamSomehow();
* const err = getStreamSomehow();
* const myConsole = new console.Console(out, err);
*
* myConsole.log('hello world');
* // Prints: hello world, to out
* myConsole.log('hello %s', 'world');
* // Prints: hello world, to out
* myConsole.error(new Error('Whoops, something bad happened'));
* // Prints: [Error: Whoops, something bad happened], to err
*
* const name = 'Will Robinson';
* myConsole.warn(`Danger ${name}! Danger!`);
* // Prints: Danger Will Robinson! Danger!, to err
* ```
* @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/console.js)
*/
declare module 'console' {
import console = require('node:console');
export = console;
}
declare module 'node:console' {
import { InspectOptions } from 'util';
import { InspectOptions } from 'node:util';
global {
// This needs to be global to avoid TS2403 in case lib.dom.d.ts is present in the same build
interface Console {
Console: NodeJS.ConsoleConstructor;
Console: console.ConsoleConstructor;
/**
* A simple assertion test that verifies whether `value` is truthy.
* If it is not, an `AssertionError` is thrown.
* If provided, the error `message` is formatted using `util.format()` and used as the error message.
* `console.assert()` writes a message if `value` is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) or omitted. It only
* writes a message and does not otherwise affect execution. The output always
* starts with `"Assertion failed"`. If provided, `message` is formatted using `util.format()`.
*
* If `value` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), nothing happens.
*
* ```js
* console.assert(true, 'does nothing');
*
* console.assert(false, 'Whoops %s work', 'didn\'t');
* // Assertion failed: Whoops didn't work
*
* console.assert();
* // Assertion failed
* ```
* @since v0.1.101
* @param value The value tested for being truthy.
* @param message All arguments besides `value` are used as error message.
*/
assert(value: any, message?: string, ...optionalParams: any[]): void;
/**
* When `stdout` is a TTY, calling `console.clear()` will attempt to clear the TTY.
* When `stdout` is not a TTY, this method does nothing.
* When `stdout` is a TTY, calling `console.clear()` will attempt to clear the
* TTY. When `stdout` is not a TTY, this method does nothing.
*
* The specific operation of `console.clear()` can vary across operating systems
* and terminal types. For most Linux operating systems, `console.clear()`operates similarly to the `clear` shell command. On Windows, `console.clear()`will clear only the output in the
* current terminal viewport for the Node.js
* binary.
* @since v8.3.0
*/
clear(): void;
/**
* Maintains an internal counter specific to `label` and outputs to `stdout` the number of times `console.count()` has been called with the given `label`.
* Maintains an internal counter specific to `label` and outputs to `stdout` the
* number of times `console.count()` has been called with the given `label`.
*
* ```js
* > console.count()
* default: 1
* undefined
* > console.count('default')
* default: 2
* undefined
* > console.count('abc')
* abc: 1
* undefined
* > console.count('xyz')
* xyz: 1
* undefined
* > console.count('abc')
* abc: 2
* undefined
* > console.count()
* default: 3
* undefined
* >
* ```
* @since v8.3.0
* @param label The display label for the counter.
*/
count(label?: string): void;
/**
* Resets the internal counter specific to `label`.
*
* ```js
* > console.count('abc');
* abc: 1
* undefined
* > console.countReset('abc');
* undefined
* > console.count('abc');
* abc: 1
* undefined
* >
* ```
* @since v8.3.0
* @param label The display label for the counter.
*/
countReset(label?: string): void;
/**
* The `console.debug()` function is an alias for {@link console.log}.
* The `console.debug()` function is an alias for {@link log}.
* @since v8.0.0
*/
debug(message?: any, ...optionalParams: any[]): void;
/**
* Uses {@link util.inspect} on `obj` and prints the resulting string to `stdout`.
* Uses `util.inspect()` on `obj` and prints the resulting string to `stdout`.
* This function bypasses any custom `inspect()` function defined on `obj`.
* @since v0.1.101
*/
dir(obj: any, options?: InspectOptions): void;
/**
* This method calls {@link console.log} passing it the arguments received. Please note that this method does not produce any XML formatting
* This method calls `console.log()` passing it the arguments received.
* This method does not produce any XML formatting.
* @since v8.0.0
*/
dirxml(...data: any[]): void;
/**
* Prints to `stderr` with newline.
* Prints to `stderr` with newline. Multiple arguments can be passed, with the
* first used as the primary message and all additional used as substitution
* values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to `util.format()`).
*
* ```js
* const code = 5;
* console.error('error #%d', code);
* // Prints: error #5, to stderr
* console.error('error', code);
* // Prints: error 5, to stderr
* ```
*
* If formatting elements (e.g. `%d`) are not found in the first string then `util.inspect()` is called on each argument and the resulting string
* values are concatenated. See `util.format()` for more information.
* @since v0.1.100
*/
error(message?: any, ...optionalParams: any[]): void;
/**
* Increases indentation of subsequent lines by two spaces.
* If one or more `label`s are provided, those are printed first without the additional indentation.
* Increases indentation of subsequent lines by spaces for `groupIndentation`length.
*
* If one or more `label`s are provided, those are printed first without the
* additional indentation.
* @since v8.5.0
*/
group(...label: any[]): void;
/**
* The `console.groupCollapsed()` function is an alias for {@link console.group}.
* An alias for {@link group}.
* @since v8.5.0
*/
groupCollapsed(...label: any[]): void;
/**
* Decreases indentation of subsequent lines by two spaces.
* Decreases indentation of subsequent lines by spaces for `groupIndentation`length.
* @since v8.5.0
*/
groupEnd(): void;
/**
* The {@link console.info} function is an alias for {@link console.log}.
* The `console.info()` function is an alias for {@link log}.
* @since v0.1.100
*/
info(message?: any, ...optionalParams: any[]): void;
/**
* Prints to `stdout` with newline.
* Prints to `stdout` with newline. Multiple arguments can be passed, with the
* first used as the primary message and all additional used as substitution
* values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to `util.format()`).
*
* ```js
* const count = 5;
* console.log('count: %d', count);
* // Prints: count: 5, to stdout
* console.log('count:', count);
* // Prints: count: 5, to stdout
* ```
*
* See `util.format()` for more information.
* @since v0.1.100
*/
log(message?: any, ...optionalParams: any[]): void;
/**
* This method does not display anything unless used in the inspector.
* Prints to `stdout` the array `array` formatted as a table.
* Try to construct a table with the columns of the properties of `tabularData`(or use `properties`) and rows of `tabularData` and log it. Falls back to just
* logging the argument if it cant be parsed as tabular.
*
* ```js
* // These can't be parsed as tabular data
* console.table(Symbol());
* // Symbol()
*
* console.table(undefined);
* // undefined
*
* console.table([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }]);
* // ┌─────────┬─────┬─────┐
* // │ (index) │ a │ b │
* // ├─────────┼─────┼─────┤
* // │ 0 │ 1 │ 'Y' │
* // │ 1 │ 'Z' │ 2 │
* // └─────────┴─────┴─────┘
*
* console.table([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }], ['a']);
* // ┌─────────┬─────┐
* // │ (index) │ a │
* // ├─────────┼─────┤
* // │ 0 │ 1 │
* // │ 1 │ 'Z' │
* // └─────────┴─────┘
* ```
* @since v10.0.0
* @param properties Alternate properties for constructing the table.
*/
table(tabularData: any, properties?: ReadonlyArray<string>): void;
/**
* Starts a timer that can be used to compute the duration of an operation. Timers are identified by a unique `label`.
* Starts a timer that can be used to compute the duration of an operation. Timers
* are identified by a unique `label`. Use the same `label` when calling {@link timeEnd} to stop the timer and output the elapsed time in
* suitable time units to `stdout`. For example, if the elapsed
* time is 3869ms, `console.timeEnd()` displays "3.869s".
* @since v0.1.104
*/
time(label?: string): void;
/**
* Stops a timer that was previously started by calling {@link console.time} and prints the result to `stdout`.
* Stops a timer that was previously started by calling {@link time} and
* prints the result to `stdout`:
*
* ```js
* console.time('100-elements');
* for (let i = 0; i < 100; i++) {}
* console.timeEnd('100-elements');
* // prints 100-elements: 225.438ms
* ```
* @since v0.1.104
*/
timeEnd(label?: string): void;
/**
* For a timer that was previously started by calling {@link console.time}, prints the elapsed time and other `data` arguments to `stdout`.
* For a timer that was previously started by calling {@link time}, prints
* the elapsed time and other `data` arguments to `stdout`:
*
* ```js
* console.time('process');
* const value = expensiveProcess1(); // Returns 42
* console.timeLog('process', value);
* // Prints "process: 365.227ms 42".
* doExpensiveProcess2(value);
* console.timeEnd('process');
* ```
* @since v10.7.0
*/
timeLog(label?: string, ...data: any[]): void;
/**
* Prints to `stderr` the string 'Trace :', followed by the {@link util.format} formatted message and stack trace to the current position in the code.
* Prints to `stderr` the string `'Trace: '`, followed by the `util.format()` formatted message and stack trace to the current position in the code.
*
* ```js
* console.trace('Show me');
* // Prints: (stack trace will vary based on where trace is called)
* // Trace: Show me
* // at repl:2:9
* // at REPLServer.defaultEval (repl.js:248:27)
* // at bound (domain.js:287:14)
* // at REPLServer.runBound [as eval] (domain.js:300:12)
* // at REPLServer.<anonymous> (repl.js:412:12)
* // at emitOne (events.js:82:20)
* // at REPLServer.emit (events.js:169:7)
* // at REPLServer.Interface._onLine (readline.js:210:10)
* // at REPLServer.Interface._line (readline.js:549:8)
* // at REPLServer.Interface._ttyWrite (readline.js:826:14)
* ```
* @since v0.1.104
*/
trace(message?: any, ...optionalParams: any[]): void;
/**
* The {@link console.warn} function is an alias for {@link console.error}.
* The `console.warn()` function is an alias for {@link error}.
* @since v0.1.100
*/
warn(message?: any, ...optionalParams: any[]): void;
// --- Inspector mode only ---
/**
* This method does not display anything unless used in the inspector.
@ -112,13 +333,67 @@ declare module 'node:console' {
*/
timeStamp(label?: string): void;
}
var console: Console;
namespace NodeJS {
/**
* The `console` module provides a simple debugging console that is similar to the
* JavaScript console mechanism provided by web browsers.
*
* The module exports two specific components:
*
* * A `Console` class with methods such as `console.log()`, `console.error()` and`console.warn()` that can be used to write to any Node.js stream.
* * A global `console` instance configured to write to `process.stdout` and `process.stderr`. The global `console` can be used without calling`require('console')`.
*
* _**Warning**_: The global console object's methods are neither consistently
* synchronous like the browser APIs they resemble, nor are they consistently
* asynchronous like all other Node.js streams. See the `note on process I/O` for
* more information.
*
* Example using the global `console`:
*
* ```js
* console.log('hello world');
* // Prints: hello world, to stdout
* console.log('hello %s', 'world');
* // Prints: hello world, to stdout
* console.error(new Error('Whoops, something bad happened'));
* // Prints error message and stack trace to stderr:
* // Error: Whoops, something bad happened
* // at [eval]:5:15
* // at Script.runInThisContext (node:vm:132:18)
* // at Object.runInThisContext (node:vm:309:38)
* // at node:internal/process/execution:77:19
* // at [eval]-wrapper:6:22
* // at evalScript (node:internal/process/execution:76:60)
* // at node:internal/main/eval_string:23:3
*
* const name = 'Will Robinson';
* console.warn(`Danger ${name}! Danger!`);
* // Prints: Danger Will Robinson! Danger!, to stderr
* ```
*
* Example using the `Console` class:
*
* ```js
* const out = getStreamSomehow();
* const err = getStreamSomehow();
* const myConsole = new console.Console(out, err);
*
* myConsole.log('hello world');
* // Prints: hello world, to out
* myConsole.log('hello %s', 'world');
* // Prints: hello world, to out
* myConsole.error(new Error('Whoops, something bad happened'));
* // Prints: [Error: Whoops, something bad happened], to err
*
* const name = 'Will Robinson';
* myConsole.warn(`Danger ${name}! Danger!`);
* // Prints: Danger Will Robinson! Danger!, to err
* ```
* @see [source](https://github.com/nodejs/node/blob/v16.4.2/lib/console.js)
*/
namespace console {
interface ConsoleConstructorOptions {
stdout: WritableStream;
stderr?: WritableStream | undefined;
stdout: NodeJS.WritableStream;
stderr?: NodeJS.WritableStream | undefined;
ignoreErrors?: boolean | undefined;
colorMode?: boolean | 'auto' | undefined;
inspectOptions?: InspectOptions | undefined;
@ -126,20 +401,15 @@ declare module 'node:console' {
* Set group indentation
* @default 2
*/
groupIndentation?: number | undefined;
groupIndentation?: number | undefined;
}
interface ConsoleConstructor {
prototype: Console;
new(stdout: WritableStream, stderr?: WritableStream, ignoreErrors?: boolean): Console;
new(options: ConsoleConstructorOptions): Console;
}
interface Global {
console: typeof console;
new (stdout: NodeJS.WritableStream, stderr?: NodeJS.WritableStream, ignoreErrors?: boolean): Console;
new (options: ConsoleConstructorOptions): Console;
}
}
var console: Console;
}
export = console;
export = globalThis.console;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
[ViewState]
Mode=
Vid=
FolderType=Generic

View File

@ -1,28 +1,51 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* The `dgram` module provides an implementation of UDP datagram sockets.
*
* ```js
* import dgram from 'dgram';
*
* const server = dgram.createSocket('udp4');
*
* server.on('error', (err) => {
* console.log(`server error:\n${err.stack}`);
* server.close();
* });
*
* server.on('message', (msg, rinfo) => {
* console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
* });
*
* server.on('listening', () => {
* const address = server.address();
* console.log(`server listening ${address.address}:${address.port}`);
* });
*
* server.bind(41234);
* // Prints: server listening 0.0.0.0:41234
* ```
* @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/dgram.js)
*/
declare module 'dgram' {
import { AddressInfo } from 'net';
import * as dns from 'dns';
import EventEmitter = require('events');
import { AddressInfo } from 'node:net';
import * as dns from 'node:dns';
import { EventEmitter, Abortable } from 'node:events';
interface RemoteInfo {
address: string;
family: 'IPv4' | 'IPv6';
port: number;
size: number;
}
interface BindOptions {
port?: number | undefined;
address?: string | undefined;
exclusive?: boolean | undefined;
fd?: number | undefined;
}
type SocketType = "udp4" | "udp6";
interface SocketOptions {
type SocketType = 'udp4' | 'udp6';
interface SocketOptions extends Abortable {
type: SocketType;
reuseAddr?: boolean | undefined;
/**
@ -33,64 +56,447 @@ declare module 'dgram' {
sendBufferSize?: number | undefined;
lookup?: ((hostname: string, options: dns.LookupOneOptions, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void) => void) | undefined;
}
/**
* Creates a `dgram.Socket` object. Once the socket is created, calling `socket.bind()` will instruct the socket to begin listening for datagram
* messages. When `address` and `port` are not passed to `socket.bind()` the
* method will bind the socket to the "all interfaces" address on a random port
* (it does the right thing for both `udp4` and `udp6` sockets). The bound address
* and port can be retrieved using `socket.address().address` and `socket.address().port`.
*
* If the `signal` option is enabled, calling `.abort()` on the corresponding`AbortController` is similar to calling `.close()` on the socket:
*
* ```js
* const controller = new AbortController();
* const { signal } = controller;
* const server = dgram.createSocket({ type: 'udp4', signal });
* server.on('message', (msg, rinfo) => {
* console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
* });
* // Later, when you want to close the server.
* controller.abort();
* ```
* @since v0.11.13
* @param options Available options are:
* @param callback Attached as a listener for `'message'` events. Optional.
*/
function createSocket(type: SocketType, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket;
function createSocket(options: SocketOptions, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket;
/**
* Encapsulates the datagram functionality.
*
* New instances of `dgram.Socket` are created using {@link createSocket}.
* The `new` keyword is not to be used to create `dgram.Socket` instances.
* @since v0.1.99
*/
class Socket extends EventEmitter {
/**
* Tells the kernel to join a multicast group at the given `multicastAddress` and`multicastInterface` using the `IP_ADD_MEMBERSHIP` socket option. If the`multicastInterface` argument is not
* specified, the operating system will choose
* one interface and will add membership to it. To add membership to every
* available interface, call `addMembership` multiple times, once per interface.
*
* When called on an unbound socket, this method will implicitly bind to a random
* port, listening on all interfaces.
*
* When sharing a UDP socket across multiple `cluster` workers, the`socket.addMembership()` function must be called only once or an`EADDRINUSE` error will occur:
*
* ```js
* import cluster from 'cluster';
* import dgram from 'dgram';
*
* if (cluster.isPrimary) {
* cluster.fork(); // Works ok.
* cluster.fork(); // Fails with EADDRINUSE.
* } else {
* const s = dgram.createSocket('udp4');
* s.bind(1234, () => {
* s.addMembership('224.0.0.114');
* });
* }
* ```
* @since v0.6.9
*/
addMembership(multicastAddress: string, multicastInterface?: string): void;
/**
* Returns an object containing the address information for a socket.
* For UDP sockets, this object will contain `address`, `family` and `port`properties.
*
* This method throws `EBADF` if called on an unbound socket.
* @since v0.1.99
*/
address(): AddressInfo;
/**
* For UDP sockets, causes the `dgram.Socket` to listen for datagram
* messages on a named `port` and optional `address`. If `port` is not
* specified or is `0`, the operating system will attempt to bind to a
* random port. If `address` is not specified, the operating system will
* attempt to listen on all addresses. Once binding is complete, a`'listening'` event is emitted and the optional `callback` function is
* called.
*
* Specifying both a `'listening'` event listener and passing a`callback` to the `socket.bind()` method is not harmful but not very
* useful.
*
* A bound datagram socket keeps the Node.js process running to receive
* datagram messages.
*
* If binding fails, an `'error'` event is generated. In rare case (e.g.
* attempting to bind with a closed socket), an `Error` may be thrown.
*
* Example of a UDP server listening on port 41234:
*
* ```js
* import dgram from 'dgram';
*
* const server = dgram.createSocket('udp4');
*
* server.on('error', (err) => {
* console.log(`server error:\n${err.stack}`);
* server.close();
* });
*
* server.on('message', (msg, rinfo) => {
* console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
* });
*
* server.on('listening', () => {
* const address = server.address();
* console.log(`server listening ${address.address}:${address.port}`);
* });
*
* server.bind(41234);
* // Prints: server listening 0.0.0.0:41234
* ```
* @since v0.1.99
* @param callback with no parameters. Called when binding is complete.
*/
bind(port?: number, address?: string, callback?: () => void): this;
bind(port?: number, callback?: () => void): this;
bind(callback?: () => void): this;
bind(options: BindOptions, callback?: () => void): this;
/**
* Close the underlying socket and stop listening for data on it. If a callback is
* provided, it is added as a listener for the `'close'` event.
* @since v0.1.99
* @param callback Called when the socket has been closed.
*/
close(callback?: () => void): this;
/**
* Associates the `dgram.Socket` to a remote address and port. Every
* message sent by this handle is automatically sent to that destination. Also,
* the socket will only receive messages from that remote peer.
* Trying to call `connect()` on an already connected socket will result
* in an `ERR_SOCKET_DGRAM_IS_CONNECTED` exception. If `address` is not
* provided, `'127.0.0.1'` (for `udp4` sockets) or `'::1'` (for `udp6` sockets)
* will be used by default. Once the connection is complete, a `'connect'` event
* is emitted and the optional `callback` function is called. In case of failure,
* the `callback` is called or, failing this, an `'error'` event is emitted.
* @since v12.0.0
* @param callback Called when the connection is completed or on error.
*/
connect(port: number, address?: string, callback?: () => void): void;
connect(port: number, callback: () => void): void;
/**
* A synchronous function that disassociates a connected `dgram.Socket` from
* its remote address. Trying to call `disconnect()` on an unbound or already
* disconnected socket will result in an `ERR_SOCKET_DGRAM_NOT_CONNECTED` exception.
* @since v12.0.0
*/
disconnect(): void;
/**
* Instructs the kernel to leave a multicast group at `multicastAddress` using the`IP_DROP_MEMBERSHIP` socket option. This method is automatically called by the
* kernel when the socket is closed or the process terminates, so most apps will
* never have reason to call this.
*
* If `multicastInterface` is not specified, the operating system will attempt to
* drop membership on all valid interfaces.
* @since v0.6.9
*/
dropMembership(multicastAddress: string, multicastInterface?: string): void;
/**
* This method throws `ERR_SOCKET_BUFFER_SIZE` if called on an unbound socket.
* @since v8.7.0
* @return the `SO_RCVBUF` socket receive buffer size in bytes.
*/
getRecvBufferSize(): number;
/**
* This method throws `ERR_SOCKET_BUFFER_SIZE` if called on an unbound socket.
* @since v8.7.0
* @return the `SO_SNDBUF` socket send buffer size in bytes.
*/
getSendBufferSize(): number;
/**
* By default, binding a socket will cause it to block the Node.js process from
* exiting as long as the socket is open. The `socket.unref()` method can be used
* to exclude the socket from the reference counting that keeps the Node.js
* process active. The `socket.ref()` method adds the socket back to the reference
* counting and restores the default behavior.
*
* Calling `socket.ref()` multiples times will have no additional effect.
*
* The `socket.ref()` method returns a reference to the socket so calls can be
* chained.
* @since v0.9.1
*/
ref(): this;
/**
* Returns an object containing the `address`, `family`, and `port` of the remote
* endpoint. This method throws an `ERR_SOCKET_DGRAM_NOT_CONNECTED` exception
* if the socket is not connected.
* @since v12.0.0
*/
remoteAddress(): AddressInfo;
/**
* Broadcasts a datagram on the socket.
* For connectionless sockets, the destination `port` and `address` must be
* specified. Connected sockets, on the other hand, will use their associated
* remote endpoint, so the `port` and `address` arguments must not be set.
*
* The `msg` argument contains the message to be sent.
* Depending on its type, different behavior can apply. If `msg` is a `Buffer`,
* any `TypedArray` or a `DataView`,
* the `offset` and `length` specify the offset within the `Buffer` where the
* message begins and the number of bytes in the message, respectively.
* If `msg` is a `String`, then it is automatically converted to a `Buffer`with `'utf8'` encoding. With messages that
* contain multi-byte characters, `offset` and `length` will be calculated with
* respect to `byte length` and not the character position.
* If `msg` is an array, `offset` and `length` must not be specified.
*
* The `address` argument is a string. If the value of `address` is a host name,
* DNS will be used to resolve the address of the host. If `address` is not
* provided or otherwise falsy, `'127.0.0.1'` (for `udp4` sockets) or `'::1'`(for `udp6` sockets) will be used by default.
*
* If the socket has not been previously bound with a call to `bind`, the socket
* is assigned a random port number and is bound to the "all interfaces" address
* (`'0.0.0.0'` for `udp4` sockets, `'::0'` for `udp6` sockets.)
*
* An optional `callback` function may be specified to as a way of reporting
* DNS errors or for determining when it is safe to reuse the `buf` object.
* DNS lookups delay the time to send for at least one tick of the
* Node.js event loop.
*
* The only way to know for sure that the datagram has been sent is by using a`callback`. If an error occurs and a `callback` is given, the error will be
* passed as the first argument to the `callback`. If a `callback` is not given,
* the error is emitted as an `'error'` event on the `socket` object.
*
* Offset and length are optional but both _must_ be set if either are used.
* They are supported only when the first argument is a `Buffer`, a `TypedArray`,
* or a `DataView`.
*
* This method throws `ERR_SOCKET_BAD_PORT` if called on an unbound socket.
*
* Example of sending a UDP packet to a port on `localhost`;
*
* ```js
* import dgram from 'dgram';
* import { Buffer } from 'buffer';
*
* const message = Buffer.from('Some bytes');
* const client = dgram.createSocket('udp4');
* client.send(message, 41234, 'localhost', (err) => {
* client.close();
* });
* ```
*
* Example of sending a UDP packet composed of multiple buffers to a port on`127.0.0.1`;
*
* ```js
* import dgram from 'dgram';
* import { Buffer } from 'buffer';
*
* const buf1 = Buffer.from('Some ');
* const buf2 = Buffer.from('bytes');
* const client = dgram.createSocket('udp4');
* client.send([buf1, buf2], 41234, (err) => {
* client.close();
* });
* ```
*
* Sending multiple buffers might be faster or slower depending on the
* application and operating system. Run benchmarks to
* determine the optimal strategy on a case-by-case basis. Generally speaking,
* however, sending multiple buffers is faster.
*
* Example of sending a UDP packet using a socket connected to a port on`localhost`:
*
* ```js
* import dgram from 'dgram';
* import { Buffer } from 'buffer';
*
* const message = Buffer.from('Some bytes');
* const client = dgram.createSocket('udp4');
* client.connect(41234, 'localhost', (err) => {
* client.send(message, (err) => {
* client.close();
* });
* });
* ```
* @since v0.1.99
* @param msg Message to be sent.
* @param offset Offset in the buffer where the message starts.
* @param length Number of bytes in the message.
* @param port Destination port.
* @param address Destination host name or IP address.
* @param callback Called when the message has been sent.
*/
send(msg: string | Uint8Array | ReadonlyArray<any>, port?: number, address?: string, callback?: (error: Error | null, bytes: number) => void): void;
send(msg: string | Uint8Array | ReadonlyArray<any>, port?: number, callback?: (error: Error | null, bytes: number) => void): void;
send(msg: string | Uint8Array | ReadonlyArray<any>, callback?: (error: Error | null, bytes: number) => void): void;
send(msg: string | Uint8Array, offset: number, length: number, port?: number, address?: string, callback?: (error: Error | null, bytes: number) => void): void;
send(msg: string | Uint8Array, offset: number, length: number, port?: number, callback?: (error: Error | null, bytes: number) => void): void;
send(msg: string | Uint8Array, offset: number, length: number, callback?: (error: Error | null, bytes: number) => void): void;
/**
* Sets or clears the `SO_BROADCAST` socket option. When set to `true`, UDP
* packets may be sent to a local interface's broadcast address.
*
* This method throws `EBADF` if called on an unbound socket.
* @since v0.6.9
*/
setBroadcast(flag: boolean): void;
/**
* _All references to scope in this section are referring to [IPv6 Zone Indices](https://en.wikipedia.org/wiki/IPv6_address#Scoped_literal_IPv6_addresses), which are defined by [RFC
* 4007](https://tools.ietf.org/html/rfc4007). In string form, an IP_
* _with a scope index is written as `'IP%scope'` where scope is an interface name_
* _or interface number._
*
* Sets the default outgoing multicast interface of the socket to a chosen
* interface or back to system interface selection. The `multicastInterface` must
* be a valid string representation of an IP from the socket's family.
*
* For IPv4 sockets, this should be the IP configured for the desired physical
* interface. All packets sent to multicast on the socket will be sent on the
* interface determined by the most recent successful use of this call.
*
* For IPv6 sockets, `multicastInterface` should include a scope to indicate the
* interface as in the examples that follow. In IPv6, individual `send` calls can
* also use explicit scope in addresses, so only packets sent to a multicast
* address without specifying an explicit scope are affected by the most recent
* successful use of this call.
*
* This method throws `EBADF` if called on an unbound socket.
*
* #### Example: IPv6 outgoing multicast interface
*
* On most systems, where scope format uses the interface name:
*
* ```js
* const socket = dgram.createSocket('udp6');
*
* socket.bind(1234, () => {
* socket.setMulticastInterface('::%eth1');
* });
* ```
*
* On Windows, where scope format uses an interface number:
*
* ```js
* const socket = dgram.createSocket('udp6');
*
* socket.bind(1234, () => {
* socket.setMulticastInterface('::%2');
* });
* ```
*
* #### Example: IPv4 outgoing multicast interface
*
* All systems use an IP of the host on the desired physical interface:
*
* ```js
* const socket = dgram.createSocket('udp4');
*
* socket.bind(1234, () => {
* socket.setMulticastInterface('10.0.0.2');
* });
* ```
* @since v8.6.0
*/
setMulticastInterface(multicastInterface: string): void;
/**
* Sets or clears the `IP_MULTICAST_LOOP` socket option. When set to `true`,
* multicast packets will also be received on the local interface.
*
* This method throws `EBADF` if called on an unbound socket.
* @since v0.3.8
*/
setMulticastLoopback(flag: boolean): boolean;
/**
* Sets the `IP_MULTICAST_TTL` socket option. While TTL generally stands for
* "Time to Live", in this context it specifies the number of IP hops that a
* packet is allowed to travel through, specifically for multicast traffic. Each
* router or gateway that forwards a packet decrements the TTL. If the TTL is
* decremented to 0 by a router, it will not be forwarded.
*
* The `ttl` argument may be between 0 and 255\. The default on most systems is `1`.
*
* This method throws `EBADF` if called on an unbound socket.
* @since v0.3.8
*/
setMulticastTTL(ttl: number): number;
/**
* Sets the `SO_RCVBUF` socket option. Sets the maximum socket receive buffer
* in bytes.
*
* This method throws `ERR_SOCKET_BUFFER_SIZE` if called on an unbound socket.
* @since v8.7.0
*/
setRecvBufferSize(size: number): void;
/**
* Sets the `SO_SNDBUF` socket option. Sets the maximum socket send buffer
* in bytes.
*
* This method throws `ERR_SOCKET_BUFFER_SIZE` if called on an unbound socket.
* @since v8.7.0
*/
setSendBufferSize(size: number): void;
/**
* Sets the `IP_TTL` socket option. While TTL generally stands for "Time to Live",
* in this context it specifies the number of IP hops that a packet is allowed to
* travel through. Each router or gateway that forwards a packet decrements the
* TTL. If the TTL is decremented to 0 by a router, it will not be forwarded.
* Changing TTL values is typically done for network probes or when multicasting.
*
* The `ttl` argument may be between between 1 and 255\. The default on most systems
* is 64.
*
* This method throws `EBADF` if called on an unbound socket.
* @since v0.1.101
*/
setTTL(ttl: number): number;
/**
* By default, binding a socket will cause it to block the Node.js process from
* exiting as long as the socket is open. The `socket.unref()` method can be used
* to exclude the socket from the reference counting that keeps the Node.js
* process active, allowing the process to exit even if the socket is still
* listening.
*
* Calling `socket.unref()` multiple times will have no addition effect.
*
* The `socket.unref()` method returns a reference to the socket so calls can be
* chained.
* @since v0.9.1
*/
unref(): this;
/**
* Tells the kernel to join a source-specific multicast channel at the given
* `sourceAddress` and `groupAddress`, using the `multicastInterface` with the
* `IP_ADD_SOURCE_MEMBERSHIP` socket option.
* If the `multicastInterface` argument
* Tells the kernel to join a source-specific multicast channel at the given`sourceAddress` and `groupAddress`, using the `multicastInterface` with the`IP_ADD_SOURCE_MEMBERSHIP` socket
* option. If the `multicastInterface` argument
* is not specified, the operating system will choose one interface and will add
* membership to it.
* To add membership to every available interface, call
* `socket.addSourceSpecificMembership()` multiple times, once per interface.
* membership to it. To add membership to every available interface, call`socket.addSourceSpecificMembership()` multiple times, once per interface.
*
* When called on an unbound socket, this method will implicitly bind to a random
* port, listening on all interfaces.
* @since v13.1.0, v12.16.0
*/
addSourceSpecificMembership(sourceAddress: string, groupAddress: string, multicastInterface?: string): void;
/**
* Instructs the kernel to leave a source-specific multicast channel at the given
* `sourceAddress` and `groupAddress` using the `IP_DROP_SOURCE_MEMBERSHIP`
* socket option. This method is automatically called by the kernel when the
* Instructs the kernel to leave a source-specific multicast channel at the given`sourceAddress` and `groupAddress` using the `IP_DROP_SOURCE_MEMBERSHIP`socket option. This method is
* automatically called by the kernel when the
* socket is closed or the process terminates, so most apps will never have
* reason to call this.
*
* If `multicastInterface` is not specified, the operating system will attempt to
* drop membership on all valid interfaces.
* @since v13.1.0, v12.16.0
*/
dropSourceSpecificMembership(sourceAddress: string, groupAddress: string, multicastInterface?: string): void;
/**
* events.EventEmitter
* 1. close
@ -100,46 +506,41 @@ declare module 'dgram' {
* 5. message
*/
addListener(event: string, listener: (...args: any[]) => void): this;
addListener(event: "close", listener: () => void): this;
addListener(event: "connect", listener: () => void): this;
addListener(event: "error", listener: (err: Error) => void): this;
addListener(event: "listening", listener: () => void): this;
addListener(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
addListener(event: 'close', listener: () => void): this;
addListener(event: 'connect', listener: () => void): this;
addListener(event: 'error', listener: (err: Error) => void): this;
addListener(event: 'listening', listener: () => void): this;
addListener(event: 'message', listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
emit(event: string | symbol, ...args: any[]): boolean;
emit(event: "close"): boolean;
emit(event: "connect"): boolean;
emit(event: "error", err: Error): boolean;
emit(event: "listening"): boolean;
emit(event: "message", msg: Buffer, rinfo: RemoteInfo): boolean;
emit(event: 'close'): boolean;
emit(event: 'connect'): boolean;
emit(event: 'error', err: Error): boolean;
emit(event: 'listening'): boolean;
emit(event: 'message', msg: Buffer, rinfo: RemoteInfo): boolean;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "close", listener: () => void): this;
on(event: "connect", listener: () => void): this;
on(event: "error", listener: (err: Error) => void): this;
on(event: "listening", listener: () => void): this;
on(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
on(event: 'close', listener: () => void): this;
on(event: 'connect', listener: () => void): this;
on(event: 'error', listener: (err: Error) => void): this;
on(event: 'listening', listener: () => void): this;
on(event: 'message', listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "close", listener: () => void): this;
once(event: "connect", listener: () => void): this;
once(event: "error", listener: (err: Error) => void): this;
once(event: "listening", listener: () => void): this;
once(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
once(event: 'close', listener: () => void): this;
once(event: 'connect', listener: () => void): this;
once(event: 'error', listener: (err: Error) => void): this;
once(event: 'listening', listener: () => void): this;
once(event: 'message', listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "close", listener: () => void): this;
prependListener(event: "connect", listener: () => void): this;
prependListener(event: "error", listener: (err: Error) => void): this;
prependListener(event: "listening", listener: () => void): this;
prependListener(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
prependListener(event: 'close', listener: () => void): this;
prependListener(event: 'connect', listener: () => void): this;
prependListener(event: 'error', listener: (err: Error) => void): this;
prependListener(event: 'listening', listener: () => void): this;
prependListener(event: 'message', listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "close", listener: () => void): this;
prependOnceListener(event: "connect", listener: () => void): this;
prependOnceListener(event: "error", listener: (err: Error) => void): this;
prependOnceListener(event: "listening", listener: () => void): this;
prependOnceListener(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
prependOnceListener(event: 'close', listener: () => void): this;
prependOnceListener(event: 'connect', listener: () => void): this;
prependOnceListener(event: 'error', listener: (err: Error) => void): this;
prependOnceListener(event: 'listening', listener: () => void): this;
prependOnceListener(event: 'message', listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
}
}
declare module 'node:dgram' {

View File

@ -0,0 +1,155 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* The `diagnostics_channel` module provides an API to create named channels
* to report arbitrary message data for diagnostics purposes.
*
* It can be accessed using:
*
* ```js
* import diagnostics_channel from 'diagnostics_channel';
* ```
*
* It is intended that a module writer wanting to report diagnostics messages
* will create one or many top-level channels to report messages through.
* Channels may also be acquired at runtime but it is not encouraged
* due to the additional overhead of doing so. Channels may be exported for
* convenience, but as long as the name is known it can be acquired anywhere.
*
* If you intend for your module to produce diagnostics data for others to
* consume it is recommended that you include documentation of what named
* channels are used along with the shape of the message data. Channel names
* should generally include the module name to avoid collisions with data from
* other modules.
* @experimental
* @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/diagnostics_channel.js)
*/
declare module 'diagnostics_channel' {
/**
* Check if there are active subscribers to the named channel. This is helpful if
* the message you want to send might be expensive to prepare.
*
* This API is optional but helpful when trying to publish messages from very
* performance-sensitive code.
*
* ```js
* import diagnostics_channel from 'diagnostics_channel';
*
* if (diagnostics_channel.hasSubscribers('my-channel')) {
* // There are subscribers, prepare and publish message
* }
* ```
* @since v15.1.0, v14.17.0
* @param name The channel name
* @return If there are active subscribers
*/
function hasSubscribers(name: string | symbol): boolean;
/**
* This is the primary entry-point for anyone wanting to interact with a named
* channel. It produces a channel object which is optimized to reduce overhead at
* publish time as much as possible.
*
* ```js
* import diagnostics_channel from 'diagnostics_channel';
*
* const channel = diagnostics_channel.channel('my-channel');
* ```
* @since v15.1.0, v14.17.0
* @param name The channel name
* @return The named channel object
*/
function channel(name: string | symbol): Channel;
type ChannelListener = (message: unknown, name: string | symbol) => void;
/**
* The class `Channel` represents an individual named channel within the data
* pipeline. It is use to track subscribers and to publish messages when there
* are subscribers present. It exists as a separate object to avoid channel
* lookups at publish time, enabling very fast publish speeds and allowing
* for heavy use while incurring very minimal cost. Channels are created with {@link channel}, constructing a channel directly
* with `new Channel(name)` is not supported.
* @since v15.1.0, v14.17.0
*/
class Channel {
readonly name: string | symbol;
/**
* Check if there are active subscribers to this channel. This is helpful if
* the message you want to send might be expensive to prepare.
*
* This API is optional but helpful when trying to publish messages from very
* performance-sensitive code.
*
* ```js
* import diagnostics_channel from 'diagnostics_channel';
*
* const channel = diagnostics_channel.channel('my-channel');
*
* if (channel.hasSubscribers) {
* // There are subscribers, prepare and publish message
* }
* ```
* @since v15.1.0, v14.17.0
*/
readonly hasSubscribers: boolean;
private constructor(name: string | symbol);
/**
* Publish a message to any subscribers to the channel. This will
* trigger message handlers synchronously so they will execute within
* the same context.
*
* ```js
* import diagnostics_channel from 'diagnostics_channel';
*
* const channel = diagnostics_channel.channel('my-channel');
*
* channel.publish({
* some: 'message'
* });
* ```
* @since v15.1.0, v14.17.0
* @param message The message to send to the channel subscribers
*/
publish(message: unknown): void;
/**
* Register a message handler to subscribe to this channel. This message handler
* will be run synchronously whenever a message is published to the channel. Any
* errors thrown in the message handler will trigger an `'uncaughtException'`.
*
* ```js
* import diagnostics_channel from 'diagnostics_channel';
*
* const channel = diagnostics_channel.channel('my-channel');
*
* channel.subscribe((message, name) => {
* // Received data
* });
* ```
* @since v15.1.0, v14.17.0
* @param onMessage The handler to receive channel messages
*/
subscribe(onMessage: ChannelListener): void;
/**
* Remove a message handler previously registered to this channel with `channel.subscribe(onMessage)`.
*
* ```js
* import diagnostics_channel from 'diagnostics_channel';
*
* const channel = diagnostics_channel.channel('my-channel');
*
* function onMessage(message, name) {
* // Received data
* }
*
* channel.subscribe(onMessage);
*
* channel.unsubscribe(onMessage);
* ```
* @since v15.1.0, v14.17.0
* @param onMessage The previous subscribed handler to remove
*/
unsubscribe(onMessage: ChannelListener): void;
}
}
declare module 'node:diagnostics_channel' {
export * from 'diagnostics_channel';
}

View File

@ -1,89 +1,194 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* The `dns` module enables name resolution. For example, use it to look up IP
* addresses of host names.
*
* Although named for the [Domain Name System (DNS)](https://en.wikipedia.org/wiki/Domain_Name_System), it does not always use the
* DNS protocol for lookups. {@link lookup} uses the operating system
* facilities to perform name resolution. It may not need to perform any network
* communication. To perform name resolution the way other applications on the same
* system do, use {@link lookup}.
*
* ```js
* const dns = require('dns');
*
* dns.lookup('example.org', (err, address, family) => {
* console.log('address: %j family: IPv%s', address, family);
* });
* // address: "93.184.216.34" family: IPv4
* ```
*
* All other functions in the `dns` module connect to an actual DNS server to
* perform name resolution. They will always use the network to perform DNS
* queries. These functions do not use the same set of configuration files used by {@link lookup} (e.g. `/etc/hosts`). Use these functions to always perform
* DNS queries, bypassing other name-resolution facilities.
*
* ```js
* const dns = require('dns');
*
* dns.resolve4('archive.org', (err, addresses) => {
* if (err) throw err;
*
* console.log(`addresses: ${JSON.stringify(addresses)}`);
*
* addresses.forEach((a) => {
* dns.reverse(a, (err, hostnames) => {
* if (err) {
* throw err;
* }
* console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
* });
* });
* });
* ```
*
* See the `Implementation considerations section` for more information.
* @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/dns.js)
*/
declare module 'dns' {
import * as dnsPromises from 'node:dns/promises';
// Supported getaddrinfo flags.
const ADDRCONFIG: number;
const V4MAPPED: number;
export const ADDRCONFIG: number;
export const V4MAPPED: number;
/**
* If `dns.V4MAPPED` is specified, return resolved IPv6 addresses as
* well as IPv4 mapped IPv6 addresses.
*/
const ALL: number;
interface LookupOptions {
export const ALL: number;
export interface LookupOptions {
family?: number | undefined;
hints?: number | undefined;
all?: boolean | undefined;
verbatim?: boolean | undefined;
}
interface LookupOneOptions extends LookupOptions {
export interface LookupOneOptions extends LookupOptions {
all?: false | undefined;
}
interface LookupAllOptions extends LookupOptions {
export interface LookupAllOptions extends LookupOptions {
all: true;
}
interface LookupAddress {
export interface LookupAddress {
address: string;
family: number;
}
function lookup(hostname: string, family: number, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
function lookup(hostname: string, options: LookupOneOptions, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
function lookup(hostname: string, options: LookupAllOptions, callback: (err: NodeJS.ErrnoException | null, addresses: LookupAddress[]) => void): void;
function lookup(hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, address: string | LookupAddress[], family: number) => void): void;
function lookup(hostname: string, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
// NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime.
namespace lookup {
/**
* Resolves a host name (e.g. `'nodejs.org'`) into the first found A (IPv4) or
* AAAA (IPv6) record. All `option` properties are optional. If `options` is an
* integer, then it must be `4` or `6` if `options` is not provided, then IPv4
* and IPv6 addresses are both returned if found.
*
* With the `all` option set to `true`, the arguments for `callback` change to`(err, addresses)`, with `addresses` being an array of objects with the
* properties `address` and `family`.
*
* On error, `err` is an `Error` object, where `err.code` is the error code.
* Keep in mind that `err.code` will be set to `'ENOTFOUND'` not only when
* the host name does not exist but also when the lookup fails in other ways
* such as no available file descriptors.
*
* `dns.lookup()` does not necessarily have anything to do with the DNS protocol.
* The implementation uses an operating system facility that can associate names
* with addresses, and vice versa. This implementation can have subtle but
* important consequences on the behavior of any Node.js program. Please take some
* time to consult the `Implementation considerations section` before using`dns.lookup()`.
*
* Example usage:
*
* ```js
* const dns = require('dns');
* const options = {
* family: 6,
* hints: dns.ADDRCONFIG | dns.V4MAPPED,
* };
* dns.lookup('example.com', options, (err, address, family) =>
* console.log('address: %j family: IPv%s', address, family));
* // address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
*
* // When options.all is true, the result will be an Array.
* options.all = true;
* dns.lookup('example.com', options, (err, addresses) =>
* console.log('addresses: %j', addresses));
* // addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
* ```
*
* If this method is invoked as its `util.promisify()` ed version, and `all`is not set to `true`, it returns a `Promise` for an `Object` with `address` and`family` properties.
* @since v0.1.90
*/
export function lookup(hostname: string, family: number, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
export function lookup(hostname: string, options: LookupOneOptions, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
export function lookup(hostname: string, options: LookupAllOptions, callback: (err: NodeJS.ErrnoException | null, addresses: LookupAddress[]) => void): void;
export function lookup(hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, address: string | LookupAddress[], family: number) => void): void;
export function lookup(hostname: string, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
export namespace lookup {
function __promisify__(hostname: string, options: LookupAllOptions): Promise<LookupAddress[]>;
function __promisify__(hostname: string, options?: LookupOneOptions | number): Promise<LookupAddress>;
function __promisify__(hostname: string, options: LookupOptions): Promise<LookupAddress | LookupAddress[]>;
}
function lookupService(address: string, port: number, callback: (err: NodeJS.ErrnoException | null, hostname: string, service: string) => void): void;
namespace lookupService {
function __promisify__(address: string, port: number): Promise<{ hostname: string, service: string }>;
/**
* Resolves the given `address` and `port` into a host name and service using
* the operating system's underlying `getnameinfo` implementation.
*
* If `address` is not a valid IP address, a `TypeError` will be thrown.
* The `port` will be coerced to a number. If it is not a legal port, a `TypeError`will be thrown.
*
* On an error, `err` is an `Error` object, where `err.code` is the error code.
*
* ```js
* const dns = require('dns');
* dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
* console.log(hostname, service);
* // Prints: localhost ssh
* });
* ```
*
* If this method is invoked as its `util.promisify()` ed version, it returns a`Promise` for an `Object` with `hostname` and `service` properties.
* @since v0.11.14
*/
export function lookupService(address: string, port: number, callback: (err: NodeJS.ErrnoException | null, hostname: string, service: string) => void): void;
export namespace lookupService {
function __promisify__(
address: string,
port: number
): Promise<{
hostname: string;
service: string;
}>;
}
interface ResolveOptions {
export interface ResolveOptions {
ttl: boolean;
}
interface ResolveWithTtlOptions extends ResolveOptions {
export interface ResolveWithTtlOptions extends ResolveOptions {
ttl: true;
}
interface RecordWithTtl {
export interface RecordWithTtl {
address: string;
ttl: number;
}
/** @deprecated Use `AnyARecord` or `AnyAaaaRecord` instead. */
type AnyRecordWithTtl = AnyARecord | AnyAaaaRecord;
interface AnyARecord extends RecordWithTtl {
type: "A";
export type AnyRecordWithTtl = AnyARecord | AnyAaaaRecord;
export interface AnyARecord extends RecordWithTtl {
type: 'A';
}
interface AnyAaaaRecord extends RecordWithTtl {
type: "AAAA";
export interface AnyAaaaRecord extends RecordWithTtl {
type: 'AAAA';
}
interface MxRecord {
export interface CaaRecord {
critial: number;
issue?: string | undefined;
issuewild?: string | undefined;
iodef?: string | undefined;
contactemail?: string | undefined;
contactphone?: string | undefined;
}
export interface MxRecord {
priority: number;
exchange: string;
}
interface AnyMxRecord extends MxRecord {
type: "MX";
export interface AnyMxRecord extends MxRecord {
type: 'MX';
}
interface NaptrRecord {
export interface NaptrRecord {
flags: string;
service: string;
regexp: string;
@ -91,12 +196,10 @@ declare module 'dns' {
order: number;
preference: number;
}
interface AnyNaptrRecord extends NaptrRecord {
type: "NAPTR";
export interface AnyNaptrRecord extends NaptrRecord {
type: 'NAPTR';
}
interface SoaRecord {
export interface SoaRecord {
nsname: string;
hostmaster: string;
serial: number;
@ -105,188 +208,415 @@ declare module 'dns' {
expire: number;
minttl: number;
}
interface AnySoaRecord extends SoaRecord {
type: "SOA";
export interface AnySoaRecord extends SoaRecord {
type: 'SOA';
}
interface SrvRecord {
export interface SrvRecord {
priority: number;
weight: number;
port: number;
name: string;
}
interface AnySrvRecord extends SrvRecord {
type: "SRV";
export interface AnySrvRecord extends SrvRecord {
type: 'SRV';
}
interface AnyTxtRecord {
type: "TXT";
export interface AnyTxtRecord {
type: 'TXT';
entries: string[];
}
interface AnyNsRecord {
type: "NS";
export interface AnyNsRecord {
type: 'NS';
value: string;
}
interface AnyPtrRecord {
type: "PTR";
export interface AnyPtrRecord {
type: 'PTR';
value: string;
}
interface AnyCnameRecord {
type: "CNAME";
export interface AnyCnameRecord {
type: 'CNAME';
value: string;
}
type AnyRecord = AnyARecord |
AnyAaaaRecord |
AnyCnameRecord |
AnyMxRecord |
AnyNaptrRecord |
AnyNsRecord |
AnyPtrRecord |
AnySoaRecord |
AnySrvRecord |
AnyTxtRecord;
function resolve(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
function resolve(hostname: string, rrtype: "A", callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
function resolve(hostname: string, rrtype: "AAAA", callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
function resolve(hostname: string, rrtype: "ANY", callback: (err: NodeJS.ErrnoException | null, addresses: AnyRecord[]) => void): void;
function resolve(hostname: string, rrtype: "CNAME", callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
function resolve(hostname: string, rrtype: "MX", callback: (err: NodeJS.ErrnoException | null, addresses: MxRecord[]) => void): void;
function resolve(hostname: string, rrtype: "NAPTR", callback: (err: NodeJS.ErrnoException | null, addresses: NaptrRecord[]) => void): void;
function resolve(hostname: string, rrtype: "NS", callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
function resolve(hostname: string, rrtype: "PTR", callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
function resolve(hostname: string, rrtype: "SOA", callback: (err: NodeJS.ErrnoException | null, addresses: SoaRecord) => void): void;
function resolve(hostname: string, rrtype: "SRV", callback: (err: NodeJS.ErrnoException | null, addresses: SrvRecord[]) => void): void;
function resolve(hostname: string, rrtype: "TXT", callback: (err: NodeJS.ErrnoException | null, addresses: string[][]) => void): void;
function resolve(
export type AnyRecord = AnyARecord | AnyAaaaRecord | AnyCnameRecord | AnyMxRecord | AnyNaptrRecord | AnyNsRecord | AnyPtrRecord | AnySoaRecord | AnySrvRecord | AnyTxtRecord;
/**
* Uses the DNS protocol to resolve a host name (e.g. `'nodejs.org'`) into an array
* of the resource records. The `callback` function has arguments`(err, records)`. When successful, `records` will be an array of resource
* records. The type and structure of individual results varies based on `rrtype`:
*
* <omitted>
*
* On error, `err` is an `Error` object, where `err.code` is one of the `DNS error codes`.
* @since v0.1.27
* @param hostname Host name to resolve.
* @param [rrtype='A'] Resource record type.
*/
export function resolve(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export function resolve(hostname: string, rrtype: 'A', callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export function resolve(hostname: string, rrtype: 'AAAA', callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export function resolve(hostname: string, rrtype: 'ANY', callback: (err: NodeJS.ErrnoException | null, addresses: AnyRecord[]) => void): void;
export function resolve(hostname: string, rrtype: 'CNAME', callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export function resolve(hostname: string, rrtype: 'MX', callback: (err: NodeJS.ErrnoException | null, addresses: MxRecord[]) => void): void;
export function resolve(hostname: string, rrtype: 'NAPTR', callback: (err: NodeJS.ErrnoException | null, addresses: NaptrRecord[]) => void): void;
export function resolve(hostname: string, rrtype: 'NS', callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export function resolve(hostname: string, rrtype: 'PTR', callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export function resolve(hostname: string, rrtype: 'SOA', callback: (err: NodeJS.ErrnoException | null, addresses: SoaRecord) => void): void;
export function resolve(hostname: string, rrtype: 'SRV', callback: (err: NodeJS.ErrnoException | null, addresses: SrvRecord[]) => void): void;
export function resolve(hostname: string, rrtype: 'TXT', callback: (err: NodeJS.ErrnoException | null, addresses: string[][]) => void): void;
export function resolve(
hostname: string,
rrtype: string,
callback: (err: NodeJS.ErrnoException | null, addresses: string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[]) => void,
callback: (err: NodeJS.ErrnoException | null, addresses: string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[]) => void
): void;
// NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime.
namespace resolve {
function __promisify__(hostname: string, rrtype?: "A" | "AAAA" | "CNAME" | "NS" | "PTR"): Promise<string[]>;
function __promisify__(hostname: string, rrtype: "ANY"): Promise<AnyRecord[]>;
function __promisify__(hostname: string, rrtype: "MX"): Promise<MxRecord[]>;
function __promisify__(hostname: string, rrtype: "NAPTR"): Promise<NaptrRecord[]>;
function __promisify__(hostname: string, rrtype: "SOA"): Promise<SoaRecord>;
function __promisify__(hostname: string, rrtype: "SRV"): Promise<SrvRecord[]>;
function __promisify__(hostname: string, rrtype: "TXT"): Promise<string[][]>;
export namespace resolve {
function __promisify__(hostname: string, rrtype?: 'A' | 'AAAA' | 'CNAME' | 'NS' | 'PTR'): Promise<string[]>;
function __promisify__(hostname: string, rrtype: 'ANY'): Promise<AnyRecord[]>;
function __promisify__(hostname: string, rrtype: 'MX'): Promise<MxRecord[]>;
function __promisify__(hostname: string, rrtype: 'NAPTR'): Promise<NaptrRecord[]>;
function __promisify__(hostname: string, rrtype: 'SOA'): Promise<SoaRecord>;
function __promisify__(hostname: string, rrtype: 'SRV'): Promise<SrvRecord[]>;
function __promisify__(hostname: string, rrtype: 'TXT'): Promise<string[][]>;
function __promisify__(hostname: string, rrtype: string): Promise<string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[]>;
}
function resolve4(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
function resolve4(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException | null, addresses: RecordWithTtl[]) => void): void;
function resolve4(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException | null, addresses: string[] | RecordWithTtl[]) => void): void;
// NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime.
namespace resolve4 {
/**
* Uses the DNS protocol to resolve a IPv4 addresses (`A` records) for the`hostname`. The `addresses` argument passed to the `callback` function
* will contain an array of IPv4 addresses (e.g.`['74.125.79.104', '74.125.79.105', '74.125.79.106']`).
* @since v0.1.16
* @param hostname Host name to resolve.
*/
export function resolve4(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export function resolve4(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException | null, addresses: RecordWithTtl[]) => void): void;
export function resolve4(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException | null, addresses: string[] | RecordWithTtl[]) => void): void;
export namespace resolve4 {
function __promisify__(hostname: string): Promise<string[]>;
function __promisify__(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
function __promisify__(hostname: string, options?: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
}
function resolve6(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
function resolve6(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException | null, addresses: RecordWithTtl[]) => void): void;
function resolve6(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException | null, addresses: string[] | RecordWithTtl[]) => void): void;
// NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime.
namespace resolve6 {
/**
* Uses the DNS protocol to resolve a IPv6 addresses (`AAAA` records) for the`hostname`. The `addresses` argument passed to the `callback` function
* will contain an array of IPv6 addresses.
* @since v0.1.16
* @param hostname Host name to resolve.
*/
export function resolve6(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export function resolve6(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException | null, addresses: RecordWithTtl[]) => void): void;
export function resolve6(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException | null, addresses: string[] | RecordWithTtl[]) => void): void;
export namespace resolve6 {
function __promisify__(hostname: string): Promise<string[]>;
function __promisify__(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
function __promisify__(hostname: string, options?: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
}
function resolveCname(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
namespace resolveCname {
/**
* Uses the DNS protocol to resolve `CNAME` records for the `hostname`. The`addresses` argument passed to the `callback` function
* will contain an array of canonical name records available for the `hostname`(e.g. `['bar.example.com']`).
* @since v0.3.2
*/
export function resolveCname(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export namespace resolveCname {
function __promisify__(hostname: string): Promise<string[]>;
}
function resolveMx(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: MxRecord[]) => void): void;
namespace resolveMx {
/**
* Uses the DNS protocol to resolve `CAA` records for the `hostname`. The`addresses` argument passed to the `callback` function
* will contain an array of certification authority authorization records
* available for the `hostname` (e.g. `[{critical: 0, iodef: 'mailto:pki@example.com'}, {critical: 128, issue: 'pki.example.com'}]`).
* @since v15.0.0
*/
export function resolveCaa(hostname: string, callback: (err: NodeJS.ErrnoException | null, records: CaaRecord[]) => void): void;
export namespace resolveCaa {
function __promisify__(hostname: string): Promise<CaaRecord[]>;
}
/**
* Uses the DNS protocol to resolve mail exchange records (`MX` records) for the`hostname`. The `addresses` argument passed to the `callback` function will
* contain an array of objects containing both a `priority` and `exchange`property (e.g. `[{priority: 10, exchange: 'mx.example.com'}, ...]`).
* @since v0.1.27
*/
export function resolveMx(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: MxRecord[]) => void): void;
export namespace resolveMx {
function __promisify__(hostname: string): Promise<MxRecord[]>;
}
function resolveNaptr(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: NaptrRecord[]) => void): void;
namespace resolveNaptr {
/**
* Uses the DNS protocol to resolve regular expression based records (`NAPTR`records) for the `hostname`. The `addresses` argument passed to the `callback`function will contain an array of
* objects with the following properties:
*
* * `flags`
* * `service`
* * `regexp`
* * `replacement`
* * `order`
* * `preference`
*
* ```js
* {
* flags: 's',
* service: 'SIP+D2U',
* regexp: '',
* replacement: '_sip._udp.example.com',
* order: 30,
* preference: 100
* }
* ```
* @since v0.9.12
*/
export function resolveNaptr(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: NaptrRecord[]) => void): void;
export namespace resolveNaptr {
function __promisify__(hostname: string): Promise<NaptrRecord[]>;
}
function resolveNs(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
namespace resolveNs {
/**
* Uses the DNS protocol to resolve name server records (`NS` records) for the`hostname`. The `addresses` argument passed to the `callback` function will
* contain an array of name server records available for `hostname`(e.g. `['ns1.example.com', 'ns2.example.com']`).
* @since v0.1.90
*/
export function resolveNs(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export namespace resolveNs {
function __promisify__(hostname: string): Promise<string[]>;
}
function resolvePtr(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
namespace resolvePtr {
/**
* Uses the DNS protocol to resolve pointer records (`PTR` records) for the`hostname`. The `addresses` argument passed to the `callback` function will
* be an array of strings containing the reply records.
* @since v6.0.0
*/
export function resolvePtr(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void): void;
export namespace resolvePtr {
function __promisify__(hostname: string): Promise<string[]>;
}
function resolveSoa(hostname: string, callback: (err: NodeJS.ErrnoException | null, address: SoaRecord) => void): void;
namespace resolveSoa {
/**
* Uses the DNS protocol to resolve a start of authority record (`SOA` record) for
* the `hostname`. The `address` argument passed to the `callback` function will
* be an object with the following properties:
*
* * `nsname`
* * `hostmaster`
* * `serial`
* * `refresh`
* * `retry`
* * `expire`
* * `minttl`
*
* ```js
* {
* nsname: 'ns.example.com',
* hostmaster: 'root.example.com',
* serial: 2013101809,
* refresh: 10000,
* retry: 2400,
* expire: 604800,
* minttl: 3600
* }
* ```
* @since v0.11.10
*/
export function resolveSoa(hostname: string, callback: (err: NodeJS.ErrnoException | null, address: SoaRecord) => void): void;
export namespace resolveSoa {
function __promisify__(hostname: string): Promise<SoaRecord>;
}
function resolveSrv(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: SrvRecord[]) => void): void;
namespace resolveSrv {
/**
* Uses the DNS protocol to resolve service records (`SRV` records) for the`hostname`. The `addresses` argument passed to the `callback` function will
* be an array of objects with the following properties:
*
* * `priority`
* * `weight`
* * `port`
* * `name`
*
* ```js
* {
* priority: 10,
* weight: 5,
* port: 21223,
* name: 'service.example.com'
* }
* ```
* @since v0.1.27
*/
export function resolveSrv(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: SrvRecord[]) => void): void;
export namespace resolveSrv {
function __promisify__(hostname: string): Promise<SrvRecord[]>;
}
function resolveTxt(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[][]) => void): void;
namespace resolveTxt {
/**
* Uses the DNS protocol to resolve text queries (`TXT` records) for the`hostname`. The `records` argument passed to the `callback` function is a
* two-dimensional array of the text records available for `hostname` (e.g.`[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of
* one record. Depending on the use case, these could be either joined together or
* treated separately.
* @since v0.1.27
*/
export function resolveTxt(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: string[][]) => void): void;
export namespace resolveTxt {
function __promisify__(hostname: string): Promise<string[][]>;
}
function resolveAny(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: AnyRecord[]) => void): void;
namespace resolveAny {
/**
* Uses the DNS protocol to resolve all records (also known as `ANY` or `*` query).
* The `ret` argument passed to the `callback` function will be an array containing
* various types of records. Each object has a property `type` that indicates the
* type of the current record. And depending on the `type`, additional properties
* will be present on the object:
*
* <omitted>
*
* Here is an example of the `ret` object passed to the callback:
*
* ```js
* [ { type: 'A', address: '127.0.0.1', ttl: 299 },
* { type: 'CNAME', value: 'example.com' },
* { type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },
* { type: 'NS', value: 'ns1.example.com' },
* { type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
* { type: 'SOA',
* nsname: 'ns1.example.com',
* hostmaster: 'admin.example.com',
* serial: 156696742,
* refresh: 900,
* retry: 900,
* expire: 1800,
* minttl: 60 } ]
* ```
*
* DNS server operators may choose not to respond to `ANY`queries. It may be better to call individual methods like {@link resolve4},{@link resolveMx}, and so on. For more details, see [RFC
* 8482](https://tools.ietf.org/html/rfc8482).
*/
export function resolveAny(hostname: string, callback: (err: NodeJS.ErrnoException | null, addresses: AnyRecord[]) => void): void;
export namespace resolveAny {
function __promisify__(hostname: string): Promise<AnyRecord[]>;
}
function reverse(ip: string, callback: (err: NodeJS.ErrnoException | null, hostnames: string[]) => void): void;
function setServers(servers: ReadonlyArray<string>): void;
function getServers(): string[];
function setDefaultResultOrder(order: 'ipv4first' | 'verbatim'): void;
/**
* Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an
* array of host names.
*
* On error, `err` is an `Error` object, where `err.code` is
* one of the `DNS error codes`.
* @since v0.1.16
*/
export function reverse(ip: string, callback: (err: NodeJS.ErrnoException | null, hostnames: string[]) => void): void;
/**
* Sets the IP address and port of servers to be used when performing DNS
* resolution. The `servers` argument is an array of [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6) formatted
* addresses. If the port is the IANA default DNS port (53) it can be omitted.
*
* ```js
* dns.setServers([
* '4.4.4.4',
* '[2001:4860:4860::8888]',
* '4.4.4.4:1053',
* '[2001:4860:4860::8888]:1053',
* ]);
* ```
*
* An error will be thrown if an invalid address is provided.
*
* The `dns.setServers()` method must not be called while a DNS query is in
* progress.
*
* The {@link setServers} method affects only {@link resolve},`dns.resolve*()` and {@link reverse} (and specifically _not_ {@link lookup}).
*
* This method works much like [resolve.conf](https://man7.org/linux/man-pages/man5/resolv.conf.5.html).
* That is, if attempting to resolve with the first server provided results in a`NOTFOUND` error, the `resolve()` method will _not_ attempt to resolve with
* subsequent servers provided. Fallback DNS servers will only be used if the
* earlier ones time out or result in some other error.
* @since v0.11.3
* @param servers array of `RFC 5952` formatted addresses
*/
export function setServers(servers: ReadonlyArray<string>): void;
/**
* Returns an array of IP address strings, formatted according to [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6),
* that are currently configured for DNS resolution. A string will include a port
* section if a custom port is used.
*
* ```js
* [
* '4.4.4.4',
* '2001:4860:4860::8888',
* '4.4.4.4:1053',
* '[2001:4860:4860::8888]:1053',
* ]
* ```
* @since v0.11.3
*/
export function getServers(): string[];
/**
* Set the default value of `verbatim` in {@link lookup}. The value could be:
* - `ipv4first`: sets default `verbatim` `false`.
* - `verbatim`: sets default `verbatim` `true`.
*
* The default is `ipv4first` and {@link setDefaultResultOrder} have higher priority than `--dns-result-order`.
* When using worker threads, {@link setDefaultResultOrder} from the main thread won't affect the default dns orders in workers.
* @since v14.18.0
* @param order must be 'ipv4first' or 'verbatim'.
*/
export function setDefaultResultOrder(order: 'ipv4first' | 'verbatim'): void;
// Error codes
const NODATA: string;
const FORMERR: string;
const SERVFAIL: string;
const NOTFOUND: string;
const NOTIMP: string;
const REFUSED: string;
const BADQUERY: string;
const BADNAME: string;
const BADFAMILY: string;
const BADRESP: string;
const CONNREFUSED: string;
const TIMEOUT: string;
const EOF: string;
const FILE: string;
const NOMEM: string;
const DESTRUCTION: string;
const BADSTR: string;
const BADFLAGS: string;
const NONAME: string;
const BADHINTS: string;
const NOTINITIALIZED: string;
const LOADIPHLPAPI: string;
const ADDRGETNETWORKPARAMS: string;
const CANCELLED: string;
interface ResolverOptions {
export const NODATA: string;
export const FORMERR: string;
export const SERVFAIL: string;
export const NOTFOUND: string;
export const NOTIMP: string;
export const REFUSED: string;
export const BADQUERY: string;
export const BADNAME: string;
export const BADFAMILY: string;
export const BADRESP: string;
export const CONNREFUSED: string;
export const TIMEOUT: string;
export const EOF: string;
export const FILE: string;
export const NOMEM: string;
export const DESTRUCTION: string;
export const BADSTR: string;
export const BADFLAGS: string;
export const NONAME: string;
export const BADHINTS: string;
export const NOTINITIALIZED: string;
export const LOADIPHLPAPI: string;
export const ADDRGETNETWORKPARAMS: string;
export const CANCELLED: string;
export interface ResolverOptions {
timeout?: number | undefined;
/**
* @default 4
*/
tries?: number;
}
class Resolver {
/**
* An independent resolver for DNS requests.
*
* Creating a new resolver uses the default server settings. Setting
* the servers used for a resolver using `resolver.setServers()` does not affect
* other resolvers:
*
* ```js
* const { Resolver } = require('dns');
* const resolver = new Resolver();
* resolver.setServers(['4.4.4.4']);
*
* // This request will use the server at 4.4.4.4, independent of global settings.
* resolver.resolve4('example.org', (err, addresses) => {
* // ...
* });
* ```
*
* The following methods from the `dns` module are available:
*
* * `resolver.getServers()`
* * `resolver.resolve()`
* * `resolver.resolve4()`
* * `resolver.resolve6()`
* * `resolver.resolveAny()`
* * `resolver.resolveCaa()`
* * `resolver.resolveCname()`
* * `resolver.resolveMx()`
* * `resolver.resolveNaptr()`
* * `resolver.resolveNs()`
* * `resolver.resolvePtr()`
* * `resolver.resolveSoa()`
* * `resolver.resolveSrv()`
* * `resolver.resolveTxt()`
* * `resolver.reverse()`
* * `resolver.setServers()`
* @since v8.3.0
*/
export class Resolver {
constructor(options?: ResolverOptions);
/**
* Cancel all outstanding DNS queries made by this resolver. The corresponding
* callbacks will be called with an error with code `ECANCELLED`.
* @since v8.3.0
*/
cancel(): void;
getServers: typeof getServers;
resolve: typeof resolve;
@ -302,88 +632,25 @@ declare module 'dns' {
resolveSrv: typeof resolveSrv;
resolveTxt: typeof resolveTxt;
reverse: typeof reverse;
/**
* The resolver instance will send its requests from the specified IP address.
* This allows programs to specify outbound interfaces when used on multi-homed
* systems.
*
* If a v4 or v6 address is not specified, it is set to the default, and the
* operating system will choose a local address automatically.
*
* The resolver will use the v4 local address when making requests to IPv4 DNS
* servers, and the v6 local address when making requests to IPv6 DNS servers.
* The `rrtype` of resolution requests has no impact on the local address used.
* @since v15.1.0
* @param [ipv4='0.0.0.0'] A string representation of an IPv4 address.
* @param [ipv6='::0'] A string representation of an IPv6 address.
*/
setLocalAddress(ipv4?: string, ipv6?: string): void;
setServers: typeof setServers;
}
namespace promises {
function getServers(): string[];
function lookup(hostname: string, family: number): Promise<LookupAddress>;
function lookup(hostname: string, options: LookupOneOptions): Promise<LookupAddress>;
function lookup(hostname: string, options: LookupAllOptions): Promise<LookupAddress[]>;
function lookup(hostname: string, options: LookupOptions): Promise<LookupAddress | LookupAddress[]>;
function lookup(hostname: string): Promise<LookupAddress>;
function lookupService(address: string, port: number): Promise<{ hostname: string, service: string }>;
function resolve(hostname: string): Promise<string[]>;
function resolve(hostname: string, rrtype: "A"): Promise<string[]>;
function resolve(hostname: string, rrtype: "AAAA"): Promise<string[]>;
function resolve(hostname: string, rrtype: "ANY"): Promise<AnyRecord[]>;
function resolve(hostname: string, rrtype: "CNAME"): Promise<string[]>;
function resolve(hostname: string, rrtype: "MX"): Promise<MxRecord[]>;
function resolve(hostname: string, rrtype: "NAPTR"): Promise<NaptrRecord[]>;
function resolve(hostname: string, rrtype: "NS"): Promise<string[]>;
function resolve(hostname: string, rrtype: "PTR"): Promise<string[]>;
function resolve(hostname: string, rrtype: "SOA"): Promise<SoaRecord>;
function resolve(hostname: string, rrtype: "SRV"): Promise<SrvRecord[]>;
function resolve(hostname: string, rrtype: "TXT"): Promise<string[][]>;
function resolve(hostname: string, rrtype: string): Promise<string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[]>;
function resolve4(hostname: string): Promise<string[]>;
function resolve4(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
function resolve4(hostname: string, options: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
function resolve6(hostname: string): Promise<string[]>;
function resolve6(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
function resolve6(hostname: string, options: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
function resolveAny(hostname: string): Promise<AnyRecord[]>;
function resolveCname(hostname: string): Promise<string[]>;
function resolveMx(hostname: string): Promise<MxRecord[]>;
function resolveNaptr(hostname: string): Promise<NaptrRecord[]>;
function resolveNs(hostname: string): Promise<string[]>;
function resolvePtr(hostname: string): Promise<string[]>;
function resolveSoa(hostname: string): Promise<SoaRecord>;
function resolveSrv(hostname: string): Promise<SrvRecord[]>;
function resolveTxt(hostname: string): Promise<string[][]>;
function reverse(ip: string): Promise<string[]>;
function setServers(servers: ReadonlyArray<string>): void;
function setDefaultResultOrder(order: 'ipv4first' | 'verbatim'): void;
class Resolver {
constructor(options?: ResolverOptions);
cancel(): void;
getServers: typeof getServers;
resolve: typeof resolve;
resolve4: typeof resolve4;
resolve6: typeof resolve6;
resolveAny: typeof resolveAny;
resolveCname: typeof resolveCname;
resolveMx: typeof resolveMx;
resolveNaptr: typeof resolveNaptr;
resolveNs: typeof resolveNs;
resolvePtr: typeof resolvePtr;
resolveSoa: typeof resolveSoa;
resolveSrv: typeof resolveSrv;
resolveTxt: typeof resolveTxt;
reverse: typeof reverse;
setLocalAddress(ipv4?: string, ipv6?: string): void;
setServers: typeof setServers;
}
}
export { dnsPromises as promises };
}
declare module 'node:dns' {
export * from 'dns';

View File

@ -0,0 +1,371 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* The `dns.promises` API provides an alternative set of asynchronous DNS methods
* that return `Promise` objects rather than using callbacks. The API is accessible
* via `require('dns').promises` or `require('dns/promises')`.
* @since v10.6.0
*/
declare module 'dns/promises' {
import {
LookupAddress,
LookupOneOptions,
LookupAllOptions,
LookupOptions,
AnyRecord,
CaaRecord,
MxRecord,
NaptrRecord,
SoaRecord,
SrvRecord,
ResolveWithTtlOptions,
RecordWithTtl,
ResolveOptions,
ResolverOptions,
} from 'node:dns';
/**
* Returns an array of IP address strings, formatted according to [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6),
* that are currently configured for DNS resolution. A string will include a port
* section if a custom port is used.
*
* ```js
* [
* '4.4.4.4',
* '2001:4860:4860::8888',
* '4.4.4.4:1053',
* '[2001:4860:4860::8888]:1053',
* ]
* ```
* @since v10.6.0
*/
function getServers(): string[];
/**
* Resolves a host name (e.g. `'nodejs.org'`) into the first found A (IPv4) or
* AAAA (IPv6) record. All `option` properties are optional. If `options` is an
* integer, then it must be `4` or `6` if `options` is not provided, then IPv4
* and IPv6 addresses are both returned if found.
*
* With the `all` option set to `true`, the `Promise` is resolved with `addresses`being an array of objects with the properties `address` and `family`.
*
* On error, the `Promise` is rejected with an `Error` object, where `err.code`is the error code.
* Keep in mind that `err.code` will be set to `'ENOTFOUND'` not only when
* the host name does not exist but also when the lookup fails in other ways
* such as no available file descriptors.
*
* `dnsPromises.lookup()` does not necessarily have anything to do with the DNS
* protocol. The implementation uses an operating system facility that can
* associate names with addresses, and vice versa. This implementation can have
* subtle but important consequences on the behavior of any Node.js program. Please
* take some time to consult the `Implementation considerations section` before
* using `dnsPromises.lookup()`.
*
* Example usage:
*
* ```js
* const dns = require('dns');
* const dnsPromises = dns.promises;
* const options = {
* family: 6,
* hints: dns.ADDRCONFIG | dns.V4MAPPED,
* };
*
* dnsPromises.lookup('example.com', options).then((result) => {
* console.log('address: %j family: IPv%s', result.address, result.family);
* // address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
* });
*
* // When options.all is true, the result will be an Array.
* options.all = true;
* dnsPromises.lookup('example.com', options).then((result) => {
* console.log('addresses: %j', result);
* // addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
* });
* ```
* @since v10.6.0
*/
function lookup(hostname: string, family: number): Promise<LookupAddress>;
function lookup(hostname: string, options: LookupOneOptions): Promise<LookupAddress>;
function lookup(hostname: string, options: LookupAllOptions): Promise<LookupAddress[]>;
function lookup(hostname: string, options: LookupOptions): Promise<LookupAddress | LookupAddress[]>;
function lookup(hostname: string): Promise<LookupAddress>;
/**
* Resolves the given `address` and `port` into a host name and service using
* the operating system's underlying `getnameinfo` implementation.
*
* If `address` is not a valid IP address, a `TypeError` will be thrown.
* The `port` will be coerced to a number. If it is not a legal port, a `TypeError`will be thrown.
*
* On error, the `Promise` is rejected with an `Error` object, where `err.code`is the error code.
*
* ```js
* const dnsPromises = require('dns').promises;
* dnsPromises.lookupService('127.0.0.1', 22).then((result) => {
* console.log(result.hostname, result.service);
* // Prints: localhost ssh
* });
* ```
* @since v10.6.0
*/
function lookupService(
address: string,
port: number
): Promise<{
hostname: string;
service: string;
}>;
/**
* Uses the DNS protocol to resolve a host name (e.g. `'nodejs.org'`) into an array
* of the resource records. When successful, the `Promise` is resolved with an
* array of resource records. The type and structure of individual results vary
* based on `rrtype`:
*
* <omitted>
*
* On error, the `Promise` is rejected with an `Error` object, where `err.code`is one of the `DNS error codes`.
* @since v10.6.0
* @param hostname Host name to resolve.
* @param [rrtype='A'] Resource record type.
*/
function resolve(hostname: string): Promise<string[]>;
function resolve(hostname: string, rrtype: 'A'): Promise<string[]>;
function resolve(hostname: string, rrtype: 'AAAA'): Promise<string[]>;
function resolve(hostname: string, rrtype: 'ANY'): Promise<AnyRecord[]>;
function resolve(hostname: string, rrtype: 'CAA'): Promise<CaaRecord[]>;
function resolve(hostname: string, rrtype: 'CNAME'): Promise<string[]>;
function resolve(hostname: string, rrtype: 'MX'): Promise<MxRecord[]>;
function resolve(hostname: string, rrtype: 'NAPTR'): Promise<NaptrRecord[]>;
function resolve(hostname: string, rrtype: 'NS'): Promise<string[]>;
function resolve(hostname: string, rrtype: 'PTR'): Promise<string[]>;
function resolve(hostname: string, rrtype: 'SOA'): Promise<SoaRecord>;
function resolve(hostname: string, rrtype: 'SRV'): Promise<SrvRecord[]>;
function resolve(hostname: string, rrtype: 'TXT'): Promise<string[][]>;
function resolve(hostname: string, rrtype: string): Promise<string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[]>;
/**
* Uses the DNS protocol to resolve IPv4 addresses (`A` records) for the`hostname`. On success, the `Promise` is resolved with an array of IPv4
* addresses (e.g. `['74.125.79.104', '74.125.79.105', '74.125.79.106']`).
* @since v10.6.0
* @param hostname Host name to resolve.
*/
function resolve4(hostname: string): Promise<string[]>;
function resolve4(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
function resolve4(hostname: string, options: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
/**
* Uses the DNS protocol to resolve IPv6 addresses (`AAAA` records) for the`hostname`. On success, the `Promise` is resolved with an array of IPv6
* addresses.
* @since v10.6.0
* @param hostname Host name to resolve.
*/
function resolve6(hostname: string): Promise<string[]>;
function resolve6(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
function resolve6(hostname: string, options: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
/**
* Uses the DNS protocol to resolve all records (also known as `ANY` or `*` query).
* On success, the `Promise` is resolved with an array containing various types of
* records. Each object has a property `type` that indicates the type of the
* current record. And depending on the `type`, additional properties will be
* present on the object:
*
* <omitted>
*
* Here is an example of the result object:
*
* ```js
* [ { type: 'A', address: '127.0.0.1', ttl: 299 },
* { type: 'CNAME', value: 'example.com' },
* { type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },
* { type: 'NS', value: 'ns1.example.com' },
* { type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
* { type: 'SOA',
* nsname: 'ns1.example.com',
* hostmaster: 'admin.example.com',
* serial: 156696742,
* refresh: 900,
* retry: 900,
* expire: 1800,
* minttl: 60 } ]
* ```
* @since v10.6.0
*/
function resolveAny(hostname: string): Promise<AnyRecord[]>;
/**
* Uses the DNS protocol to resolve `CAA` records for the `hostname`. On success,
* the `Promise` is resolved with an array of objects containing available
* certification authority authorization records available for the `hostname`(e.g. `[{critical: 0, iodef: 'mailto:pki@example.com'},{critical: 128, issue: 'pki.example.com'}]`).
* @since v15.0.0
*/
function resolveCaa(hostname: string): Promise<CaaRecord[]>;
/**
* Uses the DNS protocol to resolve `CNAME` records for the `hostname`. On success,
* the `Promise` is resolved with an array of canonical name records available for
* the `hostname` (e.g. `['bar.example.com']`).
* @since v10.6.0
*/
function resolveCname(hostname: string): Promise<string[]>;
/**
* Uses the DNS protocol to resolve mail exchange records (`MX` records) for the`hostname`. On success, the `Promise` is resolved with an array of objects
* containing both a `priority` and `exchange` property (e.g.`[{priority: 10, exchange: 'mx.example.com'}, ...]`).
* @since v10.6.0
*/
function resolveMx(hostname: string): Promise<MxRecord[]>;
/**
* Uses the DNS protocol to resolve regular expression based records (`NAPTR`records) for the `hostname`. On success, the `Promise` is resolved with an array
* of objects with the following properties:
*
* * `flags`
* * `service`
* * `regexp`
* * `replacement`
* * `order`
* * `preference`
*
* ```js
* {
* flags: 's',
* service: 'SIP+D2U',
* regexp: '',
* replacement: '_sip._udp.example.com',
* order: 30,
* preference: 100
* }
* ```
* @since v10.6.0
*/
function resolveNaptr(hostname: string): Promise<NaptrRecord[]>;
/**
* Uses the DNS protocol to resolve name server records (`NS` records) for the`hostname`. On success, the `Promise` is resolved with an array of name server
* records available for `hostname` (e.g.`['ns1.example.com', 'ns2.example.com']`).
* @since v10.6.0
*/
function resolveNs(hostname: string): Promise<string[]>;
/**
* Uses the DNS protocol to resolve pointer records (`PTR` records) for the`hostname`. On success, the `Promise` is resolved with an array of strings
* containing the reply records.
* @since v10.6.0
*/
function resolvePtr(hostname: string): Promise<string[]>;
/**
* Uses the DNS protocol to resolve a start of authority record (`SOA` record) for
* the `hostname`. On success, the `Promise` is resolved with an object with the
* following properties:
*
* * `nsname`
* * `hostmaster`
* * `serial`
* * `refresh`
* * `retry`
* * `expire`
* * `minttl`
*
* ```js
* {
* nsname: 'ns.example.com',
* hostmaster: 'root.example.com',
* serial: 2013101809,
* refresh: 10000,
* retry: 2400,
* expire: 604800,
* minttl: 3600
* }
* ```
* @since v10.6.0
*/
function resolveSoa(hostname: string): Promise<SoaRecord>;
/**
* Uses the DNS protocol to resolve service records (`SRV` records) for the`hostname`. On success, the `Promise` is resolved with an array of objects with
* the following properties:
*
* * `priority`
* * `weight`
* * `port`
* * `name`
*
* ```js
* {
* priority: 10,
* weight: 5,
* port: 21223,
* name: 'service.example.com'
* }
* ```
* @since v10.6.0
*/
function resolveSrv(hostname: string): Promise<SrvRecord[]>;
/**
* Uses the DNS protocol to resolve text queries (`TXT` records) for the`hostname`. On success, the `Promise` is resolved with a two-dimensional array
* of the text records available for `hostname` (e.g.`[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of
* one record. Depending on the use case, these could be either joined together or
* treated separately.
* @since v10.6.0
*/
function resolveTxt(hostname: string): Promise<string[][]>;
/**
* Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an
* array of host names.
*
* On error, the `Promise` is rejected with an `Error` object, where `err.code`is one of the `DNS error codes`.
* @since v10.6.0
*/
function reverse(ip: string): Promise<string[]>;
/**
* Sets the IP address and port of servers to be used when performing DNS
* resolution. The `servers` argument is an array of [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6) formatted
* addresses. If the port is the IANA default DNS port (53) it can be omitted.
*
* ```js
* dnsPromises.setServers([
* '4.4.4.4',
* '[2001:4860:4860::8888]',
* '4.4.4.4:1053',
* '[2001:4860:4860::8888]:1053',
* ]);
* ```
*
* An error will be thrown if an invalid address is provided.
*
* The `dnsPromises.setServers()` method must not be called while a DNS query is in
* progress.
*
* This method works much like [resolve.conf](https://man7.org/linux/man-pages/man5/resolv.conf.5.html).
* That is, if attempting to resolve with the first server provided results in a`NOTFOUND` error, the `resolve()` method will _not_ attempt to resolve with
* subsequent servers provided. Fallback DNS servers will only be used if the
* earlier ones time out or result in some other error.
* @since v10.6.0
* @param servers array of `RFC 5952` formatted addresses
*/
function setServers(servers: ReadonlyArray<string>): void;
/**
* Set the default value of `verbatim` in {@link lookup}. The value could be:
* - `ipv4first`: sets default `verbatim` `false`.
* - `verbatim`: sets default `verbatim` `true`.
*
* The default is `ipv4first` and {@link setDefaultResultOrder} have higher priority than `--dns-result-order`.
* When using worker threads, {@link setDefaultResultOrder} from the main thread won't affect the default dns orders in workers.
* @since v14.18.0
* @param order must be 'ipv4first' or 'verbatim'.
*/
function setDefaultResultOrder(order: 'ipv4first' | 'verbatim'): void;
class Resolver {
constructor(options?: ResolverOptions);
cancel(): void;
getServers: typeof getServers;
resolve: typeof resolve;
resolve4: typeof resolve4;
resolve6: typeof resolve6;
resolveAny: typeof resolveAny;
resolveCname: typeof resolveCname;
resolveMx: typeof resolveMx;
resolveNaptr: typeof resolveNaptr;
resolveNs: typeof resolveNs;
resolvePtr: typeof resolvePtr;
resolveSoa: typeof resolveSoa;
resolveSrv: typeof resolveSrv;
resolveTxt: typeof resolveTxt;
reverse: typeof reverse;
setLocalAddress(ipv4?: string, ipv6?: string): void;
setServers: typeof setServers;
}
}
declare module 'node:dns/promises' {
export * from 'dns/promises';
}

View File

@ -1,28 +1,171 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* **This module is pending deprecation.** Once a replacement API has been
* finalized, this module will be fully deprecated. Most developers should
* **not** have cause to use this module. Users who absolutely must have
* the functionality that domains provide may rely on it for the time being
* but should expect to have to migrate to a different solution
* in the future.
*
* Domains provide a way to handle multiple different IO operations as a
* single group. If any of the event emitters or callbacks registered to a
* domain emit an `'error'` event, or throw an error, then the domain object
* will be notified, rather than losing the context of the error in the`process.on('uncaughtException')` handler, or causing the program to
* exit immediately with an error code.
* @deprecated Since v1.4.2 - Deprecated
* @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/domain.js)
*/
declare module 'domain' {
import EventEmitter = require('events');
global {
namespace NodeJS {
interface Domain extends EventEmitter {
run<T>(fn: (...args: any[]) => T, ...args: any[]): T;
add(emitter: EventEmitter | Timer): void;
remove(emitter: EventEmitter | Timer): void;
bind<T extends Function>(cb: T): T;
intercept<T extends Function>(cb: T): T;
}
}
}
interface Domain extends NodeJS.Domain {}
import EventEmitter = require('node:events');
/**
* The `Domain` class encapsulates the functionality of routing errors and
* uncaught exceptions to the active `Domain` object.
*
* To handle the errors that it catches, listen to its `'error'` event.
*/
class Domain extends EventEmitter {
/**
* An array of timers and event emitters that have been explicitly added
* to the domain.
*/
members: Array<EventEmitter | NodeJS.Timer>;
/**
* The `enter()` method is plumbing used by the `run()`, `bind()`, and`intercept()` methods to set the active domain. It sets `domain.active` and`process.domain` to the domain, and implicitly
* pushes the domain onto the domain
* stack managed by the domain module (see {@link exit} for details on the
* domain stack). The call to `enter()` delimits the beginning of a chain of
* asynchronous calls and I/O operations bound to a domain.
*
* Calling `enter()` changes only the active domain, and does not alter the domain
* itself. `enter()` and `exit()` can be called an arbitrary number of times on a
* single domain.
*/
enter(): void;
/**
* The `exit()` method exits the current domain, popping it off the domain stack.
* Any time execution is going to switch to the context of a different chain of
* asynchronous calls, it's important to ensure that the current domain is exited.
* The call to `exit()` delimits either the end of or an interruption to the chain
* of asynchronous calls and I/O operations bound to a domain.
*
* If there are multiple, nested domains bound to the current execution context,`exit()` will exit any domains nested within this domain.
*
* Calling `exit()` changes only the active domain, and does not alter the domain
* itself. `enter()` and `exit()` can be called an arbitrary number of times on a
* single domain.
*/
exit(): void;
/**
* Run the supplied function in the context of the domain, implicitly
* binding all event emitters, timers, and lowlevel requests that are
* created in that context. Optionally, arguments can be passed to
* the function.
*
* This is the most basic way to use a domain.
*
* ```js
* const domain = require('domain');
* const fs = require('fs');
* const d = domain.create();
* d.on('error', (er) => {
* console.error('Caught error!', er);
* });
* d.run(() => {
* process.nextTick(() => {
* setTimeout(() => { // Simulating some various async stuff
* fs.open('non-existent file', 'r', (er, fd) => {
* if (er) throw er;
* // proceed...
* });
* }, 100);
* });
* });
* ```
*
* In this example, the `d.on('error')` handler will be triggered, rather
* than crashing the program.
*/
run<T>(fn: (...args: any[]) => T, ...args: any[]): T;
/**
* Explicitly adds an emitter to the domain. If any event handlers called by
* the emitter throw an error, or if the emitter emits an `'error'` event, it
* will be routed to the domain's `'error'` event, just like with implicit
* binding.
*
* This also works with timers that are returned from `setInterval()` and `setTimeout()`. If their callback function throws, it will be caught by
* the domain `'error'` handler.
*
* If the Timer or `EventEmitter` was already bound to a domain, it is removed
* from that one, and bound to this one instead.
* @param emitter emitter or timer to be added to the domain
*/
add(emitter: EventEmitter | NodeJS.Timer): void;
/**
* The opposite of {@link add}. Removes domain handling from the
* specified emitter.
* @param emitter emitter or timer to be removed from the domain
*/
remove(emitter: EventEmitter | NodeJS.Timer): void;
/**
* The returned function will be a wrapper around the supplied callback
* function. When the returned function is called, any errors that are
* thrown will be routed to the domain's `'error'` event.
*
* ```js
* const d = domain.create();
*
* function readSomeFile(filename, cb) {
* fs.readFile(filename, 'utf8', d.bind((er, data) => {
* // If this throws, it will also be passed to the domain.
* return cb(er, data ? JSON.parse(data) : null);
* }));
* }
*
* d.on('error', (er) => {
* // An error occurred somewhere. If we throw it now, it will crash the program
* // with the normal line number and stack message.
* });
* ```
* @param callback The callback function
* @return The bound function
*/
bind<T extends Function>(callback: T): T;
/**
* This method is almost identical to {@link bind}. However, in
* addition to catching thrown errors, it will also intercept `Error` objects sent as the first argument to the function.
*
* In this way, the common `if (err) return callback(err);` pattern can be replaced
* with a single error handler in a single place.
*
* ```js
* const d = domain.create();
*
* function readSomeFile(filename, cb) {
* fs.readFile(filename, 'utf8', d.intercept((data) => {
* // Note, the first argument is never passed to the
* // callback since it is assumed to be the 'Error' argument
* // and thus intercepted by the domain.
*
* // If this throws, it will also be passed to the domain
* // so the error-handling logic can be moved to the 'error'
* // event on the domain instead of being repeated throughout
* // the program.
* return cb(null, JSON.parse(data));
* }));
* }
*
* d.on('error', (er) => {
* // An error occurred somewhere. If we throw it now, it will crash the program
* // with the normal line number and stack message.
* });
* ```
* @param callback The callback function
* @return The intercepted function
*/
intercept<T extends Function>(callback: T): T;
}
function create(): Domain;
}
declare module 'node:domain' {

View File

@ -1,6 +1,42 @@
/* NOTE: Do not edit directly! This file is generated using `npm run update-types` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/**
* Much of the Node.js core API is built around an idiomatic asynchronous
* event-driven architecture in which certain kinds of objects (called "emitters")
* emit named events that cause `Function` objects ("listeners") to be called.
*
* For instance: a `net.Server` object emits an event each time a peer
* connects to it; a `fs.ReadStream` emits an event when the file is opened;
* a `stream` emits an event whenever data is available to be read.
*
* All objects that emit events are instances of the `EventEmitter` class. These
* objects expose an `eventEmitter.on()` function that allows one or more
* functions to be attached to named events emitted by the object. Typically,
* event names are camel-cased strings but any valid JavaScript property key
* can be used.
*
* When the `EventEmitter` object emits an event, all of the functions attached
* to that specific event are called _synchronously_. Any values returned by the
* called listeners are _ignored_ and discarded.
*
* The following example shows a simple `EventEmitter` instance with a single
* listener. The `eventEmitter.on()` method is used to register listeners, while
* the `eventEmitter.emit()` method is used to trigger the event.
*
* ```js
* const EventEmitter = require('events');
*
* class MyEmitter extends EventEmitter {}
*
* const myEmitter = new MyEmitter();
* myEmitter.on('event', () => {
* console.log('an event occurred!');
* });
* myEmitter.emit('event');
* ```
* @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/events.js)
*/
declare module 'events' {
interface EventEmitterOptions {
/**
@ -8,26 +44,243 @@ declare module 'events' {
*/
captureRejections?: boolean | undefined;
}
interface NodeEventTarget {
once(event: string | symbol, listener: (...args: any[]) => void): this;
once(eventName: string | symbol, listener: (...args: any[]) => void): this;
}
interface DOMEventTarget {
addEventListener(event: string, listener: (...args: any[]) => void, opts?: { once: boolean }): any;
addEventListener(
eventName: string,
listener: (...args: any[]) => void,
opts?: {
once: boolean;
}
): any;
}
interface StaticEventEmitterOptions {
signal?: AbortSignal | undefined;
}
interface EventEmitter extends NodeJS.EventEmitter {}
/**
* The `EventEmitter` class is defined and exposed by the `events` module:
*
* ```js
* const EventEmitter = require('events');
* ```
*
* All `EventEmitter`s emit the event `'newListener'` when new listeners are
* added and `'removeListener'` when existing listeners are removed.
*
* It supports the following option:
* @since v0.1.26
*/
class EventEmitter {
constructor(options?: EventEmitterOptions);
static once(emitter: NodeEventTarget, event: string | symbol): Promise<any[]>;
static once(emitter: DOMEventTarget, event: string): Promise<any[]>;
static on(emitter: NodeJS.EventEmitter, event: string): AsyncIterableIterator<any>;
/** @deprecated since v4.0.0 */
static listenerCount(emitter: NodeJS.EventEmitter, event: string | symbol): number;
/**
* Creates a `Promise` that is fulfilled when the `EventEmitter` emits the given
* event or that is rejected if the `EventEmitter` emits `'error'` while waiting.
* The `Promise` will resolve with an array of all the arguments emitted to the
* given event.
*
* This method is intentionally generic and works with the web platform [EventTarget](https://dom.spec.whatwg.org/#interface-eventtarget) interface, which has no special`'error'` event
* semantics and does not listen to the `'error'` event.
*
* ```js
* const { once, EventEmitter } = require('events');
*
* async function run() {
* const ee = new EventEmitter();
*
* process.nextTick(() => {
* ee.emit('myevent', 42);
* });
*
* const [value] = await once(ee, 'myevent');
* console.log(value);
*
* const err = new Error('kaboom');
* process.nextTick(() => {
* ee.emit('error', err);
* });
*
* try {
* await once(ee, 'myevent');
* } catch (err) {
* console.log('error happened', err);
* }
* }
*
* run();
* ```
*
* The special handling of the `'error'` event is only used when `events.once()`is used to wait for another event. If `events.once()` is used to wait for the
* '`error'` event itself, then it is treated as any other kind of event without
* special handling:
*
* ```js
* const { EventEmitter, once } = require('events');
*
* const ee = new EventEmitter();
*
* once(ee, 'error')
* .then(([err]) => console.log('ok', err.message))
* .catch((err) => console.log('error', err.message));
*
* ee.emit('error', new Error('boom'));
*
* // Prints: ok boom
* ```
*
* An `AbortSignal` can be used to cancel waiting for the event:
*
* ```js
* const { EventEmitter, once } = require('events');
*
* const ee = new EventEmitter();
* const ac = new AbortController();
*
* async function foo(emitter, event, signal) {
* try {
* await once(emitter, event, { signal });
* console.log('event emitted!');
* } catch (error) {
* if (error.name === 'AbortError') {
* console.error('Waiting for the event was canceled!');
* } else {
* console.error('There was an error', error.message);
* }
* }
* }
*
* foo(ee, 'foo', ac.signal);
* ac.abort(); // Abort waiting for the event
* ee.emit('foo'); // Prints: Waiting for the event was canceled!
* ```
* @since v11.13.0, v10.16.0
*/
static once(emitter: NodeEventTarget, eventName: string | symbol, options?: StaticEventEmitterOptions): Promise<any[]>;
static once(emitter: DOMEventTarget, eventName: string, options?: StaticEventEmitterOptions): Promise<any[]>;
/**
* ```js
* const { on, EventEmitter } = require('events');
*
* (async () => {
* const ee = new EventEmitter();
*
* // Emit later on
* process.nextTick(() => {
* ee.emit('foo', 'bar');
* ee.emit('foo', 42);
* });
*
* for await (const event of on(ee, 'foo')) {
* // The execution of this inner block is synchronous and it
* // processes one event at a time (even with await). Do not use
* // if concurrent execution is required.
* console.log(event); // prints ['bar'] [42]
* }
* // Unreachable here
* })();
* ```
*
* Returns an `AsyncIterator` that iterates `eventName` events. It will throw
* if the `EventEmitter` emits `'error'`. It removes all listeners when
* exiting the loop. The `value` returned by each iteration is an array
* composed of the emitted event arguments.
*
* An `AbortSignal` can be used to cancel waiting on events:
*
* ```js
* const { on, EventEmitter } = require('events');
* const ac = new AbortController();
*
* (async () => {
* const ee = new EventEmitter();
*
* // Emit later on
* process.nextTick(() => {
* ee.emit('foo', 'bar');
* ee.emit('foo', 42);
* });
*
* for await (const event of on(ee, 'foo', { signal: ac.signal })) {
* // The execution of this inner block is synchronous and it
* // processes one event at a time (even with await). Do not use
* // if concurrent execution is required.
* console.log(event); // prints ['bar'] [42]
* }
* // Unreachable here
* })();
*
* process.nextTick(() => ac.abort());
* ```
* @since v13.6.0, v12.16.0
* @param eventName The name of the event being listened for
* @return that iterates `eventName` events emitted by the `emitter`
*/
static on(emitter: NodeJS.EventEmitter, eventName: string, options?: StaticEventEmitterOptions): AsyncIterableIterator<any>;
/**
* A class method that returns the number of listeners for the given `eventName`registered on the given `emitter`.
*
* ```js
* const { EventEmitter, listenerCount } = require('events');
* const myEmitter = new EventEmitter();
* myEmitter.on('event', () => {});
* myEmitter.on('event', () => {});
* console.log(listenerCount(myEmitter, 'event'));
* // Prints: 2
* ```
* @since v0.9.12
* @deprecated Since v3.2.0 - Use `listenerCount` instead.
* @param emitter The emitter to query
* @param eventName The event name
*/
static listenerCount(emitter: NodeJS.EventEmitter, eventName: string | symbol): number;
/**
* Returns a copy of the array of listeners for the event named `eventName`.
*
* For `EventEmitter`s this behaves exactly the same as calling `.listeners` on
* the emitter.
*
* For `EventTarget`s this is the only way to get the event listeners for the
* event target. This is useful for debugging and diagnostic purposes.
*
* ```js
* const { getEventListeners, EventEmitter } = require('events');
*
* {
* const ee = new EventEmitter();
* const listener = () => console.log('Events are fun');
* ee.on('foo', listener);
* getEventListeners(ee, 'foo'); // [listener]
* }
* {
* const et = new EventTarget();
* const listener = () => console.log('Events are fun');
* et.addEventListener('foo', listener);
* getEventListeners(et, 'foo'); // [listener]
* }
* ```
* @since v15.2.0
*/
static getEventListeners(emitter: DOMEventTarget | NodeJS.EventEmitter, name: string | symbol): Function[];
/**
* ```js
* const {
* setMaxListeners,
* EventEmitter
* } = require('events');
*
* const target = new EventTarget();
* const emitter = new EventEmitter();
*
* setMaxListeners(5, target, emitter);
* ```
* @since v15.4.0
* @param n A non-negative number. The maximum number of listeners per `EventTarget` event.
* @param eventsTargets Zero or more {EventTarget} or {EventEmitter} instances. If none are specified, `n` is set as the default max for all newly created {EventTarget} and {EventEmitter}
* objects.
*/
static setMaxListeners(n?: number, ...eventTargets: Array<DOMEventTarget | NodeJS.EventEmitter>): void;
/**
* This symbol shall be used to install a listener for only monitoring `'error'`
* events. Listeners installed using this symbol are called before the regular
@ -39,7 +292,6 @@ declare module 'events' {
*/
static readonly errorMonitor: unique symbol;
static readonly captureRejectionSymbol: unique symbol;
/**
* Sets or gets the default captureRejection value for all emitters.
*/
@ -47,36 +299,343 @@ declare module 'events' {
static captureRejections: boolean;
static defaultMaxListeners: number;
}
import internal = require('events');
import internal = require('node:events');
namespace EventEmitter {
// Should just be `export { EventEmitter }`, but that doesn't work in TypeScript 3.4
export { internal as EventEmitter };
export interface Abortable {
/**
* When provided the corresponding `AbortController` can be used to cancel an asynchronous action.
*/
signal?: AbortSignal | undefined;
}
}
global {
namespace NodeJS {
interface EventEmitter {
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
on(event: string | symbol, listener: (...args: any[]) => void): this;
once(event: string | symbol, listener: (...args: any[]) => void): this;
removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
off(event: string | symbol, listener: (...args: any[]) => void): this;
/**
* Alias for `emitter.on(eventName, listener)`.
* @since v0.1.26
*/
addListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
/**
* Adds the `listener` function to the end of the listeners array for the
* event named `eventName`. No checks are made to see if the `listener` has
* already been added. Multiple calls passing the same combination of `eventName`and `listener` will result in the `listener` being added, and called, multiple
* times.
*
* ```js
* server.on('connection', (stream) => {
* console.log('someone connected!');
* });
* ```
*
* Returns a reference to the `EventEmitter`, so that calls can be chained.
*
* By default, event listeners are invoked in the order they are added. The`emitter.prependListener()` method can be used as an alternative to add the
* event listener to the beginning of the listeners array.
*
* ```js
* const myEE = new EventEmitter();
* myEE.on('foo', () => console.log('a'));
* myEE.prependListener('foo', () => console.log('b'));
* myEE.emit('foo');
* // Prints:
* // b
* // a
* ```
* @since v0.1.101
* @param eventName The name of the event.
* @param listener The callback function
*/
on(eventName: string | symbol, listener: (...args: any[]) => void): this;
/**
* Adds a **one-time**`listener` function for the event named `eventName`. The
* next time `eventName` is triggered, this listener is removed and then invoked.
*
* ```js
* server.once('connection', (stream) => {
* console.log('Ah, we have our first user!');
* });
* ```
*
* Returns a reference to the `EventEmitter`, so that calls can be chained.
*
* By default, event listeners are invoked in the order they are added. The`emitter.prependOnceListener()` method can be used as an alternative to add the
* event listener to the beginning of the listeners array.
*
* ```js
* const myEE = new EventEmitter();
* myEE.once('foo', () => console.log('a'));
* myEE.prependOnceListener('foo', () => console.log('b'));
* myEE.emit('foo');
* // Prints:
* // b
* // a
* ```
* @since v0.3.0
* @param eventName The name of the event.
* @param listener The callback function
*/
once(eventName: string | symbol, listener: (...args: any[]) => void): this;
/**
* Removes the specified `listener` from the listener array for the event named`eventName`.
*
* ```js
* const callback = (stream) => {
* console.log('someone connected!');
* };
* server.on('connection', callback);
* // ...
* server.removeListener('connection', callback);
* ```
*
* `removeListener()` will remove, at most, one instance of a listener from the
* listener array. If any single listener has been added multiple times to the
* listener array for the specified `eventName`, then `removeListener()` must be
* called multiple times to remove each instance.
*
* Once an event is emitted, all listeners attached to it at the
* time of emitting are called in order. This implies that any`removeListener()` or `removeAllListeners()` calls _after_ emitting and_before_ the last listener finishes execution will
* not remove them from`emit()` in progress. Subsequent events behave as expected.
*
* ```js
* const myEmitter = new MyEmitter();
*
* const callbackA = () => {
* console.log('A');
* myEmitter.removeListener('event', callbackB);
* };
*
* const callbackB = () => {
* console.log('B');
* };
*
* myEmitter.on('event', callbackA);
*
* myEmitter.on('event', callbackB);
*
* // callbackA removes listener callbackB but it will still be called.
* // Internal listener array at time of emit [callbackA, callbackB]
* myEmitter.emit('event');
* // Prints:
* // A
* // B
*
* // callbackB is now removed.
* // Internal listener array [callbackA]
* myEmitter.emit('event');
* // Prints:
* // A
* ```
*
* Because listeners are managed using an internal array, calling this will
* change the position indices of any listener registered _after_ the listener
* being removed. This will not impact the order in which listeners are called,
* but it means that any copies of the listener array as returned by
* the `emitter.listeners()` method will need to be recreated.
*
* When a single function has been added as a handler multiple times for a single
* event (as in the example below), `removeListener()` will remove the most
* recently added instance. In the example the `once('ping')`listener is removed:
*
* ```js
* const ee = new EventEmitter();
*
* function pong() {
* console.log('pong');
* }
*
* ee.on('ping', pong);
* ee.once('ping', pong);
* ee.removeListener('ping', pong);
*
* ee.emit('ping');
* ee.emit('ping');
* ```
*
* Returns a reference to the `EventEmitter`, so that calls can be chained.
* @since v0.1.26
*/
removeListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
/**
* Alias for `emitter.removeListener()`.
* @since v10.0.0
*/
off(eventName: string | symbol, listener: (...args: any[]) => void): this;
/**
* Removes all listeners, or those of the specified `eventName`.
*
* It is bad practice to remove listeners added elsewhere in the code,
* particularly when the `EventEmitter` instance was created by some other
* component or module (e.g. sockets or file streams).
*
* Returns a reference to the `EventEmitter`, so that calls can be chained.
* @since v0.1.26
*/
removeAllListeners(event?: string | symbol): this;
/**
* By default `EventEmitter`s will print a warning if more than `10` listeners are
* added for a particular event. This is a useful default that helps finding
* memory leaks. The `emitter.setMaxListeners()` method allows the limit to be
* modified for this specific `EventEmitter` instance. The value can be set to`Infinity` (or `0`) to indicate an unlimited number of listeners.
*
* Returns a reference to the `EventEmitter`, so that calls can be chained.
* @since v0.3.5
*/
setMaxListeners(n: number): this;
/**
* Returns the current max listener value for the `EventEmitter` which is either
* set by `emitter.setMaxListeners(n)` or defaults to {@link defaultMaxListeners}.
* @since v1.0.0
*/
getMaxListeners(): number;
listeners(event: string | symbol): Function[];
rawListeners(event: string | symbol): Function[];
emit(event: string | symbol, ...args: any[]): boolean;
listenerCount(event: string | symbol): number;
// Added in Node 6...
prependListener(event: string | symbol, listener: (...args: any[]) => void): this;
prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this;
/**
* Returns a copy of the array of listeners for the event named `eventName`.
*
* ```js
* server.on('connection', (stream) => {
* console.log('someone connected!');
* });
* console.log(util.inspect(server.listeners('connection')));
* // Prints: [ [Function] ]
* ```
* @since v0.1.26
*/
listeners(eventName: string | symbol): Function[];
/**
* Returns a copy of the array of listeners for the event named `eventName`,
* including any wrappers (such as those created by `.once()`).
*
* ```js
* const emitter = new EventEmitter();
* emitter.once('log', () => console.log('log once'));
*
* // Returns a new Array with a function `onceWrapper` which has a property
* // `listener` which contains the original listener bound above
* const listeners = emitter.rawListeners('log');
* const logFnWrapper = listeners[0];
*
* // Logs "log once" to the console and does not unbind the `once` event
* logFnWrapper.listener();
*
* // Logs "log once" to the console and removes the listener
* logFnWrapper();
*
* emitter.on('log', () => console.log('log persistently'));
* // Will return a new Array with a single function bound by `.on()` above
* const newListeners = emitter.rawListeners('log');
*
* // Logs "log persistently" twice
* newListeners[0]();
* emitter.emit('log');
* ```
* @since v9.4.0
*/
rawListeners(eventName: string | symbol): Function[];
/**
* Synchronously calls each of the listeners registered for the event named`eventName`, in the order they were registered, passing the supplied arguments
* to each.
*
* Returns `true` if the event had listeners, `false` otherwise.
*
* ```js
* const EventEmitter = require('events');
* const myEmitter = new EventEmitter();
*
* // First listener
* myEmitter.on('event', function firstListener() {
* console.log('Helloooo! first listener');
* });
* // Second listener
* myEmitter.on('event', function secondListener(arg1, arg2) {
* console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
* });
* // Third listener
* myEmitter.on('event', function thirdListener(...args) {
* const parameters = args.join(', ');
* console.log(`event with parameters ${parameters} in third listener`);
* });
*
* console.log(myEmitter.listeners('event'));
*
* myEmitter.emit('event', 1, 2, 3, 4, 5);
*
* // Prints:
* // [
* // [Function: firstListener],
* // [Function: secondListener],
* // [Function: thirdListener]
* // ]
* // Helloooo! first listener
* // event with parameters 1, 2 in second listener
* // event with parameters 1, 2, 3, 4, 5 in third listener
* ```
* @since v0.1.26
*/
emit(eventName: string | symbol, ...args: any[]): boolean;
/**
* Returns the number of listeners listening to the event named `eventName`.
* @since v3.2.0
* @param eventName The name of the event being listened for
*/
listenerCount(eventName: string | symbol): number;
/**
* Adds the `listener` function to the _beginning_ of the listeners array for the
* event named `eventName`. No checks are made to see if the `listener` has
* already been added. Multiple calls passing the same combination of `eventName`and `listener` will result in the `listener` being added, and called, multiple
* times.
*
* ```js
* server.prependListener('connection', (stream) => {
* console.log('someone connected!');
* });
* ```
*
* Returns a reference to the `EventEmitter`, so that calls can be chained.
* @since v6.0.0
* @param eventName The name of the event.
* @param listener The callback function
*/
prependListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
/**
* Adds a **one-time**`listener` function for the event named `eventName` to the_beginning_ of the listeners array. The next time `eventName` is triggered, this
* listener is removed, and then invoked.
*
* ```js
* server.prependOnceListener('connection', (stream) => {
* console.log('Ah, we have our first user!');
* });
* ```
*
* Returns a reference to the `EventEmitter`, so that calls can be chained.
* @since v6.0.0
* @param eventName The name of the event.
* @param listener The callback function
*/
prependOnceListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
/**
* Returns an array listing the events for which the emitter has registered
* listeners. The values in the array are strings or `Symbol`s.
*
* ```js
* const EventEmitter = require('events');
* const myEE = new EventEmitter();
* myEE.on('foo', () => {});
* myEE.on('bar', () => {});
*
* const sym = Symbol('symbol');
* myEE.on(sym, () => {});
*
* console.log(myEE.eventNames());
* // Prints: [ 'foo', 'bar', Symbol(symbol) ]
* ```
* @since v6.0.0
*/
eventNames(): Array<string | symbol>;
}
}
}
export = EventEmitter;
}
declare module 'node:events' {

File diff suppressed because it is too large Load Diff

View File

@ -16,23 +16,6 @@ interface ErrorConstructor {
stackTraceLimit: number;
}
// Node.js ESNEXT support
interface String {
/** Removes whitespace from the left end of a string. */
trimLeft(): string;
/** Removes whitespace from the right end of a string. */
trimRight(): string;
/** Returns a copy with leading whitespace removed. */
trimStart(): string;
/** Returns a copy with trailing whitespace removed. */
trimEnd(): string;
}
interface ImportMeta {
url: string;
}
/*-----------------------------------------------*
* *
* GLOBAL *
@ -40,9 +23,9 @@ interface ImportMeta {
------------------------------------------------*/
// For backwards compability
interface NodeRequire extends NodeJS.Require {}
interface RequireResolve extends NodeJS.RequireResolve {}
interface NodeModule extends NodeJS.Module {}
interface NodeRequire extends NodeJS.Require { }
interface RequireResolve extends NodeJS.RequireResolve { }
interface NodeModule extends NodeJS.Module { }
declare var process: NodeJS.Process;
declare var console: Console;
@ -50,61 +33,36 @@ declare var console: Console;
declare var __filename: string;
declare var __dirname: string;
declare function setTimeout(callback: (...args: any[]) => void, ms?: number, ...args: any[]): NodeJS.Timeout;
declare namespace setTimeout {
function __promisify__(ms: number): Promise<void>;
function __promisify__<T>(ms: number, value: T): Promise<T>;
}
declare function clearTimeout(timeoutId: NodeJS.Timeout): void;
declare function setInterval(callback: (...args: any[]) => void, ms?: number, ...args: any[]): NodeJS.Timeout;
declare function clearInterval(intervalId: NodeJS.Timeout): void;
declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): NodeJS.Immediate;
declare namespace setImmediate {
function __promisify__(): Promise<void>;
function __promisify__<T>(value: T): Promise<T>;
}
declare function clearImmediate(immediateId: NodeJS.Immediate): void;
declare function queueMicrotask(callback: () => void): void;
declare var require: NodeRequire;
declare var module: NodeModule;
// Same as module.exports
declare var exports: any;
// Buffer class
type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "base64url" | "latin1" | "binary" | "hex";
type WithImplicitCoercion<T> = T | { valueOf(): T };
/**
* Only available if `--expose-gc` is passed to the process.
*/
declare var gc: undefined | (() => void);
//#region borrowed
// from https://github.com/microsoft/TypeScript/blob/38da7c600c83e7b31193a62495239a0fe478cb67/lib/lib.webworker.d.ts#L633 until moved to separate lib
/**
* A controller object that allows you to abort one or more DOM requests as and when desired.
* @since v14.7.0
*/
/** A controller object that allows you to abort one or more DOM requests as and when desired. */
interface AbortController {
/**
* Returns the AbortSignal object associated with this object.
* @since v14.7.0
*/
readonly signal: AbortSignal;
/**
* Invoking this method will set this object's AbortSignal's aborted flag and signal to any observers that the associated activity is to be aborted.
* @since v14.7.0
*/
abort(): void;
}
/**
* A signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object.
* @since v14.7.0
*/
/** A signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object. */
interface AbortSignal {
/**
* Returns true if this AbortSignal's AbortController has signaled to abort, and false otherwise.
* @since v14.7.0
*/
readonly aborted: boolean;
}
@ -117,335 +75,35 @@ declare var AbortController: {
declare var AbortSignal: {
prototype: AbortSignal;
new(): AbortSignal;
// TODO: Add abort() static
abort(reason?: any): AbortSignal;
timeout(milliseconds: number): AbortSignal;
};
//#endregion borrowed
/**
* Raw data is stored in instances of the Buffer class.
* A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized.
* Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'base64url'|'binary'(deprecated)|'hex'
*/
declare class Buffer extends Uint8Array {
//#region ArrayLike.at()
interface RelativeIndexable<T> {
/**
* Allocates a new buffer containing the given {str}.
*
* @param str String to store in buffer.
* @param encoding encoding to use, optional. Default is 'utf8'
* @deprecated since v10.0.0 - Use `Buffer.from(string[, encoding])` instead.
* Takes an integer value and returns the item at that index,
* allowing for positive and negative integers.
* Negative integers count back from the last item in the array.
*/
constructor(str: string, encoding?: BufferEncoding);
/**
* Allocates a new buffer of {size} octets.
*
* @param size count of octets to allocate.
* @deprecated since v10.0.0 - Use `Buffer.alloc()` instead (also see `Buffer.allocUnsafe()`).
*/
constructor(size: number);
/**
* Allocates a new buffer containing the given {array} of octets.
*
* @param array The octets to store.
* @deprecated since v10.0.0 - Use `Buffer.from(array)` instead.
*/
constructor(array: Uint8Array);
/**
* Produces a Buffer backed by the same allocated memory as
* the given {ArrayBuffer}/{SharedArrayBuffer}.
*
*
* @param arrayBuffer The ArrayBuffer with which to share memory.
* @deprecated since v10.0.0 - Use `Buffer.from(arrayBuffer[, byteOffset[, length]])` instead.
*/
constructor(arrayBuffer: ArrayBuffer | SharedArrayBuffer);
/**
* Allocates a new buffer containing the given {array} of octets.
*
* @param array The octets to store.
* @deprecated since v10.0.0 - Use `Buffer.from(array)` instead.
*/
constructor(array: ReadonlyArray<any>);
/**
* Copies the passed {buffer} data onto a new {Buffer} instance.
*
* @param buffer The buffer to copy.
* @deprecated since v10.0.0 - Use `Buffer.from(buffer)` instead.
*/
constructor(buffer: Buffer);
/**
* When passed a reference to the .buffer property of a TypedArray instance,
* the newly created Buffer will share the same allocated memory as the TypedArray.
* The optional {byteOffset} and {length} arguments specify a memory range
* within the {arrayBuffer} that will be shared by the Buffer.
*
* @param arrayBuffer The .buffer property of any TypedArray or a new ArrayBuffer()
*/
static from(arrayBuffer: WithImplicitCoercion<ArrayBuffer | SharedArrayBuffer>, byteOffset?: number, length?: number): Buffer;
/**
* Creates a new Buffer using the passed {data}
* @param data data to create a new Buffer
*/
static from(data: Uint8Array | ReadonlyArray<number>): Buffer;
static from(data: WithImplicitCoercion<Uint8Array | ReadonlyArray<number> | string>): Buffer;
/**
* Creates a new Buffer containing the given JavaScript string {str}.
* If provided, the {encoding} parameter identifies the character encoding.
* If not provided, {encoding} defaults to 'utf8'.
*/
static from(str: WithImplicitCoercion<string> | { [Symbol.toPrimitive](hint: 'string'): string }, encoding?: BufferEncoding): Buffer;
/**
* Creates a new Buffer using the passed {data}
* @param values to create a new Buffer
*/
static of(...items: number[]): Buffer;
/**
* Returns true if {obj} is a Buffer
*
* @param obj object to test.
*/
static isBuffer(obj: any): obj is Buffer;
/**
* Returns true if {encoding} is a valid encoding argument.
* Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'base64url'|'binary'(deprecated)|'hex'
*
* @param encoding string to test.
*/
static isEncoding(encoding: string): encoding is BufferEncoding;
/**
* Gives the actual byte length of a string. encoding defaults to 'utf8'.
* This is not the same as String.prototype.length since that returns the number of characters in a string.
*
* @param string string to test.
* @param encoding encoding used to evaluate (defaults to 'utf8')
*/
static byteLength(
string: string | NodeJS.ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
encoding?: BufferEncoding
): number;
/**
* Returns a buffer which is the result of concatenating all the buffers in the list together.
*
* If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.
* If the list has exactly one item, then the first item of the list is returned.
* If the list has more than one item, then a new Buffer is created.
*
* @param list An array of Buffer objects to concatenate
* @param totalLength Total length of the buffers when concatenated.
* If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.
*/
static concat(list: ReadonlyArray<Uint8Array>, totalLength?: number): Buffer;
/**
* The same as buf1.compare(buf2).
*/
static compare(buf1: Uint8Array, buf2: Uint8Array): number;
/**
* Allocates a new buffer of {size} octets.
*
* @param size count of octets to allocate.
* @param fill if specified, buffer will be initialized by calling buf.fill(fill).
* If parameter is omitted, buffer will be filled with zeros.
* @param encoding encoding used for call to buf.fill while initalizing
*/
static alloc(size: number, fill?: string | Buffer | number, encoding?: BufferEncoding): Buffer;
/**
* Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents
* of the newly created Buffer are unknown and may contain sensitive data.
*
* @param size count of octets to allocate
*/
static allocUnsafe(size: number): Buffer;
/**
* Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents
* of the newly created Buffer are unknown and may contain sensitive data.
*
* @param size count of octets to allocate
*/
static allocUnsafeSlow(size: number): Buffer;
/**
* This is the number of bytes used to determine the size of pre-allocated, internal Buffer instances used for pooling. This value may be modified.
*/
static poolSize: number;
write(string: string, encoding?: BufferEncoding): number;
write(string: string, offset: number, encoding?: BufferEncoding): number;
write(string: string, offset: number, length: number, encoding?: BufferEncoding): number;
toString(encoding?: BufferEncoding, start?: number, end?: number): string;
toJSON(): { type: 'Buffer'; data: number[] };
equals(otherBuffer: Uint8Array): boolean;
compare(
otherBuffer: Uint8Array,
targetStart?: number,
targetEnd?: number,
sourceStart?: number,
sourceEnd?: number
): number;
copy(targetBuffer: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
/**
* Returns a new `Buffer` that references **the same memory as the original**, but offset and cropped by the start and end indices.
*
* This method is incompatible with `Uint8Array#slice()`, which returns a copy of the original memory.
*
* @param begin Where the new `Buffer` will start. Default: `0`.
* @param end Where the new `Buffer` will end (not inclusive). Default: `buf.length`.
*/
slice(begin?: number, end?: number): Buffer;
/**
* Returns a new `Buffer` that references **the same memory as the original**, but offset and cropped by the start and end indices.
*
* This method is compatible with `Uint8Array#subarray()`.
*
* @param begin Where the new `Buffer` will start. Default: `0`.
* @param end Where the new `Buffer` will end (not inclusive). Default: `buf.length`.
*/
subarray(begin?: number, end?: number): Buffer;
writeBigInt64BE(value: bigint, offset?: number): number;
writeBigInt64LE(value: bigint, offset?: number): number;
writeBigUInt64BE(value: bigint, offset?: number): number;
/**
* @alias Buffer.writeBigUInt64BE
* @since v14.10.0, v12.19.0
*/
writeBigUint64BE(value: bigint, offset?: number): number;
writeBigUInt64LE(value: bigint, offset?: number): number;
/**
* @alias Buffer.writeBigUInt64LE
* @since v14.10.0, v12.19.0
*/
writeBigUint64LE(value: bigint, offset?: number): number;
writeUIntLE(value: number, offset: number, byteLength: number): number;
/**
* @alias Buffer.writeUIntLE
* @since v14.9.0, v12.19.0
*/
writeUintLE(value: number, offset: number, byteLength: number): number;
writeUIntBE(value: number, offset: number, byteLength: number): number;
/**
* @alias Buffer.writeUIntBE
* @since v14.9.0, v12.19.0
*/
writeUintBE(value: number, offset: number, byteLength: number): number;
writeIntLE(value: number, offset: number, byteLength: number): number;
writeIntBE(value: number, offset: number, byteLength: number): number;
readBigUInt64BE(offset?: number): bigint;
/**
* @alias Buffer.readBigUInt64BE
* @since v14.10.0, v12.19.0
*/
readBigUint64BE(offset?: number): bigint;
readBigUInt64LE(offset?: number): bigint;
/**
* @alias Buffer.readBigUInt64LE
* @since v14.10.0, v12.19.0
*/
readBigUint64LE(offset?: number): bigint;
readBigInt64BE(offset?: number): bigint;
readBigInt64LE(offset?: number): bigint;
readUIntLE(offset: number, byteLength: number): number;
/**
* @alias Buffer.readUIntLE
* @since v14.9.0, v12.19.0
*/
readUintLE(offset: number, byteLength: number): number;
readUIntBE(offset: number, byteLength: number): number;
/**
* @alias Buffer.readUIntBE
* @since v14.9.0, v12.19.0
*/
readUintBE(offset: number, byteLength: number): number;
readIntLE(offset: number, byteLength: number): number;
readIntBE(offset: number, byteLength: number): number;
readUInt8(offset?: number): number;
/**
* @alias Buffer.readUInt8
* @since v14.9.0, v12.19.0
*/
readUint8(offset?: number): number;
readUInt16LE(offset?: number): number;
/**
* @alias Buffer.readUInt16LE
* @since v14.9.0, v12.19.0
*/
readUint16LE(offset?: number): number;
readUInt16BE(offset?: number): number;
/**
* @alias Buffer.readUInt16BE
* @since v14.9.0, v12.19.0
*/
readUint16BE(offset?: number): number;
readUInt32LE(offset?: number): number;
/**
* @alias Buffer.readUInt32LE
* @since v14.9.0, v12.19.0
*/
readUint32LE(offset?: number): number;
readUInt32BE(offset?: number): number;
/**
* @alias Buffer.readUInt32BE
* @since v14.9.0, v12.19.0
*/
readUint32BE(offset?: number): number;
readInt8(offset?: number): number;
readInt16LE(offset?: number): number;
readInt16BE(offset?: number): number;
readInt32LE(offset?: number): number;
readInt32BE(offset?: number): number;
readFloatLE(offset?: number): number;
readFloatBE(offset?: number): number;
readDoubleLE(offset?: number): number;
readDoubleBE(offset?: number): number;
reverse(): this;
swap16(): Buffer;
swap32(): Buffer;
swap64(): Buffer;
writeUInt8(value: number, offset?: number): number;
/**
* @alias Buffer.writeUInt8
* @since v14.9.0, v12.19.0
*/
writeUint8(value: number, offset?: number): number;
writeUInt16LE(value: number, offset?: number): number;
/**
* @alias Buffer.writeUInt16LE
* @since v14.9.0, v12.19.0
*/
writeUint16LE(value: number, offset?: number): number;
writeUInt16BE(value: number, offset?: number): number;
/**
* @alias Buffer.writeUInt16BE
* @since v14.9.0, v12.19.0
*/
writeUint16BE(value: number, offset?: number): number;
writeUInt32LE(value: number, offset?: number): number;
/**
* @alias Buffer.writeUInt32LE
* @since v14.9.0, v12.19.0
*/
writeUint32LE(value: number, offset?: number): number;
writeUInt32BE(value: number, offset?: number): number;
/**
* @alias Buffer.writeUInt32BE
* @since v14.9.0, v12.19.0
*/
writeUint32BE(value: number, offset?: number): number;
writeInt8(value: number, offset?: number): number;
writeInt16LE(value: number, offset?: number): number;
writeInt16BE(value: number, offset?: number): number;
writeInt32LE(value: number, offset?: number): number;
writeInt32BE(value: number, offset?: number): number;
writeFloatLE(value: number, offset?: number): number;
writeFloatBE(value: number, offset?: number): number;
writeDoubleLE(value: number, offset?: number): number;
writeDoubleBE(value: number, offset?: number): number;
fill(value: string | Uint8Array | number, offset?: number, end?: number, encoding?: BufferEncoding): this;
indexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number;
lastIndexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number;
entries(): IterableIterator<[number, number]>;
includes(value: string | number | Buffer, byteOffset?: number, encoding?: BufferEncoding): boolean;
keys(): IterableIterator<number>;
values(): IterableIterator<number>;
at(index: number): T | undefined;
}
interface String extends RelativeIndexable<string> {}
interface Array<T> extends RelativeIndexable<T> {}
interface ReadonlyArray<T> extends RelativeIndexable<T> {}
interface Int8Array extends RelativeIndexable<number> {}
interface Uint8Array extends RelativeIndexable<number> {}
interface Uint8ClampedArray extends RelativeIndexable<number> {}
interface Int16Array extends RelativeIndexable<number> {}
interface Uint16Array extends RelativeIndexable<number> {}
interface Int32Array extends RelativeIndexable<number> {}
interface Uint32Array extends RelativeIndexable<number> {}
interface Float32Array extends RelativeIndexable<number> {}
interface Float64Array extends RelativeIndexable<number> {}
interface BigInt64Array extends RelativeIndexable<bigint> {}
interface BigUint64Array extends RelativeIndexable<bigint> {}
//#endregion ArrayLike.at() end
/*----------------------------------------------*
* *
@ -453,52 +111,11 @@ declare class Buffer extends Uint8Array {
* *
*-----------------------------------------------*/
declare namespace NodeJS {
interface InspectOptions {
/**
* If set to `true`, getters are going to be
* inspected as well. If set to `'get'` only getters without setter are going
* to be inspected. If set to `'set'` only getters having a corresponding
* setter are going to be inspected. This might cause side effects depending on
* the getter function.
* @default `false`
*/
getters?: 'get' | 'set' | boolean | undefined;
showHidden?: boolean | undefined;
/**
* @default 2
*/
depth?: number | null | undefined;
colors?: boolean | undefined;
customInspect?: boolean | undefined;
showProxy?: boolean | undefined;
maxArrayLength?: number | null | undefined;
/**
* Specifies the maximum number of characters to
* include when formatting. Set to `null` or `Infinity` to show all elements.
* Set to `0` or negative to show no characters.
* @default Infinity
*/
maxStringLength?: number | null | undefined;
breakLength?: number | undefined;
/**
* Setting this to `false` causes each object key
* to be displayed on a new line. It will also add new lines to text that is
* longer than `breakLength`. If set to a number, the most `n` inner elements
* are united on a single line as long as all properties fit into
* `breakLength`. Short array elements are also grouped together. Note that no
* text will be reduced below 16 characters, no matter the `breakLength` size.
* For more information, see the example below.
* @default `true`
*/
compact?: boolean | number | undefined;
sorted?: boolean | ((a: string, b: string) => number) | undefined;
}
interface CallSite {
/**
* Value of "this"
*/
getThis(): any;
getThis(): unknown;
/**
* Type of "this" as a string.
@ -593,99 +210,18 @@ declare namespace NodeJS {
writable: boolean;
write(buffer: Uint8Array | string, cb?: (err?: Error | null) => void): boolean;
write(str: string, encoding?: BufferEncoding, cb?: (err?: Error | null) => void): boolean;
end(cb?: () => void): this;
end(data: string | Uint8Array, cb?: () => void): this;
end(str: string, encoding?: BufferEncoding, cb?: () => void): this;
end(cb?: () => void): void;
end(data: string | Uint8Array, cb?: () => void): void;
end(str: string, encoding?: BufferEncoding, cb?: () => void): void;
}
interface ReadWriteStream extends ReadableStream, WritableStream { }
interface Global {
Array: typeof Array;
ArrayBuffer: typeof ArrayBuffer;
Boolean: typeof Boolean;
Buffer: typeof Buffer;
DataView: typeof DataView;
Date: typeof Date;
Error: typeof Error;
EvalError: typeof EvalError;
Float32Array: typeof Float32Array;
Float64Array: typeof Float64Array;
Function: typeof Function;
Infinity: typeof Infinity;
Int16Array: typeof Int16Array;
Int32Array: typeof Int32Array;
Int8Array: typeof Int8Array;
Intl: typeof Intl;
JSON: typeof JSON;
Map: MapConstructor;
Math: typeof Math;
NaN: typeof NaN;
Number: typeof Number;
Object: typeof Object;
Promise: typeof Promise;
RangeError: typeof RangeError;
ReferenceError: typeof ReferenceError;
RegExp: typeof RegExp;
Set: SetConstructor;
String: typeof String;
Symbol: Function;
SyntaxError: typeof SyntaxError;
TypeError: typeof TypeError;
URIError: typeof URIError;
Uint16Array: typeof Uint16Array;
Uint32Array: typeof Uint32Array;
Uint8Array: typeof Uint8Array;
Uint8ClampedArray: typeof Uint8ClampedArray;
WeakMap: WeakMapConstructor;
WeakSet: WeakSetConstructor;
clearImmediate: (immediateId: Immediate) => void;
clearInterval: (intervalId: Timeout) => void;
clearTimeout: (timeoutId: Timeout) => void;
decodeURI: typeof decodeURI;
decodeURIComponent: typeof decodeURIComponent;
encodeURI: typeof encodeURI;
encodeURIComponent: typeof encodeURIComponent;
escape: (str: string) => string;
eval: typeof eval;
global: Global;
isFinite: typeof isFinite;
isNaN: typeof isNaN;
parseFloat: typeof parseFloat;
parseInt: typeof parseInt;
setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => Immediate;
setInterval: (callback: (...args: any[]) => void, ms?: number, ...args: any[]) => Timeout;
setTimeout: (callback: (...args: any[]) => void, ms?: number, ...args: any[]) => Timeout;
queueMicrotask: typeof queueMicrotask;
undefined: typeof undefined;
unescape: (str: string) => string;
gc: () => void;
v8debug?: any;
}
interface RefCounted {
ref(): this;
unref(): this;
}
// compatibility with older typings
interface Timer extends RefCounted {
hasRef(): boolean;
refresh(): this;
[Symbol.toPrimitive](): number;
}
interface Immediate extends RefCounted {
hasRef(): boolean;
_onImmediate: Function; // to distinguish it from the Timeout class
}
interface Timeout extends Timer {
hasRef(): boolean;
refresh(): this;
[Symbol.toPrimitive](): number;
}
type TypedArray =
| Uint8Array
| Uint8ClampedArray
@ -722,16 +258,20 @@ declare namespace NodeJS {
'.node': (m: Module, filename: string) => any;
}
interface Module {
/**
* `true` if the module is running during the Node.js preload
*/
isPreloading: boolean;
exports: any;
require: Require;
id: string;
filename: string;
loaded: boolean;
/** @deprecated since 14.6.0 Please use `require.main` and `module.children` instead. */
/** @deprecated since v14.6.0 Please use `require.main` and `module.children` instead. */
parent: Module | null | undefined;
children: Module[];
/**
* @since 11.14.0
* @since v11.14.0
*
* The directory name of the module. This is usually the same as the path.dirname() of the module.id.
*/

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More