mirror of
https://github.com/dawidd6/action-ansible-playbook.git
synced 2026-04-28 09:12:08 -06:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 126642a1c6 | |||
| c1f089fb01 | |||
| 7e7e9693e6 | |||
| 6c0a4f8651 | |||
| 38a0e05fb9 | |||
| c1bb1f797d | |||
| a5b82fe457 | |||
| 0f426bd96f | |||
| 0fe8953f25 | |||
| 17560e521b | |||
| 9d86fb9606 | |||
| 04bb1103fa | |||
| e8303e5fa5 | |||
| f78fdf2ef7 | |||
| fa6e11acb4 | |||
| a5344369ce | |||
| f16dd80db2 | |||
| 27b165ba8f | |||
| bcd983bdd2 | |||
| fea91eae77 | |||
| 9cb5a68aaf | |||
| 82b249279e | |||
| 3363d6aa33 | |||
| 81d0380e46 | |||
| 2c4beafd88 | |||
| 57803a1669 | |||
| 7c352ee131 | |||
| 1b8d29ad11 | |||
| 75091e5206 | |||
| 029e36f26a | |||
| d9e30df17d | |||
| c9d6829953 | |||
| 929b771549 | |||
| 9d50e1392c |
@@ -0,0 +1,16 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
|
||||
{
|
||||
"name": "Node.js & TypeScript",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"GitHub.vscode-github-actions",
|
||||
"esbenp.prettier-vscode",
|
||||
"mads-hartmann.bash-ide-vscode",
|
||||
"ms-azuretools.vscode-containers"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
name: NPM Updates
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
npm-updates:
|
||||
uses: dawidd6/reusable-workflows/.github/workflows/npm-updates.yml@master
|
||||
secrets:
|
||||
personal_access_token: ${{secrets.TOKEN}}
|
||||
+18
-53
@@ -5,68 +5,32 @@ on:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
remote:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SSH_PRIVATE_KEY: |
|
||||
SSH_PRIVATE_KEY: |-
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
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
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
SSH_PUBLIC_KEY: |
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDDWY9FVubMDUsZZuT2uT2U3ELfgztmUIeL84CCCUy0V8/p/3mGg0CZKCCiaVOBA3KyTX+RN+FW4i9UNWuhNXqLLEzpvR4E7BIyCVmfrQ89kJfMX5Wy1+sxQflV09u5qFVNbjneDVkCHAD4Q8MEwSnZXPNtmBft0I7RadisiteSd+In6w1gStWb1apjnxrtqiJjh4KBEP/0UYzIahByua4c9Hq0oI3TMihUqX/CPNYfaNFSFFtlt/tXvZU36VbAnJyIftX5KXhhmKhv8mZbQUg9xZySg7X6EtQBDQulJqgLLPu5r4bTCBGh4sfdzfbJBWMAcV6xjNDKaGf8pVkFE990jYePOqP5ydi/J/LS3dHz8rqt261FJhpCip8VoXGha2Xn0H+/n8gQTuzRmzLYHlknhJt1izWUDvhRQaf5eNdWivtNPG8NYFXzeekcUYE6GfeCpItFxnwktvspjkIaFunLfPvLkkNjSViJlpZdNRCYg59fnhyxO7jT7IKeUKNEdoM=
|
||||
SSH_PUBLIC_KEY: |-
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5lWJTlb5uVieTv0Zivsh1U59dGXr1yDCbIzezeOCF2 noname
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup remote
|
||||
run: |
|
||||
echo "$SSH_PUBLIC_KEY" | sudo tee /etc/ssh/authorized_keys
|
||||
sudo tee /etc/ssh/sshd_config <<EOF
|
||||
PasswordAuthentication no
|
||||
PubkeyAuthentication yes
|
||||
AuthorizedKeysFile /etc/ssh/authorized_keys
|
||||
PermitRootLogin no
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
EOF
|
||||
sudo systemctl restart ssh
|
||||
mkdir "$HOME/.ssh"
|
||||
echo "$SSH_PUBLIC_KEY" | tee "$HOME/.ssh/authorized_keys"
|
||||
chmod 600 "$HOME/.ssh/authorized_keys"
|
||||
echo 'SSH_KNOWN_HOSTS<<EOF' >> $GITHUB_ENV
|
||||
echo $(ssh-keyscan localhost) >> $GITHUB_ENV
|
||||
echo $(ssh-keyscan localhost 2>/dev/null) >> $GITHUB_ENV
|
||||
echo 'EOF' >> $GITHUB_ENV
|
||||
- name: With everything
|
||||
uses: ./
|
||||
@@ -78,7 +42,7 @@ jobs:
|
||||
configuration: |
|
||||
[defaults]
|
||||
callbacks_enabled = ansible.posix.profile_tasks, ansible.posix.timer
|
||||
stdout_callback = yaml
|
||||
stdout_callback = debug
|
||||
nocows = false
|
||||
vault_password: test
|
||||
requirements: requirements.yml
|
||||
@@ -86,6 +50,7 @@ jobs:
|
||||
[all]
|
||||
localhost
|
||||
options: |
|
||||
-vv
|
||||
-e docker_image=docker_url
|
||||
-e docker_username=user
|
||||
-e docker_password=pass
|
||||
@@ -96,7 +61,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: With check mode
|
||||
uses: ./
|
||||
with:
|
||||
@@ -112,7 +77,7 @@ jobs:
|
||||
configuration: |
|
||||
[defaults]
|
||||
callbacks_enabled = ansible.posix.profile_tasks, ansible.posix.timer
|
||||
stdout_callback = yaml
|
||||
stdout_callback = debug
|
||||
nocows = false
|
||||
options: --inventory hosts
|
||||
- name: With requirements
|
||||
|
||||
@@ -8,7 +8,7 @@ Should work on any OS, if `ansible-playbook` command is available in `PATH`.
|
||||
|
||||
```yaml
|
||||
- name: Run playbook
|
||||
uses: dawidd6/action-ansible-playbook@v4
|
||||
uses: dawidd6/action-ansible-playbook@<REF>
|
||||
with:
|
||||
# Required, playbook filepath
|
||||
playbook: deploy.yml
|
||||
|
||||
+1
-1
@@ -47,6 +47,6 @@ outputs:
|
||||
output:
|
||||
description: The captured output of both stdout and stderr from the Ansible Playbook run
|
||||
runs:
|
||||
using: node20
|
||||
using: node24
|
||||
main: main.js
|
||||
post: post.js
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const core = require('@actions/core')
|
||||
const exec = require('@actions/exec')
|
||||
const yaml = require('yaml')
|
||||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import * as yaml from 'yaml'
|
||||
import * as fs from 'node:fs'
|
||||
import * as os from 'node:os'
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
@@ -18,7 +18,7 @@ async function main() {
|
||||
const sudo = core.getBooleanInput("sudo")
|
||||
const noColor = core.getBooleanInput("no_color")
|
||||
const checkMode = core.getBooleanInput("check_mode")
|
||||
const fileMode = 0600
|
||||
const fileMode = 0o600
|
||||
|
||||
let cmd = ["ansible-playbook", playbook]
|
||||
|
||||
@@ -63,7 +63,7 @@ async function main() {
|
||||
const inventoryFile = ".ansible_inventory"
|
||||
fs.writeFileSync(inventoryFile, inventory, { mode: fileMode })
|
||||
core.saveState("inventoryFile", inventoryFile)
|
||||
cmd.push("--inventory-file")
|
||||
cmd.push("--inventory")
|
||||
cmd.push(inventoryFile)
|
||||
}
|
||||
|
||||
|
||||
+26
-35
@@ -4,49 +4,40 @@
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
|
||||
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz",
|
||||
"integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/http-client": "^2.0.1"
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/http-client": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/exec": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
|
||||
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
"@actions/io": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
|
||||
"integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
|
||||
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
"undici": "^6.23.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/io": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
||||
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
|
||||
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
@@ -57,27 +48,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||
"version": "6.24.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.0.tgz",
|
||||
"integrity": "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
"node": ">=18.17"
|
||||
}
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
|
||||
"integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
|
||||
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/eemeli"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import * as core from '@actions/core';
|
||||
|
||||
#### Inputs/Outputs
|
||||
|
||||
Action inputs can be read with `getInput` which returns a `string` or `getBooleanInput` which parses a boolean based on the [yaml 1.2 specification](https://yaml.org/spec/1.2/spec.html#id2804923). If `required` set to be false, the input should have a default value in `action.yml`.
|
||||
Action inputs can be read with `getInput` which returns a `string` or `getBooleanInput` which parses a boolean based on the [yaml 1.2 specification](https://yaml.org/spec/1.2/spec.html#id2804923). If `required` is set to be false, the input should have a default value in `action.yml`.
|
||||
|
||||
Outputs can be set with `setOutput` which makes them available to be mapped into inputs of other actions to ensure they are decoupled.
|
||||
|
||||
|
||||
+27
-4
@@ -2,14 +2,37 @@ export interface CommandProperties {
|
||||
[key: string]: any;
|
||||
}
|
||||
/**
|
||||
* Commands
|
||||
* Issues a command to the GitHub Actions runner
|
||||
*
|
||||
* @param command - The command name to issue
|
||||
* @param properties - Additional properties for the command (key-value pairs)
|
||||
* @param message - The message to include with the command
|
||||
* @remarks
|
||||
* This function outputs a specially formatted string to stdout that the Actions
|
||||
* runner interprets as a command. These commands can control workflow behavior,
|
||||
* set outputs, create annotations, mask values, and more.
|
||||
*
|
||||
* Command Format:
|
||||
* ::name key=value,key=value::message
|
||||
*
|
||||
* Examples:
|
||||
* ::warning::This is the message
|
||||
* ::set-env name=MY_VAR::some value
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Issue a warning annotation
|
||||
* issueCommand('warning', {}, 'This is a warning message');
|
||||
* // Output: ::warning::This is a warning message
|
||||
*
|
||||
* // Set an environment variable
|
||||
* issueCommand('set-env', { name: 'MY_VAR' }, 'some value');
|
||||
* // Output: ::set-env name=MY_VAR::some value
|
||||
*
|
||||
* // Add a secret mask
|
||||
* issueCommand('add-mask', {}, 'secretValue123');
|
||||
* // Output: ::add-mask::secretValue123
|
||||
* ```
|
||||
*
|
||||
* @internal
|
||||
* This is an internal utility function that powers the public API functions
|
||||
* such as setSecret, warning, error, and exportVariable.
|
||||
*/
|
||||
export declare function issueCommand(command: string, properties: CommandProperties, message: any): void;
|
||||
export declare function issue(name: string, message?: string): void;
|
||||
|
||||
+33
-38
@@ -1,50 +1,45 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.issue = exports.issueCommand = void 0;
|
||||
const os = __importStar(require("os"));
|
||||
const utils_1 = require("./utils");
|
||||
import * as os from 'os';
|
||||
import { toCommandValue } from './utils.js';
|
||||
/**
|
||||
* Commands
|
||||
* Issues a command to the GitHub Actions runner
|
||||
*
|
||||
* @param command - The command name to issue
|
||||
* @param properties - Additional properties for the command (key-value pairs)
|
||||
* @param message - The message to include with the command
|
||||
* @remarks
|
||||
* This function outputs a specially formatted string to stdout that the Actions
|
||||
* runner interprets as a command. These commands can control workflow behavior,
|
||||
* set outputs, create annotations, mask values, and more.
|
||||
*
|
||||
* Command Format:
|
||||
* ::name key=value,key=value::message
|
||||
*
|
||||
* Examples:
|
||||
* ::warning::This is the message
|
||||
* ::set-env name=MY_VAR::some value
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Issue a warning annotation
|
||||
* issueCommand('warning', {}, 'This is a warning message');
|
||||
* // Output: ::warning::This is a warning message
|
||||
*
|
||||
* // Set an environment variable
|
||||
* issueCommand('set-env', { name: 'MY_VAR' }, 'some value');
|
||||
* // Output: ::set-env name=MY_VAR::some value
|
||||
*
|
||||
* // Add a secret mask
|
||||
* issueCommand('add-mask', {}, 'secretValue123');
|
||||
* // Output: ::add-mask::secretValue123
|
||||
* ```
|
||||
*
|
||||
* @internal
|
||||
* This is an internal utility function that powers the public API functions
|
||||
* such as setSecret, warning, error, and exportVariable.
|
||||
*/
|
||||
function issueCommand(command, properties, message) {
|
||||
export function issueCommand(command, properties, message) {
|
||||
const cmd = new Command(command, properties, message);
|
||||
process.stdout.write(cmd.toString() + os.EOL);
|
||||
}
|
||||
exports.issueCommand = issueCommand;
|
||||
function issue(name, message = '') {
|
||||
export function issue(name, message = '') {
|
||||
issueCommand(name, {}, message);
|
||||
}
|
||||
exports.issue = issue;
|
||||
const CMD_STRING = '::';
|
||||
class Command {
|
||||
constructor(command, properties, message) {
|
||||
@@ -80,13 +75,13 @@ class Command {
|
||||
}
|
||||
}
|
||||
function escapeData(s) {
|
||||
return (0, utils_1.toCommandValue)(s)
|
||||
return toCommandValue(s)
|
||||
.replace(/%/g, '%25')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A');
|
||||
}
|
||||
function escapeProperty(s) {
|
||||
return (0, utils_1.toCommandValue)(s)
|
||||
return toCommandValue(s)
|
||||
.replace(/%/g, '%25')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A')
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAwB;AACxB,mCAAsC;AAWtC;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAC1B,OAAe,EACf,UAA6B,EAC7B,OAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAC/C,CAAC;AAPD,oCAOC;AAED,SAAgB,KAAK,CAAC,IAAY,EAAE,OAAO,GAAG,EAAE;IAC9C,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACjC,CAAC;AAFD,sBAEC;AAED,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,OAAO;IAKX,YAAY,OAAe,EAAE,UAA6B,EAAE,OAAe;QACzE,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,GAAG,iBAAiB,CAAA;SAC5B;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,QAAQ;QACN,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC9D,MAAM,IAAI,GAAG,CAAA;YACb,IAAI,KAAK,GAAG,IAAI,CAAA;YAChB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE;gBACjC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;oBACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,GAAG,EAAE;wBACP,IAAI,KAAK,EAAE;4BACT,KAAK,GAAG,KAAK,CAAA;yBACd;6BAAM;4BACL,MAAM,IAAI,GAAG,CAAA;yBACd;wBAED,MAAM,IAAI,GAAG,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAA;qBAC1C;iBACF;aACF;SACF;QAED,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;QACpD,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,SAAS,UAAU,CAAC,CAAM;IACxB,OAAO,IAAA,sBAAc,EAAC,CAAC,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,CAAM;IAC5B,OAAO,IAAA,sBAAc,EAAC,CAAC,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzB,CAAC"}
|
||||
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAA;AAWzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAe,EACf,UAA6B,EAC7B,OAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAC/C,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,OAAO,GAAG,EAAE;IAC9C,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,OAAO;IAKX,YAAY,OAAe,EAAE,UAA6B,EAAE,OAAe;QACzE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,iBAAiB,CAAA;QAC7B,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,QAAQ;QACN,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,GAAG,CAAA;YACb,IAAI,KAAK,GAAG,IAAI,CAAA;YAChB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,GAAG,EAAE,CAAC;wBACR,IAAI,KAAK,EAAE,CAAC;4BACV,KAAK,GAAG,KAAK,CAAA;wBACf,CAAC;6BAAM,CAAC;4BACN,MAAM,IAAI,GAAG,CAAA;wBACf,CAAC;wBAED,MAAM,IAAI,GAAG,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAA;oBAC3C,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;QACpD,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,SAAS,UAAU,CAAC,CAAM;IACxB,OAAO,cAAc,CAAC,CAAC,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,CAAM;IAC5B,OAAO,cAAc,CAAC,CAAC,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzB,CAAC"}
|
||||
+30
-5
@@ -59,7 +59,32 @@ export interface AnnotationProperties {
|
||||
export declare function exportVariable(name: string, val: any): void;
|
||||
/**
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*
|
||||
* @param secret - Value of the secret to be masked
|
||||
* @remarks
|
||||
* This function instructs the Actions runner to mask the specified value in any
|
||||
* logs produced during the workflow run. Once registered, the secret value will
|
||||
* be replaced with asterisks (***) whenever it appears in console output, logs,
|
||||
* or error messages.
|
||||
*
|
||||
* This is useful for protecting sensitive information such as:
|
||||
* - API keys
|
||||
* - Access tokens
|
||||
* - Authentication credentials
|
||||
* - URL parameters containing signatures (SAS tokens)
|
||||
*
|
||||
* Note that masking only affects future logs; any previous appearances of the
|
||||
* secret in logs before calling this function will remain unmasked.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Register an API token as a secret
|
||||
* const apiToken = "abc123xyz456";
|
||||
* setSecret(apiToken);
|
||||
*
|
||||
* // Now any logs containing this value will show *** instead
|
||||
* console.log(`Using token: ${apiToken}`); // Outputs: "Using token: ***"
|
||||
* ```
|
||||
*/
|
||||
export declare function setSecret(secret: string): void;
|
||||
/**
|
||||
@@ -187,16 +212,16 @@ export declare function getIDToken(aud?: string): Promise<string>;
|
||||
/**
|
||||
* Summary exports
|
||||
*/
|
||||
export { summary } from './summary';
|
||||
export { summary } from './summary.js';
|
||||
/**
|
||||
* @deprecated use core.summary
|
||||
*/
|
||||
export { markdownSummary } from './summary';
|
||||
export { markdownSummary } from './summary.js';
|
||||
/**
|
||||
* Path exports
|
||||
*/
|
||||
export { toPosixPath, toWin32Path, toPlatformPath } from './path-utils';
|
||||
export { toPosixPath, toWin32Path, toPlatformPath } from './path-utils.js';
|
||||
/**
|
||||
* Platform utilities exports
|
||||
*/
|
||||
export * as platform from './platform';
|
||||
export * as platform from './platform.js';
|
||||
|
||||
+77
-104
@@ -1,27 +1,3 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -31,18 +7,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.platform = exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = exports.markdownSummary = exports.summary = exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;
|
||||
const command_1 = require("./command");
|
||||
const file_command_1 = require("./file-command");
|
||||
const utils_1 = require("./utils");
|
||||
const os = __importStar(require("os"));
|
||||
const path = __importStar(require("path"));
|
||||
const oidc_utils_1 = require("./oidc-utils");
|
||||
import { issue, issueCommand } from './command.js';
|
||||
import { issueFileCommand, prepareKeyValueMessage } from './file-command.js';
|
||||
import { toCommandProperties, toCommandValue } from './utils.js';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { OidcClient } from './oidc-utils.js';
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
var ExitCode;
|
||||
export var ExitCode;
|
||||
(function (ExitCode) {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
@@ -52,7 +26,7 @@ var ExitCode;
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
ExitCode[ExitCode["Failure"] = 1] = "Failure";
|
||||
})(ExitCode || (exports.ExitCode = ExitCode = {}));
|
||||
})(ExitCode || (ExitCode = {}));
|
||||
//-----------------------------------------------------------------------
|
||||
// Variables
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -62,39 +36,61 @@ var ExitCode;
|
||||
* @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function exportVariable(name, val) {
|
||||
const convertedVal = (0, utils_1.toCommandValue)(val);
|
||||
export function exportVariable(name, val) {
|
||||
const convertedVal = toCommandValue(val);
|
||||
process.env[name] = convertedVal;
|
||||
const filePath = process.env['GITHUB_ENV'] || '';
|
||||
if (filePath) {
|
||||
return (0, file_command_1.issueFileCommand)('ENV', (0, file_command_1.prepareKeyValueMessage)(name, val));
|
||||
return issueFileCommand('ENV', prepareKeyValueMessage(name, val));
|
||||
}
|
||||
(0, command_1.issueCommand)('set-env', { name }, convertedVal);
|
||||
issueCommand('set-env', { name }, convertedVal);
|
||||
}
|
||||
exports.exportVariable = exportVariable;
|
||||
/**
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*
|
||||
* @param secret - Value of the secret to be masked
|
||||
* @remarks
|
||||
* This function instructs the Actions runner to mask the specified value in any
|
||||
* logs produced during the workflow run. Once registered, the secret value will
|
||||
* be replaced with asterisks (***) whenever it appears in console output, logs,
|
||||
* or error messages.
|
||||
*
|
||||
* This is useful for protecting sensitive information such as:
|
||||
* - API keys
|
||||
* - Access tokens
|
||||
* - Authentication credentials
|
||||
* - URL parameters containing signatures (SAS tokens)
|
||||
*
|
||||
* Note that masking only affects future logs; any previous appearances of the
|
||||
* secret in logs before calling this function will remain unmasked.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Register an API token as a secret
|
||||
* const apiToken = "abc123xyz456";
|
||||
* setSecret(apiToken);
|
||||
*
|
||||
* // Now any logs containing this value will show *** instead
|
||||
* console.log(`Using token: ${apiToken}`); // Outputs: "Using token: ***"
|
||||
* ```
|
||||
*/
|
||||
function setSecret(secret) {
|
||||
(0, command_1.issueCommand)('add-mask', {}, secret);
|
||||
export function setSecret(secret) {
|
||||
issueCommand('add-mask', {}, secret);
|
||||
}
|
||||
exports.setSecret = setSecret;
|
||||
/**
|
||||
* Prepends inputPath to the PATH (for this action and future actions)
|
||||
* @param inputPath
|
||||
*/
|
||||
function addPath(inputPath) {
|
||||
export function addPath(inputPath) {
|
||||
const filePath = process.env['GITHUB_PATH'] || '';
|
||||
if (filePath) {
|
||||
(0, file_command_1.issueFileCommand)('PATH', inputPath);
|
||||
issueFileCommand('PATH', inputPath);
|
||||
}
|
||||
else {
|
||||
(0, command_1.issueCommand)('add-path', {}, inputPath);
|
||||
issueCommand('add-path', {}, inputPath);
|
||||
}
|
||||
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
|
||||
}
|
||||
exports.addPath = addPath;
|
||||
/**
|
||||
* Gets the value of an input.
|
||||
* Unless trimWhitespace is set to false in InputOptions, the value is also trimmed.
|
||||
@@ -104,7 +100,7 @@ exports.addPath = addPath;
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns string
|
||||
*/
|
||||
function getInput(name, options) {
|
||||
export function getInput(name, options) {
|
||||
const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
|
||||
if (options && options.required && !val) {
|
||||
throw new Error(`Input required and not supplied: ${name}`);
|
||||
@@ -114,7 +110,6 @@ function getInput(name, options) {
|
||||
}
|
||||
return val.trim();
|
||||
}
|
||||
exports.getInput = getInput;
|
||||
/**
|
||||
* Gets the values of an multiline input. Each value is also trimmed.
|
||||
*
|
||||
@@ -123,7 +118,7 @@ exports.getInput = getInput;
|
||||
* @returns string[]
|
||||
*
|
||||
*/
|
||||
function getMultilineInput(name, options) {
|
||||
export function getMultilineInput(name, options) {
|
||||
const inputs = getInput(name, options)
|
||||
.split('\n')
|
||||
.filter(x => x !== '');
|
||||
@@ -132,7 +127,6 @@ function getMultilineInput(name, options) {
|
||||
}
|
||||
return inputs.map(input => input.trim());
|
||||
}
|
||||
exports.getMultilineInput = getMultilineInput;
|
||||
/**
|
||||
* Gets the input value of the boolean type in the YAML 1.2 "core schema" specification.
|
||||
* Support boolean input list: `true | True | TRUE | false | False | FALSE` .
|
||||
@@ -143,7 +137,7 @@ exports.getMultilineInput = getMultilineInput;
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns boolean
|
||||
*/
|
||||
function getBooleanInput(name, options) {
|
||||
export function getBooleanInput(name, options) {
|
||||
const trueValue = ['true', 'True', 'TRUE'];
|
||||
const falseValue = ['false', 'False', 'FALSE'];
|
||||
const val = getInput(name, options);
|
||||
@@ -154,7 +148,6 @@ function getBooleanInput(name, options) {
|
||||
throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` +
|
||||
`Support boolean input list: \`true | True | TRUE | false | False | FALSE\``);
|
||||
}
|
||||
exports.getBooleanInput = getBooleanInput;
|
||||
/**
|
||||
* Sets the value of an output.
|
||||
*
|
||||
@@ -162,24 +155,22 @@ exports.getBooleanInput = getBooleanInput;
|
||||
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function setOutput(name, value) {
|
||||
export function setOutput(name, value) {
|
||||
const filePath = process.env['GITHUB_OUTPUT'] || '';
|
||||
if (filePath) {
|
||||
return (0, file_command_1.issueFileCommand)('OUTPUT', (0, file_command_1.prepareKeyValueMessage)(name, value));
|
||||
return issueFileCommand('OUTPUT', prepareKeyValueMessage(name, value));
|
||||
}
|
||||
process.stdout.write(os.EOL);
|
||||
(0, command_1.issueCommand)('set-output', { name }, (0, utils_1.toCommandValue)(value));
|
||||
issueCommand('set-output', { name }, toCommandValue(value));
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
/**
|
||||
* Enables or disables the echoing of commands into stdout for the rest of the step.
|
||||
* Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
|
||||
*
|
||||
*/
|
||||
function setCommandEcho(enabled) {
|
||||
(0, command_1.issue)('echo', enabled ? 'on' : 'off');
|
||||
export function setCommandEcho(enabled) {
|
||||
issue('echo', enabled ? 'on' : 'off');
|
||||
}
|
||||
exports.setCommandEcho = setCommandEcho;
|
||||
//-----------------------------------------------------------------------
|
||||
// Results
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -188,64 +179,57 @@ exports.setCommandEcho = setCommandEcho;
|
||||
* When the action exits it will be with an exit code of 1
|
||||
* @param message add error issue message
|
||||
*/
|
||||
function setFailed(message) {
|
||||
export function setFailed(message) {
|
||||
process.exitCode = ExitCode.Failure;
|
||||
error(message);
|
||||
}
|
||||
exports.setFailed = setFailed;
|
||||
//-----------------------------------------------------------------------
|
||||
// Logging Commands
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Gets whether Actions Step Debug is on or not
|
||||
*/
|
||||
function isDebug() {
|
||||
export function isDebug() {
|
||||
return process.env['RUNNER_DEBUG'] === '1';
|
||||
}
|
||||
exports.isDebug = isDebug;
|
||||
/**
|
||||
* Writes debug message to user log
|
||||
* @param message debug message
|
||||
*/
|
||||
function debug(message) {
|
||||
(0, command_1.issueCommand)('debug', {}, message);
|
||||
export function debug(message) {
|
||||
issueCommand('debug', {}, message);
|
||||
}
|
||||
exports.debug = debug;
|
||||
/**
|
||||
* Adds an error issue
|
||||
* @param message error issue message. Errors will be converted to string via toString()
|
||||
* @param properties optional properties to add to the annotation.
|
||||
*/
|
||||
function error(message, properties = {}) {
|
||||
(0, command_1.issueCommand)('error', (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message);
|
||||
export function error(message, properties = {}) {
|
||||
issueCommand('error', toCommandProperties(properties), message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.error = error;
|
||||
/**
|
||||
* Adds a warning issue
|
||||
* @param message warning issue message. Errors will be converted to string via toString()
|
||||
* @param properties optional properties to add to the annotation.
|
||||
*/
|
||||
function warning(message, properties = {}) {
|
||||
(0, command_1.issueCommand)('warning', (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message);
|
||||
export function warning(message, properties = {}) {
|
||||
issueCommand('warning', toCommandProperties(properties), message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.warning = warning;
|
||||
/**
|
||||
* Adds a notice issue
|
||||
* @param message notice issue message. Errors will be converted to string via toString()
|
||||
* @param properties optional properties to add to the annotation.
|
||||
*/
|
||||
function notice(message, properties = {}) {
|
||||
(0, command_1.issueCommand)('notice', (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message);
|
||||
export function notice(message, properties = {}) {
|
||||
issueCommand('notice', toCommandProperties(properties), message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.notice = notice;
|
||||
/**
|
||||
* Writes info to log with console.log.
|
||||
* @param message info message
|
||||
*/
|
||||
function info(message) {
|
||||
export function info(message) {
|
||||
process.stdout.write(message + os.EOL);
|
||||
}
|
||||
exports.info = info;
|
||||
/**
|
||||
* Begin an output group.
|
||||
*
|
||||
@@ -253,17 +237,15 @@ exports.info = info;
|
||||
*
|
||||
* @param name The name of the output group
|
||||
*/
|
||||
function startGroup(name) {
|
||||
(0, command_1.issue)('group', name);
|
||||
export function startGroup(name) {
|
||||
issue('group', name);
|
||||
}
|
||||
exports.startGroup = startGroup;
|
||||
/**
|
||||
* End an output group.
|
||||
*/
|
||||
function endGroup() {
|
||||
(0, command_1.issue)('endgroup');
|
||||
export function endGroup() {
|
||||
issue('endgroup');
|
||||
}
|
||||
exports.endGroup = endGroup;
|
||||
/**
|
||||
* Wrap an asynchronous function call in a group.
|
||||
*
|
||||
@@ -272,7 +254,7 @@ exports.endGroup = endGroup;
|
||||
* @param name The name of the group
|
||||
* @param fn The function to wrap in the group
|
||||
*/
|
||||
function group(name, fn) {
|
||||
export function group(name, fn) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
startGroup(name);
|
||||
let result;
|
||||
@@ -285,7 +267,6 @@ function group(name, fn) {
|
||||
return result;
|
||||
});
|
||||
}
|
||||
exports.group = group;
|
||||
//-----------------------------------------------------------------------
|
||||
// Wrapper action state
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -296,49 +277,41 @@ exports.group = group;
|
||||
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function saveState(name, value) {
|
||||
export function saveState(name, value) {
|
||||
const filePath = process.env['GITHUB_STATE'] || '';
|
||||
if (filePath) {
|
||||
return (0, file_command_1.issueFileCommand)('STATE', (0, file_command_1.prepareKeyValueMessage)(name, value));
|
||||
return issueFileCommand('STATE', prepareKeyValueMessage(name, value));
|
||||
}
|
||||
(0, command_1.issueCommand)('save-state', { name }, (0, utils_1.toCommandValue)(value));
|
||||
issueCommand('save-state', { name }, toCommandValue(value));
|
||||
}
|
||||
exports.saveState = saveState;
|
||||
/**
|
||||
* Gets the value of an state set by this action's main execution.
|
||||
*
|
||||
* @param name name of the state to get
|
||||
* @returns string
|
||||
*/
|
||||
function getState(name) {
|
||||
export function getState(name) {
|
||||
return process.env[`STATE_${name}`] || '';
|
||||
}
|
||||
exports.getState = getState;
|
||||
function getIDToken(aud) {
|
||||
export function getIDToken(aud) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return yield oidc_utils_1.OidcClient.getIDToken(aud);
|
||||
return yield OidcClient.getIDToken(aud);
|
||||
});
|
||||
}
|
||||
exports.getIDToken = getIDToken;
|
||||
/**
|
||||
* Summary exports
|
||||
*/
|
||||
var summary_1 = require("./summary");
|
||||
Object.defineProperty(exports, "summary", { enumerable: true, get: function () { return summary_1.summary; } });
|
||||
export { summary } from './summary.js';
|
||||
/**
|
||||
* @deprecated use core.summary
|
||||
*/
|
||||
var summary_2 = require("./summary");
|
||||
Object.defineProperty(exports, "markdownSummary", { enumerable: true, get: function () { return summary_2.markdownSummary; } });
|
||||
export { markdownSummary } from './summary.js';
|
||||
/**
|
||||
* Path exports
|
||||
*/
|
||||
var path_utils_1 = require("./path-utils");
|
||||
Object.defineProperty(exports, "toPosixPath", { enumerable: true, get: function () { return path_utils_1.toPosixPath; } });
|
||||
Object.defineProperty(exports, "toWin32Path", { enumerable: true, get: function () { return path_utils_1.toWin32Path; } });
|
||||
Object.defineProperty(exports, "toPlatformPath", { enumerable: true, get: function () { return path_utils_1.toPlatformPath; } });
|
||||
export { toPosixPath, toWin32Path, toPlatformPath } from './path-utils.js';
|
||||
/**
|
||||
* Platform utilities exports
|
||||
*/
|
||||
exports.platform = __importStar(require("./platform"));
|
||||
export * as platform from './platform.js';
|
||||
//# sourceMappingURL=core.js.map
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+8
-36
@@ -1,37 +1,11 @@
|
||||
"use strict";
|
||||
// For internal use, subject to change.
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.prepareKeyValueMessage = exports.issueFileCommand = void 0;
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
const crypto = __importStar(require("crypto"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const os = __importStar(require("os"));
|
||||
const utils_1 = require("./utils");
|
||||
function issueFileCommand(command, message) {
|
||||
import * as crypto from 'crypto';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import { toCommandValue } from './utils.js';
|
||||
export function issueFileCommand(command, message) {
|
||||
const filePath = process.env[`GITHUB_${command}`];
|
||||
if (!filePath) {
|
||||
throw new Error(`Unable to find environment variable for file command ${command}`);
|
||||
@@ -39,14 +13,13 @@ function issueFileCommand(command, message) {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error(`Missing file at path: ${filePath}`);
|
||||
}
|
||||
fs.appendFileSync(filePath, `${(0, utils_1.toCommandValue)(message)}${os.EOL}`, {
|
||||
fs.appendFileSync(filePath, `${toCommandValue(message)}${os.EOL}`, {
|
||||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
exports.issueFileCommand = issueFileCommand;
|
||||
function prepareKeyValueMessage(key, value) {
|
||||
export function prepareKeyValueMessage(key, value) {
|
||||
const delimiter = `ghadelimiter_${crypto.randomUUID()}`;
|
||||
const convertedValue = (0, utils_1.toCommandValue)(value);
|
||||
const convertedValue = toCommandValue(value);
|
||||
// These should realistically never happen, but just in case someone finds a
|
||||
// way to exploit uuid generation let's not allow keys or values that contain
|
||||
// the delimiter.
|
||||
@@ -58,5 +31,4 @@ function prepareKeyValueMessage(key, value) {
|
||||
}
|
||||
return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
|
||||
}
|
||||
exports.prepareKeyValueMessage = prepareKeyValueMessage;
|
||||
//# sourceMappingURL=file-command.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"file-command.js","sourceRoot":"","sources":["../src/file-command.ts"],"names":[],"mappings":";AAAA,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;AAEvC,mCAAmC;AACnC,uDAAuD;AAEvD,+CAAgC;AAChC,uCAAwB;AACxB,uCAAwB;AACxB,mCAAsC;AAEtC,SAAgB,gBAAgB,CAAC,OAAe,EAAE,OAAY;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,EAAE,CAAC,CAAA;IACjD,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,IAAI,KAAK,CACb,wDAAwD,OAAO,EAAE,CAClE,CAAA;KACF;IACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAA;KACrD;IAED,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,IAAA,sBAAc,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;QACjE,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAA;AACJ,CAAC;AAdD,4CAcC;AAED,SAAgB,sBAAsB,CAAC,GAAW,EAAE,KAAU;IAC5D,MAAM,SAAS,GAAG,gBAAgB,MAAM,CAAC,UAAU,EAAE,EAAE,CAAA;IACvD,MAAM,cAAc,GAAG,IAAA,sBAAc,EAAC,KAAK,CAAC,CAAA;IAE5C,4EAA4E;IAC5E,6EAA6E;IAC7E,iBAAiB;IACjB,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QAC3B,MAAM,IAAI,KAAK,CACb,4DAA4D,SAAS,GAAG,CACzE,CAAA;KACF;IAED,IAAI,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QACtC,MAAM,IAAI,KAAK,CACb,6DAA6D,SAAS,GAAG,CAC1E,CAAA;KACF;IAED,OAAO,GAAG,GAAG,KAAK,SAAS,GAAG,EAAE,CAAC,GAAG,GAAG,cAAc,GAAG,EAAE,CAAC,GAAG,GAAG,SAAS,EAAE,CAAA;AAC9E,CAAC;AApBD,wDAoBC"}
|
||||
{"version":3,"file":"file-command.js","sourceRoot":"","sources":["../src/file-command.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAEvC,mCAAmC;AACnC,uDAAuD;AAEvD,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAChC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAA;AAEzC,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAY;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,EAAE,CAAC,CAAA;IACjD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,wDAAwD,OAAO,EAAE,CAClE,CAAA;IACH,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAA;IACtD,CAAC;IAED,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;QACjE,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAW,EAAE,KAAU;IAC5D,MAAM,SAAS,GAAG,gBAAgB,MAAM,CAAC,UAAU,EAAE,EAAE,CAAA;IACvD,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IAE5C,4EAA4E;IAC5E,6EAA6E;IAC7E,iBAAiB;IACjB,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,4DAA4D,SAAS,GAAG,CACzE,CAAA;IACH,CAAC;IAED,IAAI,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,6DAA6D,SAAS,GAAG,CAC1E,CAAA;IACH,CAAC;IAED,OAAO,GAAG,GAAG,KAAK,SAAS,GAAG,EAAE,CAAC,GAAG,GAAG,cAAc,GAAG,EAAE,CAAC,GAAG,GAAG,SAAS,EAAE,CAAA;AAC9E,CAAC"}
|
||||
+8
-12
@@ -1,4 +1,3 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -8,18 +7,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.OidcClient = void 0;
|
||||
const http_client_1 = require("@actions/http-client");
|
||||
const auth_1 = require("@actions/http-client/lib/auth");
|
||||
const core_1 = require("./core");
|
||||
class OidcClient {
|
||||
import { HttpClient } from '@actions/http-client';
|
||||
import { BearerCredentialHandler } from '@actions/http-client/lib/auth';
|
||||
import { debug, setSecret } from './core.js';
|
||||
export class OidcClient {
|
||||
static createHttpClient(allowRetry = true, maxRetry = 10) {
|
||||
const requestOptions = {
|
||||
allowRetries: allowRetry,
|
||||
maxRetries: maxRetry
|
||||
};
|
||||
return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions);
|
||||
return new HttpClient('actions/oidc-client', [new BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions);
|
||||
}
|
||||
static getRequestToken() {
|
||||
const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'];
|
||||
@@ -36,8 +33,8 @@ class OidcClient {
|
||||
return runtimeUrl;
|
||||
}
|
||||
static getCall(id_token_url) {
|
||||
var _a;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
var _a;
|
||||
const httpclient = OidcClient.createHttpClient();
|
||||
const res = yield httpclient
|
||||
.getJson(id_token_url)
|
||||
@@ -62,9 +59,9 @@ class OidcClient {
|
||||
const encodedAudience = encodeURIComponent(audience);
|
||||
id_token_url = `${id_token_url}&audience=${encodedAudience}`;
|
||||
}
|
||||
(0, core_1.debug)(`ID token url is ${id_token_url}`);
|
||||
debug(`ID token url is ${id_token_url}`);
|
||||
const id_token = yield OidcClient.getCall(id_token_url);
|
||||
(0, core_1.setSecret)(id_token);
|
||||
setSecret(id_token);
|
||||
return id_token;
|
||||
}
|
||||
catch (error) {
|
||||
@@ -73,5 +70,4 @@ class OidcClient {
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.OidcClient = OidcClient;
|
||||
//# sourceMappingURL=oidc-utils.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"oidc-utils.js","sourceRoot":"","sources":["../src/oidc-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;AAGA,sDAA+C;AAC/C,wDAAqE;AACrE,iCAAuC;AAKvC,MAAa,UAAU;IACb,MAAM,CAAC,gBAAgB,CAC7B,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,EAAE;QAEb,MAAM,cAAc,GAAmB;YACrC,YAAY,EAAE,UAAU;YACxB,UAAU,EAAE,QAAQ;SACrB,CAAA;QAED,OAAO,IAAI,wBAAU,CACnB,qBAAqB,EACrB,CAAC,IAAI,8BAAuB,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,EAC3D,cAAc,CACf,CAAA;IACH,CAAC;IAEO,MAAM,CAAC,eAAe;QAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;QAC3D,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAA;SACF;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,MAAM,CAAC,aAAa;QAC1B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QAC9D,IAAI,CAAC,UAAU,EAAE;YACf,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;SAC3E;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAEO,MAAM,CAAO,OAAO,CAAC,YAAoB;;;YAC/C,MAAM,UAAU,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAA;YAEhD,MAAM,GAAG,GAAG,MAAM,UAAU;iBACzB,OAAO,CAAgB,YAAY,CAAC;iBACpC,KAAK,CAAC,KAAK,CAAC,EAAE;gBACb,MAAM,IAAI,KAAK,CACb;uBACa,KAAK,CAAC,UAAU;yBACd,KAAK,CAAC,OAAO,EAAE,CAC/B,CAAA;YACH,CAAC,CAAC,CAAA;YAEJ,MAAM,QAAQ,GAAG,MAAA,GAAG,CAAC,MAAM,0CAAE,KAAK,CAAA;YAClC,IAAI,CAAC,QAAQ,EAAE;gBACb,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;aACjE;YACD,OAAO,QAAQ,CAAA;;KAChB;IAED,MAAM,CAAO,UAAU,CAAC,QAAiB;;YACvC,IAAI;gBACF,gDAAgD;gBAChD,IAAI,YAAY,GAAW,UAAU,CAAC,aAAa,EAAE,CAAA;gBACrD,IAAI,QAAQ,EAAE;oBACZ,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;oBACpD,YAAY,GAAG,GAAG,YAAY,aAAa,eAAe,EAAE,CAAA;iBAC7D;gBAED,IAAA,YAAK,EAAC,mBAAmB,YAAY,EAAE,CAAC,CAAA;gBAExC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;gBACvD,IAAA,gBAAS,EAAC,QAAQ,CAAC,CAAA;gBACnB,OAAO,QAAQ,CAAA;aAChB;YAAC,OAAO,KAAK,EAAE;gBACd,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;aACnD;QACH,CAAC;KAAA;CACF;AAzED,gCAyEC"}
|
||||
{"version":3,"file":"oidc-utils.js","sourceRoot":"","sources":["../src/oidc-utils.ts"],"names":[],"mappings":";;;;;;;;;AAGA,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAC,uBAAuB,EAAC,MAAM,+BAA+B,CAAA;AACrE,OAAO,EAAC,KAAK,EAAE,SAAS,EAAC,MAAM,WAAW,CAAA;AAK1C,MAAM,OAAO,UAAU;IACb,MAAM,CAAC,gBAAgB,CAC7B,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,EAAE;QAEb,MAAM,cAAc,GAAmB;YACrC,YAAY,EAAE,UAAU;YACxB,UAAU,EAAE,QAAQ;SACrB,CAAA;QAED,OAAO,IAAI,UAAU,CACnB,qBAAqB,EACrB,CAAC,IAAI,uBAAuB,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,EAC3D,cAAc,CACf,CAAA;IACH,CAAC;IAEO,MAAM,CAAC,eAAe;QAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;QAC3D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAA;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,MAAM,CAAC,aAAa;QAC1B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QAC9D,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;QAC5E,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAEO,MAAM,CAAO,OAAO,CAAC,YAAoB;;;YAC/C,MAAM,UAAU,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAA;YAEhD,MAAM,GAAG,GAAG,MAAM,UAAU;iBACzB,OAAO,CAAgB,YAAY,CAAC;iBACpC,KAAK,CAAC,KAAK,CAAC,EAAE;gBACb,MAAM,IAAI,KAAK,CACb;uBACa,KAAK,CAAC,UAAU;yBACd,KAAK,CAAC,OAAO,EAAE,CAC/B,CAAA;YACH,CAAC,CAAC,CAAA;YAEJ,MAAM,QAAQ,GAAG,MAAA,GAAG,CAAC,MAAM,0CAAE,KAAK,CAAA;YAClC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;YAClE,CAAC;YACD,OAAO,QAAQ,CAAA;QACjB,CAAC;KAAA;IAED,MAAM,CAAO,UAAU,CAAC,QAAiB;;YACvC,IAAI,CAAC;gBACH,gDAAgD;gBAChD,IAAI,YAAY,GAAW,UAAU,CAAC,aAAa,EAAE,CAAA;gBACrD,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;oBACpD,YAAY,GAAG,GAAG,YAAY,aAAa,eAAe,EAAE,CAAA;gBAC9D,CAAC;gBAED,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAA;gBAExC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;gBACvD,SAAS,CAAC,QAAQ,CAAC,CAAA;gBACnB,OAAO,QAAQ,CAAA;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YACpD,CAAC;QACH,CAAC;KAAA;CACF"}
|
||||
+4
-33
@@ -1,30 +1,4 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0;
|
||||
const path = __importStar(require("path"));
|
||||
import * as path from 'path';
|
||||
/**
|
||||
* toPosixPath converts the given path to the posix form. On Windows, \\ will be
|
||||
* replaced with /.
|
||||
@@ -32,10 +6,9 @@ const path = __importStar(require("path"));
|
||||
* @param pth. Path to transform.
|
||||
* @return string Posix path.
|
||||
*/
|
||||
function toPosixPath(pth) {
|
||||
export function toPosixPath(pth) {
|
||||
return pth.replace(/[\\]/g, '/');
|
||||
}
|
||||
exports.toPosixPath = toPosixPath;
|
||||
/**
|
||||
* toWin32Path converts the given path to the win32 form. On Linux, / will be
|
||||
* replaced with \\.
|
||||
@@ -43,10 +16,9 @@ exports.toPosixPath = toPosixPath;
|
||||
* @param pth. Path to transform.
|
||||
* @return string Win32 path.
|
||||
*/
|
||||
function toWin32Path(pth) {
|
||||
export function toWin32Path(pth) {
|
||||
return pth.replace(/[/]/g, '\\');
|
||||
}
|
||||
exports.toWin32Path = toWin32Path;
|
||||
/**
|
||||
* toPlatformPath converts the given path to a platform-specific path. It does
|
||||
* this by replacing instances of / and \ with the platform-specific path
|
||||
@@ -55,8 +27,7 @@ exports.toWin32Path = toWin32Path;
|
||||
* @param pth The path to platformize.
|
||||
* @return string The platform-specific path.
|
||||
*/
|
||||
function toPlatformPath(pth) {
|
||||
export function toPlatformPath(pth) {
|
||||
return pth.replace(/[/\\]/g, path.sep);
|
||||
}
|
||||
exports.toPlatformPath = toPlatformPath;
|
||||
//# sourceMappingURL=path-utils.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA4B;AAE5B;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;AAClC,CAAC;AAFD,kCAEC;AAED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC;AAFD,kCAEC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAAC,GAAW;IACxC,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;AACxC,CAAC;AAFD,wCAEC"}
|
||||
{"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;AACxC,CAAC"}
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
/// <reference types="node" />
|
||||
export declare const platform: NodeJS.Platform;
|
||||
export declare const arch: string;
|
||||
export declare const arch: NodeJS.Architecture;
|
||||
export declare const isWindows: boolean;
|
||||
export declare const isMacOS: boolean;
|
||||
export declare const isLinux: boolean;
|
||||
|
||||
+15
-45
@@ -1,27 +1,3 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -31,13 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getDetails = exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
||||
const os_1 = __importDefault(require("os"));
|
||||
const exec = __importStar(require("@actions/exec"));
|
||||
import os from 'os';
|
||||
import * as exec from '@actions/exec';
|
||||
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
||||
silent: true
|
||||
@@ -72,23 +43,22 @@ const getLinuxInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
||||
version
|
||||
};
|
||||
});
|
||||
exports.platform = os_1.default.platform();
|
||||
exports.arch = os_1.default.arch();
|
||||
exports.isWindows = exports.platform === 'win32';
|
||||
exports.isMacOS = exports.platform === 'darwin';
|
||||
exports.isLinux = exports.platform === 'linux';
|
||||
function getDetails() {
|
||||
export const platform = os.platform();
|
||||
export const arch = os.arch();
|
||||
export const isWindows = platform === 'win32';
|
||||
export const isMacOS = platform === 'darwin';
|
||||
export const isLinux = platform === 'linux';
|
||||
export function getDetails() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return Object.assign(Object.assign({}, (yield (exports.isWindows
|
||||
return Object.assign(Object.assign({}, (yield (isWindows
|
||||
? getWindowsInfo()
|
||||
: exports.isMacOS
|
||||
: isMacOS
|
||||
? getMacOsInfo()
|
||||
: getLinuxInfo()))), { platform: exports.platform,
|
||||
arch: exports.arch,
|
||||
isWindows: exports.isWindows,
|
||||
isMacOS: exports.isMacOS,
|
||||
isLinux: exports.isLinux });
|
||||
: getLinuxInfo()))), { platform,
|
||||
arch,
|
||||
isWindows,
|
||||
isMacOS,
|
||||
isLinux });
|
||||
});
|
||||
}
|
||||
exports.getDetails = getDetails;
|
||||
//# sourceMappingURL=platform.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAAmB;AACnB,oDAAqC;AAErC,MAAM,cAAc,GAAG,GAAmD,EAAE;IAC1E,MAAM,EAAC,MAAM,EAAE,OAAO,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAChD,kFAAkF,EAClF,SAAS,EACT;QACE,MAAM,EAAE,IAAI;KACb,CACF,CAAA;IAED,MAAM,EAAC,MAAM,EAAE,IAAI,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAC7C,kFAAkF,EAClF,SAAS,EACT;QACE,MAAM,EAAE,IAAI;KACb,CACF,CAAA;IAED,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;QACjB,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;KACxB,CAAA;AACH,CAAC,CAAA,CAAA;AAED,MAAM,YAAY,GAAG,GAGlB,EAAE;;IACH,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE;QAC9D,MAAM,EAAE,IAAI;KACb,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,MAAA,MAAA,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,0CAAG,CAAC,CAAC,mCAAI,EAAE,CAAA;IACjE,MAAM,IAAI,GAAG,MAAA,MAAA,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,0CAAG,CAAC,CAAC,mCAAI,EAAE,CAAA;IAE3D,OAAO;QACL,IAAI;QACJ,OAAO;KACR,CAAA;AACH,CAAC,CAAA,CAAA;AAED,MAAM,YAAY,GAAG,GAGlB,EAAE;IACH,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;QAC3E,MAAM,EAAE,IAAI;KACb,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAEjD,OAAO;QACL,IAAI;QACJ,OAAO;KACR,CAAA;AACH,CAAC,CAAA,CAAA;AAEY,QAAA,QAAQ,GAAG,YAAE,CAAC,QAAQ,EAAE,CAAA;AACxB,QAAA,IAAI,GAAG,YAAE,CAAC,IAAI,EAAE,CAAA;AAChB,QAAA,SAAS,GAAG,gBAAQ,KAAK,OAAO,CAAA;AAChC,QAAA,OAAO,GAAG,gBAAQ,KAAK,QAAQ,CAAA;AAC/B,QAAA,OAAO,GAAG,gBAAQ,KAAK,OAAO,CAAA;AAE3C,SAAsB,UAAU;;QAS9B,uCACK,CAAC,MAAM,CAAC,iBAAS;YAClB,CAAC,CAAC,cAAc,EAAE;YAClB,CAAC,CAAC,eAAO;gBACT,CAAC,CAAC,YAAY,EAAE;gBAChB,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,KACpB,QAAQ,EAAR,gBAAQ;YACR,IAAI,EAAJ,YAAI;YACJ,SAAS,EAAT,iBAAS;YACT,OAAO,EAAP,eAAO;YACP,OAAO,EAAP,eAAO,IACR;IACH,CAAC;CAAA;AArBD,gCAqBC"}
|
||||
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,KAAK,IAAI,MAAM,eAAe,CAAA;AAErC,MAAM,cAAc,GAAG,GAAmD,EAAE;IAC1E,MAAM,EAAC,MAAM,EAAE,OAAO,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAChD,kFAAkF,EAClF,SAAS,EACT;QACE,MAAM,EAAE,IAAI;KACb,CACF,CAAA;IAED,MAAM,EAAC,MAAM,EAAE,IAAI,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAC7C,kFAAkF,EAClF,SAAS,EACT;QACE,MAAM,EAAE,IAAI;KACb,CACF,CAAA;IAED,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;QACjB,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;KACxB,CAAA;AACH,CAAC,CAAA,CAAA;AAED,MAAM,YAAY,GAAG,GAGlB,EAAE;;IACH,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE;QAC9D,MAAM,EAAE,IAAI;KACb,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,MAAA,MAAA,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,0CAAG,CAAC,CAAC,mCAAI,EAAE,CAAA;IACjE,MAAM,IAAI,GAAG,MAAA,MAAA,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,0CAAG,CAAC,CAAC,mCAAI,EAAE,CAAA;IAE3D,OAAO;QACL,IAAI;QACJ,OAAO;KACR,CAAA;AACH,CAAC,CAAA,CAAA;AAED,MAAM,YAAY,GAAG,GAGlB,EAAE;IACH,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;QAC3E,MAAM,EAAE,IAAI;KACb,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAEjD,OAAO;QACL,IAAI;QACJ,OAAO;KACR,CAAA;AACH,CAAC,CAAA,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAA;AACrC,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA;AAC7B,MAAM,CAAC,MAAM,SAAS,GAAG,QAAQ,KAAK,OAAO,CAAA;AAC7C,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,KAAK,QAAQ,CAAA;AAC5C,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,KAAK,OAAO,CAAA;AAE3C,MAAM,UAAgB,UAAU;;QAS9B,uCACK,CAAC,MAAM,CAAC,SAAS;YAClB,CAAC,CAAC,cAAc,EAAE;YAClB,CAAC,CAAC,OAAO;gBACP,CAAC,CAAC,YAAY,EAAE;gBAChB,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,KACtB,QAAQ;YACR,IAAI;YACJ,SAAS;YACT,OAAO;YACP,OAAO,IACR;IACH,CAAC;CAAA"}
|
||||
+11
-14
@@ -1,4 +1,3 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -8,13 +7,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0;
|
||||
const os_1 = require("os");
|
||||
const fs_1 = require("fs");
|
||||
const { access, appendFile, writeFile } = fs_1.promises;
|
||||
exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY';
|
||||
exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary';
|
||||
import { EOL } from 'os';
|
||||
import { constants, promises } from 'fs';
|
||||
const { access, appendFile, writeFile } = promises;
|
||||
export const SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY';
|
||||
export const SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary';
|
||||
class Summary {
|
||||
constructor() {
|
||||
this._buffer = '';
|
||||
@@ -30,12 +27,12 @@ class Summary {
|
||||
if (this._filePath) {
|
||||
return this._filePath;
|
||||
}
|
||||
const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR];
|
||||
const pathFromEnv = process.env[SUMMARY_ENV_VAR];
|
||||
if (!pathFromEnv) {
|
||||
throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`);
|
||||
throw new Error(`Unable to find environment variable for $${SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`);
|
||||
}
|
||||
try {
|
||||
yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK);
|
||||
yield access(pathFromEnv, constants.R_OK | constants.W_OK);
|
||||
}
|
||||
catch (_a) {
|
||||
throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`);
|
||||
@@ -131,7 +128,7 @@ class Summary {
|
||||
* @returns {Summary} summary instance
|
||||
*/
|
||||
addEOL() {
|
||||
return this.addRaw(os_1.EOL);
|
||||
return this.addRaw(EOL);
|
||||
}
|
||||
/**
|
||||
* Adds an HTML codeblock to the summary buffer
|
||||
@@ -278,6 +275,6 @@ const _summary = new Summary();
|
||||
/**
|
||||
* @deprecated use `core.summary`
|
||||
*/
|
||||
exports.markdownSummary = _summary;
|
||||
exports.summary = _summary;
|
||||
export const markdownSummary = _summary;
|
||||
export const summary = _summary;
|
||||
//# sourceMappingURL=summary.js.map
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { AnnotationProperties } from './core';
|
||||
import { CommandProperties } from './command';
|
||||
import { AnnotationProperties } from './core.js';
|
||||
import { CommandProperties } from './command.js';
|
||||
/**
|
||||
* Sanitizes an input into a string so it can be passed into issueCommand safely
|
||||
* @param input input to sanitize into a string
|
||||
|
||||
+2
-7
@@ -1,13 +1,10 @@
|
||||
"use strict";
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toCommandProperties = exports.toCommandValue = void 0;
|
||||
/**
|
||||
* Sanitizes an input into a string so it can be passed into issueCommand safely
|
||||
* @param input input to sanitize into a string
|
||||
*/
|
||||
function toCommandValue(input) {
|
||||
export function toCommandValue(input) {
|
||||
if (input === null || input === undefined) {
|
||||
return '';
|
||||
}
|
||||
@@ -16,14 +13,13 @@ function toCommandValue(input) {
|
||||
}
|
||||
return JSON.stringify(input);
|
||||
}
|
||||
exports.toCommandValue = toCommandValue;
|
||||
/**
|
||||
*
|
||||
* @param annotationProperties
|
||||
* @returns The command properties to send with the actual annotation command
|
||||
* See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646
|
||||
*/
|
||||
function toCommandProperties(annotationProperties) {
|
||||
export function toCommandProperties(annotationProperties) {
|
||||
if (!Object.keys(annotationProperties).length) {
|
||||
return {};
|
||||
}
|
||||
@@ -36,5 +32,4 @@ function toCommandProperties(annotationProperties) {
|
||||
endColumn: annotationProperties.endColumn
|
||||
};
|
||||
}
|
||||
exports.toCommandProperties = toCommandProperties;
|
||||
//# sourceMappingURL=utils.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AAAA,mCAAmC;AACnC,uDAAuD;;;AAKvD;;;GAGG;AACH,SAAgB,cAAc,CAAC,KAAU;IACvC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE;QACzC,OAAO,EAAE,CAAA;KACV;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,MAAM,EAAE;QAC/D,OAAO,KAAe,CAAA;KACvB;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC;AAPD,wCAOC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CACjC,oBAA0C;IAE1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,EAAE;QAC7C,OAAO,EAAE,CAAA;KACV;IAED,OAAO;QACL,KAAK,EAAE,oBAAoB,CAAC,KAAK;QACjC,IAAI,EAAE,oBAAoB,CAAC,IAAI;QAC/B,IAAI,EAAE,oBAAoB,CAAC,SAAS;QACpC,OAAO,EAAE,oBAAoB,CAAC,OAAO;QACrC,GAAG,EAAE,oBAAoB,CAAC,WAAW;QACrC,SAAS,EAAE,oBAAoB,CAAC,SAAS;KAC1C,CAAA;AACH,CAAC;AAfD,kDAeC"}
|
||||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,uDAAuD;AAKvD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAU;IACvC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAA;IACX,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,MAAM,EAAE,CAAC;QAChE,OAAO,KAAe,CAAA;IACxB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,oBAA0C;IAE1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,EAAE,CAAC;QAC9C,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO;QACL,KAAK,EAAE,oBAAoB,CAAC,KAAK;QACjC,IAAI,EAAE,oBAAoB,CAAC,IAAI;QAC/B,IAAI,EAAE,oBAAoB,CAAC,SAAS;QACpC,OAAO,EAAE,oBAAoB,CAAC,OAAO;QACrC,GAAG,EAAE,oBAAoB,CAAC,WAAW;QACrC,SAAS,EAAE,oBAAoB,CAAC,SAAS;KAC1C,CAAA;AACH,CAAC"}
|
||||
+11
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@actions/core",
|
||||
"version": "1.11.1",
|
||||
"version": "3.0.0",
|
||||
"description": "Actions core lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
@@ -9,8 +9,15 @@
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/core",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "lib/core.js",
|
||||
"types": "lib/core.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./lib/core.d.ts",
|
||||
"import": "./lib/core.js"
|
||||
}
|
||||
},
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
@@ -36,10 +43,10 @@
|
||||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/http-client": "^2.0.1"
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/http-client": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.18.112"
|
||||
"@types/node": "^25.1.0"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { ExecOptions, ExecOutput, ExecListeners } from './interfaces';
|
||||
import { ExecOptions, ExecOutput, ExecListeners } from './interfaces.js';
|
||||
export { ExecOptions, ExecOutput, ExecListeners };
|
||||
/**
|
||||
* Exec a command.
|
||||
|
||||
+7
-31
@@ -1,23 +1,3 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -27,10 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getExecOutput = exports.exec = void 0;
|
||||
const string_decoder_1 = require("string_decoder");
|
||||
const tr = __importStar(require("./toolrunner"));
|
||||
import { StringDecoder } from 'string_decoder';
|
||||
import * as tr from './toolrunner.js';
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
@@ -41,7 +19,7 @@ const tr = __importStar(require("./toolrunner"));
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
function exec(commandLine, args, options) {
|
||||
export function exec(commandLine, args, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const commandArgs = tr.argStringToArray(commandLine);
|
||||
if (commandArgs.length === 0) {
|
||||
@@ -54,7 +32,6 @@ function exec(commandLine, args, options) {
|
||||
return runner.exec();
|
||||
});
|
||||
}
|
||||
exports.exec = exec;
|
||||
/**
|
||||
* Exec a command and get the output.
|
||||
* Output will be streamed to the live console.
|
||||
@@ -65,14 +42,14 @@ exports.exec = exec;
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<ExecOutput> exit code, stdout, and stderr
|
||||
*/
|
||||
function getExecOutput(commandLine, args, options) {
|
||||
var _a, _b;
|
||||
export function getExecOutput(commandLine, args, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
var _a, _b;
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
//Using string decoder covers the case where a mult-byte character is split
|
||||
const stdoutDecoder = new string_decoder_1.StringDecoder('utf8');
|
||||
const stderrDecoder = new string_decoder_1.StringDecoder('utf8');
|
||||
const stdoutDecoder = new StringDecoder('utf8');
|
||||
const stderrDecoder = new StringDecoder('utf8');
|
||||
const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout;
|
||||
const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;
|
||||
const stdErrListener = (data) => {
|
||||
@@ -99,5 +76,4 @@ function getExecOutput(commandLine, args, options) {
|
||||
};
|
||||
});
|
||||
}
|
||||
exports.getExecOutput = getExecOutput;
|
||||
//# sourceMappingURL=exec.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAA4C;AAE5C,iDAAkC;AAIlC;;;;;;;;;GASG;AACH,SAAsB,IAAI,CACxB,WAAmB,EACnB,IAAe,EACf,OAAqB;;QAErB,MAAM,WAAW,GAAG,EAAE,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;QACpD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;SACpE;QACD,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC/B,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;QAC9C,MAAM,MAAM,GAAkB,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;QACxE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACtB,CAAC;CAAA;AAdD,oBAcC;AAED;;;;;;;;;GASG;AAEH,SAAsB,aAAa,CACjC,WAAmB,EACnB,IAAe,EACf,OAAqB;;;QAErB,IAAI,MAAM,GAAG,EAAE,CAAA;QACf,IAAI,MAAM,GAAG,EAAE,CAAA;QAEf,2EAA2E;QAC3E,MAAM,aAAa,GAAG,IAAI,8BAAa,CAAC,MAAM,CAAC,CAAA;QAC/C,MAAM,aAAa,GAAG,IAAI,8BAAa,CAAC,MAAM,CAAC,CAAA;QAE/C,MAAM,sBAAsB,SAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,0CAAE,MAAM,CAAA;QACzD,MAAM,sBAAsB,SAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,0CAAE,MAAM,CAAA;QAEzD,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;YAC5C,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACnC,IAAI,sBAAsB,EAAE;gBAC1B,sBAAsB,CAAC,IAAI,CAAC,CAAA;aAC7B;QACH,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;YAC5C,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACnC,IAAI,sBAAsB,EAAE;gBAC1B,sBAAsB,CAAC,IAAI,CAAC,CAAA;aAC7B;QACH,CAAC,CAAA;QAED,MAAM,SAAS,mCACV,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,KACrB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,cAAc,GACvB,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,IAAI,kCAAM,OAAO,KAAE,SAAS,IAAE,CAAA;QAEvE,gCAAgC;QAChC,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,CAAA;QAC7B,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,CAAA;QAE7B,OAAO;YACL,QAAQ;YACR,MAAM;YACN,MAAM;SACP,CAAA;;CACF;AA9CD,sCA8CC"}
|
||||
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,gBAAgB,CAAA;AAE5C,OAAO,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAIrC;;;;;;;;;GASG;AACH,MAAM,UAAgB,IAAI,CACxB,WAAmB,EACnB,IAAe,EACf,OAAqB;;QAErB,MAAM,WAAW,GAAG,EAAE,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;QACpD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;QACrE,CAAC;QACD,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC/B,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;QAC9C,MAAM,MAAM,GAAkB,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;QACxE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACtB,CAAC;CAAA;AAED;;;;;;;;;GASG;AAEH,MAAM,UAAgB,aAAa,CACjC,WAAmB,EACnB,IAAe,EACf,OAAqB;;;QAErB,IAAI,MAAM,GAAG,EAAE,CAAA;QACf,IAAI,MAAM,GAAG,EAAE,CAAA;QAEf,2EAA2E;QAC3E,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;QAC/C,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;QAE/C,MAAM,sBAAsB,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,0CAAE,MAAM,CAAA;QACzD,MAAM,sBAAsB,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,0CAAE,MAAM,CAAA;QAEzD,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;YAC5C,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACnC,IAAI,sBAAsB,EAAE,CAAC;gBAC3B,sBAAsB,CAAC,IAAI,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;YAC5C,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACnC,IAAI,sBAAsB,EAAE,CAAC;gBAC3B,sBAAsB,CAAC,IAAI,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC,CAAA;QAED,MAAM,SAAS,mCACV,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,KACrB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,cAAc,GACvB,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,IAAI,kCAAM,OAAO,KAAE,SAAS,IAAE,CAAA;QAEvE,gCAAgC;QAChC,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,CAAA;QAC7B,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,CAAA;QAE7B,OAAO;YACL,QAAQ;YACR,MAAM;YACN,MAAM;SACP,CAAA;IACH,CAAC;CAAA"}
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
/// <reference types="node" />
|
||||
import * as stream from 'stream';
|
||||
/**
|
||||
* Interface for exec options
|
||||
|
||||
+1
-2
@@ -1,3 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
export {};
|
||||
//# sourceMappingURL=interfaces.js.map
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
/// <reference types="node" />
|
||||
import * as events from 'events';
|
||||
import * as im from './interfaces';
|
||||
import * as im from './interfaces.js';
|
||||
export declare class ToolRunner extends events.EventEmitter {
|
||||
constructor(toolPath: string, args?: string[], options?: im.ExecOptions);
|
||||
private toolPath;
|
||||
|
||||
+13
-44
@@ -1,23 +1,3 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -27,21 +7,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.argStringToArray = exports.ToolRunner = void 0;
|
||||
const os = __importStar(require("os"));
|
||||
const events = __importStar(require("events"));
|
||||
const child = __importStar(require("child_process"));
|
||||
const path = __importStar(require("path"));
|
||||
const io = __importStar(require("@actions/io"));
|
||||
const ioUtil = __importStar(require("@actions/io/lib/io-util"));
|
||||
const timers_1 = require("timers");
|
||||
import * as os from 'os';
|
||||
import * as events from 'events';
|
||||
import * as child from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as io from '@actions/io';
|
||||
import * as ioUtil from '@actions/io/lib/io-util';
|
||||
import { setTimeout } from 'timers';
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
/*
|
||||
* Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
|
||||
*/
|
||||
class ToolRunner extends events.EventEmitter {
|
||||
export class ToolRunner extends events.EventEmitter {
|
||||
constructor(toolPath, args, options) {
|
||||
super();
|
||||
if (!toolPath) {
|
||||
@@ -260,10 +238,7 @@ class ToolRunner extends events.EventEmitter {
|
||||
}
|
||||
}
|
||||
reverse += '"';
|
||||
return reverse
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
return reverse.split('').reverse().join('');
|
||||
}
|
||||
_uvQuoteCmdArg(arg) {
|
||||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
||||
@@ -339,10 +314,7 @@ class ToolRunner extends events.EventEmitter {
|
||||
}
|
||||
}
|
||||
reverse += '"';
|
||||
return reverse
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
return reverse.split('').reverse().join('');
|
||||
}
|
||||
_cloneExecOptions(options) {
|
||||
options = options || {};
|
||||
@@ -493,14 +465,13 @@ class ToolRunner extends events.EventEmitter {
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.ToolRunner = ToolRunner;
|
||||
/**
|
||||
* Convert an arg string to an array of args. Handles escaping
|
||||
*
|
||||
* @param argString string of arguments
|
||||
* @returns string[] array of arguments
|
||||
*/
|
||||
function argStringToArray(argString) {
|
||||
export function argStringToArray(argString) {
|
||||
const args = [];
|
||||
let inQuotes = false;
|
||||
let escaped = false;
|
||||
@@ -546,7 +517,6 @@ function argStringToArray(argString) {
|
||||
}
|
||||
return args;
|
||||
}
|
||||
exports.argStringToArray = argStringToArray;
|
||||
class ExecState extends events.EventEmitter {
|
||||
constructor(options, toolPath) {
|
||||
super();
|
||||
@@ -575,7 +545,7 @@ class ExecState extends events.EventEmitter {
|
||||
this._setResult();
|
||||
}
|
||||
else if (this.processExited) {
|
||||
this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this);
|
||||
this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this);
|
||||
}
|
||||
}
|
||||
_debug(message) {
|
||||
@@ -608,8 +578,7 @@ class ExecState extends events.EventEmitter {
|
||||
return;
|
||||
}
|
||||
if (!state.processClosed && state.processExited) {
|
||||
const message = `The STDIO streams did not close within ${state.delay /
|
||||
1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
||||
const message = `The STDIO streams did not close within ${state.delay / 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
||||
state._debug(message);
|
||||
}
|
||||
state._setResult();
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+9
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@actions/exec",
|
||||
"version": "1.1.1",
|
||||
"version": "3.0.0",
|
||||
"description": "Actions exec lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
@@ -9,8 +9,15 @@
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/exec",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "lib/exec.js",
|
||||
"types": "lib/exec.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./lib/exec.d.ts",
|
||||
"import": "./lib/exec.js"
|
||||
}
|
||||
},
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
@@ -36,6 +43,6 @@
|
||||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
"@actions/io": "^3.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ A lightweight HTTP client optimized for building actions.
|
||||
- HTTP client with TypeScript generics and async/await/Promises
|
||||
- Typings included!
|
||||
- [Proxy support](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-self-hosted-runners#using-a-proxy-server-with-self-hosted-runners) just works with actions and the runner
|
||||
- Targets ES2019 (runner runs actions with node 12+). Only supported on node 12+.
|
||||
- Targets ES2019 (runner runs actions with node 24+). Only supported on node 20+.
|
||||
- Basic, Bearer and PAT Support out of the box. Extensible handlers for others.
|
||||
- Redirects supported
|
||||
|
||||
@@ -44,7 +44,7 @@ export NODE_DEBUG=http
|
||||
|
||||
## Node support
|
||||
|
||||
The http-client is built using the latest LTS version of Node 12. It may work on previous node LTS versions but it's tested and officially supported on Node12+.
|
||||
The http-client is built using Node 24. It may work on previous node LTS versions but it's tested and officially supported on Node 20+.
|
||||
|
||||
## Support and Versioning
|
||||
|
||||
|
||||
+2
-3
@@ -1,7 +1,6 @@
|
||||
/// <reference types="node" />
|
||||
import * as http from 'http';
|
||||
import * as ifm from './interfaces';
|
||||
import { HttpClientResponse } from './index';
|
||||
import * as ifm from './interfaces.js';
|
||||
import { HttpClientResponse } from './index.js';
|
||||
export declare class BasicCredentialHandler implements ifm.RequestHandler {
|
||||
username: string;
|
||||
password: string;
|
||||
|
||||
+3
-9
@@ -1,4 +1,3 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -8,9 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0;
|
||||
class BasicCredentialHandler {
|
||||
export class BasicCredentialHandler {
|
||||
constructor(username, password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
@@ -31,8 +28,7 @@ class BasicCredentialHandler {
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.BasicCredentialHandler = BasicCredentialHandler;
|
||||
class BearerCredentialHandler {
|
||||
export class BearerCredentialHandler {
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
}
|
||||
@@ -54,8 +50,7 @@ class BearerCredentialHandler {
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.BearerCredentialHandler = BearerCredentialHandler;
|
||||
class PersonalAccessTokenCredentialHandler {
|
||||
export class PersonalAccessTokenCredentialHandler {
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
}
|
||||
@@ -77,5 +72,4 @@ class PersonalAccessTokenCredentialHandler {
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler;
|
||||
//# sourceMappingURL=auth.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAa,sBAAsB;IAIjC,YAAY,QAAgB,EAAE,QAAgB;QAC5C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAED,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CACpC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AA1BD,wDA0BC;AAED,MAAa,uBAAuB;IAGlC,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAA;IAC3D,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AAxBD,0DAwBC;AAED,MAAa,oCAAoC;IAK/C,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,OAAO,IAAI,CAAC,KAAK,EAAE,CACpB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AA5BD,oFA4BC"}
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";;;;;;;;;AAIA,MAAM,OAAO,sBAAsB;IAIjC,YAAY,QAAgB,EAAE,QAAgB;QAC5C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAED,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CACpC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AAED,MAAM,OAAO,uBAAuB;IAGlC,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAA;IAC3D,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AAED,MAAM,OAAO,oCAAoC;IAK/C,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,OAAO,IAAI,CAAC,KAAK,EAAE,CACpB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF"}
|
||||
+17
-4
@@ -1,8 +1,5 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import * as http from 'http';
|
||||
import * as ifm from './interfaces';
|
||||
import * as ifm from './interfaces.js';
|
||||
import { ProxyAgent } from 'undici';
|
||||
export declare enum HttpCodes {
|
||||
OK = 200,
|
||||
@@ -122,9 +119,25 @@ export declare class HttpClient {
|
||||
getAgentDispatcher(serverUrl: string): ProxyAgent | undefined;
|
||||
private _prepareRequest;
|
||||
private _mergeHeaders;
|
||||
/**
|
||||
* Gets an existing header value or returns a default.
|
||||
* Handles converting number header values to strings since HTTP headers must be strings.
|
||||
* Note: This returns string | string[] since some headers can have multiple values.
|
||||
* For headers that must always be a single string (like Content-Type), use the
|
||||
* specialized _getExistingOrDefaultContentTypeHeader method instead.
|
||||
*/
|
||||
private _getExistingOrDefaultHeader;
|
||||
/**
|
||||
* Specialized version of _getExistingOrDefaultHeader for Content-Type header.
|
||||
* Always returns a single string (not an array) since Content-Type should be a single value.
|
||||
* Converts arrays to comma-separated strings and numbers to strings to ensure type safety.
|
||||
* This was split from _getExistingOrDefaultHeader to provide stricter typing for callers
|
||||
* that assign the result to places expecting a string (e.g., additionalHeaders[Headers.ContentType]).
|
||||
*/
|
||||
private _getExistingOrDefaultContentTypeHeader;
|
||||
private _getAgent;
|
||||
private _getProxyAgentDispatcher;
|
||||
private _getUserAgentWithOrchestrationId;
|
||||
private _performExponentialBackoff;
|
||||
private _processResponse;
|
||||
}
|
||||
|
||||
+106
-62
@@ -1,28 +1,4 @@
|
||||
"use strict";
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -32,14 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0;
|
||||
const http = __importStar(require("http"));
|
||||
const https = __importStar(require("https"));
|
||||
const pm = __importStar(require("./proxy"));
|
||||
const tunnel = __importStar(require("tunnel"));
|
||||
const undici_1 = require("undici");
|
||||
var HttpCodes;
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import * as pm from './proxy.js';
|
||||
import * as tunnel from 'tunnel';
|
||||
import { ProxyAgent } from 'undici';
|
||||
export var HttpCodes;
|
||||
(function (HttpCodes) {
|
||||
HttpCodes[HttpCodes["OK"] = 200] = "OK";
|
||||
HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices";
|
||||
@@ -68,25 +42,24 @@ var HttpCodes;
|
||||
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
|
||||
HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable";
|
||||
HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout";
|
||||
})(HttpCodes || (exports.HttpCodes = HttpCodes = {}));
|
||||
var Headers;
|
||||
})(HttpCodes || (HttpCodes = {}));
|
||||
export var Headers;
|
||||
(function (Headers) {
|
||||
Headers["Accept"] = "accept";
|
||||
Headers["ContentType"] = "content-type";
|
||||
})(Headers || (exports.Headers = Headers = {}));
|
||||
var MediaTypes;
|
||||
})(Headers || (Headers = {}));
|
||||
export var MediaTypes;
|
||||
(function (MediaTypes) {
|
||||
MediaTypes["ApplicationJson"] = "application/json";
|
||||
})(MediaTypes || (exports.MediaTypes = MediaTypes = {}));
|
||||
})(MediaTypes || (MediaTypes = {}));
|
||||
/**
|
||||
* Returns the proxy URL, depending upon the supplied url and proxy environment variables.
|
||||
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
|
||||
*/
|
||||
function getProxyUrl(serverUrl) {
|
||||
export function getProxyUrl(serverUrl) {
|
||||
const proxyUrl = pm.getProxyUrl(new URL(serverUrl));
|
||||
return proxyUrl ? proxyUrl.href : '';
|
||||
}
|
||||
exports.getProxyUrl = getProxyUrl;
|
||||
const HttpRedirectCodes = [
|
||||
HttpCodes.MovedPermanently,
|
||||
HttpCodes.ResourceMoved,
|
||||
@@ -102,7 +75,7 @@ const HttpResponseRetryCodes = [
|
||||
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
|
||||
const ExponentialBackoffCeiling = 10;
|
||||
const ExponentialBackoffTimeSlice = 5;
|
||||
class HttpClientError extends Error {
|
||||
export class HttpClientError extends Error {
|
||||
constructor(message, statusCode) {
|
||||
super(message);
|
||||
this.name = 'HttpClientError';
|
||||
@@ -110,8 +83,7 @@ class HttpClientError extends Error {
|
||||
Object.setPrototypeOf(this, HttpClientError.prototype);
|
||||
}
|
||||
}
|
||||
exports.HttpClientError = HttpClientError;
|
||||
class HttpClientResponse {
|
||||
export class HttpClientResponse {
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
@@ -142,13 +114,11 @@ class HttpClientResponse {
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.HttpClientResponse = HttpClientResponse;
|
||||
function isHttps(requestUrl) {
|
||||
export function isHttps(requestUrl) {
|
||||
const parsedUrl = new URL(requestUrl);
|
||||
return parsedUrl.protocol === 'https:';
|
||||
}
|
||||
exports.isHttps = isHttps;
|
||||
class HttpClient {
|
||||
export class HttpClient {
|
||||
constructor(userAgent, handlers, requestOptions) {
|
||||
this._ignoreSslError = false;
|
||||
this._allowRedirects = true;
|
||||
@@ -158,7 +128,7 @@ class HttpClient {
|
||||
this._maxRetries = 1;
|
||||
this._keepAlive = false;
|
||||
this._disposed = false;
|
||||
this.userAgent = userAgent;
|
||||
this.userAgent = this._getUserAgentWithOrchestrationId(userAgent);
|
||||
this.handlers = handlers || [];
|
||||
this.requestOptions = requestOptions;
|
||||
if (requestOptions) {
|
||||
@@ -230,36 +200,39 @@ class HttpClient {
|
||||
* Gets a typed object from an endpoint
|
||||
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
|
||||
*/
|
||||
getJson(requestUrl, additionalHeaders = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
getJson(requestUrl_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (requestUrl, additionalHeaders = {}) {
|
||||
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
|
||||
const res = yield this.get(requestUrl, additionalHeaders);
|
||||
return this._processResponse(res, this.requestOptions);
|
||||
});
|
||||
}
|
||||
postJson(requestUrl, obj, additionalHeaders = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
postJson(requestUrl_1, obj_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (requestUrl, obj, additionalHeaders = {}) {
|
||||
const data = JSON.stringify(obj, null, 2);
|
||||
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
|
||||
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
|
||||
additionalHeaders[Headers.ContentType] =
|
||||
this._getExistingOrDefaultContentTypeHeader(additionalHeaders, MediaTypes.ApplicationJson);
|
||||
const res = yield this.post(requestUrl, data, additionalHeaders);
|
||||
return this._processResponse(res, this.requestOptions);
|
||||
});
|
||||
}
|
||||
putJson(requestUrl, obj, additionalHeaders = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
putJson(requestUrl_1, obj_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (requestUrl, obj, additionalHeaders = {}) {
|
||||
const data = JSON.stringify(obj, null, 2);
|
||||
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
|
||||
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
|
||||
additionalHeaders[Headers.ContentType] =
|
||||
this._getExistingOrDefaultContentTypeHeader(additionalHeaders, MediaTypes.ApplicationJson);
|
||||
const res = yield this.put(requestUrl, data, additionalHeaders);
|
||||
return this._processResponse(res, this.requestOptions);
|
||||
});
|
||||
}
|
||||
patchJson(requestUrl, obj, additionalHeaders = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
patchJson(requestUrl_1, obj_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (requestUrl, obj, additionalHeaders = {}) {
|
||||
const data = JSON.stringify(obj, null, 2);
|
||||
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
|
||||
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
|
||||
additionalHeaders[Headers.ContentType] =
|
||||
this._getExistingOrDefaultContentTypeHeader(additionalHeaders, MediaTypes.ApplicationJson);
|
||||
const res = yield this.patch(requestUrl, data, additionalHeaders);
|
||||
return this._processResponse(res, this.requestOptions);
|
||||
});
|
||||
@@ -488,12 +461,73 @@ class HttpClient {
|
||||
}
|
||||
return lowercaseKeys(headers || {});
|
||||
}
|
||||
/**
|
||||
* Gets an existing header value or returns a default.
|
||||
* Handles converting number header values to strings since HTTP headers must be strings.
|
||||
* Note: This returns string | string[] since some headers can have multiple values.
|
||||
* For headers that must always be a single string (like Content-Type), use the
|
||||
* specialized _getExistingOrDefaultContentTypeHeader method instead.
|
||||
*/
|
||||
_getExistingOrDefaultHeader(additionalHeaders, header, _default) {
|
||||
let clientHeader;
|
||||
if (this.requestOptions && this.requestOptions.headers) {
|
||||
clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
|
||||
const headerValue = lowercaseKeys(this.requestOptions.headers)[header];
|
||||
if (headerValue) {
|
||||
clientHeader =
|
||||
typeof headerValue === 'number' ? headerValue.toString() : headerValue;
|
||||
}
|
||||
}
|
||||
return additionalHeaders[header] || clientHeader || _default;
|
||||
const additionalValue = additionalHeaders[header];
|
||||
if (additionalValue !== undefined) {
|
||||
return typeof additionalValue === 'number'
|
||||
? additionalValue.toString()
|
||||
: additionalValue;
|
||||
}
|
||||
if (clientHeader !== undefined) {
|
||||
return clientHeader;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
/**
|
||||
* Specialized version of _getExistingOrDefaultHeader for Content-Type header.
|
||||
* Always returns a single string (not an array) since Content-Type should be a single value.
|
||||
* Converts arrays to comma-separated strings and numbers to strings to ensure type safety.
|
||||
* This was split from _getExistingOrDefaultHeader to provide stricter typing for callers
|
||||
* that assign the result to places expecting a string (e.g., additionalHeaders[Headers.ContentType]).
|
||||
*/
|
||||
_getExistingOrDefaultContentTypeHeader(additionalHeaders, _default) {
|
||||
let clientHeader;
|
||||
if (this.requestOptions && this.requestOptions.headers) {
|
||||
const headerValue = lowercaseKeys(this.requestOptions.headers)[Headers.ContentType];
|
||||
if (headerValue) {
|
||||
if (typeof headerValue === 'number') {
|
||||
clientHeader = String(headerValue);
|
||||
}
|
||||
else if (Array.isArray(headerValue)) {
|
||||
clientHeader = headerValue.join(', ');
|
||||
}
|
||||
else {
|
||||
clientHeader = headerValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
const additionalValue = additionalHeaders[Headers.ContentType];
|
||||
// Return the first non-undefined value, converting numbers or arrays to strings if necessary
|
||||
if (additionalValue !== undefined) {
|
||||
if (typeof additionalValue === 'number') {
|
||||
return String(additionalValue);
|
||||
}
|
||||
else if (Array.isArray(additionalValue)) {
|
||||
return additionalValue.join(', ');
|
||||
}
|
||||
else {
|
||||
return additionalValue;
|
||||
}
|
||||
}
|
||||
if (clientHeader !== undefined) {
|
||||
return clientHeader;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
_getAgent(parsedUrl) {
|
||||
let agent;
|
||||
@@ -560,7 +594,7 @@ class HttpClient {
|
||||
return proxyAgent;
|
||||
}
|
||||
const usingSsl = parsedUrl.protocol === 'https:';
|
||||
proxyAgent = new undici_1.ProxyAgent(Object.assign({ uri: proxyUrl.href, pipelining: !this._keepAlive ? 0 : 1 }, ((proxyUrl.username || proxyUrl.password) && {
|
||||
proxyAgent = new ProxyAgent(Object.assign({ uri: proxyUrl.href, pipelining: !this._keepAlive ? 0 : 1 }, ((proxyUrl.username || proxyUrl.password) && {
|
||||
token: `Basic ${Buffer.from(`${proxyUrl.username}:${proxyUrl.password}`).toString('base64')}`
|
||||
})));
|
||||
this._proxyAgentDispatcher = proxyAgent;
|
||||
@@ -574,6 +608,17 @@ class HttpClient {
|
||||
}
|
||||
return proxyAgent;
|
||||
}
|
||||
_getUserAgentWithOrchestrationId(userAgent) {
|
||||
const baseUserAgent = userAgent || 'actions/http-client';
|
||||
const orchId = process.env['ACTIONS_ORCHESTRATION_ID'];
|
||||
if (orchId) {
|
||||
// Sanitize the orchestration ID to ensure it contains only valid characters
|
||||
// Valid characters: 0-9, a-z, _, -, .
|
||||
const sanitizedId = orchId.replace(/[^a-z0-9_.-]/gi, '_');
|
||||
return `${baseUserAgent} actions_orchestration_id/${sanitizedId}`;
|
||||
}
|
||||
return baseUserAgent;
|
||||
}
|
||||
_performExponentialBackoff(retryNumber) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);
|
||||
@@ -647,6 +692,5 @@ class HttpClient {
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.HttpClient = HttpClient;
|
||||
const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-4
@@ -1,9 +1,6 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import { HttpClientResponse } from './index';
|
||||
import { HttpClientResponse } from './index.js';
|
||||
export interface HttpClient {
|
||||
options(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
||||
get(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
||||
|
||||
+1
-2
@@ -1,3 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
export {};
|
||||
//# sourceMappingURL=interfaces.js.map
|
||||
+2
-7
@@ -1,7 +1,4 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.checkBypass = exports.getProxyUrl = void 0;
|
||||
function getProxyUrl(reqUrl) {
|
||||
export function getProxyUrl(reqUrl) {
|
||||
const usingSsl = reqUrl.protocol === 'https:';
|
||||
if (checkBypass(reqUrl)) {
|
||||
return undefined;
|
||||
@@ -27,8 +24,7 @@ function getProxyUrl(reqUrl) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
exports.getProxyUrl = getProxyUrl;
|
||||
function checkBypass(reqUrl) {
|
||||
export function checkBypass(reqUrl) {
|
||||
if (!reqUrl.hostname) {
|
||||
return false;
|
||||
}
|
||||
@@ -71,7 +67,6 @@ function checkBypass(reqUrl) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
exports.checkBypass = checkBypass;
|
||||
function isLoopbackAddress(host) {
|
||||
const hostLower = host.toLowerCase();
|
||||
return (hostLower === 'localhost' ||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
||||
+26
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@actions/http-client",
|
||||
"version": "2.2.3",
|
||||
"version": "4.0.0",
|
||||
"description": "Actions Http Client",
|
||||
"keywords": [
|
||||
"github",
|
||||
@@ -9,8 +9,27 @@
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/http-client",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./lib/index.d.ts",
|
||||
"import": "./lib/index.js"
|
||||
},
|
||||
"./lib/auth": {
|
||||
"types": "./lib/auth.d.ts",
|
||||
"import": "./lib/auth.js"
|
||||
},
|
||||
"./lib/proxy": {
|
||||
"types": "./lib/proxy.d.ts",
|
||||
"import": "./lib/proxy.js"
|
||||
},
|
||||
"./lib/interfaces": {
|
||||
"types": "./lib/interfaces.d.ts",
|
||||
"import": "./lib/interfaces.js"
|
||||
}
|
||||
},
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
@@ -39,13 +58,16 @@
|
||||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "20.7.1",
|
||||
"@types/node": "24.1.0",
|
||||
"@types/tunnel": "0.0.3",
|
||||
"proxy": "^2.1.1",
|
||||
"@types/proxy": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
"undici": "^6.23.0"
|
||||
},
|
||||
"overrides": {
|
||||
"uri-js": "npm:uri-js-replace@^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -1,7 +1,18 @@
|
||||
/// <reference types="node" />
|
||||
import * as fs from 'fs';
|
||||
export declare const chmod: typeof fs.promises.chmod, copyFile: typeof fs.promises.copyFile, lstat: typeof fs.promises.lstat, mkdir: typeof fs.promises.mkdir, open: typeof fs.promises.open, readdir: typeof fs.promises.readdir, readlink: typeof fs.promises.readlink, rename: typeof fs.promises.rename, rm: typeof fs.promises.rm, rmdir: typeof fs.promises.rmdir, stat: typeof fs.promises.stat, symlink: typeof fs.promises.symlink, unlink: typeof fs.promises.unlink;
|
||||
export declare const chmod: typeof fs.promises.chmod, copyFile: typeof fs.promises.copyFile, lstat: typeof fs.promises.lstat, mkdir: typeof fs.promises.mkdir, open: typeof fs.promises.open, readdir: typeof fs.promises.readdir, rename: typeof fs.promises.rename, rm: typeof fs.promises.rm, rmdir: typeof fs.promises.rmdir, stat: typeof fs.promises.stat, symlink: typeof fs.promises.symlink, unlink: typeof fs.promises.unlink;
|
||||
export declare const IS_WINDOWS: boolean;
|
||||
/**
|
||||
* Custom implementation of readlink to ensure Windows junctions
|
||||
* maintain trailing backslash for backward compatibility with Node.js < 24
|
||||
*
|
||||
* In Node.js 20, Windows junctions (directory symlinks) always returned paths
|
||||
* with trailing backslashes. Node.js 24 removed this behavior, which breaks
|
||||
* code that relied on this format for path operations.
|
||||
*
|
||||
* This implementation restores the Node 20 behavior by adding a trailing
|
||||
* backslash to all junction results on Windows.
|
||||
*/
|
||||
export declare function readlink(fsPath: string): Promise<string>;
|
||||
export declare const UV_FS_O_EXLOCK = 268435456;
|
||||
export declare const READONLY: number;
|
||||
export declare function exists(fsPath: string): Promise<boolean>;
|
||||
|
||||
+49
-53
@@ -1,23 +1,3 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -27,23 +7,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
_a = fs.promises
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
export const { chmod, copyFile, lstat, mkdir, open, readdir, rename, rm, rmdir, stat, symlink, unlink } = fs.promises;
|
||||
// export const {open} = 'fs'
|
||||
, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
||||
// export const {open} = 'fs'
|
||||
exports.IS_WINDOWS = process.platform === 'win32';
|
||||
export const IS_WINDOWS = process.platform === 'win32';
|
||||
/**
|
||||
* Custom implementation of readlink to ensure Windows junctions
|
||||
* maintain trailing backslash for backward compatibility with Node.js < 24
|
||||
*
|
||||
* In Node.js 20, Windows junctions (directory symlinks) always returned paths
|
||||
* with trailing backslashes. Node.js 24 removed this behavior, which breaks
|
||||
* code that relied on this format for path operations.
|
||||
*
|
||||
* This implementation restores the Node 20 behavior by adding a trailing
|
||||
* backslash to all junction results on Windows.
|
||||
*/
|
||||
export function readlink(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const result = yield fs.promises.readlink(fsPath);
|
||||
// On Windows, restore Node 20 behavior: add trailing backslash to all results
|
||||
// since junctions on Windows are always directory links
|
||||
if (IS_WINDOWS && !result.endsWith('\\')) {
|
||||
return `${result}\\`;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691
|
||||
exports.UV_FS_O_EXLOCK = 0x10000000;
|
||||
exports.READONLY = fs.constants.O_RDONLY;
|
||||
function exists(fsPath) {
|
||||
export const UV_FS_O_EXLOCK = 0x10000000;
|
||||
export const READONLY = fs.constants.O_RDONLY;
|
||||
export function exists(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield exports.stat(fsPath);
|
||||
yield stat(fsPath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
@@ -54,42 +51,39 @@ function exists(fsPath) {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
exports.exists = exists;
|
||||
function isDirectory(fsPath, useStat = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
||||
export function isDirectory(fsPath_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (fsPath, useStat = false) {
|
||||
const stats = useStat ? yield stat(fsPath) : yield lstat(fsPath);
|
||||
return stats.isDirectory();
|
||||
});
|
||||
}
|
||||
exports.isDirectory = isDirectory;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
function isRooted(p) {
|
||||
export function isRooted(p) {
|
||||
p = normalizeSeparators(p);
|
||||
if (!p) {
|
||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
||||
}
|
||||
if (exports.IS_WINDOWS) {
|
||||
if (IS_WINDOWS) {
|
||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
||||
); // e.g. C: or C:\hello
|
||||
}
|
||||
return p.startsWith('/');
|
||||
}
|
||||
exports.isRooted = isRooted;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
function tryGetExecutablePath(filePath, extensions) {
|
||||
export function tryGetExecutablePath(filePath, extensions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let stats = undefined;
|
||||
try {
|
||||
// test file exists
|
||||
stats = yield exports.stat(filePath);
|
||||
stats = yield stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
@@ -98,7 +92,7 @@ function tryGetExecutablePath(filePath, extensions) {
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
if (IS_WINDOWS) {
|
||||
// on Windows, test for valid extension
|
||||
const upperExt = path.extname(filePath).toUpperCase();
|
||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
||||
@@ -117,7 +111,7 @@ function tryGetExecutablePath(filePath, extensions) {
|
||||
filePath = originalFilePath + extension;
|
||||
stats = undefined;
|
||||
try {
|
||||
stats = yield exports.stat(filePath);
|
||||
stats = yield stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
@@ -126,12 +120,12 @@ function tryGetExecutablePath(filePath, extensions) {
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
if (IS_WINDOWS) {
|
||||
// preserve the case of the actual file (since an extension was appended)
|
||||
try {
|
||||
const directory = path.dirname(filePath);
|
||||
const upperName = path.basename(filePath).toUpperCase();
|
||||
for (const actualName of yield exports.readdir(directory)) {
|
||||
for (const actualName of yield readdir(directory)) {
|
||||
if (upperName === actualName.toUpperCase()) {
|
||||
filePath = path.join(directory, actualName);
|
||||
break;
|
||||
@@ -154,10 +148,9 @@ function tryGetExecutablePath(filePath, extensions) {
|
||||
return '';
|
||||
});
|
||||
}
|
||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
||||
function normalizeSeparators(p) {
|
||||
p = p || '';
|
||||
if (exports.IS_WINDOWS) {
|
||||
if (IS_WINDOWS) {
|
||||
// convert slashes on Windows
|
||||
p = p.replace(/\//g, '\\');
|
||||
// remove redundant slashes
|
||||
@@ -171,13 +164,16 @@ function normalizeSeparators(p) {
|
||||
// 256 128 64 32 16 8 4 2 1
|
||||
function isUnixExecutable(stats) {
|
||||
return ((stats.mode & 1) > 0 ||
|
||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
||||
((stats.mode & 8) > 0 &&
|
||||
process.getgid !== undefined &&
|
||||
stats.gid === process.getgid()) ||
|
||||
((stats.mode & 64) > 0 &&
|
||||
process.getuid !== undefined &&
|
||||
stats.uid === process.getuid()));
|
||||
}
|
||||
// Get the path of cmd.exe in windows
|
||||
function getCmdPath() {
|
||||
export function getCmdPath() {
|
||||
var _a;
|
||||
return (_a = process.env['COMSPEC']) !== null && _a !== void 0 ? _a : `cmd.exe`;
|
||||
}
|
||||
exports.getCmdPath = getCmdPath;
|
||||
//# sourceMappingURL=io-util.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"io-util.js","sourceRoot":"","sources":["../src/io-util.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"io-util.js","sourceRoot":"","sources":["../src/io-util.ts"],"names":[],"mappings":"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"}
|
||||
+12
-40
@@ -1,23 +1,3 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
@@ -27,11 +7,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
|
||||
const assert_1 = require("assert");
|
||||
const path = __importStar(require("path"));
|
||||
const ioUtil = __importStar(require("./io-util"));
|
||||
import { ok } from 'assert';
|
||||
import * as path from 'path';
|
||||
import * as ioUtil from './io-util.js';
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
||||
@@ -40,8 +18,8 @@ const ioUtil = __importStar(require("./io-util"));
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
function cp(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
export function cp(source_1, dest_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (source, dest, options = {}) {
|
||||
const { force, recursive, copySourceDirectory } = readCopyOptions(options);
|
||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
||||
// Dest is an existing file, but not forcing
|
||||
@@ -73,7 +51,6 @@ function cp(source, dest, options = {}) {
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.cp = cp;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
@@ -81,8 +58,8 @@ exports.cp = cp;
|
||||
* @param dest destination path
|
||||
* @param options optional. See MoveOptions.
|
||||
*/
|
||||
function mv(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
export function mv(source_1, dest_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (source, dest, options = {}) {
|
||||
if (yield ioUtil.exists(dest)) {
|
||||
let destExists = true;
|
||||
if (yield ioUtil.isDirectory(dest)) {
|
||||
@@ -103,13 +80,12 @@ function mv(source, dest, options = {}) {
|
||||
yield ioUtil.rename(source, dest);
|
||||
});
|
||||
}
|
||||
exports.mv = mv;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
function rmRF(inputPath) {
|
||||
export function rmRF(inputPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
// Check for invalid characters
|
||||
@@ -132,7 +108,6 @@ function rmRF(inputPath) {
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.rmRF = rmRF;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
@@ -140,13 +115,12 @@ exports.rmRF = rmRF;
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
function mkdirP(fsPath) {
|
||||
export function mkdirP(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
||||
ok(fsPath, 'a path argument must be provided');
|
||||
yield ioUtil.mkdir(fsPath, { recursive: true });
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
@@ -155,7 +129,7 @@ exports.mkdirP = mkdirP;
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
function which(tool, check) {
|
||||
export function which(tool, check) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!tool) {
|
||||
throw new Error("parameter 'tool' is required");
|
||||
@@ -180,13 +154,12 @@ function which(tool, check) {
|
||||
return '';
|
||||
});
|
||||
}
|
||||
exports.which = which;
|
||||
/**
|
||||
* Returns a list of all occurrences of the given tool on the system path.
|
||||
*
|
||||
* @returns Promise<string[]> the paths of the tool
|
||||
*/
|
||||
function findInPath(tool) {
|
||||
export function findInPath(tool) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!tool) {
|
||||
throw new Error("parameter 'tool' is required");
|
||||
@@ -237,7 +210,6 @@ function findInPath(tool) {
|
||||
return matches;
|
||||
});
|
||||
}
|
||||
exports.findInPath = findInPath;
|
||||
function readCopyOptions(options) {
|
||||
const force = options.force == null ? true : options.force;
|
||||
const recursive = Boolean(options.recursive);
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+12
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@actions/io",
|
||||
"version": "1.1.3",
|
||||
"version": "3.0.2",
|
||||
"description": "Actions io lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
@@ -9,8 +9,19 @@
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/io",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "lib/io.js",
|
||||
"types": "lib/io.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./lib/io.d.ts",
|
||||
"import": "./lib/io.js"
|
||||
},
|
||||
"./lib/io-util": {
|
||||
"types": "./lib/io-util.d.ts",
|
||||
"import": "./lib/io-util.js"
|
||||
}
|
||||
},
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
Copyright Brian White. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
-271
@@ -1,271 +0,0 @@
|
||||
# busboy
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://github.com/fastify/busboy/actions)
|
||||
[](https://coveralls.io/r/fastify/busboy?branch=master)
|
||||
[](https://standardjs.com/)
|
||||
[](https://github.com/fastify/.github/blob/main/SECURITY.md)
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://www.npmjs.com/package/@fastify/busboy)
|
||||
[](https://www.npmjs.com/package/@fastify/busboy)
|
||||
|
||||
</div>
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A Node.js module for parsing incoming HTML form data.
|
||||
|
||||
This is an officially supported fork by [fastify](https://github.com/fastify/) organization of the amazing library [originally created](https://github.com/mscdex/busboy) by Brian White,
|
||||
aimed at addressing long-standing issues with it.
|
||||
|
||||
Benchmark (Mean time for 500 Kb payload, 2000 cycles, 1000 cycle warmup):
|
||||
|
||||
| Library | Version | Mean time in nanoseconds (less is better) |
|
||||
|-----------------------|---------|-------------------------------------------|
|
||||
| busboy | 0.3.1 | `340114` |
|
||||
| @fastify/busboy | 1.0.0 | `270984` |
|
||||
|
||||
[Changelog](https://github.com/fastify/busboy/blob/master/CHANGELOG.md) since busboy 0.31.
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
* [Node.js](http://nodejs.org/) 10+
|
||||
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
npm i @fastify/busboy
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
* Parsing (multipart) with default options:
|
||||
|
||||
```javascript
|
||||
const http = require('node:http');
|
||||
const { inspect } = require('node:util');
|
||||
const Busboy = require('busboy');
|
||||
|
||||
http.createServer((req, res) => {
|
||||
if (req.method === 'POST') {
|
||||
const busboy = new Busboy({ headers: req.headers });
|
||||
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
|
||||
console.log(`File [${fieldname}]: filename: ${filename}, encoding: ${encoding}, mimetype: ${mimetype}`);
|
||||
file.on('data', data => {
|
||||
console.log(`File [${fieldname}] got ${data.length} bytes`);
|
||||
});
|
||||
file.on('end', () => {
|
||||
console.log(`File [${fieldname}] Finished`);
|
||||
});
|
||||
});
|
||||
busboy.on('field', (fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) => {
|
||||
console.log(`Field [${fieldname}]: value: ${inspect(val)}`);
|
||||
});
|
||||
busboy.on('finish', () => {
|
||||
console.log('Done parsing form!');
|
||||
res.writeHead(303, { Connection: 'close', Location: '/' });
|
||||
res.end();
|
||||
});
|
||||
req.pipe(busboy);
|
||||
} else if (req.method === 'GET') {
|
||||
res.writeHead(200, { Connection: 'close' });
|
||||
res.end(`<html><head></head><body>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<input type="text" name="textfield"><br>
|
||||
<input type="file" name="filefield"><br>
|
||||
<input type="submit">
|
||||
</form>
|
||||
</body></html>`);
|
||||
}
|
||||
}).listen(8000, () => {
|
||||
console.log('Listening for requests');
|
||||
});
|
||||
|
||||
// Example output, using http://nodejs.org/images/ryan-speaker.jpg as the file:
|
||||
//
|
||||
// Listening for requests
|
||||
// File [filefield]: filename: ryan-speaker.jpg, encoding: binary
|
||||
// File [filefield] got 11971 bytes
|
||||
// Field [textfield]: value: 'testing! :-)'
|
||||
// File [filefield] Finished
|
||||
// Done parsing form!
|
||||
```
|
||||
|
||||
* Save all incoming files to disk:
|
||||
|
||||
```javascript
|
||||
const http = require('node:http');
|
||||
const path = require('node:path');
|
||||
const os = require('node:os');
|
||||
const fs = require('node:fs');
|
||||
|
||||
const Busboy = require('busboy');
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
if (req.method === 'POST') {
|
||||
const busboy = new Busboy({ headers: req.headers });
|
||||
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
||||
var saveTo = path.join(os.tmpdir(), path.basename(fieldname));
|
||||
file.pipe(fs.createWriteStream(saveTo));
|
||||
});
|
||||
busboy.on('finish', function() {
|
||||
res.writeHead(200, { 'Connection': 'close' });
|
||||
res.end("That's all folks!");
|
||||
});
|
||||
return req.pipe(busboy);
|
||||
}
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
}).listen(8000, function() {
|
||||
console.log('Listening for requests');
|
||||
});
|
||||
```
|
||||
|
||||
* Parsing (urlencoded) with default options:
|
||||
|
||||
```javascript
|
||||
const http = require('node:http');
|
||||
const { inspect } = require('node:util');
|
||||
|
||||
const Busboy = require('busboy');
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
if (req.method === 'POST') {
|
||||
const busboy = new Busboy({ headers: req.headers });
|
||||
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
||||
console.log('File [' + fieldname + ']: filename: ' + filename);
|
||||
file.on('data', function(data) {
|
||||
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
|
||||
});
|
||||
file.on('end', function() {
|
||||
console.log('File [' + fieldname + '] Finished');
|
||||
});
|
||||
});
|
||||
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
|
||||
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
|
||||
});
|
||||
busboy.on('finish', function() {
|
||||
console.log('Done parsing form!');
|
||||
res.writeHead(303, { Connection: 'close', Location: '/' });
|
||||
res.end();
|
||||
});
|
||||
req.pipe(busboy);
|
||||
} else if (req.method === 'GET') {
|
||||
res.writeHead(200, { Connection: 'close' });
|
||||
res.end('<html><head></head><body>\
|
||||
<form method="POST">\
|
||||
<input type="text" name="textfield"><br />\
|
||||
<select name="selectfield">\
|
||||
<option value="1">1</option>\
|
||||
<option value="10">10</option>\
|
||||
<option value="100">100</option>\
|
||||
<option value="9001">9001</option>\
|
||||
</select><br />\
|
||||
<input type="checkbox" name="checkfield">Node.js rules!<br />\
|
||||
<input type="submit">\
|
||||
</form>\
|
||||
</body></html>');
|
||||
}
|
||||
}).listen(8000, function() {
|
||||
console.log('Listening for requests');
|
||||
});
|
||||
|
||||
// Example output:
|
||||
//
|
||||
// Listening for requests
|
||||
// Field [textfield]: value: 'testing! :-)'
|
||||
// Field [selectfield]: value: '9001'
|
||||
// Field [checkfield]: value: 'on'
|
||||
// Done parsing form!
|
||||
```
|
||||
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
_Busboy_ is a _Writable_ stream
|
||||
|
||||
Busboy (special) events
|
||||
-----------------------
|
||||
|
||||
* **file**(< _string_ >fieldname, < _ReadableStream_ >stream, < _string_ >filename, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new file form field found. `transferEncoding` contains the 'Content-Transfer-Encoding' value for the file stream. `mimeType` contains the 'Content-Type' value for the file stream.
|
||||
* Note: if you listen for this event, you should always handle the `stream` no matter if you care about the file contents or not (e.g. you can simply just do `stream.resume();` if you want to discard the contents), otherwise the 'finish' event will never fire on the Busboy instance. However, if you don't care about **any** incoming files, you can simply not listen for the 'file' event at all and any/all files will be automatically and safely discarded (these discarded files do still count towards `files` and `parts` limits).
|
||||
* If a configured file size limit was reached, `stream` will both have a boolean property `truncated` (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens.
|
||||
* The property `bytesRead` informs about the number of bytes that have been read so far.
|
||||
|
||||
* **field**(< _string_ >fieldname, < _string_ >value, < _boolean_ >fieldnameTruncated, < _boolean_ >valueTruncated, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new non-file field found.
|
||||
|
||||
* **partsLimit**() - Emitted when specified `parts` limit has been reached. No more 'file' or 'field' events will be emitted.
|
||||
|
||||
* **filesLimit**() - Emitted when specified `files` limit has been reached. No more 'file' events will be emitted.
|
||||
|
||||
* **fieldsLimit**() - Emitted when specified `fields` limit has been reached. No more 'field' events will be emitted.
|
||||
|
||||
|
||||
Busboy methods
|
||||
--------------
|
||||
|
||||
* **(constructor)**(< _object_ >config) - Creates and returns a new Busboy instance.
|
||||
|
||||
* The constructor takes the following valid `config` settings:
|
||||
|
||||
* **headers** - _object_ - These are the HTTP headers of the incoming request, which are used by individual parsers.
|
||||
|
||||
* **autoDestroy** - _boolean_ - Whether this stream should automatically call .destroy() on itself after ending. (Default: false).
|
||||
|
||||
* **highWaterMark** - _integer_ - highWaterMark to use for this Busboy instance (Default: WritableStream default).
|
||||
|
||||
* **fileHwm** - _integer_ - highWaterMark to use for file streams (Default: ReadableStream default).
|
||||
|
||||
* **defCharset** - _string_ - Default character set to use when one isn't defined (Default: 'utf8').
|
||||
|
||||
* **preservePath** - _boolean_ - If paths in the multipart 'filename' field shall be preserved. (Default: false).
|
||||
|
||||
* **isPartAFile** - __function__ - Use this function to override the default file detection functionality. It has following parameters:
|
||||
|
||||
* fieldName - __string__ The name of the field.
|
||||
|
||||
* contentType - __string__ The content-type of the part, e.g. `text/plain`, `image/jpeg`, `application/octet-stream`
|
||||
|
||||
* fileName - __string__ The name of a file supplied by the part.
|
||||
|
||||
(Default: `(fieldName, contentType, fileName) => (contentType === 'application/octet-stream' || fileName !== undefined)`)
|
||||
|
||||
* **limits** - _object_ - Various limits on incoming data. Valid properties are:
|
||||
|
||||
* **fieldNameSize** - _integer_ - Max field name size (in bytes) (Default: 100 bytes).
|
||||
|
||||
* **fieldSize** - _integer_ - Max field value size (in bytes) (Default: 1 MiB, which is 1024 x 1024 bytes).
|
||||
|
||||
* **fields** - _integer_ - Max number of non-file fields (Default: Infinity).
|
||||
|
||||
* **fileSize** - _integer_ - For multipart forms, the max file size (in bytes) (Default: Infinity).
|
||||
|
||||
* **files** - _integer_ - For multipart forms, the max number of file fields (Default: Infinity).
|
||||
|
||||
* **parts** - _integer_ - For multipart forms, the max number of parts (fields + files) (Default: Infinity).
|
||||
|
||||
* **headerPairs** - _integer_ - For multipart forms, the max number of header key=>value pairs to parse **Default:** 2000
|
||||
|
||||
* **headerSize** - _integer_ - For multipart forms, the max size of a multipart header **Default:** 81920.
|
||||
|
||||
* The constructor can throw errors:
|
||||
|
||||
* **Busboy expected an options-Object.** - Busboy expected an Object as first parameters.
|
||||
|
||||
* **Busboy expected an options-Object with headers-attribute.** - The first parameter is lacking of a headers-attribute.
|
||||
|
||||
* **Limit $limit is not a valid number** - Busboy expected the desired limit to be of type number. Busboy throws this Error to prevent a potential security issue by falling silently back to the Busboy-defaults. Potential source for this Error can be the direct use of environment variables without transforming them to the type number.
|
||||
|
||||
* **Unsupported Content-Type.** - The `Content-Type` isn't one Busboy can parse.
|
||||
|
||||
* **Missing Content-Type-header.** - The provided headers don't include `Content-Type` at all.
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
Copyright Brian White. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
-213
@@ -1,213 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const WritableStream = require('node:stream').Writable
|
||||
const inherits = require('node:util').inherits
|
||||
|
||||
const StreamSearch = require('../../streamsearch/sbmh')
|
||||
|
||||
const PartStream = require('./PartStream')
|
||||
const HeaderParser = require('./HeaderParser')
|
||||
|
||||
const DASH = 45
|
||||
const B_ONEDASH = Buffer.from('-')
|
||||
const B_CRLF = Buffer.from('\r\n')
|
||||
const EMPTY_FN = function () {}
|
||||
|
||||
function Dicer (cfg) {
|
||||
if (!(this instanceof Dicer)) { return new Dicer(cfg) }
|
||||
WritableStream.call(this, cfg)
|
||||
|
||||
if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string')) { throw new TypeError('Boundary required') }
|
||||
|
||||
if (typeof cfg.boundary === 'string') { this.setBoundary(cfg.boundary) } else { this._bparser = undefined }
|
||||
|
||||
this._headerFirst = cfg.headerFirst
|
||||
|
||||
this._dashes = 0
|
||||
this._parts = 0
|
||||
this._finished = false
|
||||
this._realFinish = false
|
||||
this._isPreamble = true
|
||||
this._justMatched = false
|
||||
this._firstWrite = true
|
||||
this._inHeader = true
|
||||
this._part = undefined
|
||||
this._cb = undefined
|
||||
this._ignoreData = false
|
||||
this._partOpts = { highWaterMark: cfg.partHwm }
|
||||
this._pause = false
|
||||
|
||||
const self = this
|
||||
this._hparser = new HeaderParser(cfg)
|
||||
this._hparser.on('header', function (header) {
|
||||
self._inHeader = false
|
||||
self._part.emit('header', header)
|
||||
})
|
||||
}
|
||||
inherits(Dicer, WritableStream)
|
||||
|
||||
Dicer.prototype.emit = function (ev) {
|
||||
if (ev === 'finish' && !this._realFinish) {
|
||||
if (!this._finished) {
|
||||
const self = this
|
||||
process.nextTick(function () {
|
||||
self.emit('error', new Error('Unexpected end of multipart data'))
|
||||
if (self._part && !self._ignoreData) {
|
||||
const type = (self._isPreamble ? 'Preamble' : 'Part')
|
||||
self._part.emit('error', new Error(type + ' terminated early due to unexpected end of multipart data'))
|
||||
self._part.push(null)
|
||||
process.nextTick(function () {
|
||||
self._realFinish = true
|
||||
self.emit('finish')
|
||||
self._realFinish = false
|
||||
})
|
||||
return
|
||||
}
|
||||
self._realFinish = true
|
||||
self.emit('finish')
|
||||
self._realFinish = false
|
||||
})
|
||||
}
|
||||
} else { WritableStream.prototype.emit.apply(this, arguments) }
|
||||
}
|
||||
|
||||
Dicer.prototype._write = function (data, encoding, cb) {
|
||||
// ignore unexpected data (e.g. extra trailer data after finished)
|
||||
if (!this._hparser && !this._bparser) { return cb() }
|
||||
|
||||
if (this._headerFirst && this._isPreamble) {
|
||||
if (!this._part) {
|
||||
this._part = new PartStream(this._partOpts)
|
||||
if (this.listenerCount('preamble') !== 0) { this.emit('preamble', this._part) } else { this._ignore() }
|
||||
}
|
||||
const r = this._hparser.push(data)
|
||||
if (!this._inHeader && r !== undefined && r < data.length) { data = data.slice(r) } else { return cb() }
|
||||
}
|
||||
|
||||
// allows for "easier" testing
|
||||
if (this._firstWrite) {
|
||||
this._bparser.push(B_CRLF)
|
||||
this._firstWrite = false
|
||||
}
|
||||
|
||||
this._bparser.push(data)
|
||||
|
||||
if (this._pause) { this._cb = cb } else { cb() }
|
||||
}
|
||||
|
||||
Dicer.prototype.reset = function () {
|
||||
this._part = undefined
|
||||
this._bparser = undefined
|
||||
this._hparser = undefined
|
||||
}
|
||||
|
||||
Dicer.prototype.setBoundary = function (boundary) {
|
||||
const self = this
|
||||
this._bparser = new StreamSearch('\r\n--' + boundary)
|
||||
this._bparser.on('info', function (isMatch, data, start, end) {
|
||||
self._oninfo(isMatch, data, start, end)
|
||||
})
|
||||
}
|
||||
|
||||
Dicer.prototype._ignore = function () {
|
||||
if (this._part && !this._ignoreData) {
|
||||
this._ignoreData = true
|
||||
this._part.on('error', EMPTY_FN)
|
||||
// we must perform some kind of read on the stream even though we are
|
||||
// ignoring the data, otherwise node's Readable stream will not emit 'end'
|
||||
// after pushing null to the stream
|
||||
this._part.resume()
|
||||
}
|
||||
}
|
||||
|
||||
Dicer.prototype._oninfo = function (isMatch, data, start, end) {
|
||||
let buf; const self = this; let i = 0; let r; let shouldWriteMore = true
|
||||
|
||||
if (!this._part && this._justMatched && data) {
|
||||
while (this._dashes < 2 && (start + i) < end) {
|
||||
if (data[start + i] === DASH) {
|
||||
++i
|
||||
++this._dashes
|
||||
} else {
|
||||
if (this._dashes) { buf = B_ONEDASH }
|
||||
this._dashes = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
if (this._dashes === 2) {
|
||||
if ((start + i) < end && this.listenerCount('trailer') !== 0) { this.emit('trailer', data.slice(start + i, end)) }
|
||||
this.reset()
|
||||
this._finished = true
|
||||
// no more parts will be added
|
||||
if (self._parts === 0) {
|
||||
self._realFinish = true
|
||||
self.emit('finish')
|
||||
self._realFinish = false
|
||||
}
|
||||
}
|
||||
if (this._dashes) { return }
|
||||
}
|
||||
if (this._justMatched) { this._justMatched = false }
|
||||
if (!this._part) {
|
||||
this._part = new PartStream(this._partOpts)
|
||||
this._part._read = function (n) {
|
||||
self._unpause()
|
||||
}
|
||||
if (this._isPreamble && this.listenerCount('preamble') !== 0) {
|
||||
this.emit('preamble', this._part)
|
||||
} else if (this._isPreamble !== true && this.listenerCount('part') !== 0) {
|
||||
this.emit('part', this._part)
|
||||
} else {
|
||||
this._ignore()
|
||||
}
|
||||
if (!this._isPreamble) { this._inHeader = true }
|
||||
}
|
||||
if (data && start < end && !this._ignoreData) {
|
||||
if (this._isPreamble || !this._inHeader) {
|
||||
if (buf) { shouldWriteMore = this._part.push(buf) }
|
||||
shouldWriteMore = this._part.push(data.slice(start, end))
|
||||
if (!shouldWriteMore) { this._pause = true }
|
||||
} else if (!this._isPreamble && this._inHeader) {
|
||||
if (buf) { this._hparser.push(buf) }
|
||||
r = this._hparser.push(data.slice(start, end))
|
||||
if (!this._inHeader && r !== undefined && r < end) { this._oninfo(false, data, start + r, end) }
|
||||
}
|
||||
}
|
||||
if (isMatch) {
|
||||
this._hparser.reset()
|
||||
if (this._isPreamble) { this._isPreamble = false } else {
|
||||
if (start !== end) {
|
||||
++this._parts
|
||||
this._part.on('end', function () {
|
||||
if (--self._parts === 0) {
|
||||
if (self._finished) {
|
||||
self._realFinish = true
|
||||
self.emit('finish')
|
||||
self._realFinish = false
|
||||
} else {
|
||||
self._unpause()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
this._part.push(null)
|
||||
this._part = undefined
|
||||
this._ignoreData = false
|
||||
this._justMatched = true
|
||||
this._dashes = 0
|
||||
}
|
||||
}
|
||||
|
||||
Dicer.prototype._unpause = function () {
|
||||
if (!this._pause) { return }
|
||||
|
||||
this._pause = false
|
||||
if (this._cb) {
|
||||
const cb = this._cb
|
||||
this._cb = undefined
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Dicer
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const EventEmitter = require('node:events').EventEmitter
|
||||
const inherits = require('node:util').inherits
|
||||
const getLimit = require('../../../lib/utils/getLimit')
|
||||
|
||||
const StreamSearch = require('../../streamsearch/sbmh')
|
||||
|
||||
const B_DCRLF = Buffer.from('\r\n\r\n')
|
||||
const RE_CRLF = /\r\n/g
|
||||
const RE_HDR = /^([^:]+):[ \t]?([\x00-\xFF]+)?$/ // eslint-disable-line no-control-regex
|
||||
|
||||
function HeaderParser (cfg) {
|
||||
EventEmitter.call(this)
|
||||
|
||||
cfg = cfg || {}
|
||||
const self = this
|
||||
this.nread = 0
|
||||
this.maxed = false
|
||||
this.npairs = 0
|
||||
this.maxHeaderPairs = getLimit(cfg, 'maxHeaderPairs', 2000)
|
||||
this.maxHeaderSize = getLimit(cfg, 'maxHeaderSize', 80 * 1024)
|
||||
this.buffer = ''
|
||||
this.header = {}
|
||||
this.finished = false
|
||||
this.ss = new StreamSearch(B_DCRLF)
|
||||
this.ss.on('info', function (isMatch, data, start, end) {
|
||||
if (data && !self.maxed) {
|
||||
if (self.nread + end - start >= self.maxHeaderSize) {
|
||||
end = self.maxHeaderSize - self.nread + start
|
||||
self.nread = self.maxHeaderSize
|
||||
self.maxed = true
|
||||
} else { self.nread += (end - start) }
|
||||
|
||||
self.buffer += data.toString('binary', start, end)
|
||||
}
|
||||
if (isMatch) { self._finish() }
|
||||
})
|
||||
}
|
||||
inherits(HeaderParser, EventEmitter)
|
||||
|
||||
HeaderParser.prototype.push = function (data) {
|
||||
const r = this.ss.push(data)
|
||||
if (this.finished) { return r }
|
||||
}
|
||||
|
||||
HeaderParser.prototype.reset = function () {
|
||||
this.finished = false
|
||||
this.buffer = ''
|
||||
this.header = {}
|
||||
this.ss.reset()
|
||||
}
|
||||
|
||||
HeaderParser.prototype._finish = function () {
|
||||
if (this.buffer) { this._parseHeader() }
|
||||
this.ss.matches = this.ss.maxMatches
|
||||
const header = this.header
|
||||
this.header = {}
|
||||
this.buffer = ''
|
||||
this.finished = true
|
||||
this.nread = this.npairs = 0
|
||||
this.maxed = false
|
||||
this.emit('header', header)
|
||||
}
|
||||
|
||||
HeaderParser.prototype._parseHeader = function () {
|
||||
if (this.npairs === this.maxHeaderPairs) { return }
|
||||
|
||||
const lines = this.buffer.split(RE_CRLF)
|
||||
const len = lines.length
|
||||
let m, h
|
||||
|
||||
for (var i = 0; i < len; ++i) { // eslint-disable-line no-var
|
||||
if (lines[i].length === 0) { continue }
|
||||
if (lines[i][0] === '\t' || lines[i][0] === ' ') {
|
||||
// folded header content
|
||||
// RFC2822 says to just remove the CRLF and not the whitespace following
|
||||
// it, so we follow the RFC and include the leading whitespace ...
|
||||
if (h) {
|
||||
this.header[h][this.header[h].length - 1] += lines[i]
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
const posColon = lines[i].indexOf(':')
|
||||
if (
|
||||
posColon === -1 ||
|
||||
posColon === 0
|
||||
) {
|
||||
return
|
||||
}
|
||||
m = RE_HDR.exec(lines[i])
|
||||
h = m[1].toLowerCase()
|
||||
this.header[h] = this.header[h] || []
|
||||
this.header[h].push((m[2] || ''))
|
||||
if (++this.npairs === this.maxHeaderPairs) { break }
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HeaderParser
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const inherits = require('node:util').inherits
|
||||
const ReadableStream = require('node:stream').Readable
|
||||
|
||||
function PartStream (opts) {
|
||||
ReadableStream.call(this, opts)
|
||||
}
|
||||
inherits(PartStream, ReadableStream)
|
||||
|
||||
PartStream.prototype._read = function (n) {}
|
||||
|
||||
module.exports = PartStream
|
||||
-164
@@ -1,164 +0,0 @@
|
||||
// Type definitions for dicer 0.2
|
||||
// Project: https://github.com/mscdex/dicer
|
||||
// Definitions by: BendingBender <https://github.com/BendingBender>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.2
|
||||
/// <reference types="node" />
|
||||
|
||||
import stream = require("stream");
|
||||
|
||||
// tslint:disable:unified-signatures
|
||||
|
||||
/**
|
||||
* A very fast streaming multipart parser for node.js.
|
||||
* Dicer is a WritableStream
|
||||
*
|
||||
* Dicer (special) events:
|
||||
* - on('finish', ()) - Emitted when all parts have been parsed and the Dicer instance has been ended.
|
||||
* - on('part', (stream: PartStream)) - Emitted when a new part has been found.
|
||||
* - on('preamble', (stream: PartStream)) - Emitted for preamble if you should happen to need it (can usually be ignored).
|
||||
* - on('trailer', (data: Buffer)) - Emitted when trailing data was found after the terminating boundary (as with the preamble, this can usually be ignored too).
|
||||
*/
|
||||
export class Dicer extends stream.Writable {
|
||||
/**
|
||||
* Creates and returns a new Dicer instance with the following valid config settings:
|
||||
*
|
||||
* @param config The configuration to use
|
||||
*/
|
||||
constructor(config: Dicer.Config);
|
||||
/**
|
||||
* Sets the boundary to use for parsing and performs some initialization needed for parsing.
|
||||
* You should only need to use this if you set headerFirst to true in the constructor and are parsing the boundary from the preamble header.
|
||||
*
|
||||
* @param boundary The boundary to use
|
||||
*/
|
||||
setBoundary(boundary: string): void;
|
||||
addListener(event: "finish", listener: () => void): this;
|
||||
addListener(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
||||
addListener(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
||||
addListener(event: "trailer", listener: (data: Buffer) => void): this;
|
||||
addListener(event: "close", listener: () => void): this;
|
||||
addListener(event: "drain", listener: () => void): this;
|
||||
addListener(event: "error", listener: (err: Error) => void): this;
|
||||
addListener(event: "pipe", listener: (src: stream.Readable) => void): this;
|
||||
addListener(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
||||
addListener(event: string, listener: (...args: any[]) => void): this;
|
||||
on(event: "finish", listener: () => void): this;
|
||||
on(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
||||
on(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
||||
on(event: "trailer", listener: (data: Buffer) => void): this;
|
||||
on(event: "close", listener: () => void): this;
|
||||
on(event: "drain", listener: () => void): this;
|
||||
on(event: "error", listener: (err: Error) => void): this;
|
||||
on(event: "pipe", listener: (src: stream.Readable) => void): this;
|
||||
on(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
||||
on(event: string, listener: (...args: any[]) => void): this;
|
||||
once(event: "finish", listener: () => void): this;
|
||||
once(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
||||
once(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
||||
once(event: "trailer", listener: (data: Buffer) => void): this;
|
||||
once(event: "close", listener: () => void): this;
|
||||
once(event: "drain", listener: () => void): this;
|
||||
once(event: "error", listener: (err: Error) => void): this;
|
||||
once(event: "pipe", listener: (src: stream.Readable) => void): this;
|
||||
once(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
||||
once(event: string, listener: (...args: any[]) => void): this;
|
||||
prependListener(event: "finish", listener: () => void): this;
|
||||
prependListener(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
||||
prependListener(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
||||
prependListener(event: "trailer", listener: (data: Buffer) => void): this;
|
||||
prependListener(event: "close", listener: () => void): this;
|
||||
prependListener(event: "drain", listener: () => void): this;
|
||||
prependListener(event: "error", listener: (err: Error) => void): this;
|
||||
prependListener(event: "pipe", listener: (src: stream.Readable) => void): this;
|
||||
prependListener(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
||||
prependListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependOnceListener(event: "finish", listener: () => void): this;
|
||||
prependOnceListener(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
||||
prependOnceListener(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
||||
prependOnceListener(event: "trailer", listener: (data: Buffer) => void): this;
|
||||
prependOnceListener(event: "close", listener: () => void): this;
|
||||
prependOnceListener(event: "drain", listener: () => void): this;
|
||||
prependOnceListener(event: "error", listener: (err: Error) => void): this;
|
||||
prependOnceListener(event: "pipe", listener: (src: stream.Readable) => void): this;
|
||||
prependOnceListener(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
||||
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
||||
removeListener(event: "finish", listener: () => void): this;
|
||||
removeListener(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
||||
removeListener(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
||||
removeListener(event: "trailer", listener: (data: Buffer) => void): this;
|
||||
removeListener(event: "close", listener: () => void): this;
|
||||
removeListener(event: "drain", listener: () => void): this;
|
||||
removeListener(event: "error", listener: (err: Error) => void): this;
|
||||
removeListener(event: "pipe", listener: (src: stream.Readable) => void): this;
|
||||
removeListener(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
||||
removeListener(event: string, listener: (...args: any[]) => void): this;
|
||||
}
|
||||
|
||||
declare namespace Dicer {
|
||||
interface Config {
|
||||
/**
|
||||
* This is the boundary used to detect the beginning of a new part.
|
||||
*/
|
||||
boundary?: string | undefined;
|
||||
/**
|
||||
* If true, preamble header parsing will be performed first.
|
||||
*/
|
||||
headerFirst?: boolean | undefined;
|
||||
/**
|
||||
* The maximum number of header key=>value pairs to parse Default: 2000 (same as node's http).
|
||||
*/
|
||||
maxHeaderPairs?: number | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* PartStream is a _ReadableStream_
|
||||
*
|
||||
* PartStream (special) events:
|
||||
* - on('header', (header: object)) - An object containing the header for this particular part. Each property value is an array of one or more string values.
|
||||
*/
|
||||
interface PartStream extends stream.Readable {
|
||||
addListener(event: "header", listener: (header: object) => void): this;
|
||||
addListener(event: "close", listener: () => void): this;
|
||||
addListener(event: "data", listener: (chunk: Buffer | string) => void): this;
|
||||
addListener(event: "end", listener: () => void): this;
|
||||
addListener(event: "readable", listener: () => void): this;
|
||||
addListener(event: "error", listener: (err: Error) => void): this;
|
||||
addListener(event: string, listener: (...args: any[]) => void): this;
|
||||
on(event: "header", listener: (header: object) => void): this;
|
||||
on(event: "close", listener: () => void): this;
|
||||
on(event: "data", listener: (chunk: Buffer | string) => void): this;
|
||||
on(event: "end", listener: () => void): this;
|
||||
on(event: "readable", listener: () => void): this;
|
||||
on(event: "error", listener: (err: Error) => void): this;
|
||||
on(event: string, listener: (...args: any[]) => void): this;
|
||||
once(event: "header", listener: (header: object) => void): this;
|
||||
once(event: "close", listener: () => void): this;
|
||||
once(event: "data", listener: (chunk: Buffer | string) => void): this;
|
||||
once(event: "end", listener: () => void): this;
|
||||
once(event: "readable", listener: () => void): this;
|
||||
once(event: "error", listener: (err: Error) => void): this;
|
||||
once(event: string, listener: (...args: any[]) => void): this;
|
||||
prependListener(event: "header", listener: (header: object) => void): this;
|
||||
prependListener(event: "close", listener: () => void): this;
|
||||
prependListener(event: "data", listener: (chunk: Buffer | string) => void): this;
|
||||
prependListener(event: "end", listener: () => void): this;
|
||||
prependListener(event: "readable", listener: () => void): this;
|
||||
prependListener(event: "error", listener: (err: Error) => void): this;
|
||||
prependListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependOnceListener(event: "header", listener: (header: object) => void): this;
|
||||
prependOnceListener(event: "close", listener: () => void): this;
|
||||
prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this;
|
||||
prependOnceListener(event: "end", listener: () => void): this;
|
||||
prependOnceListener(event: "readable", listener: () => void): this;
|
||||
prependOnceListener(event: "error", listener: (err: Error) => void): this;
|
||||
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
||||
removeListener(event: "header", listener: (header: object) => void): this;
|
||||
removeListener(event: "close", listener: () => void): this;
|
||||
removeListener(event: "data", listener: (chunk: Buffer | string) => void): this;
|
||||
removeListener(event: "end", listener: () => void): this;
|
||||
removeListener(event: "readable", listener: () => void): this;
|
||||
removeListener(event: "error", listener: (err: Error) => void): this;
|
||||
removeListener(event: string, listener: (...args: any[]) => void): this;
|
||||
}
|
||||
}
|
||||
-228
@@ -1,228 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Copyright Brian White. All rights reserved.
|
||||
*
|
||||
* @see https://github.com/mscdex/streamsearch
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* Based heavily on the Streaming Boyer-Moore-Horspool C++ implementation
|
||||
* by Hongli Lai at: https://github.com/FooBarWidget/boyer-moore-horspool
|
||||
*/
|
||||
const EventEmitter = require('node:events').EventEmitter
|
||||
const inherits = require('node:util').inherits
|
||||
|
||||
function SBMH (needle) {
|
||||
if (typeof needle === 'string') {
|
||||
needle = Buffer.from(needle)
|
||||
}
|
||||
|
||||
if (!Buffer.isBuffer(needle)) {
|
||||
throw new TypeError('The needle has to be a String or a Buffer.')
|
||||
}
|
||||
|
||||
const needleLength = needle.length
|
||||
|
||||
if (needleLength === 0) {
|
||||
throw new Error('The needle cannot be an empty String/Buffer.')
|
||||
}
|
||||
|
||||
if (needleLength > 256) {
|
||||
throw new Error('The needle cannot have a length bigger than 256.')
|
||||
}
|
||||
|
||||
this.maxMatches = Infinity
|
||||
this.matches = 0
|
||||
|
||||
this._occ = new Array(256)
|
||||
.fill(needleLength) // Initialize occurrence table.
|
||||
this._lookbehind_size = 0
|
||||
this._needle = needle
|
||||
this._bufpos = 0
|
||||
|
||||
this._lookbehind = Buffer.alloc(needleLength)
|
||||
|
||||
// Populate occurrence table with analysis of the needle,
|
||||
// ignoring last letter.
|
||||
for (var i = 0; i < needleLength - 1; ++i) { // eslint-disable-line no-var
|
||||
this._occ[needle[i]] = needleLength - 1 - i
|
||||
}
|
||||
}
|
||||
inherits(SBMH, EventEmitter)
|
||||
|
||||
SBMH.prototype.reset = function () {
|
||||
this._lookbehind_size = 0
|
||||
this.matches = 0
|
||||
this._bufpos = 0
|
||||
}
|
||||
|
||||
SBMH.prototype.push = function (chunk, pos) {
|
||||
if (!Buffer.isBuffer(chunk)) {
|
||||
chunk = Buffer.from(chunk, 'binary')
|
||||
}
|
||||
const chlen = chunk.length
|
||||
this._bufpos = pos || 0
|
||||
let r
|
||||
while (r !== chlen && this.matches < this.maxMatches) { r = this._sbmh_feed(chunk) }
|
||||
return r
|
||||
}
|
||||
|
||||
SBMH.prototype._sbmh_feed = function (data) {
|
||||
const len = data.length
|
||||
const needle = this._needle
|
||||
const needleLength = needle.length
|
||||
const lastNeedleChar = needle[needleLength - 1]
|
||||
|
||||
// Positive: points to a position in `data`
|
||||
// pos == 3 points to data[3]
|
||||
// Negative: points to a position in the lookbehind buffer
|
||||
// pos == -2 points to lookbehind[lookbehind_size - 2]
|
||||
let pos = -this._lookbehind_size
|
||||
let ch
|
||||
|
||||
if (pos < 0) {
|
||||
// Lookbehind buffer is not empty. Perform Boyer-Moore-Horspool
|
||||
// search with character lookup code that considers both the
|
||||
// lookbehind buffer and the current round's haystack data.
|
||||
//
|
||||
// Loop until
|
||||
// there is a match.
|
||||
// or until
|
||||
// we've moved past the position that requires the
|
||||
// lookbehind buffer. In this case we switch to the
|
||||
// optimized loop.
|
||||
// or until
|
||||
// the character to look at lies outside the haystack.
|
||||
while (pos < 0 && pos <= len - needleLength) {
|
||||
ch = this._sbmh_lookup_char(data, pos + needleLength - 1)
|
||||
|
||||
if (
|
||||
ch === lastNeedleChar &&
|
||||
this._sbmh_memcmp(data, pos, needleLength - 1)
|
||||
) {
|
||||
this._lookbehind_size = 0
|
||||
++this.matches
|
||||
this.emit('info', true)
|
||||
|
||||
return (this._bufpos = pos + needleLength)
|
||||
}
|
||||
pos += this._occ[ch]
|
||||
}
|
||||
|
||||
// No match.
|
||||
|
||||
if (pos < 0) {
|
||||
// There's too few data for Boyer-Moore-Horspool to run,
|
||||
// so let's use a different algorithm to skip as much as
|
||||
// we can.
|
||||
// Forward pos until
|
||||
// the trailing part of lookbehind + data
|
||||
// looks like the beginning of the needle
|
||||
// or until
|
||||
// pos == 0
|
||||
while (pos < 0 && !this._sbmh_memcmp(data, pos, len - pos)) { ++pos }
|
||||
}
|
||||
|
||||
if (pos >= 0) {
|
||||
// Discard lookbehind buffer.
|
||||
this.emit('info', false, this._lookbehind, 0, this._lookbehind_size)
|
||||
this._lookbehind_size = 0
|
||||
} else {
|
||||
// Cut off part of the lookbehind buffer that has
|
||||
// been processed and append the entire haystack
|
||||
// into it.
|
||||
const bytesToCutOff = this._lookbehind_size + pos
|
||||
if (bytesToCutOff > 0) {
|
||||
// The cut off data is guaranteed not to contain the needle.
|
||||
this.emit('info', false, this._lookbehind, 0, bytesToCutOff)
|
||||
}
|
||||
|
||||
this._lookbehind.copy(this._lookbehind, 0, bytesToCutOff,
|
||||
this._lookbehind_size - bytesToCutOff)
|
||||
this._lookbehind_size -= bytesToCutOff
|
||||
|
||||
data.copy(this._lookbehind, this._lookbehind_size)
|
||||
this._lookbehind_size += len
|
||||
|
||||
this._bufpos = len
|
||||
return len
|
||||
}
|
||||
}
|
||||
|
||||
pos += (pos >= 0) * this._bufpos
|
||||
|
||||
// Lookbehind buffer is now empty. We only need to check if the
|
||||
// needle is in the haystack.
|
||||
if (data.indexOf(needle, pos) !== -1) {
|
||||
pos = data.indexOf(needle, pos)
|
||||
++this.matches
|
||||
if (pos > 0) { this.emit('info', true, data, this._bufpos, pos) } else { this.emit('info', true) }
|
||||
|
||||
return (this._bufpos = pos + needleLength)
|
||||
} else {
|
||||
pos = len - needleLength
|
||||
}
|
||||
|
||||
// There was no match. If there's trailing haystack data that we cannot
|
||||
// match yet using the Boyer-Moore-Horspool algorithm (because the trailing
|
||||
// data is less than the needle size) then match using a modified
|
||||
// algorithm that starts matching from the beginning instead of the end.
|
||||
// Whatever trailing data is left after running this algorithm is added to
|
||||
// the lookbehind buffer.
|
||||
while (
|
||||
pos < len &&
|
||||
(
|
||||
data[pos] !== needle[0] ||
|
||||
(
|
||||
(Buffer.compare(
|
||||
data.subarray(pos, pos + len - pos),
|
||||
needle.subarray(0, len - pos)
|
||||
) !== 0)
|
||||
)
|
||||
)
|
||||
) {
|
||||
++pos
|
||||
}
|
||||
if (pos < len) {
|
||||
data.copy(this._lookbehind, 0, pos, pos + (len - pos))
|
||||
this._lookbehind_size = len - pos
|
||||
}
|
||||
|
||||
// Everything until pos is guaranteed not to contain needle data.
|
||||
if (pos > 0) { this.emit('info', false, data, this._bufpos, pos < len ? pos : len) }
|
||||
|
||||
this._bufpos = len
|
||||
return len
|
||||
}
|
||||
|
||||
SBMH.prototype._sbmh_lookup_char = function (data, pos) {
|
||||
return (pos < 0)
|
||||
? this._lookbehind[this._lookbehind_size + pos]
|
||||
: data[pos]
|
||||
}
|
||||
|
||||
SBMH.prototype._sbmh_memcmp = function (data, pos, len) {
|
||||
for (var i = 0; i < len; ++i) { // eslint-disable-line no-var
|
||||
if (this._sbmh_lookup_char(data, pos + i) !== this._needle[i]) { return false }
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
module.exports = SBMH
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
// Definitions by: Jacob Baskin <https://github.com/jacobbaskin>
|
||||
// BendingBender <https://github.com/BendingBender>
|
||||
// Igor Savin <https://github.com/kibertoad>
|
||||
|
||||
/// <reference types="node" />
|
||||
|
||||
import * as http from 'http';
|
||||
import { Readable, Writable } from 'stream';
|
||||
export { Dicer } from "../deps/dicer/lib/dicer";
|
||||
|
||||
export const Busboy: BusboyConstructor;
|
||||
export default Busboy;
|
||||
|
||||
export interface BusboyConfig {
|
||||
/**
|
||||
* These are the HTTP headers of the incoming request, which are used by individual parsers.
|
||||
*/
|
||||
headers: BusboyHeaders;
|
||||
/**
|
||||
* `highWaterMark` to use for this Busboy instance.
|
||||
* @default WritableStream default.
|
||||
*/
|
||||
highWaterMark?: number | undefined;
|
||||
/**
|
||||
* highWaterMark to use for file streams.
|
||||
* @default ReadableStream default.
|
||||
*/
|
||||
fileHwm?: number | undefined;
|
||||
/**
|
||||
* Default character set to use when one isn't defined.
|
||||
* @default 'utf8'
|
||||
*/
|
||||
defCharset?: string | undefined;
|
||||
/**
|
||||
* Detect if a Part is a file.
|
||||
*
|
||||
* By default a file is detected if contentType
|
||||
* is application/octet-stream or fileName is not
|
||||
* undefined.
|
||||
*
|
||||
* Modify this to handle e.g. Blobs.
|
||||
*/
|
||||
isPartAFile?: (fieldName: string | undefined, contentType: string | undefined, fileName: string | undefined) => boolean;
|
||||
/**
|
||||
* If paths in the multipart 'filename' field shall be preserved.
|
||||
* @default false
|
||||
*/
|
||||
preservePath?: boolean | undefined;
|
||||
/**
|
||||
* Various limits on incoming data.
|
||||
*/
|
||||
limits?:
|
||||
| {
|
||||
/**
|
||||
* Max field name size (in bytes)
|
||||
* @default 100 bytes
|
||||
*/
|
||||
fieldNameSize?: number | undefined;
|
||||
/**
|
||||
* Max field value size (in bytes)
|
||||
* @default 1MB
|
||||
*/
|
||||
fieldSize?: number | undefined;
|
||||
/**
|
||||
* Max number of non-file fields
|
||||
* @default Infinity
|
||||
*/
|
||||
fields?: number | undefined;
|
||||
/**
|
||||
* For multipart forms, the max file size (in bytes)
|
||||
* @default Infinity
|
||||
*/
|
||||
fileSize?: number | undefined;
|
||||
/**
|
||||
* For multipart forms, the max number of file fields
|
||||
* @default Infinity
|
||||
*/
|
||||
files?: number | undefined;
|
||||
/**
|
||||
* For multipart forms, the max number of parts (fields + files)
|
||||
* @default Infinity
|
||||
*/
|
||||
parts?: number | undefined;
|
||||
/**
|
||||
* For multipart forms, the max number of header key=>value pairs to parse
|
||||
* @default 2000
|
||||
*/
|
||||
headerPairs?: number | undefined;
|
||||
|
||||
/**
|
||||
* For multipart forms, the max size of a header part
|
||||
* @default 81920
|
||||
*/
|
||||
headerSize?: number | undefined;
|
||||
}
|
||||
| undefined;
|
||||
}
|
||||
|
||||
export type BusboyHeaders = { 'content-type': string } & http.IncomingHttpHeaders;
|
||||
|
||||
export interface BusboyFileStream extends
|
||||
Readable {
|
||||
|
||||
truncated: boolean;
|
||||
|
||||
/**
|
||||
* The number of bytes that have been read so far.
|
||||
*/
|
||||
bytesRead: number;
|
||||
}
|
||||
|
||||
export interface Busboy extends Writable {
|
||||
addListener<Event extends keyof BusboyEvents>(event: Event, listener: BusboyEvents[Event]): this;
|
||||
|
||||
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
on<Event extends keyof BusboyEvents>(event: Event, listener: BusboyEvents[Event]): this;
|
||||
|
||||
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
once<Event extends keyof BusboyEvents>(event: Event, listener: BusboyEvents[Event]): this;
|
||||
|
||||
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
removeListener<Event extends keyof BusboyEvents>(event: Event, listener: BusboyEvents[Event]): this;
|
||||
|
||||
removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
off<Event extends keyof BusboyEvents>(event: Event, listener: BusboyEvents[Event]): this;
|
||||
|
||||
off(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
prependListener<Event extends keyof BusboyEvents>(event: Event, listener: BusboyEvents[Event]): this;
|
||||
|
||||
prependListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
prependOnceListener<Event extends keyof BusboyEvents>(event: Event, listener: BusboyEvents[Event]): this;
|
||||
|
||||
prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
}
|
||||
|
||||
export interface BusboyEvents {
|
||||
/**
|
||||
* Emitted for each new file form field found.
|
||||
*
|
||||
* * Note: if you listen for this event, you should always handle the `stream` no matter if you care about the
|
||||
* file contents or not (e.g. you can simply just do `stream.resume();` if you want to discard the contents),
|
||||
* otherwise the 'finish' event will never fire on the Busboy instance. However, if you don't care about **any**
|
||||
* incoming files, you can simply not listen for the 'file' event at all and any/all files will be automatically
|
||||
* and safely discarded (these discarded files do still count towards `files` and `parts` limits).
|
||||
* * If a configured file size limit was reached, `stream` will both have a boolean property `truncated`
|
||||
* (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens.
|
||||
*
|
||||
* @param listener.transferEncoding Contains the 'Content-Transfer-Encoding' value for the file stream.
|
||||
* @param listener.mimeType Contains the 'Content-Type' value for the file stream.
|
||||
*/
|
||||
file: (
|
||||
fieldname: string,
|
||||
stream: BusboyFileStream,
|
||||
filename: string,
|
||||
transferEncoding: string,
|
||||
mimeType: string,
|
||||
) => void;
|
||||
/**
|
||||
* Emitted for each new non-file field found.
|
||||
*/
|
||||
field: (
|
||||
fieldname: string,
|
||||
value: string,
|
||||
fieldnameTruncated: boolean,
|
||||
valueTruncated: boolean,
|
||||
transferEncoding: string,
|
||||
mimeType: string,
|
||||
) => void;
|
||||
finish: () => void;
|
||||
/**
|
||||
* Emitted when specified `parts` limit has been reached. No more 'file' or 'field' events will be emitted.
|
||||
*/
|
||||
partsLimit: () => void;
|
||||
/**
|
||||
* Emitted when specified `files` limit has been reached. No more 'file' events will be emitted.
|
||||
*/
|
||||
filesLimit: () => void;
|
||||
/**
|
||||
* Emitted when specified `fields` limit has been reached. No more 'field' events will be emitted.
|
||||
*/
|
||||
fieldsLimit: () => void;
|
||||
error: (error: unknown) => void;
|
||||
}
|
||||
|
||||
export interface BusboyConstructor {
|
||||
(options: BusboyConfig): Busboy;
|
||||
|
||||
new(options: BusboyConfig): Busboy;
|
||||
}
|
||||
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const WritableStream = require('node:stream').Writable
|
||||
const { inherits } = require('node:util')
|
||||
const Dicer = require('../deps/dicer/lib/Dicer')
|
||||
|
||||
const MultipartParser = require('./types/multipart')
|
||||
const UrlencodedParser = require('./types/urlencoded')
|
||||
const parseParams = require('./utils/parseParams')
|
||||
|
||||
function Busboy (opts) {
|
||||
if (!(this instanceof Busboy)) { return new Busboy(opts) }
|
||||
|
||||
if (typeof opts !== 'object') {
|
||||
throw new TypeError('Busboy expected an options-Object.')
|
||||
}
|
||||
if (typeof opts.headers !== 'object') {
|
||||
throw new TypeError('Busboy expected an options-Object with headers-attribute.')
|
||||
}
|
||||
if (typeof opts.headers['content-type'] !== 'string') {
|
||||
throw new TypeError('Missing Content-Type-header.')
|
||||
}
|
||||
|
||||
const {
|
||||
headers,
|
||||
...streamOptions
|
||||
} = opts
|
||||
|
||||
this.opts = {
|
||||
autoDestroy: false,
|
||||
...streamOptions
|
||||
}
|
||||
WritableStream.call(this, this.opts)
|
||||
|
||||
this._done = false
|
||||
this._parser = this.getParserByHeaders(headers)
|
||||
this._finished = false
|
||||
}
|
||||
inherits(Busboy, WritableStream)
|
||||
|
||||
Busboy.prototype.emit = function (ev) {
|
||||
if (ev === 'finish') {
|
||||
if (!this._done) {
|
||||
this._parser?.end()
|
||||
return
|
||||
} else if (this._finished) {
|
||||
return
|
||||
}
|
||||
this._finished = true
|
||||
}
|
||||
WritableStream.prototype.emit.apply(this, arguments)
|
||||
}
|
||||
|
||||
Busboy.prototype.getParserByHeaders = function (headers) {
|
||||
const parsed = parseParams(headers['content-type'])
|
||||
|
||||
const cfg = {
|
||||
defCharset: this.opts.defCharset,
|
||||
fileHwm: this.opts.fileHwm,
|
||||
headers,
|
||||
highWaterMark: this.opts.highWaterMark,
|
||||
isPartAFile: this.opts.isPartAFile,
|
||||
limits: this.opts.limits,
|
||||
parsedConType: parsed,
|
||||
preservePath: this.opts.preservePath
|
||||
}
|
||||
|
||||
if (MultipartParser.detect.test(parsed[0])) {
|
||||
return new MultipartParser(this, cfg)
|
||||
}
|
||||
if (UrlencodedParser.detect.test(parsed[0])) {
|
||||
return new UrlencodedParser(this, cfg)
|
||||
}
|
||||
throw new Error('Unsupported Content-Type.')
|
||||
}
|
||||
|
||||
Busboy.prototype._write = function (chunk, encoding, cb) {
|
||||
this._parser.write(chunk, cb)
|
||||
}
|
||||
|
||||
module.exports = Busboy
|
||||
module.exports.default = Busboy
|
||||
module.exports.Busboy = Busboy
|
||||
|
||||
module.exports.Dicer = Dicer
|
||||
-306
@@ -1,306 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
// TODO:
|
||||
// * support 1 nested multipart level
|
||||
// (see second multipart example here:
|
||||
// http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data)
|
||||
// * support limits.fieldNameSize
|
||||
// -- this will require modifications to utils.parseParams
|
||||
|
||||
const { Readable } = require('node:stream')
|
||||
const { inherits } = require('node:util')
|
||||
|
||||
const Dicer = require('../../deps/dicer/lib/Dicer')
|
||||
|
||||
const parseParams = require('../utils/parseParams')
|
||||
const decodeText = require('../utils/decodeText')
|
||||
const basename = require('../utils/basename')
|
||||
const getLimit = require('../utils/getLimit')
|
||||
|
||||
const RE_BOUNDARY = /^boundary$/i
|
||||
const RE_FIELD = /^form-data$/i
|
||||
const RE_CHARSET = /^charset$/i
|
||||
const RE_FILENAME = /^filename$/i
|
||||
const RE_NAME = /^name$/i
|
||||
|
||||
Multipart.detect = /^multipart\/form-data/i
|
||||
function Multipart (boy, cfg) {
|
||||
let i
|
||||
let len
|
||||
const self = this
|
||||
let boundary
|
||||
const limits = cfg.limits
|
||||
const isPartAFile = cfg.isPartAFile || ((fieldName, contentType, fileName) => (contentType === 'application/octet-stream' || fileName !== undefined))
|
||||
const parsedConType = cfg.parsedConType || []
|
||||
const defCharset = cfg.defCharset || 'utf8'
|
||||
const preservePath = cfg.preservePath
|
||||
const fileOpts = { highWaterMark: cfg.fileHwm }
|
||||
|
||||
for (i = 0, len = parsedConType.length; i < len; ++i) {
|
||||
if (Array.isArray(parsedConType[i]) &&
|
||||
RE_BOUNDARY.test(parsedConType[i][0])) {
|
||||
boundary = parsedConType[i][1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function checkFinished () {
|
||||
if (nends === 0 && finished && !boy._done) {
|
||||
finished = false
|
||||
self.end()
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof boundary !== 'string') { throw new Error('Multipart: Boundary not found') }
|
||||
|
||||
const fieldSizeLimit = getLimit(limits, 'fieldSize', 1 * 1024 * 1024)
|
||||
const fileSizeLimit = getLimit(limits, 'fileSize', Infinity)
|
||||
const filesLimit = getLimit(limits, 'files', Infinity)
|
||||
const fieldsLimit = getLimit(limits, 'fields', Infinity)
|
||||
const partsLimit = getLimit(limits, 'parts', Infinity)
|
||||
const headerPairsLimit = getLimit(limits, 'headerPairs', 2000)
|
||||
const headerSizeLimit = getLimit(limits, 'headerSize', 80 * 1024)
|
||||
|
||||
let nfiles = 0
|
||||
let nfields = 0
|
||||
let nends = 0
|
||||
let curFile
|
||||
let curField
|
||||
let finished = false
|
||||
|
||||
this._needDrain = false
|
||||
this._pause = false
|
||||
this._cb = undefined
|
||||
this._nparts = 0
|
||||
this._boy = boy
|
||||
|
||||
const parserCfg = {
|
||||
boundary,
|
||||
maxHeaderPairs: headerPairsLimit,
|
||||
maxHeaderSize: headerSizeLimit,
|
||||
partHwm: fileOpts.highWaterMark,
|
||||
highWaterMark: cfg.highWaterMark
|
||||
}
|
||||
|
||||
this.parser = new Dicer(parserCfg)
|
||||
this.parser.on('drain', function () {
|
||||
self._needDrain = false
|
||||
if (self._cb && !self._pause) {
|
||||
const cb = self._cb
|
||||
self._cb = undefined
|
||||
cb()
|
||||
}
|
||||
}).on('part', function onPart (part) {
|
||||
if (++self._nparts > partsLimit) {
|
||||
self.parser.removeListener('part', onPart)
|
||||
self.parser.on('part', skipPart)
|
||||
boy.hitPartsLimit = true
|
||||
boy.emit('partsLimit')
|
||||
return skipPart(part)
|
||||
}
|
||||
|
||||
// hack because streams2 _always_ doesn't emit 'end' until nextTick, so let
|
||||
// us emit 'end' early since we know the part has ended if we are already
|
||||
// seeing the next part
|
||||
if (curField) {
|
||||
const field = curField
|
||||
field.emit('end')
|
||||
field.removeAllListeners('end')
|
||||
}
|
||||
|
||||
part.on('header', function (header) {
|
||||
let contype
|
||||
let fieldname
|
||||
let parsed
|
||||
let charset
|
||||
let encoding
|
||||
let filename
|
||||
let nsize = 0
|
||||
|
||||
if (header['content-type']) {
|
||||
parsed = parseParams(header['content-type'][0])
|
||||
if (parsed[0]) {
|
||||
contype = parsed[0].toLowerCase()
|
||||
for (i = 0, len = parsed.length; i < len; ++i) {
|
||||
if (RE_CHARSET.test(parsed[i][0])) {
|
||||
charset = parsed[i][1].toLowerCase()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contype === undefined) { contype = 'text/plain' }
|
||||
if (charset === undefined) { charset = defCharset }
|
||||
|
||||
if (header['content-disposition']) {
|
||||
parsed = parseParams(header['content-disposition'][0])
|
||||
if (!RE_FIELD.test(parsed[0])) { return skipPart(part) }
|
||||
for (i = 0, len = parsed.length; i < len; ++i) {
|
||||
if (RE_NAME.test(parsed[i][0])) {
|
||||
fieldname = parsed[i][1]
|
||||
} else if (RE_FILENAME.test(parsed[i][0])) {
|
||||
filename = parsed[i][1]
|
||||
if (!preservePath) { filename = basename(filename) }
|
||||
}
|
||||
}
|
||||
} else { return skipPart(part) }
|
||||
|
||||
if (header['content-transfer-encoding']) { encoding = header['content-transfer-encoding'][0].toLowerCase() } else { encoding = '7bit' }
|
||||
|
||||
let onData,
|
||||
onEnd
|
||||
|
||||
if (isPartAFile(fieldname, contype, filename)) {
|
||||
// file/binary field
|
||||
if (nfiles === filesLimit) {
|
||||
if (!boy.hitFilesLimit) {
|
||||
boy.hitFilesLimit = true
|
||||
boy.emit('filesLimit')
|
||||
}
|
||||
return skipPart(part)
|
||||
}
|
||||
|
||||
++nfiles
|
||||
|
||||
if (boy.listenerCount('file') === 0) {
|
||||
self.parser._ignore()
|
||||
return
|
||||
}
|
||||
|
||||
++nends
|
||||
const file = new FileStream(fileOpts)
|
||||
curFile = file
|
||||
file.on('end', function () {
|
||||
--nends
|
||||
self._pause = false
|
||||
checkFinished()
|
||||
if (self._cb && !self._needDrain) {
|
||||
const cb = self._cb
|
||||
self._cb = undefined
|
||||
cb()
|
||||
}
|
||||
})
|
||||
file._read = function (n) {
|
||||
if (!self._pause) { return }
|
||||
self._pause = false
|
||||
if (self._cb && !self._needDrain) {
|
||||
const cb = self._cb
|
||||
self._cb = undefined
|
||||
cb()
|
||||
}
|
||||
}
|
||||
boy.emit('file', fieldname, file, filename, encoding, contype)
|
||||
|
||||
onData = function (data) {
|
||||
if ((nsize += data.length) > fileSizeLimit) {
|
||||
const extralen = fileSizeLimit - nsize + data.length
|
||||
if (extralen > 0) { file.push(data.slice(0, extralen)) }
|
||||
file.truncated = true
|
||||
file.bytesRead = fileSizeLimit
|
||||
part.removeAllListeners('data')
|
||||
file.emit('limit')
|
||||
return
|
||||
} else if (!file.push(data)) { self._pause = true }
|
||||
|
||||
file.bytesRead = nsize
|
||||
}
|
||||
|
||||
onEnd = function () {
|
||||
curFile = undefined
|
||||
file.push(null)
|
||||
}
|
||||
} else {
|
||||
// non-file field
|
||||
if (nfields === fieldsLimit) {
|
||||
if (!boy.hitFieldsLimit) {
|
||||
boy.hitFieldsLimit = true
|
||||
boy.emit('fieldsLimit')
|
||||
}
|
||||
return skipPart(part)
|
||||
}
|
||||
|
||||
++nfields
|
||||
++nends
|
||||
let buffer = ''
|
||||
let truncated = false
|
||||
curField = part
|
||||
|
||||
onData = function (data) {
|
||||
if ((nsize += data.length) > fieldSizeLimit) {
|
||||
const extralen = (fieldSizeLimit - (nsize - data.length))
|
||||
buffer += data.toString('binary', 0, extralen)
|
||||
truncated = true
|
||||
part.removeAllListeners('data')
|
||||
} else { buffer += data.toString('binary') }
|
||||
}
|
||||
|
||||
onEnd = function () {
|
||||
curField = undefined
|
||||
if (buffer.length) { buffer = decodeText(buffer, 'binary', charset) }
|
||||
boy.emit('field', fieldname, buffer, false, truncated, encoding, contype)
|
||||
--nends
|
||||
checkFinished()
|
||||
}
|
||||
}
|
||||
|
||||
/* As of node@2efe4ab761666 (v0.10.29+/v0.11.14+), busboy had become
|
||||
broken. Streams2/streams3 is a huge black box of confusion, but
|
||||
somehow overriding the sync state seems to fix things again (and still
|
||||
seems to work for previous node versions).
|
||||
*/
|
||||
part._readableState.sync = false
|
||||
|
||||
part.on('data', onData)
|
||||
part.on('end', onEnd)
|
||||
}).on('error', function (err) {
|
||||
if (curFile) { curFile.emit('error', err) }
|
||||
})
|
||||
}).on('error', function (err) {
|
||||
boy.emit('error', err)
|
||||
}).on('finish', function () {
|
||||
finished = true
|
||||
checkFinished()
|
||||
})
|
||||
}
|
||||
|
||||
Multipart.prototype.write = function (chunk, cb) {
|
||||
const r = this.parser.write(chunk)
|
||||
if (r && !this._pause) {
|
||||
cb()
|
||||
} else {
|
||||
this._needDrain = !r
|
||||
this._cb = cb
|
||||
}
|
||||
}
|
||||
|
||||
Multipart.prototype.end = function () {
|
||||
const self = this
|
||||
|
||||
if (self.parser.writable) {
|
||||
self.parser.end()
|
||||
} else if (!self._boy._done) {
|
||||
process.nextTick(function () {
|
||||
self._boy._done = true
|
||||
self._boy.emit('finish')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function skipPart (part) {
|
||||
part.resume()
|
||||
}
|
||||
|
||||
function FileStream (opts) {
|
||||
Readable.call(this, opts)
|
||||
|
||||
this.bytesRead = 0
|
||||
|
||||
this.truncated = false
|
||||
}
|
||||
|
||||
inherits(FileStream, Readable)
|
||||
|
||||
FileStream.prototype._read = function (n) {}
|
||||
|
||||
module.exports = Multipart
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const Decoder = require('../utils/Decoder')
|
||||
const decodeText = require('../utils/decodeText')
|
||||
const getLimit = require('../utils/getLimit')
|
||||
|
||||
const RE_CHARSET = /^charset$/i
|
||||
|
||||
UrlEncoded.detect = /^application\/x-www-form-urlencoded/i
|
||||
function UrlEncoded (boy, cfg) {
|
||||
const limits = cfg.limits
|
||||
const parsedConType = cfg.parsedConType
|
||||
this.boy = boy
|
||||
|
||||
this.fieldSizeLimit = getLimit(limits, 'fieldSize', 1 * 1024 * 1024)
|
||||
this.fieldNameSizeLimit = getLimit(limits, 'fieldNameSize', 100)
|
||||
this.fieldsLimit = getLimit(limits, 'fields', Infinity)
|
||||
|
||||
let charset
|
||||
for (var i = 0, len = parsedConType.length; i < len; ++i) { // eslint-disable-line no-var
|
||||
if (Array.isArray(parsedConType[i]) &&
|
||||
RE_CHARSET.test(parsedConType[i][0])) {
|
||||
charset = parsedConType[i][1].toLowerCase()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (charset === undefined) { charset = cfg.defCharset || 'utf8' }
|
||||
|
||||
this.decoder = new Decoder()
|
||||
this.charset = charset
|
||||
this._fields = 0
|
||||
this._state = 'key'
|
||||
this._checkingBytes = true
|
||||
this._bytesKey = 0
|
||||
this._bytesVal = 0
|
||||
this._key = ''
|
||||
this._val = ''
|
||||
this._keyTrunc = false
|
||||
this._valTrunc = false
|
||||
this._hitLimit = false
|
||||
}
|
||||
|
||||
UrlEncoded.prototype.write = function (data, cb) {
|
||||
if (this._fields === this.fieldsLimit) {
|
||||
if (!this.boy.hitFieldsLimit) {
|
||||
this.boy.hitFieldsLimit = true
|
||||
this.boy.emit('fieldsLimit')
|
||||
}
|
||||
return cb()
|
||||
}
|
||||
|
||||
let idxeq; let idxamp; let i; let p = 0; const len = data.length
|
||||
|
||||
while (p < len) {
|
||||
if (this._state === 'key') {
|
||||
idxeq = idxamp = undefined
|
||||
for (i = p; i < len; ++i) {
|
||||
if (!this._checkingBytes) { ++p }
|
||||
if (data[i] === 0x3D/* = */) {
|
||||
idxeq = i
|
||||
break
|
||||
} else if (data[i] === 0x26/* & */) {
|
||||
idxamp = i
|
||||
break
|
||||
}
|
||||
if (this._checkingBytes && this._bytesKey === this.fieldNameSizeLimit) {
|
||||
this._hitLimit = true
|
||||
break
|
||||
} else if (this._checkingBytes) { ++this._bytesKey }
|
||||
}
|
||||
|
||||
if (idxeq !== undefined) {
|
||||
// key with assignment
|
||||
if (idxeq > p) { this._key += this.decoder.write(data.toString('binary', p, idxeq)) }
|
||||
this._state = 'val'
|
||||
|
||||
this._hitLimit = false
|
||||
this._checkingBytes = true
|
||||
this._val = ''
|
||||
this._bytesVal = 0
|
||||
this._valTrunc = false
|
||||
this.decoder.reset()
|
||||
|
||||
p = idxeq + 1
|
||||
} else if (idxamp !== undefined) {
|
||||
// key with no assignment
|
||||
++this._fields
|
||||
let key; const keyTrunc = this._keyTrunc
|
||||
if (idxamp > p) { key = (this._key += this.decoder.write(data.toString('binary', p, idxamp))) } else { key = this._key }
|
||||
|
||||
this._hitLimit = false
|
||||
this._checkingBytes = true
|
||||
this._key = ''
|
||||
this._bytesKey = 0
|
||||
this._keyTrunc = false
|
||||
this.decoder.reset()
|
||||
|
||||
if (key.length) {
|
||||
this.boy.emit('field', decodeText(key, 'binary', this.charset),
|
||||
'',
|
||||
keyTrunc,
|
||||
false)
|
||||
}
|
||||
|
||||
p = idxamp + 1
|
||||
if (this._fields === this.fieldsLimit) { return cb() }
|
||||
} else if (this._hitLimit) {
|
||||
// we may not have hit the actual limit if there are encoded bytes...
|
||||
if (i > p) { this._key += this.decoder.write(data.toString('binary', p, i)) }
|
||||
p = i
|
||||
if ((this._bytesKey = this._key.length) === this.fieldNameSizeLimit) {
|
||||
// yep, we actually did hit the limit
|
||||
this._checkingBytes = false
|
||||
this._keyTrunc = true
|
||||
}
|
||||
} else {
|
||||
if (p < len) { this._key += this.decoder.write(data.toString('binary', p)) }
|
||||
p = len
|
||||
}
|
||||
} else {
|
||||
idxamp = undefined
|
||||
for (i = p; i < len; ++i) {
|
||||
if (!this._checkingBytes) { ++p }
|
||||
if (data[i] === 0x26/* & */) {
|
||||
idxamp = i
|
||||
break
|
||||
}
|
||||
if (this._checkingBytes && this._bytesVal === this.fieldSizeLimit) {
|
||||
this._hitLimit = true
|
||||
break
|
||||
} else if (this._checkingBytes) { ++this._bytesVal }
|
||||
}
|
||||
|
||||
if (idxamp !== undefined) {
|
||||
++this._fields
|
||||
if (idxamp > p) { this._val += this.decoder.write(data.toString('binary', p, idxamp)) }
|
||||
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||
decodeText(this._val, 'binary', this.charset),
|
||||
this._keyTrunc,
|
||||
this._valTrunc)
|
||||
this._state = 'key'
|
||||
|
||||
this._hitLimit = false
|
||||
this._checkingBytes = true
|
||||
this._key = ''
|
||||
this._bytesKey = 0
|
||||
this._keyTrunc = false
|
||||
this.decoder.reset()
|
||||
|
||||
p = idxamp + 1
|
||||
if (this._fields === this.fieldsLimit) { return cb() }
|
||||
} else if (this._hitLimit) {
|
||||
// we may not have hit the actual limit if there are encoded bytes...
|
||||
if (i > p) { this._val += this.decoder.write(data.toString('binary', p, i)) }
|
||||
p = i
|
||||
if ((this._val === '' && this.fieldSizeLimit === 0) ||
|
||||
(this._bytesVal = this._val.length) === this.fieldSizeLimit) {
|
||||
// yep, we actually did hit the limit
|
||||
this._checkingBytes = false
|
||||
this._valTrunc = true
|
||||
}
|
||||
} else {
|
||||
if (p < len) { this._val += this.decoder.write(data.toString('binary', p)) }
|
||||
p = len
|
||||
}
|
||||
}
|
||||
}
|
||||
cb()
|
||||
}
|
||||
|
||||
UrlEncoded.prototype.end = function () {
|
||||
if (this.boy._done) { return }
|
||||
|
||||
if (this._state === 'key' && this._key.length > 0) {
|
||||
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||
'',
|
||||
this._keyTrunc,
|
||||
false)
|
||||
} else if (this._state === 'val') {
|
||||
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||
decodeText(this._val, 'binary', this.charset),
|
||||
this._keyTrunc,
|
||||
this._valTrunc)
|
||||
}
|
||||
this.boy._done = true
|
||||
this.boy.emit('finish')
|
||||
}
|
||||
|
||||
module.exports = UrlEncoded
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const RE_PLUS = /\+/g
|
||||
|
||||
const HEX = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
|
||||
function Decoder () {
|
||||
this.buffer = undefined
|
||||
}
|
||||
Decoder.prototype.write = function (str) {
|
||||
// Replace '+' with ' ' before decoding
|
||||
str = str.replace(RE_PLUS, ' ')
|
||||
let res = ''
|
||||
let i = 0; let p = 0; const len = str.length
|
||||
for (; i < len; ++i) {
|
||||
if (this.buffer !== undefined) {
|
||||
if (!HEX[str.charCodeAt(i)]) {
|
||||
res += '%' + this.buffer
|
||||
this.buffer = undefined
|
||||
--i // retry character
|
||||
} else {
|
||||
this.buffer += str[i]
|
||||
++p
|
||||
if (this.buffer.length === 2) {
|
||||
res += String.fromCharCode(parseInt(this.buffer, 16))
|
||||
this.buffer = undefined
|
||||
}
|
||||
}
|
||||
} else if (str[i] === '%') {
|
||||
if (i > p) {
|
||||
res += str.substring(p, i)
|
||||
p = i
|
||||
}
|
||||
this.buffer = ''
|
||||
++p
|
||||
}
|
||||
}
|
||||
if (p < len && this.buffer === undefined) { res += str.substring(p) }
|
||||
return res
|
||||
}
|
||||
Decoder.prototype.reset = function () {
|
||||
this.buffer = undefined
|
||||
}
|
||||
|
||||
module.exports = Decoder
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = function basename (path) {
|
||||
if (typeof path !== 'string') { return '' }
|
||||
for (var i = path.length - 1; i >= 0; --i) { // eslint-disable-line no-var
|
||||
switch (path.charCodeAt(i)) {
|
||||
case 0x2F: // '/'
|
||||
case 0x5C: // '\'
|
||||
path = path.slice(i + 1)
|
||||
return (path === '..' || path === '.' ? '' : path)
|
||||
}
|
||||
}
|
||||
return (path === '..' || path === '.' ? '' : path)
|
||||
}
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
// Node has always utf-8
|
||||
const utf8Decoder = new TextDecoder('utf-8')
|
||||
const textDecoders = new Map([
|
||||
['utf-8', utf8Decoder],
|
||||
['utf8', utf8Decoder]
|
||||
])
|
||||
|
||||
function getDecoder (charset) {
|
||||
let lc
|
||||
while (true) {
|
||||
switch (charset) {
|
||||
case 'utf-8':
|
||||
case 'utf8':
|
||||
return decoders.utf8
|
||||
case 'latin1':
|
||||
case 'ascii': // TODO: Make these a separate, strict decoder?
|
||||
case 'us-ascii':
|
||||
case 'iso-8859-1':
|
||||
case 'iso8859-1':
|
||||
case 'iso88591':
|
||||
case 'iso_8859-1':
|
||||
case 'windows-1252':
|
||||
case 'iso_8859-1:1987':
|
||||
case 'cp1252':
|
||||
case 'x-cp1252':
|
||||
return decoders.latin1
|
||||
case 'utf16le':
|
||||
case 'utf-16le':
|
||||
case 'ucs2':
|
||||
case 'ucs-2':
|
||||
return decoders.utf16le
|
||||
case 'base64':
|
||||
return decoders.base64
|
||||
default:
|
||||
if (lc === undefined) {
|
||||
lc = true
|
||||
charset = charset.toLowerCase()
|
||||
continue
|
||||
}
|
||||
return decoders.other.bind(charset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const decoders = {
|
||||
utf8: (data, sourceEncoding) => {
|
||||
if (data.length === 0) {
|
||||
return ''
|
||||
}
|
||||
if (typeof data === 'string') {
|
||||
data = Buffer.from(data, sourceEncoding)
|
||||
}
|
||||
return data.utf8Slice(0, data.length)
|
||||
},
|
||||
|
||||
latin1: (data, sourceEncoding) => {
|
||||
if (data.length === 0) {
|
||||
return ''
|
||||
}
|
||||
if (typeof data === 'string') {
|
||||
return data
|
||||
}
|
||||
return data.latin1Slice(0, data.length)
|
||||
},
|
||||
|
||||
utf16le: (data, sourceEncoding) => {
|
||||
if (data.length === 0) {
|
||||
return ''
|
||||
}
|
||||
if (typeof data === 'string') {
|
||||
data = Buffer.from(data, sourceEncoding)
|
||||
}
|
||||
return data.ucs2Slice(0, data.length)
|
||||
},
|
||||
|
||||
base64: (data, sourceEncoding) => {
|
||||
if (data.length === 0) {
|
||||
return ''
|
||||
}
|
||||
if (typeof data === 'string') {
|
||||
data = Buffer.from(data, sourceEncoding)
|
||||
}
|
||||
return data.base64Slice(0, data.length)
|
||||
},
|
||||
|
||||
other: (data, sourceEncoding) => {
|
||||
if (data.length === 0) {
|
||||
return ''
|
||||
}
|
||||
if (typeof data === 'string') {
|
||||
data = Buffer.from(data, sourceEncoding)
|
||||
}
|
||||
|
||||
if (textDecoders.has(this.toString())) {
|
||||
try {
|
||||
return textDecoders.get(this).decode(data)
|
||||
} catch {}
|
||||
}
|
||||
return typeof data === 'string'
|
||||
? data
|
||||
: data.toString()
|
||||
}
|
||||
}
|
||||
|
||||
function decodeText (text, sourceEncoding, destEncoding) {
|
||||
if (text) {
|
||||
return getDecoder(destEncoding)(text, sourceEncoding)
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
module.exports = decodeText
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = function getLimit (limits, name, defaultLimit) {
|
||||
if (
|
||||
!limits ||
|
||||
limits[name] === undefined ||
|
||||
limits[name] === null
|
||||
) { return defaultLimit }
|
||||
|
||||
if (
|
||||
typeof limits[name] !== 'number' ||
|
||||
isNaN(limits[name])
|
||||
) { throw new TypeError('Limit ' + name + ' is not a valid number') }
|
||||
|
||||
return limits[name]
|
||||
}
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
/* eslint-disable object-property-newline */
|
||||
'use strict'
|
||||
|
||||
const decodeText = require('./decodeText')
|
||||
|
||||
const RE_ENCODED = /%[a-fA-F0-9][a-fA-F0-9]/g
|
||||
|
||||
const EncodedLookup = {
|
||||
'%00': '\x00', '%01': '\x01', '%02': '\x02', '%03': '\x03', '%04': '\x04',
|
||||
'%05': '\x05', '%06': '\x06', '%07': '\x07', '%08': '\x08', '%09': '\x09',
|
||||
'%0a': '\x0a', '%0A': '\x0a', '%0b': '\x0b', '%0B': '\x0b', '%0c': '\x0c',
|
||||
'%0C': '\x0c', '%0d': '\x0d', '%0D': '\x0d', '%0e': '\x0e', '%0E': '\x0e',
|
||||
'%0f': '\x0f', '%0F': '\x0f', '%10': '\x10', '%11': '\x11', '%12': '\x12',
|
||||
'%13': '\x13', '%14': '\x14', '%15': '\x15', '%16': '\x16', '%17': '\x17',
|
||||
'%18': '\x18', '%19': '\x19', '%1a': '\x1a', '%1A': '\x1a', '%1b': '\x1b',
|
||||
'%1B': '\x1b', '%1c': '\x1c', '%1C': '\x1c', '%1d': '\x1d', '%1D': '\x1d',
|
||||
'%1e': '\x1e', '%1E': '\x1e', '%1f': '\x1f', '%1F': '\x1f', '%20': '\x20',
|
||||
'%21': '\x21', '%22': '\x22', '%23': '\x23', '%24': '\x24', '%25': '\x25',
|
||||
'%26': '\x26', '%27': '\x27', '%28': '\x28', '%29': '\x29', '%2a': '\x2a',
|
||||
'%2A': '\x2a', '%2b': '\x2b', '%2B': '\x2b', '%2c': '\x2c', '%2C': '\x2c',
|
||||
'%2d': '\x2d', '%2D': '\x2d', '%2e': '\x2e', '%2E': '\x2e', '%2f': '\x2f',
|
||||
'%2F': '\x2f', '%30': '\x30', '%31': '\x31', '%32': '\x32', '%33': '\x33',
|
||||
'%34': '\x34', '%35': '\x35', '%36': '\x36', '%37': '\x37', '%38': '\x38',
|
||||
'%39': '\x39', '%3a': '\x3a', '%3A': '\x3a', '%3b': '\x3b', '%3B': '\x3b',
|
||||
'%3c': '\x3c', '%3C': '\x3c', '%3d': '\x3d', '%3D': '\x3d', '%3e': '\x3e',
|
||||
'%3E': '\x3e', '%3f': '\x3f', '%3F': '\x3f', '%40': '\x40', '%41': '\x41',
|
||||
'%42': '\x42', '%43': '\x43', '%44': '\x44', '%45': '\x45', '%46': '\x46',
|
||||
'%47': '\x47', '%48': '\x48', '%49': '\x49', '%4a': '\x4a', '%4A': '\x4a',
|
||||
'%4b': '\x4b', '%4B': '\x4b', '%4c': '\x4c', '%4C': '\x4c', '%4d': '\x4d',
|
||||
'%4D': '\x4d', '%4e': '\x4e', '%4E': '\x4e', '%4f': '\x4f', '%4F': '\x4f',
|
||||
'%50': '\x50', '%51': '\x51', '%52': '\x52', '%53': '\x53', '%54': '\x54',
|
||||
'%55': '\x55', '%56': '\x56', '%57': '\x57', '%58': '\x58', '%59': '\x59',
|
||||
'%5a': '\x5a', '%5A': '\x5a', '%5b': '\x5b', '%5B': '\x5b', '%5c': '\x5c',
|
||||
'%5C': '\x5c', '%5d': '\x5d', '%5D': '\x5d', '%5e': '\x5e', '%5E': '\x5e',
|
||||
'%5f': '\x5f', '%5F': '\x5f', '%60': '\x60', '%61': '\x61', '%62': '\x62',
|
||||
'%63': '\x63', '%64': '\x64', '%65': '\x65', '%66': '\x66', '%67': '\x67',
|
||||
'%68': '\x68', '%69': '\x69', '%6a': '\x6a', '%6A': '\x6a', '%6b': '\x6b',
|
||||
'%6B': '\x6b', '%6c': '\x6c', '%6C': '\x6c', '%6d': '\x6d', '%6D': '\x6d',
|
||||
'%6e': '\x6e', '%6E': '\x6e', '%6f': '\x6f', '%6F': '\x6f', '%70': '\x70',
|
||||
'%71': '\x71', '%72': '\x72', '%73': '\x73', '%74': '\x74', '%75': '\x75',
|
||||
'%76': '\x76', '%77': '\x77', '%78': '\x78', '%79': '\x79', '%7a': '\x7a',
|
||||
'%7A': '\x7a', '%7b': '\x7b', '%7B': '\x7b', '%7c': '\x7c', '%7C': '\x7c',
|
||||
'%7d': '\x7d', '%7D': '\x7d', '%7e': '\x7e', '%7E': '\x7e', '%7f': '\x7f',
|
||||
'%7F': '\x7f', '%80': '\x80', '%81': '\x81', '%82': '\x82', '%83': '\x83',
|
||||
'%84': '\x84', '%85': '\x85', '%86': '\x86', '%87': '\x87', '%88': '\x88',
|
||||
'%89': '\x89', '%8a': '\x8a', '%8A': '\x8a', '%8b': '\x8b', '%8B': '\x8b',
|
||||
'%8c': '\x8c', '%8C': '\x8c', '%8d': '\x8d', '%8D': '\x8d', '%8e': '\x8e',
|
||||
'%8E': '\x8e', '%8f': '\x8f', '%8F': '\x8f', '%90': '\x90', '%91': '\x91',
|
||||
'%92': '\x92', '%93': '\x93', '%94': '\x94', '%95': '\x95', '%96': '\x96',
|
||||
'%97': '\x97', '%98': '\x98', '%99': '\x99', '%9a': '\x9a', '%9A': '\x9a',
|
||||
'%9b': '\x9b', '%9B': '\x9b', '%9c': '\x9c', '%9C': '\x9c', '%9d': '\x9d',
|
||||
'%9D': '\x9d', '%9e': '\x9e', '%9E': '\x9e', '%9f': '\x9f', '%9F': '\x9f',
|
||||
'%a0': '\xa0', '%A0': '\xa0', '%a1': '\xa1', '%A1': '\xa1', '%a2': '\xa2',
|
||||
'%A2': '\xa2', '%a3': '\xa3', '%A3': '\xa3', '%a4': '\xa4', '%A4': '\xa4',
|
||||
'%a5': '\xa5', '%A5': '\xa5', '%a6': '\xa6', '%A6': '\xa6', '%a7': '\xa7',
|
||||
'%A7': '\xa7', '%a8': '\xa8', '%A8': '\xa8', '%a9': '\xa9', '%A9': '\xa9',
|
||||
'%aa': '\xaa', '%Aa': '\xaa', '%aA': '\xaa', '%AA': '\xaa', '%ab': '\xab',
|
||||
'%Ab': '\xab', '%aB': '\xab', '%AB': '\xab', '%ac': '\xac', '%Ac': '\xac',
|
||||
'%aC': '\xac', '%AC': '\xac', '%ad': '\xad', '%Ad': '\xad', '%aD': '\xad',
|
||||
'%AD': '\xad', '%ae': '\xae', '%Ae': '\xae', '%aE': '\xae', '%AE': '\xae',
|
||||
'%af': '\xaf', '%Af': '\xaf', '%aF': '\xaf', '%AF': '\xaf', '%b0': '\xb0',
|
||||
'%B0': '\xb0', '%b1': '\xb1', '%B1': '\xb1', '%b2': '\xb2', '%B2': '\xb2',
|
||||
'%b3': '\xb3', '%B3': '\xb3', '%b4': '\xb4', '%B4': '\xb4', '%b5': '\xb5',
|
||||
'%B5': '\xb5', '%b6': '\xb6', '%B6': '\xb6', '%b7': '\xb7', '%B7': '\xb7',
|
||||
'%b8': '\xb8', '%B8': '\xb8', '%b9': '\xb9', '%B9': '\xb9', '%ba': '\xba',
|
||||
'%Ba': '\xba', '%bA': '\xba', '%BA': '\xba', '%bb': '\xbb', '%Bb': '\xbb',
|
||||
'%bB': '\xbb', '%BB': '\xbb', '%bc': '\xbc', '%Bc': '\xbc', '%bC': '\xbc',
|
||||
'%BC': '\xbc', '%bd': '\xbd', '%Bd': '\xbd', '%bD': '\xbd', '%BD': '\xbd',
|
||||
'%be': '\xbe', '%Be': '\xbe', '%bE': '\xbe', '%BE': '\xbe', '%bf': '\xbf',
|
||||
'%Bf': '\xbf', '%bF': '\xbf', '%BF': '\xbf', '%c0': '\xc0', '%C0': '\xc0',
|
||||
'%c1': '\xc1', '%C1': '\xc1', '%c2': '\xc2', '%C2': '\xc2', '%c3': '\xc3',
|
||||
'%C3': '\xc3', '%c4': '\xc4', '%C4': '\xc4', '%c5': '\xc5', '%C5': '\xc5',
|
||||
'%c6': '\xc6', '%C6': '\xc6', '%c7': '\xc7', '%C7': '\xc7', '%c8': '\xc8',
|
||||
'%C8': '\xc8', '%c9': '\xc9', '%C9': '\xc9', '%ca': '\xca', '%Ca': '\xca',
|
||||
'%cA': '\xca', '%CA': '\xca', '%cb': '\xcb', '%Cb': '\xcb', '%cB': '\xcb',
|
||||
'%CB': '\xcb', '%cc': '\xcc', '%Cc': '\xcc', '%cC': '\xcc', '%CC': '\xcc',
|
||||
'%cd': '\xcd', '%Cd': '\xcd', '%cD': '\xcd', '%CD': '\xcd', '%ce': '\xce',
|
||||
'%Ce': '\xce', '%cE': '\xce', '%CE': '\xce', '%cf': '\xcf', '%Cf': '\xcf',
|
||||
'%cF': '\xcf', '%CF': '\xcf', '%d0': '\xd0', '%D0': '\xd0', '%d1': '\xd1',
|
||||
'%D1': '\xd1', '%d2': '\xd2', '%D2': '\xd2', '%d3': '\xd3', '%D3': '\xd3',
|
||||
'%d4': '\xd4', '%D4': '\xd4', '%d5': '\xd5', '%D5': '\xd5', '%d6': '\xd6',
|
||||
'%D6': '\xd6', '%d7': '\xd7', '%D7': '\xd7', '%d8': '\xd8', '%D8': '\xd8',
|
||||
'%d9': '\xd9', '%D9': '\xd9', '%da': '\xda', '%Da': '\xda', '%dA': '\xda',
|
||||
'%DA': '\xda', '%db': '\xdb', '%Db': '\xdb', '%dB': '\xdb', '%DB': '\xdb',
|
||||
'%dc': '\xdc', '%Dc': '\xdc', '%dC': '\xdc', '%DC': '\xdc', '%dd': '\xdd',
|
||||
'%Dd': '\xdd', '%dD': '\xdd', '%DD': '\xdd', '%de': '\xde', '%De': '\xde',
|
||||
'%dE': '\xde', '%DE': '\xde', '%df': '\xdf', '%Df': '\xdf', '%dF': '\xdf',
|
||||
'%DF': '\xdf', '%e0': '\xe0', '%E0': '\xe0', '%e1': '\xe1', '%E1': '\xe1',
|
||||
'%e2': '\xe2', '%E2': '\xe2', '%e3': '\xe3', '%E3': '\xe3', '%e4': '\xe4',
|
||||
'%E4': '\xe4', '%e5': '\xe5', '%E5': '\xe5', '%e6': '\xe6', '%E6': '\xe6',
|
||||
'%e7': '\xe7', '%E7': '\xe7', '%e8': '\xe8', '%E8': '\xe8', '%e9': '\xe9',
|
||||
'%E9': '\xe9', '%ea': '\xea', '%Ea': '\xea', '%eA': '\xea', '%EA': '\xea',
|
||||
'%eb': '\xeb', '%Eb': '\xeb', '%eB': '\xeb', '%EB': '\xeb', '%ec': '\xec',
|
||||
'%Ec': '\xec', '%eC': '\xec', '%EC': '\xec', '%ed': '\xed', '%Ed': '\xed',
|
||||
'%eD': '\xed', '%ED': '\xed', '%ee': '\xee', '%Ee': '\xee', '%eE': '\xee',
|
||||
'%EE': '\xee', '%ef': '\xef', '%Ef': '\xef', '%eF': '\xef', '%EF': '\xef',
|
||||
'%f0': '\xf0', '%F0': '\xf0', '%f1': '\xf1', '%F1': '\xf1', '%f2': '\xf2',
|
||||
'%F2': '\xf2', '%f3': '\xf3', '%F3': '\xf3', '%f4': '\xf4', '%F4': '\xf4',
|
||||
'%f5': '\xf5', '%F5': '\xf5', '%f6': '\xf6', '%F6': '\xf6', '%f7': '\xf7',
|
||||
'%F7': '\xf7', '%f8': '\xf8', '%F8': '\xf8', '%f9': '\xf9', '%F9': '\xf9',
|
||||
'%fa': '\xfa', '%Fa': '\xfa', '%fA': '\xfa', '%FA': '\xfa', '%fb': '\xfb',
|
||||
'%Fb': '\xfb', '%fB': '\xfb', '%FB': '\xfb', '%fc': '\xfc', '%Fc': '\xfc',
|
||||
'%fC': '\xfc', '%FC': '\xfc', '%fd': '\xfd', '%Fd': '\xfd', '%fD': '\xfd',
|
||||
'%FD': '\xfd', '%fe': '\xfe', '%Fe': '\xfe', '%fE': '\xfe', '%FE': '\xfe',
|
||||
'%ff': '\xff', '%Ff': '\xff', '%fF': '\xff', '%FF': '\xff'
|
||||
}
|
||||
|
||||
function encodedReplacer (match) {
|
||||
return EncodedLookup[match]
|
||||
}
|
||||
|
||||
const STATE_KEY = 0
|
||||
const STATE_VALUE = 1
|
||||
const STATE_CHARSET = 2
|
||||
const STATE_LANG = 3
|
||||
|
||||
function parseParams (str) {
|
||||
const res = []
|
||||
let state = STATE_KEY
|
||||
let charset = ''
|
||||
let inquote = false
|
||||
let escaping = false
|
||||
let p = 0
|
||||
let tmp = ''
|
||||
const len = str.length
|
||||
|
||||
for (var i = 0; i < len; ++i) { // eslint-disable-line no-var
|
||||
const char = str[i]
|
||||
if (char === '\\' && inquote) {
|
||||
if (escaping) { escaping = false } else {
|
||||
escaping = true
|
||||
continue
|
||||
}
|
||||
} else if (char === '"') {
|
||||
if (!escaping) {
|
||||
if (inquote) {
|
||||
inquote = false
|
||||
state = STATE_KEY
|
||||
} else { inquote = true }
|
||||
continue
|
||||
} else { escaping = false }
|
||||
} else {
|
||||
if (escaping && inquote) { tmp += '\\' }
|
||||
escaping = false
|
||||
if ((state === STATE_CHARSET || state === STATE_LANG) && char === "'") {
|
||||
if (state === STATE_CHARSET) {
|
||||
state = STATE_LANG
|
||||
charset = tmp.substring(1)
|
||||
} else { state = STATE_VALUE }
|
||||
tmp = ''
|
||||
continue
|
||||
} else if (state === STATE_KEY &&
|
||||
(char === '*' || char === '=') &&
|
||||
res.length) {
|
||||
state = char === '*'
|
||||
? STATE_CHARSET
|
||||
: STATE_VALUE
|
||||
res[p] = [tmp, undefined]
|
||||
tmp = ''
|
||||
continue
|
||||
} else if (!inquote && char === ';') {
|
||||
state = STATE_KEY
|
||||
if (charset) {
|
||||
if (tmp.length) {
|
||||
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
|
||||
'binary',
|
||||
charset)
|
||||
}
|
||||
charset = ''
|
||||
} else if (tmp.length) {
|
||||
tmp = decodeText(tmp, 'binary', 'utf8')
|
||||
}
|
||||
if (res[p] === undefined) { res[p] = tmp } else { res[p][1] = tmp }
|
||||
tmp = ''
|
||||
++p
|
||||
continue
|
||||
} else if (!inquote && (char === ' ' || char === '\t')) { continue }
|
||||
}
|
||||
tmp += char
|
||||
}
|
||||
if (charset && tmp.length) {
|
||||
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
|
||||
'binary',
|
||||
charset)
|
||||
} else if (tmp) {
|
||||
tmp = decodeText(tmp, 'binary', 'utf8')
|
||||
}
|
||||
|
||||
if (res[p] === undefined) {
|
||||
if (tmp) { res[p] = tmp }
|
||||
} else { res[p][1] = tmp }
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
module.exports = parseParams
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"name": "@fastify/busboy",
|
||||
"version": "2.1.1",
|
||||
"private": false,
|
||||
"author": "Brian White <mscdex@mscdex.net>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Igor Savin",
|
||||
"email": "kibertoad@gmail.com",
|
||||
"url": "https://github.com/kibertoad"
|
||||
},
|
||||
{
|
||||
"name": "Aras Abbasi",
|
||||
"email": "aras.abbasi@gmail.com",
|
||||
"url": "https://github.com/uzlopak"
|
||||
}
|
||||
],
|
||||
"description": "A streaming parser for HTML form data for node.js",
|
||||
"main": "lib/main",
|
||||
"type": "commonjs",
|
||||
"types": "lib/main.d.ts",
|
||||
"scripts": {
|
||||
"bench:busboy": "cd benchmarks && npm install && npm run benchmark-fastify",
|
||||
"bench:dicer": "node bench/dicer/dicer-bench-multipart-parser.js",
|
||||
"coveralls": "nyc report --reporter=lcov",
|
||||
"lint": "npm run lint:standard",
|
||||
"lint:everything": "npm run lint && npm run test:types",
|
||||
"lint:fix": "standard --fix",
|
||||
"lint:standard": "standard --verbose | snazzy",
|
||||
"test:mocha": "tap",
|
||||
"test:types": "tsd",
|
||||
"test:coverage": "nyc npm run test",
|
||||
"test": "npm run test:mocha"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.1.0",
|
||||
"busboy": "^1.0.0",
|
||||
"photofinish": "^1.8.0",
|
||||
"snazzy": "^9.0.0",
|
||||
"standard": "^17.0.0",
|
||||
"tap": "^16.3.8",
|
||||
"tinybench": "^2.5.1",
|
||||
"tsd": "^0.30.0",
|
||||
"typescript": "^5.0.2"
|
||||
},
|
||||
"keywords": [
|
||||
"uploads",
|
||||
"forms",
|
||||
"multipart",
|
||||
"form-data"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fastify/busboy.git"
|
||||
},
|
||||
"tsd": {
|
||||
"directory": "test/types",
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": false,
|
||||
"module": "commonjs",
|
||||
"target": "ES2017"
|
||||
}
|
||||
},
|
||||
"standard": {
|
||||
"globals": [
|
||||
"describe",
|
||||
"it"
|
||||
],
|
||||
"ignore": [
|
||||
"bench"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
"LICENSE",
|
||||
"lib/*",
|
||||
"deps/encoding/*",
|
||||
"deps/dicer/lib",
|
||||
"deps/streamsearch/",
|
||||
"deps/dicer/LICENSE"
|
||||
]
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/node-tunnel.iml" filepath="$PROJECT_DIR$/.idea/node-tunnel.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
+797
@@ -0,0 +1,797 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="3caed8aa-31ae-4b3d-ad18-6f9796663516" name="Default" comment="">
|
||||
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.travis.yml" afterPath="$PROJECT_DIR$/.travis.yml" />
|
||||
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/CHANGELOG.md" afterPath="$PROJECT_DIR$/CHANGELOG.md" />
|
||||
</list>
|
||||
<ignored path="$PROJECT_DIR$/.tmp/" />
|
||||
<ignored path="$PROJECT_DIR$/temp/" />
|
||||
<ignored path="$PROJECT_DIR$/tmp/" />
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="TRACKING_ENABLED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||
<file leaf-file-name="package.json" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="34">
|
||||
<caret line="2" column="19" lean-forward="false" selection-start-line="2" selection-start-column="19" selection-end-line="2" selection-end-column="19" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="README.md" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="2312">
|
||||
<caret line="136" column="67" lean-forward="false" selection-start-line="136" selection-start-column="67" selection-end-line="136" selection-end-column="67" />
|
||||
<folding>
|
||||
<marker date="1497272379133" expanded="true" signature="590:646" ph="{...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="601:644" ph="{"host": 'localhost'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="674:737" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="884:1330" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="964:1328" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1103:1192" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1290:1324" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1357:1419" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1514:2209" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1540:1623" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1842:2207" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1981:2070" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2168:2202" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2237:2300" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2395:3180" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2475:3178" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2615:2704" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2802:2836" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3207:3269" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3366:4398" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3392:3475" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="3694:4396" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3834:3923" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="4021:4055" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="4426:4489" ph="{"host": 'example.com'...}" />
|
||||
</folding>
|
||||
</first_editor>
|
||||
<second_editor />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name=".travis.yml" pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/.travis.yml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="102">
|
||||
<caret line="6" column="0" lean-forward="true" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="tunnel.js" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/tunnel.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="697">
|
||||
<caret line="41" column="19" lean-forward="false" selection-start-line="41" selection-start-column="19" selection-end-line="41" selection-end-column="19" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="http-over-http-error.js" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http-error.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="935">
|
||||
<caret line="55" column="26" lean-forward="true" selection-start-line="55" selection-start-column="26" selection-end-line="55" selection-end-column="26" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="http-over-http-error2.js" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http-error2.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1207">
|
||||
<caret line="71" column="0" lean-forward="false" selection-start-line="71" selection-start-column="0" selection-end-line="71" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="https-over-http.js" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-http.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1479">
|
||||
<caret line="87" column="0" lean-forward="false" selection-start-line="87" selection-start-column="0" selection-end-line="87" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="https-over-https.js" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-https.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="http-over-http.js" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1088">
|
||||
<caret line="64" column="26" lean-forward="true" selection-start-line="64" selection-start-column="26" selection-end-line="64" selection-end-column="26" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="CHANGELOG.md" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="102">
|
||||
<caret line="6" column="0" lean-forward="false" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
|
||||
<folding />
|
||||
</first_editor>
|
||||
<second_editor />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="JavaScript File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="FindInProjectRecents">
|
||||
<findStrings>
|
||||
<find>max</find>
|
||||
<find>onconne</find>
|
||||
</findStrings>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="CHANGED_PATHS">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/test/http-over-http-error.js" />
|
||||
<option value="$PROJECT_DIR$/README.md" />
|
||||
<option value="$PROJECT_DIR$/package.json" />
|
||||
<option value="$PROJECT_DIR$/test/http-over-http-error2.js" />
|
||||
<option value="$PROJECT_DIR$/test/https-over-http-localaddress.js" />
|
||||
<option value="$PROJECT_DIR$/test/https-over-http.js" />
|
||||
<option value="$PROJECT_DIR$/lib/tunnel.js" />
|
||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||
<option value="$PROJECT_DIR$/.travis.yml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
|
||||
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
</component>
|
||||
<component name="JsFlowSettings">
|
||||
<service-enabled>false</service-enabled>
|
||||
<exe-path />
|
||||
<annotation-enable>false</annotation-enable>
|
||||
<other-services-enabled>false</other-services-enabled>
|
||||
<auto-save>true</auto-save>
|
||||
</component>
|
||||
<component name="JsGulpfileManager">
|
||||
<detection-done>true</detection-done>
|
||||
<sorting>DEFINITION_ORDER</sorting>
|
||||
</component>
|
||||
<component name="NodeModulesDirectoryManager">
|
||||
<handled-path value="$PROJECT_DIR$/node_modules" />
|
||||
</component>
|
||||
<component name="ProjectFrameBounds">
|
||||
<option name="x" value="785" />
|
||||
<option name="y" value="40" />
|
||||
<option name="width" value="1788" />
|
||||
<option name="height" value="1407" />
|
||||
</component>
|
||||
<component name="ProjectView">
|
||||
<navigator currentView="ProjectPane" proportions="" version="1">
|
||||
<flattenPackages />
|
||||
<showMembers />
|
||||
<showModules />
|
||||
<showLibraryContents />
|
||||
<hideEmptyPackages />
|
||||
<abbreviatePackageNames />
|
||||
<autoscrollToSource />
|
||||
<autoscrollFromSource ProjectPane="true" />
|
||||
<sortByType />
|
||||
<manualOrder />
|
||||
<foldersAlwaysOnTop value="true" />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="Scope" />
|
||||
<pane id="Scratches" />
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
<path>
|
||||
<item name="node-tunnel" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="node-tunnel" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="node-tunnel" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="node-tunnel" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="node-tunnel" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="node-tunnel" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="test" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||
<property name="HbShouldOpenHtmlAsHb" value="" />
|
||||
<property name="nodejs_interpreter_path" value="$PROJECT_DIR$/../../nvmw/v6.10.3/node" />
|
||||
</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="C:\Users\koichik\git\koichik\node-tunnel\test" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunDashboard">
|
||||
<option name="ruleStates">
|
||||
<list>
|
||||
<RuleState>
|
||||
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
<RuleState>
|
||||
<option name="name" value="StatusDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
|
||||
<node-interpreter>project</node-interpreter>
|
||||
<node-options />
|
||||
<gulpfile />
|
||||
<tasks />
|
||||
<arguments />
|
||||
<envs />
|
||||
</configuration>
|
||||
<configuration default="true" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application">
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="DartTestRunConfigurationType" factoryName="Dart Test">
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="JavaScriptTestRunnerJest" factoryName="Jest">
|
||||
<node-interpreter value="project" />
|
||||
<working-dir value="" />
|
||||
<envs />
|
||||
<scope-kind value="ALL" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="JavaScriptTestRunnerKarma" factoryName="Karma">
|
||||
<config-file value="" />
|
||||
<node-interpreter value="project" />
|
||||
<envs />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="JavaScriptTestRunnerProtractor" factoryName="Protractor">
|
||||
<config-file value="" />
|
||||
<node-interpreter value="project" />
|
||||
<envs />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="NodeJSConfigurationType" factoryName="Node.js" path-to-node="project" working-dir="">
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="cucumber.js" factoryName="Cucumber.js">
|
||||
<option name="cucumberJsArguments" value="" />
|
||||
<option name="executablePath" />
|
||||
<option name="filePath" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="js.build_tools.npm" factoryName="npm">
|
||||
<command value="run" />
|
||||
<scripts />
|
||||
<node-interpreter value="project" />
|
||||
<envs />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="mocha-javascript-test-runner" factoryName="Mocha">
|
||||
<node-interpreter>project</node-interpreter>
|
||||
<node-options />
|
||||
<working-directory />
|
||||
<pass-parent-env>true</pass-parent-env>
|
||||
<envs />
|
||||
<ui />
|
||||
<extra-mocha-options />
|
||||
<test-kind>DIRECTORY</test-kind>
|
||||
<test-directory />
|
||||
<recursive>false</recursive>
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="ShelveChangesManager" show_recycled="false">
|
||||
<option name="remove_strategy" value="false" />
|
||||
</component>
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="3caed8aa-31ae-4b3d-ad18-6f9796663516" name="Default" comment="" />
|
||||
<created>1497256565348</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1497256565348</updated>
|
||||
<workItem from="1497256566573" duration="8794000" />
|
||||
<workItem from="1497272051717" duration="2328000" />
|
||||
<workItem from="1536577850117" duration="8708000" />
|
||||
<workItem from="1536636907096" duration="739000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TimeTrackingManager">
|
||||
<option name="totallyTimeSpent" value="20569000" />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="785" y="40" width="1788" height="1407" extended-state="0" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="SvgViewer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32967034" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="npm" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="1" />
|
||||
</component>
|
||||
<component name="VcsContentAnnotationSettings">
|
||||
<option name="myLimit" value="2678400000" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager />
|
||||
<watches-manager />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="34">
|
||||
<caret line="2" column="19" lean-forward="false" selection-start-line="2" selection-start-column="19" selection-end-line="2" selection-end-column="19" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="2312">
|
||||
<caret line="136" column="67" lean-forward="false" selection-start-line="136" selection-start-column="67" selection-end-line="136" selection-end-column="67" />
|
||||
<folding>
|
||||
<marker date="1497272379133" expanded="true" signature="590:646" ph="{...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="601:644" ph="{"host": 'localhost'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="674:737" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="884:1330" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="964:1328" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1103:1192" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1290:1324" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1357:1419" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1514:2209" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1540:1623" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1842:2207" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1981:2070" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2168:2202" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2237:2300" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2395:3180" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2475:3178" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2615:2704" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2802:2836" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3207:3269" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3366:4398" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3392:3475" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="3694:4396" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3834:3923" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="4021:4055" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="4426:4489" ph="{"host": 'example.com'...}" />
|
||||
</folding>
|
||||
</first_editor>
|
||||
<second_editor />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.travis.yml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="102">
|
||||
<caret line="6" column="0" lean-forward="true" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http-error.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="935">
|
||||
<caret line="55" column="26" lean-forward="true" selection-start-line="55" selection-start-column="26" selection-end-line="55" selection-end-column="26" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http-error2.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1207">
|
||||
<caret line="71" column="0" lean-forward="false" selection-start-line="71" selection-start-column="0" selection-end-line="71" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-http.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1479">
|
||||
<caret line="87" column="0" lean-forward="false" selection-start-line="87" selection-start-column="0" selection-end-line="87" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-https.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1088">
|
||||
<caret line="64" column="26" lean-forward="true" selection-start-line="64" selection-start-column="26" selection-end-line="64" selection-end-column="26" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/tunnel.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="697">
|
||||
<caret line="41" column="19" lean-forward="false" selection-start-line="41" selection-start-column="19" selection-end-line="41" selection-end-column="19" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="34">
|
||||
<caret line="2" column="19" lean-forward="false" selection-start-line="2" selection-start-column="19" selection-end-line="2" selection-end-column="19" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="2312">
|
||||
<caret line="136" column="67" lean-forward="false" selection-start-line="136" selection-start-column="67" selection-end-line="136" selection-end-column="67" />
|
||||
<folding>
|
||||
<marker date="1497272379133" expanded="true" signature="590:646" ph="{...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="601:644" ph="{"host": 'localhost'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="674:737" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="884:1330" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="964:1328" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1103:1192" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1290:1324" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1357:1419" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1514:2209" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1540:1623" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1842:2207" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1981:2070" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2168:2202" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2237:2300" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2395:3180" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2475:3178" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2615:2704" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2802:2836" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3207:3269" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3366:4398" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3392:3475" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="3694:4396" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3834:3923" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="4021:4055" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="4426:4489" ph="{"host": 'example.com'...}" />
|
||||
</folding>
|
||||
</first_editor>
|
||||
<second_editor />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/tunnel.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="2550">
|
||||
<caret line="150" column="0" lean-forward="false" selection-start-line="150" selection-start-column="0" selection-end-line="150" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="51">
|
||||
<caret line="3" column="21" lean-forward="false" selection-start-line="3" selection-start-column="21" selection-end-line="3" selection-end-column="21" />
|
||||
<folding />
|
||||
</first_editor>
|
||||
<second_editor />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.travis.yml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="119">
|
||||
<caret line="7" column="0" lean-forward="true" selection-start-line="7" selection-start-column="0" selection-end-line="7" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding>
|
||||
<marker date="1497272379133" expanded="true" signature="590:646" ph="{...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="601:644" ph="{"host": 'localhost'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="674:737" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="884:1330" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="964:1328" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1103:1192" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1290:1324" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1357:1419" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1514:2209" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1540:1623" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1842:2207" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1981:2070" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2168:2202" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2237:2300" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2395:3180" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2475:3178" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2615:2704" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2802:2836" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3207:3269" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3366:4398" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3392:3475" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="3694:4396" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3834:3923" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="4021:4055" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="4426:4489" ph="{"host": 'example.com'...}" />
|
||||
</folding>
|
||||
</first_editor>
|
||||
<second_editor />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.travis.yml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/tunnel.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="2550">
|
||||
<caret line="150" column="0" lean-forward="false" selection-start-line="150" selection-start-column="0" selection-end-line="150" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-https.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-https-error.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="136">
|
||||
<caret line="8" column="0" lean-forward="false" selection-start-line="7" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http-error.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1309">
|
||||
<caret line="77" column="0" lean-forward="false" selection-start-line="77" selection-start-column="0" selection-end-line="77" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-https.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-https.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-https-error.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="2312">
|
||||
<caret line="136" column="67" lean-forward="false" selection-start-line="136" selection-start-column="67" selection-end-line="136" selection-end-column="67" />
|
||||
<folding>
|
||||
<marker date="1497272379133" expanded="true" signature="590:646" ph="{...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="601:644" ph="{"host": 'localhost'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="674:737" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="884:1330" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="964:1328" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1103:1192" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1290:1324" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1357:1419" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1514:2209" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1540:1623" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="1842:2207" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="1981:2070" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2168:2202" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2237:2300" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2395:3180" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2475:3178" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="2615:2704" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="2802:2836" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3207:3269" ph="{"host": 'example.com'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3366:4398" ph="{"maxSockets": poolSize...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3392:3475" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="3694:4396" ph="{"host": proxyHost...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="3834:3923" ph="//..." />
|
||||
<marker date="1497272379133" expanded="true" signature="4021:4055" ph="{"User-Agent": 'Node'...}" />
|
||||
<marker date="1497272379133" expanded="true" signature="4426:4489" ph="{"host": 'example.com'...}" />
|
||||
</folding>
|
||||
</first_editor>
|
||||
<second_editor />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="34">
|
||||
<caret line="2" column="19" lean-forward="false" selection-start-line="2" selection-start-column="19" selection-end-line="2" selection-end-column="19" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http-error.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="935">
|
||||
<caret line="55" column="26" lean-forward="true" selection-start-line="55" selection-start-column="26" selection-end-line="55" selection-end-column="26" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http-error2.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1207">
|
||||
<caret line="71" column="0" lean-forward="false" selection-start-line="71" selection-start-column="0" selection-end-line="71" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-http-localaddress.js" />
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-https.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/http-over-http.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1088">
|
||||
<caret line="64" column="26" lean-forward="true" selection-start-line="64" selection-start-column="26" selection-end-line="64" selection-end-column="26" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/https-over-http.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1479">
|
||||
<caret line="87" column="0" lean-forward="false" selection-start-line="87" selection-start-column="0" selection-end-line="87" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/tunnel.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="697">
|
||||
<caret line="41" column="19" lean-forward="false" selection-start-line="41" selection-start-column="19" selection-end-line="41" selection-end-column="19" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="102">
|
||||
<caret line="6" column="0" lean-forward="false" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
|
||||
<folding />
|
||||
</first_editor>
|
||||
<second_editor />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.travis.yml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="102">
|
||||
<caret line="6" column="0" lean-forward="true" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
||||
+75
-45
@@ -7,8 +7,12 @@ An HTTP/1.1 client, written from scratch for Node.js.
|
||||
> Undici means eleven in Italian. 1.1 -> 11 -> Eleven -> Undici.
|
||||
It is also a Stranger Things reference.
|
||||
|
||||
## How to get involved
|
||||
|
||||
Have a question about using Undici? Open a [Q&A Discussion](https://github.com/nodejs/undici/discussions/new) or join our official OpenJS [Slack](https://openjs-foundation.slack.com/archives/C01QF9Q31QD) channel.
|
||||
|
||||
Looking to contribute? Start by reading the [contributing guide](./CONTRIBUTING.md)
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
@@ -17,34 +21,41 @@ npm i undici
|
||||
|
||||
## Benchmarks
|
||||
|
||||
The benchmark is a simple `hello world` [example](benchmarks/benchmark.js) using a
|
||||
number of unix sockets (connections) with a pipelining depth of 10 running on Node 20.6.0.
|
||||
The benchmark is a simple getting data [example](https://github.com/nodejs/undici/blob/main/benchmarks/benchmark.js) using a
|
||||
50 TCP connections with a pipelining depth of 10 running on Node 20.10.0.
|
||||
|
||||
### Connections 1
|
||||
| _Tests_ | _Samples_ | _Result_ | _Tolerance_ | _Difference with slowest_ |
|
||||
| :-----------------: | :-------: | :--------------: | :---------: | :-----------------------: |
|
||||
| undici - fetch | 30 | 3704.43 req/sec | ± 2.95 % | - |
|
||||
| http - no keepalive | 20 | 4275.30 req/sec | ± 2.60 % | + 15.41 % |
|
||||
| node-fetch | 10 | 4759.42 req/sec | ± 0.87 % | + 28.48 % |
|
||||
| request | 40 | 4803.37 req/sec | ± 2.77 % | + 29.67 % |
|
||||
| axios | 45 | 4951.97 req/sec | ± 2.88 % | + 33.68 % |
|
||||
| got | 10 | 5969.67 req/sec | ± 2.64 % | + 61.15 % |
|
||||
| superagent | 10 | 9471.48 req/sec | ± 1.50 % | + 155.68 % |
|
||||
| http - keepalive | 25 | 10327.49 req/sec | ± 2.95 % | + 178.79 % |
|
||||
| undici - pipeline | 10 | 15053.41 req/sec | ± 1.63 % | + 306.36 % |
|
||||
| undici - request | 10 | 19264.24 req/sec | ± 1.74 % | + 420.03 % |
|
||||
| undici - stream | 15 | 20317.29 req/sec | ± 2.13 % | + 448.46 % |
|
||||
| undici - dispatch | 10 | 24883.28 req/sec | ± 1.54 % | + 571.72 % |
|
||||
|
||||
The benchmark is a simple sending data [example](https://github.com/nodejs/undici/blob/main/benchmarks/post-benchmark.js) using a
|
||||
50 TCP connections with a pipelining depth of 10 running on Node 20.10.0.
|
||||
|
||||
| Tests | Samples | Result | Tolerance | Difference with slowest |
|
||||
|---------------------|---------|---------------|-----------|-------------------------|
|
||||
| http - no keepalive | 15 | 5.32 req/sec | ± 2.61 % | - |
|
||||
| http - keepalive | 10 | 5.35 req/sec | ± 2.47 % | + 0.44 % |
|
||||
| undici - fetch | 15 | 41.85 req/sec | ± 2.49 % | + 686.04 % |
|
||||
| undici - pipeline | 40 | 50.36 req/sec | ± 2.77 % | + 845.92 % |
|
||||
| undici - stream | 15 | 60.58 req/sec | ± 2.75 % | + 1037.72 % |
|
||||
| undici - request | 10 | 61.19 req/sec | ± 2.60 % | + 1049.24 % |
|
||||
| undici - dispatch | 20 | 64.84 req/sec | ± 2.81 % | + 1117.81 % |
|
||||
|
||||
|
||||
### Connections 50
|
||||
|
||||
| Tests | Samples | Result | Tolerance | Difference with slowest |
|
||||
|---------------------|---------|------------------|-----------|-------------------------|
|
||||
| undici - fetch | 30 | 2107.19 req/sec | ± 2.69 % | - |
|
||||
| http - no keepalive | 10 | 2698.90 req/sec | ± 2.68 % | + 28.08 % |
|
||||
| http - keepalive | 10 | 4639.49 req/sec | ± 2.55 % | + 120.17 % |
|
||||
| undici - pipeline | 40 | 6123.33 req/sec | ± 2.97 % | + 190.59 % |
|
||||
| undici - stream | 50 | 9426.51 req/sec | ± 2.92 % | + 347.35 % |
|
||||
| undici - request | 10 | 10162.88 req/sec | ± 2.13 % | + 382.29 % |
|
||||
| undici - dispatch | 50 | 11191.11 req/sec | ± 2.98 % | + 431.09 % |
|
||||
| _Tests_ | _Samples_ | _Result_ | _Tolerance_ | _Difference with slowest_ |
|
||||
| :-----------------: | :-------: | :-------------: | :---------: | :-----------------------: |
|
||||
| undici - fetch | 20 | 1968.42 req/sec | ± 2.63 % | - |
|
||||
| http - no keepalive | 25 | 2330.30 req/sec | ± 2.99 % | + 18.38 % |
|
||||
| node-fetch | 20 | 2485.36 req/sec | ± 2.70 % | + 26.26 % |
|
||||
| got | 15 | 2787.68 req/sec | ± 2.56 % | + 41.62 % |
|
||||
| request | 30 | 2805.10 req/sec | ± 2.59 % | + 42.50 % |
|
||||
| axios | 10 | 3040.45 req/sec | ± 1.72 % | + 54.46 % |
|
||||
| superagent | 20 | 3358.29 req/sec | ± 2.51 % | + 70.61 % |
|
||||
| http - keepalive | 20 | 3477.94 req/sec | ± 2.51 % | + 76.69 % |
|
||||
| undici - pipeline | 25 | 3812.61 req/sec | ± 2.80 % | + 93.69 % |
|
||||
| undici - request | 10 | 6067.00 req/sec | ± 0.94 % | + 208.22 % |
|
||||
| undici - stream | 10 | 6391.61 req/sec | ± 1.98 % | + 224.71 % |
|
||||
| undici - dispatch | 10 | 6397.00 req/sec | ± 1.48 % | + 224.98 % |
|
||||
|
||||
|
||||
## Quick Start
|
||||
@@ -62,9 +73,7 @@ const {
|
||||
console.log('response received', statusCode)
|
||||
console.log('headers', headers)
|
||||
|
||||
for await (const data of body) {
|
||||
console.log('data', data)
|
||||
}
|
||||
for await (const data of body) { console.log('data', data) }
|
||||
|
||||
console.log('trailers', trailers)
|
||||
```
|
||||
@@ -73,10 +82,15 @@ console.log('trailers', trailers)
|
||||
|
||||
The `body` mixins are the most common way to format the request/response body. Mixins include:
|
||||
|
||||
- [`.formData()`](https://fetch.spec.whatwg.org/#dom-body-formdata)
|
||||
- [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
|
||||
- [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
|
||||
- [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
|
||||
- [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
|
||||
- [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
|
||||
|
||||
> [!NOTE]
|
||||
> The body returned from `undici.request` does not implement `.formData()`.
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
@@ -110,7 +124,7 @@ This section documents our most commonly used API methods. Additional APIs are d
|
||||
Arguments:
|
||||
|
||||
* **url** `string | URL | UrlObject`
|
||||
* **options** [`RequestOptions`](./docs/api/Dispatcher.md#parameter-requestoptions)
|
||||
* **options** [`RequestOptions`](./docs/docs/api/Dispatcher.md#parameter-requestoptions)
|
||||
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
|
||||
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
|
||||
* **maxRedirections** `Integer` - Default: `0`
|
||||
@@ -119,14 +133,14 @@ Returns a promise with the result of the `Dispatcher.request` method.
|
||||
|
||||
Calls `options.dispatcher.request(options)`.
|
||||
|
||||
See [Dispatcher.request](./docs/api/Dispatcher.md#dispatcherrequestoptions-callback) for more details.
|
||||
See [Dispatcher.request](./docs/docs/api/Dispatcher.md#dispatcherrequestoptions-callback) for more details, and [request examples](./examples/README.md) for examples.
|
||||
|
||||
### `undici.stream([url, options, ]factory): Promise`
|
||||
|
||||
Arguments:
|
||||
|
||||
* **url** `string | URL | UrlObject`
|
||||
* **options** [`StreamOptions`](./docs/api/Dispatcher.md#parameter-streamoptions)
|
||||
* **options** [`StreamOptions`](./docs/docs/api/Dispatcher.md#parameter-streamoptions)
|
||||
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
|
||||
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
|
||||
* **maxRedirections** `Integer` - Default: `0`
|
||||
@@ -136,14 +150,14 @@ Returns a promise with the result of the `Dispatcher.stream` method.
|
||||
|
||||
Calls `options.dispatcher.stream(options, factory)`.
|
||||
|
||||
See [Dispatcher.stream](docs/api/Dispatcher.md#dispatcherstreamoptions-factory-callback) for more details.
|
||||
See [Dispatcher.stream](./docs/docs/api/Dispatcher.md#dispatcherstreamoptions-factory-callback) for more details.
|
||||
|
||||
### `undici.pipeline([url, options, ]handler): Duplex`
|
||||
|
||||
Arguments:
|
||||
|
||||
* **url** `string | URL | UrlObject`
|
||||
* **options** [`PipelineOptions`](docs/api/Dispatcher.md#parameter-pipelineoptions)
|
||||
* **options** [`PipelineOptions`](./docs/docs/api/Dispatcher.md#parameter-pipelineoptions)
|
||||
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
|
||||
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
|
||||
* **maxRedirections** `Integer` - Default: `0`
|
||||
@@ -153,7 +167,7 @@ Returns: `stream.Duplex`
|
||||
|
||||
Calls `options.dispatch.pipeline(options, handler)`.
|
||||
|
||||
See [Dispatcher.pipeline](docs/api/Dispatcher.md#dispatcherpipelineoptions-handler) for more details.
|
||||
See [Dispatcher.pipeline](./docs/docs/api/Dispatcher.md#dispatcherpipelineoptions-handler) for more details.
|
||||
|
||||
### `undici.connect([url, options]): Promise`
|
||||
|
||||
@@ -162,7 +176,7 @@ Starts two-way communications with the requested resource using [HTTP CONNECT](h
|
||||
Arguments:
|
||||
|
||||
* **url** `string | URL | UrlObject`
|
||||
* **options** [`ConnectOptions`](docs/api/Dispatcher.md#parameter-connectoptions)
|
||||
* **options** [`ConnectOptions`](./docs/docs/api/Dispatcher.md#parameter-connectoptions)
|
||||
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
|
||||
* **maxRedirections** `Integer` - Default: `0`
|
||||
* **callback** `(err: Error | null, data: ConnectData | null) => void` (optional)
|
||||
@@ -171,7 +185,7 @@ Returns a promise with the result of the `Dispatcher.connect` method.
|
||||
|
||||
Calls `options.dispatch.connect(options)`.
|
||||
|
||||
See [Dispatcher.connect](docs/api/Dispatcher.md#dispatcherconnectoptions-callback) for more details.
|
||||
See [Dispatcher.connect](./docs/docs/api/Dispatcher.md#dispatcherconnectoptions-callback) for more details.
|
||||
|
||||
### `undici.fetch(input[, init]): Promise`
|
||||
|
||||
@@ -180,8 +194,6 @@ Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method).
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
|
||||
* https://fetch.spec.whatwg.org/#fetch-method
|
||||
|
||||
Only supported on Node 16.8+.
|
||||
|
||||
Basic usage example:
|
||||
|
||||
```js
|
||||
@@ -237,11 +249,23 @@ const data = {
|
||||
await fetch('https://example.com', { body: data, method: 'POST', duplex: 'half' })
|
||||
```
|
||||
|
||||
[FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) besides text data and buffers can also utilize streams via [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects:
|
||||
|
||||
```js
|
||||
import { openAsBlob } from 'node:fs'
|
||||
|
||||
const file = await openAsBlob('./big.csv')
|
||||
const body = new FormData()
|
||||
body.set('file', file, 'big.csv')
|
||||
|
||||
await fetch('http://example.com', { method: 'POST', body })
|
||||
```
|
||||
|
||||
#### `request.duplex`
|
||||
|
||||
- half
|
||||
|
||||
In this implementation of fetch, `request.duplex` must be set if `request.body` is `ReadableStream` or `Async Iterables`. And fetch requests are currently always be full duplex. More detail refer to [Fetch Standard.](https://fetch.spec.whatwg.org/#dom-requestinit-duplex)
|
||||
In this implementation of fetch, `request.duplex` must be set if `request.body` is `ReadableStream` or `Async Iterables`, however, fetch requests are currently always full duplex. For more detail refer to the [Fetch Standard.](https://fetch.spec.whatwg.org/#dom-requestinit-duplex).
|
||||
|
||||
#### `response.body`
|
||||
|
||||
@@ -305,14 +329,20 @@ const headers = await fetch(url, { method: 'HEAD' })
|
||||
|
||||
The [Fetch Standard](https://fetch.spec.whatwg.org) requires implementations to exclude certain headers from requests and responses. In browser environments, some headers are forbidden so the user agent remains in full control over them. In Undici, these constraints are removed to give more control to the user.
|
||||
|
||||
### `undici.upgrade([url, options]): Promise`
|
||||
#### Content-Encoding
|
||||
|
||||
* https://www.rfc-editor.org/rfc/rfc9110#field.content-encoding
|
||||
|
||||
Undici limits the number of `Content-Encoding` layers in a response to **5** to prevent resource exhaustion attacks. If a server responds with more than 5 content-encodings (e.g., `Content-Encoding: gzip, gzip, gzip, gzip, gzip, gzip`), the fetch will be rejected with an error. This limit matches the approach taken by [curl](https://curl.se/docs/CVE-2022-32206.html) and [urllib3](https://github.com/advisories/GHSA-gm62-xv2j-4rw9).
|
||||
|
||||
#### `undici.upgrade([url, options]): Promise`
|
||||
|
||||
Upgrade to a different protocol. See [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.
|
||||
|
||||
Arguments:
|
||||
|
||||
* **url** `string | URL | UrlObject`
|
||||
* **options** [`UpgradeOptions`](docs/api/Dispatcher.md#parameter-upgradeoptions)
|
||||
* **options** [`UpgradeOptions`](./docs/docs/api/Dispatcher.md#parameter-upgradeoptions)
|
||||
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
|
||||
* **maxRedirections** `Integer` - Default: `0`
|
||||
* **callback** `(error: Error | null, data: UpgradeData) => void` (optional)
|
||||
@@ -321,7 +351,7 @@ Returns a promise with the result of the `Dispatcher.upgrade` method.
|
||||
|
||||
Calls `options.dispatcher.upgrade(options)`.
|
||||
|
||||
See [Dispatcher.upgrade](docs/api/Dispatcher.md#dispatcherupgradeoptions-callback) for more details.
|
||||
See [Dispatcher.upgrade](./docs/docs/api/Dispatcher.md#dispatcherupgradeoptions-callback) for more details.
|
||||
|
||||
### `undici.setGlobalDispatcher(dispatcher)`
|
||||
|
||||
@@ -415,9 +445,9 @@ Refs: https://fetch.spec.whatwg.org/#atomic-http-redirect-handling
|
||||
|
||||
If you experience problem when connecting to a remote server that is resolved by your DNS servers to a IPv6 (AAAA record)
|
||||
first, there are chances that your local router or ISP might have problem connecting to IPv6 networks. In that case
|
||||
undici will throw an error with code `UND_ERR_CONNECT_TIMEOUT`.
|
||||
undici will throw an error with code `UND_ERR_CONNECT_TIMEOUT`.
|
||||
|
||||
If the target server resolves to both a IPv6 and IPv4 (A records) address and you are using a compatible Node version
|
||||
If the target server resolves to both a IPv6 and IPv4 (A records) address and you are using a compatible Node version
|
||||
(18.3.0 and above), you can fix the problem by providing the `autoSelectFamily` option (support by both `undici.request`
|
||||
and `undici.Agent`) which will enable the family autoselection algorithm when establishing the connection.
|
||||
|
||||
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
# Fetch
|
||||
|
||||
Undici exposes a fetch() method starts the process of fetching a resource from the network.
|
||||
|
||||
Documentation and examples can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/fetch).
|
||||
|
||||
## File
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/File)
|
||||
|
||||
In Node versions v18.13.0 and above and v19.2.0 and above, undici will default to using Node's [File](https://nodejs.org/api/buffer.html#class-file) class. In versions where it's not available, it will default to the undici one.
|
||||
|
||||
## FormData
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/FormData)
|
||||
|
||||
## Response
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Response)
|
||||
|
||||
## Request
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Request)
|
||||
|
||||
## Header
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Headers)
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB |
Generated
Vendored
Generated
Vendored
+1
-1
@@ -50,7 +50,7 @@ Arguments:
|
||||
|
||||
### `BalancedPool.removeUpstream(upstream)`
|
||||
|
||||
Removes an upstream that was previously addded.
|
||||
Removes an upstream that was previously added.
|
||||
|
||||
### `BalancedPool.close([callback])`
|
||||
|
||||
Generated
Vendored
Generated
Vendored
+4
-3
@@ -19,17 +19,18 @@ Returns: `Client`
|
||||
|
||||
> ⚠️ Warning: The `H2` support is experimental.
|
||||
|
||||
* **bodyTimeout** `number | null` (optional) - Default: `300e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds.
|
||||
* **bodyTimeout** `number | null` (optional) - Default: `300e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds. Please note the `timeout` will be reset if you keep writing data to the scoket everytime.
|
||||
* **headersTimeout** `number | null` (optional) - Default: `300e3` - The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds.
|
||||
* **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout`, in milliseconds, when overridden by *keep-alive* hints from the server. Defaults to 10 minutes.
|
||||
* **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout, in milliseconds, after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds.
|
||||
* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number of milliseconds subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second.
|
||||
* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `2e3` - A number of milliseconds subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 2 seconds.
|
||||
* **maxHeaderSize** `number | null` (optional) - Default: `--max-http-header-size` or `16384` - The maximum length of request headers in bytes. Defaults to Node.js' --max-http-header-size or 16KiB.
|
||||
* **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable.
|
||||
* **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections.
|
||||
* **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
|
||||
* **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.
|
||||
* **interceptors** `{ Client: DispatchInterceptor[] }` - Default: `[RedirectInterceptor]` - A list of interceptors that are applied to the dispatch method. Additional logic can be applied (such as, but not limited to: 302 status code handling, authentication, cookies, compression and caching). Note that the behavior of interceptors is Experimental and might change at any given time.
|
||||
<!-- TODO: Remove once we drop its support -->
|
||||
* **interceptors** `{ Client: DispatchInterceptor[] }` - Default: `[RedirectInterceptor]` - A list of interceptors that are applied to the dispatch method. Additional logic can be applied (such as, but not limited to: 302 status code handling, authentication, cookies, compression and caching). Note that the behavior of interceptors is Experimental and might change at any given time. **Note: this is deprecated in favor of [Dispatcher#compose](./Dispatcher.md#dispatcher). Support will be droped in next major.**
|
||||
* **autoSelectFamily**: `boolean` (optional) - Default: depends on local Node version, on Node 18.13.0 and above is `false`. Enables a family autodetection algorithm that loosely implements section 5 of [RFC 8305](https://tools.ietf.org/html/rfc8305#section-5). See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. This option is ignored if not supported by the current Node version.
|
||||
* **autoSelectFamilyAttemptTimeout**: `number` - Default: depends on local Node version, on Node 18.13.0 and above is `250`. The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details.
|
||||
* **allowH2**: `boolean` - Default: `false`. Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation.
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
# Debug
|
||||
|
||||
Undici (and subsenquently `fetch` and `websocket`) exposes a debug statement that can be enabled by setting `NODE_DEBUG` within the environment.
|
||||
|
||||
The flags availabile are:
|
||||
|
||||
## `undici`
|
||||
|
||||
This flag enables debug statements for the core undici library.
|
||||
|
||||
```sh
|
||||
NODE_DEBUG=undici node script.js
|
||||
|
||||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: connected to nodejs.org using https:h1
|
||||
UNDICI 16241: sending request to GET https://nodejs.org//
|
||||
UNDICI 16241: received response to GET https://nodejs.org// - HTTP 307
|
||||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: trailers received from GET https://nodejs.org//
|
||||
UNDICI 16241: connected to nodejs.org using https:h1
|
||||
UNDICI 16241: sending request to GET https://nodejs.org//en
|
||||
UNDICI 16241: received response to GET https://nodejs.org//en - HTTP 200
|
||||
UNDICI 16241: trailers received from GET https://nodejs.org//en
|
||||
```
|
||||
|
||||
## `fetch`
|
||||
|
||||
This flag enables debug statements for the `fetch` API.
|
||||
|
||||
> **Note**: statements are pretty similar to the ones in the `undici` flag, but scoped to `fetch`
|
||||
|
||||
```sh
|
||||
NODE_DEBUG=fetch node script.js
|
||||
|
||||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: connected to nodejs.org using https:h1
|
||||
FETCH 16241: sending request to GET https://nodejs.org//
|
||||
FETCH 16241: received response to GET https://nodejs.org// - HTTP 307
|
||||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: trailers received from GET https://nodejs.org//
|
||||
FETCH 16241: connected to nodejs.org using https:h1
|
||||
FETCH 16241: sending request to GET https://nodejs.org//en
|
||||
FETCH 16241: received response to GET https://nodejs.org//en - HTTP 200
|
||||
FETCH 16241: trailers received from GET https://nodejs.org//en
|
||||
```
|
||||
|
||||
## `websocket`
|
||||
|
||||
This flag enables debug statements for the `Websocket` API.
|
||||
|
||||
> **Note**: statements can overlap with `UNDICI` ones if `undici` or `fetch` flag has been enabled as well.
|
||||
|
||||
```sh
|
||||
NODE_DEBUG=websocket node script.js
|
||||
|
||||
WEBSOCKET 18309: connecting to echo.websocket.org using https:h1
|
||||
WEBSOCKET 18309: connected to echo.websocket.org using https:h1
|
||||
WEBSOCKET 18309: sending request to GET https://echo.websocket.org//
|
||||
WEBSOCKET 18309: connection opened <ip_address>
|
||||
```
|
||||
Generated
Vendored
+5
-5
@@ -19,9 +19,9 @@ diagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {
|
||||
console.log('completed', request.completed)
|
||||
console.log('method', request.method)
|
||||
console.log('path', request.path)
|
||||
console.log('headers') // raw text, e.g: 'bar: bar\r\n'
|
||||
console.log('headers') // array of strings, e.g: ['foo', 'bar']
|
||||
request.addHeader('hello', 'world')
|
||||
console.log('headers', request.headers) // e.g. 'bar: bar\r\nhello: world\r\n'
|
||||
console.log('headers', request.headers) // e.g. ['foo', 'bar', 'hello', 'world']
|
||||
})
|
||||
```
|
||||
|
||||
@@ -105,7 +105,7 @@ You can not assume that this event is related to any specific request.
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => {
|
||||
// const { host, hostname, protocol, port, servername } = connectParams
|
||||
// const { host, hostname, protocol, port, servername, version } = connectParams
|
||||
// connector is a function that creates the socket
|
||||
})
|
||||
```
|
||||
@@ -118,7 +118,7 @@ This message is published after a connection is established.
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => {
|
||||
// const { host, hostname, protocol, port, servername } = connectParams
|
||||
// const { host, hostname, protocol, port, servername, version } = connectParams
|
||||
// connector is a function that creates the socket
|
||||
})
|
||||
```
|
||||
@@ -131,7 +131,7 @@ This message is published if it did not succeed to create new connection
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => {
|
||||
// const { host, hostname, protocol, port, servername } = connectParams
|
||||
// const { host, hostname, protocol, port, servername, version } = connectParams
|
||||
// connector is a function that creates the socket
|
||||
console.log(`Connect failed with ${error.message}`)
|
||||
})
|
||||
Generated
Vendored
Generated
Vendored
+468
-8
@@ -209,6 +209,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
|
||||
* **onConnect** `(abort: () => void, context: object) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails.
|
||||
* **onError** `(error: Error) => void` - Invoked when an error has occurred. May not throw.
|
||||
* **onUpgrade** `(statusCode: number, headers: Buffer[], socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`.
|
||||
* **onResponseStarted** `() => void` (optional) - Invoked when response is received, before headers have been read.
|
||||
* **onHeaders** `(statusCode: number, headers: Buffer[], resume: () => void, statusText: string) => boolean` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
|
||||
* **onData** `(chunk: Buffer) => boolean` - Invoked when response payload data is received. Not required for `upgrade` requests.
|
||||
* **onComplete** `(trailers: Buffer[]) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
|
||||
@@ -487,11 +488,13 @@ The `RequestOptions.method` property should not be value `'CONNECT'`.
|
||||
|
||||
`body` contains the following additional [body mixin](https://fetch.spec.whatwg.org/#body-mixin) methods and properties:
|
||||
|
||||
- `text()`
|
||||
- `json()`
|
||||
- `arrayBuffer()`
|
||||
- `body`
|
||||
- `bodyUsed`
|
||||
* [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
|
||||
* [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
|
||||
* [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
|
||||
* [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
|
||||
* [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
|
||||
* `body`
|
||||
* `bodyUsed`
|
||||
|
||||
`body` can not be consumed twice. For example, calling `text()` after `json()` throws `TypeError`.
|
||||
|
||||
@@ -816,6 +819,421 @@ try {
|
||||
}
|
||||
```
|
||||
|
||||
### `Dispatcher.compose(interceptors[, interceptor])`
|
||||
|
||||
Compose a new dispatcher from the current dispatcher and the given interceptors.
|
||||
|
||||
> _Notes_:
|
||||
> - The order of the interceptors matters. The first interceptor will be the first to be called.
|
||||
> - It is important to note that the `interceptor` function should return a function that follows the `Dispatcher.dispatch` signature.
|
||||
> - Any fork of the chain of `interceptors` can lead to unexpected results.
|
||||
|
||||
Arguments:
|
||||
|
||||
* **interceptors** `Interceptor[interceptor[]]`: It is an array of `Interceptor` functions passed as only argument, or several interceptors passed as separate arguments.
|
||||
|
||||
Returns: `Dispatcher`.
|
||||
|
||||
#### Parameter: `Interceptor`
|
||||
|
||||
A function that takes a `dispatch` method and returns a `dispatch`-like function.
|
||||
|
||||
#### Example 1 - Basic Compose
|
||||
|
||||
```js
|
||||
const { Client, RedirectHandler } = require('undici')
|
||||
|
||||
const redirectInterceptor = dispatch => {
|
||||
return (opts, handler) => {
|
||||
const { maxRedirections } = opts
|
||||
|
||||
if (!maxRedirections) {
|
||||
return dispatch(opts, handler)
|
||||
}
|
||||
|
||||
const redirectHandler = new RedirectHandler(
|
||||
dispatch,
|
||||
maxRedirections,
|
||||
opts,
|
||||
handler
|
||||
)
|
||||
opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting.
|
||||
return dispatch(opts, redirectHandler)
|
||||
}
|
||||
}
|
||||
|
||||
const client = new Client('http://localhost:3000')
|
||||
.compose(redirectInterceptor)
|
||||
|
||||
await client.request({ path: '/', method: 'GET' })
|
||||
```
|
||||
|
||||
#### Example 2 - Chained Compose
|
||||
|
||||
```js
|
||||
const { Client, RedirectHandler, RetryHandler } = require('undici')
|
||||
|
||||
const redirectInterceptor = dispatch => {
|
||||
return (opts, handler) => {
|
||||
const { maxRedirections } = opts
|
||||
|
||||
if (!maxRedirections) {
|
||||
return dispatch(opts, handler)
|
||||
}
|
||||
|
||||
const redirectHandler = new RedirectHandler(
|
||||
dispatch,
|
||||
maxRedirections,
|
||||
opts,
|
||||
handler
|
||||
)
|
||||
opts = { ...opts, maxRedirections: 0 }
|
||||
return dispatch(opts, redirectHandler)
|
||||
}
|
||||
}
|
||||
|
||||
const retryInterceptor = dispatch => {
|
||||
return function retryInterceptor (opts, handler) {
|
||||
return dispatch(
|
||||
opts,
|
||||
new RetryHandler(opts, {
|
||||
handler,
|
||||
dispatch
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const client = new Client('http://localhost:3000')
|
||||
.compose(redirectInterceptor)
|
||||
.compose(retryInterceptor)
|
||||
|
||||
await client.request({ path: '/', method: 'GET' })
|
||||
```
|
||||
|
||||
#### Pre-built interceptors
|
||||
|
||||
##### `redirect`
|
||||
|
||||
The `redirect` interceptor allows you to customize the way your dispatcher handles redirects.
|
||||
|
||||
It accepts the same arguments as the [`RedirectHandler` constructor](./RedirectHandler.md).
|
||||
|
||||
**Example - Basic Redirect Interceptor**
|
||||
|
||||
```js
|
||||
const { Client, interceptors } = require("undici");
|
||||
const { redirect } = interceptors;
|
||||
|
||||
const client = new Client("http://example.com").compose(
|
||||
redirect({ maxRedirections: 3, throwOnMaxRedirects: true })
|
||||
);
|
||||
client.request({ path: "/" })
|
||||
```
|
||||
|
||||
##### `retry`
|
||||
|
||||
The `retry` interceptor allows you to customize the way your dispatcher handles retries.
|
||||
|
||||
It accepts the same arguments as the [`RetryHandler` constructor](./RetryHandler.md).
|
||||
|
||||
**Example - Basic Redirect Interceptor**
|
||||
|
||||
```js
|
||||
const { Client, interceptors } = require("undici");
|
||||
const { retry } = interceptors;
|
||||
|
||||
const client = new Client("http://example.com").compose(
|
||||
retry({
|
||||
maxRetries: 3,
|
||||
minTimeout: 1000,
|
||||
maxTimeout: 10000,
|
||||
timeoutFactor: 2,
|
||||
retryAfter: true,
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
##### `dump`
|
||||
|
||||
The `dump` interceptor enables you to dump the response body from a request upon a given limit.
|
||||
|
||||
**Options**
|
||||
- `maxSize` - The maximum size (in bytes) of the response body to dump. If the size of the request's body exceeds this value then the connection will be closed. Default: `1048576`.
|
||||
|
||||
> The `Dispatcher#options` also gets extended with the options `dumpMaxSize`, `abortOnDumped`, and `waitForTrailers` which can be used to configure the interceptor at a request-per-request basis.
|
||||
|
||||
**Example - Basic Dump Interceptor**
|
||||
|
||||
```js
|
||||
const { Client, interceptors } = require("undici");
|
||||
const { dump } = interceptors;
|
||||
|
||||
const client = new Client("http://example.com").compose(
|
||||
dump({
|
||||
maxSize: 1024,
|
||||
})
|
||||
);
|
||||
|
||||
// or
|
||||
client.dispatch(
|
||||
{
|
||||
path: "/",
|
||||
method: "GET",
|
||||
dumpMaxSize: 1024,
|
||||
},
|
||||
handler
|
||||
);
|
||||
```
|
||||
|
||||
##### `dns`
|
||||
|
||||
The `dns` interceptor enables you to cache DNS lookups for a given duration, per origin.
|
||||
|
||||
>It is well suited for scenarios where you want to cache DNS lookups to avoid the overhead of resolving the same domain multiple times
|
||||
|
||||
**Options**
|
||||
- `maxTTL` - The maximum time-to-live (in milliseconds) of the DNS cache. It should be a positive integer. Default: `10000`.
|
||||
- Set `0` to disable TTL.
|
||||
- `maxItems` - The maximum number of items to cache. It should be a positive integer. Default: `Infinity`.
|
||||
- `dualStack` - Whether to resolve both IPv4 and IPv6 addresses. Default: `true`.
|
||||
- It will also attempt a happy-eyeballs-like approach to connect to the available addresses in case of a connection failure.
|
||||
- `affinity` - Whether to use IPv4 or IPv6 addresses. Default: `4`.
|
||||
- It can be either `'4` or `6`.
|
||||
- It will only take effect if `dualStack` is `false`.
|
||||
- `lookup: (hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, addresses: DNSInterceptorRecord[]) => void) => void` - Custom lookup function. Default: `dns.lookup`.
|
||||
- For more info see [dns.lookup](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback).
|
||||
- `pick: (origin: URL, records: DNSInterceptorRecords, affinity: 4 | 6) => DNSInterceptorRecord` - Custom pick function. Default: `RoundRobin`.
|
||||
- The function should return a single record from the records array.
|
||||
- By default a simplified version of Round Robin is used.
|
||||
- The `records` property can be mutated to store the state of the balancing algorithm.
|
||||
|
||||
> The `Dispatcher#options` also gets extended with the options `dns.affinity`, `dns.dualStack`, `dns.lookup` and `dns.pick` which can be used to configure the interceptor at a request-per-request basis.
|
||||
|
||||
|
||||
**DNSInterceptorRecord**
|
||||
It represents a DNS record.
|
||||
- `family` - (`number`) The IP family of the address. It can be either `4` or `6`.
|
||||
- `address` - (`string`) The IP address.
|
||||
|
||||
**DNSInterceptorOriginRecords**
|
||||
It represents a map of DNS IP addresses records for a single origin.
|
||||
- `4.ips` - (`DNSInterceptorRecord[] | null`) The IPv4 addresses.
|
||||
- `6.ips` - (`DNSInterceptorRecord[] | null`) The IPv6 addresses.
|
||||
|
||||
**Example - Basic DNS Interceptor**
|
||||
|
||||
```js
|
||||
const { Client, interceptors } = require("undici");
|
||||
const { dns } = interceptors;
|
||||
|
||||
const client = new Agent().compose([
|
||||
dns({ ...opts })
|
||||
])
|
||||
|
||||
const response = await client.request({
|
||||
origin: `http://localhost:3030`,
|
||||
...requestOpts
|
||||
})
|
||||
```
|
||||
|
||||
##### `Response Error Interceptor`
|
||||
|
||||
**Introduction**
|
||||
|
||||
The Response Error Interceptor is designed to handle HTTP response errors efficiently. It intercepts responses and throws detailed errors for responses with status codes indicating failure (4xx, 5xx). This interceptor enhances error handling by providing structured error information, including response headers, data, and status codes.
|
||||
|
||||
**ResponseError Class**
|
||||
|
||||
The `ResponseError` class extends the `UndiciError` class and encapsulates detailed error information. It captures the response status code, headers, and data, providing a structured way to handle errors.
|
||||
|
||||
**Definition**
|
||||
|
||||
```js
|
||||
class ResponseError extends UndiciError {
|
||||
constructor (message, code, { headers, data }) {
|
||||
super(message);
|
||||
this.name = 'ResponseError';
|
||||
this.message = message || 'Response error';
|
||||
this.code = 'UND_ERR_RESPONSE';
|
||||
this.statusCode = code;
|
||||
this.data = data;
|
||||
this.headers = headers;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Interceptor Handler**
|
||||
|
||||
The interceptor's handler class extends `DecoratorHandler` and overrides methods to capture response details and handle errors based on the response status code.
|
||||
|
||||
**Methods**
|
||||
|
||||
- **onConnect**: Initializes response properties.
|
||||
- **onHeaders**: Captures headers and status code. Decodes body if content type is `application/json` or `text/plain`.
|
||||
- **onData**: Appends chunks to the body if status code indicates an error.
|
||||
- **onComplete**: Finalizes error handling, constructs a `ResponseError`, and invokes the `onError` method.
|
||||
- **onError**: Propagates errors to the handler.
|
||||
|
||||
**Definition**
|
||||
|
||||
```js
|
||||
class Handler extends DecoratorHandler {
|
||||
// Private properties
|
||||
#handler;
|
||||
#statusCode;
|
||||
#contentType;
|
||||
#decoder;
|
||||
#headers;
|
||||
#body;
|
||||
|
||||
constructor (opts, { handler }) {
|
||||
super(handler);
|
||||
this.#handler = handler;
|
||||
}
|
||||
|
||||
onConnect (abort) {
|
||||
this.#statusCode = 0;
|
||||
this.#contentType = null;
|
||||
this.#decoder = null;
|
||||
this.#headers = null;
|
||||
this.#body = '';
|
||||
return this.#handler.onConnect(abort);
|
||||
}
|
||||
|
||||
onHeaders (statusCode, rawHeaders, resume, statusMessage, headers = parseHeaders(rawHeaders)) {
|
||||
this.#statusCode = statusCode;
|
||||
this.#headers = headers;
|
||||
this.#contentType = headers['content-type'];
|
||||
|
||||
if (this.#statusCode < 400) {
|
||||
return this.#handler.onHeaders(statusCode, rawHeaders, resume, statusMessage, headers);
|
||||
}
|
||||
|
||||
if (this.#contentType === 'application/json' || this.#contentType === 'text/plain') {
|
||||
this.#decoder = new TextDecoder('utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
onData (chunk) {
|
||||
if (this.#statusCode < 400) {
|
||||
return this.#handler.onData(chunk);
|
||||
}
|
||||
this.#body += this.#decoder?.decode(chunk, { stream: true }) ?? '';
|
||||
}
|
||||
|
||||
onComplete (rawTrailers) {
|
||||
if (this.#statusCode >= 400) {
|
||||
this.#body += this.#decoder?.decode(undefined, { stream: false }) ?? '';
|
||||
if (this.#contentType === 'application/json') {
|
||||
try {
|
||||
this.#body = JSON.parse(this.#body);
|
||||
} catch {
|
||||
// Do nothing...
|
||||
}
|
||||
}
|
||||
|
||||
let err;
|
||||
const stackTraceLimit = Error.stackTraceLimit;
|
||||
Error.stackTraceLimit = 0;
|
||||
try {
|
||||
err = new ResponseError('Response Error', this.#statusCode, this.#headers, this.#body);
|
||||
} finally {
|
||||
Error.stackTraceLimit = stackTraceLimit;
|
||||
}
|
||||
|
||||
this.#handler.onError(err);
|
||||
} else {
|
||||
this.#handler.onComplete(rawTrailers);
|
||||
}
|
||||
}
|
||||
|
||||
onError (err) {
|
||||
this.#handler.onError(err);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (dispatch) => (opts, handler) => opts.throwOnError
|
||||
? dispatch(opts, new Handler(opts, { handler }))
|
||||
: dispatch(opts, handler);
|
||||
```
|
||||
|
||||
**Tests**
|
||||
|
||||
Unit tests ensure the interceptor functions correctly, handling both error and non-error responses appropriately.
|
||||
|
||||
**Example Tests**
|
||||
|
||||
- **No Error if `throwOnError` is False**:
|
||||
|
||||
```js
|
||||
test('should not error if request is not meant to throw error', async (t) => {
|
||||
const opts = { throwOnError: false };
|
||||
const handler = { onError: () => {}, onData: () => {}, onComplete: () => {} };
|
||||
const interceptor = createResponseErrorInterceptor((opts, handler) => handler.onComplete());
|
||||
assert.doesNotThrow(() => interceptor(opts, handler));
|
||||
});
|
||||
```
|
||||
|
||||
- **Error if Status Code is in Specified Error Codes**:
|
||||
|
||||
```js
|
||||
test('should error if request status code is in the specified error codes', async (t) => {
|
||||
const opts = { throwOnError: true, statusCodes: [500] };
|
||||
const response = { statusCode: 500 };
|
||||
let capturedError;
|
||||
const handler = {
|
||||
onError: (err) => { capturedError = err; },
|
||||
onData: () => {},
|
||||
onComplete: () => {}
|
||||
};
|
||||
|
||||
const interceptor = createResponseErrorInterceptor((opts, handler) => {
|
||||
if (opts.throwOnError && opts.statusCodes.includes(response.statusCode)) {
|
||||
handler.onError(new Error('Response Error'));
|
||||
} else {
|
||||
handler.onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
interceptor({ ...opts, response }, handler);
|
||||
|
||||
await new Promise(resolve => setImmediate(resolve));
|
||||
|
||||
assert(capturedError, 'Expected error to be captured but it was not.');
|
||||
assert.strictEqual(capturedError.message, 'Response Error');
|
||||
assert.strictEqual(response.statusCode, 500);
|
||||
});
|
||||
```
|
||||
|
||||
- **No Error if Status Code is Not in Specified Error Codes**:
|
||||
|
||||
```js
|
||||
test('should not error if request status code is not in the specified error codes', async (t) => {
|
||||
const opts = { throwOnError: true, statusCodes: [500] };
|
||||
const response = { statusCode: 404 };
|
||||
const handler = {
|
||||
onError: () => {},
|
||||
onData: () => {},
|
||||
onComplete: () => {}
|
||||
};
|
||||
|
||||
const interceptor = createResponseErrorInterceptor((opts, handler) => {
|
||||
if (opts.throwOnError && opts.statusCodes.includes(response.statusCode)) {
|
||||
handler.onError(new Error('Response Error'));
|
||||
} else {
|
||||
handler.onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
assert.doesNotThrow(() => interceptor({ ...opts, response }, handler));
|
||||
});
|
||||
```
|
||||
|
||||
**Conclusion**
|
||||
|
||||
The Response Error Interceptor provides a robust mechanism for handling HTTP response errors by capturing detailed error information and propagating it through a structured `ResponseError` class. This enhancement improves error handling and debugging capabilities in applications using the interceptor.
|
||||
|
||||
## Instance Events
|
||||
|
||||
### Event: `'connect'`
|
||||
@@ -833,6 +1251,12 @@ Parameters:
|
||||
* **targets** `Array<Dispatcher>`
|
||||
* **error** `Error`
|
||||
|
||||
Emitted when the dispatcher has been disconnected from the origin.
|
||||
|
||||
> **Note**: For HTTP/2, this event is also emitted when the dispatcher has received the [GOAWAY Frame](https://webconcepts.info/concepts/http2-frame-type/0x7) with an Error with the message `HTTP/2: "GOAWAY" frame received` and the code `UND_ERR_INFO`.
|
||||
> Due to nature of the protocol of using binary frames, it is possible that requests gets hanging as a frame can be received between the `HEADER` and `DATA` frames.
|
||||
> It is recommended to handle this event and close the dispatcher to create a new HTTP/2 session.
|
||||
|
||||
### Event: `'connectionError'`
|
||||
|
||||
Parameters:
|
||||
@@ -854,10 +1278,12 @@ Emitted when dispatcher is no longer busy.
|
||||
|
||||
## Parameter: `UndiciHeaders`
|
||||
|
||||
* `Record<string, string | string[] | undefined> | string[] | null`
|
||||
|
||||
Header arguments such as `options.headers` in [`Client.dispatch`](Client.md#clientdispatchoptions-handlers) can be specified in two forms; either as an object specified by the `Record<string, string | string[] | undefined>` (`IncomingHttpHeaders`) type, or an array of strings. An array representation of a header list must have an even length or an `InvalidArgumentError` will be thrown.
|
||||
* `Record<string, string | string[] | undefined> | string[] | Iterable<[string, string | string[] | undefined]> | null`
|
||||
|
||||
Header arguments such as `options.headers` in [`Client.dispatch`](Client.md#clientdispatchoptions-handlers) can be specified in three forms:
|
||||
* As an object specified by the `Record<string, string | string[] | undefined>` (`IncomingHttpHeaders`) type.
|
||||
* As an array of strings. An array representation of a header list must have an even length, or an `InvalidArgumentError` will be thrown.
|
||||
* As an iterable that can encompass `Headers`, `Map`, or a custom iterator returning key-value pairs.
|
||||
Keys are lowercase and values are not modified.
|
||||
|
||||
Response headers will derive a `host` from the `url` of the [Client](Client.md#class-client) instance if no `host` header was previously specified.
|
||||
@@ -885,3 +1311,37 @@ Response headers will derive a `host` from the `url` of the [Client](Client.md#c
|
||||
'accept', '*/*'
|
||||
]
|
||||
```
|
||||
|
||||
### Example 3 - Iterable
|
||||
|
||||
```js
|
||||
new Headers({
|
||||
'content-length': '123',
|
||||
'content-type': 'text/plain',
|
||||
connection: 'keep-alive',
|
||||
host: 'mysite.com',
|
||||
accept: '*/*'
|
||||
})
|
||||
```
|
||||
or
|
||||
```js
|
||||
new Map([
|
||||
['content-length', '123'],
|
||||
['content-type', 'text/plain'],
|
||||
['connection', 'keep-alive'],
|
||||
['host', 'mysite.com'],
|
||||
['accept', '*/*']
|
||||
])
|
||||
```
|
||||
or
|
||||
```js
|
||||
{
|
||||
*[Symbol.iterator] () {
|
||||
yield ['content-length', '123']
|
||||
yield ['content-type', 'text/plain']
|
||||
yield ['connection', 'keep-alive']
|
||||
yield ['host', 'mysite.com']
|
||||
yield ['accept', '*/*']
|
||||
}
|
||||
}
|
||||
```
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
# Class: EnvHttpProxyAgent
|
||||
|
||||
Stability: Experimental.
|
||||
|
||||
Extends: `undici.Dispatcher`
|
||||
|
||||
EnvHttpProxyAgent automatically reads the proxy configuration from the environment variables `http_proxy`, `https_proxy`, and `no_proxy` and sets up the proxy agents accordingly. When `http_proxy` and `https_proxy` are set, `http_proxy` is used for HTTP requests and `https_proxy` is used for HTTPS requests. If only `http_proxy` is set, `http_proxy` is used for both HTTP and HTTPS requests. If only `https_proxy` is set, it is only used for HTTPS requests.
|
||||
|
||||
`no_proxy` is a comma or space-separated list of hostnames that should not be proxied. The list may contain leading wildcard characters (`*`). If `no_proxy` is set, the EnvHttpProxyAgent will bypass the proxy for requests to hosts that match the list. If `no_proxy` is set to `"*"`, the EnvHttpProxyAgent will bypass the proxy for all requests.
|
||||
|
||||
Uppercase environment variables are also supported: `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`. However, if both the lowercase and uppercase environment variables are set, the uppercase environment variables will be ignored.
|
||||
|
||||
## `new EnvHttpProxyAgent([options])`
|
||||
|
||||
Arguments:
|
||||
|
||||
* **options** `EnvHttpProxyAgentOptions` (optional) - extends the `Agent` options.
|
||||
|
||||
Returns: `EnvHttpProxyAgent`
|
||||
|
||||
### Parameter: `EnvHttpProxyAgentOptions`
|
||||
|
||||
Extends: [`AgentOptions`](Agent.md#parameter-agentoptions)
|
||||
|
||||
* **httpProxy** `string` (optional) - When set, it will override the `HTTP_PROXY` environment variable.
|
||||
* **httpsProxy** `string` (optional) - When set, it will override the `HTTPS_PROXY` environment variable.
|
||||
* **noProxy** `string` (optional) - When set, it will override the `NO_PROXY` environment variable.
|
||||
|
||||
Examples:
|
||||
|
||||
```js
|
||||
import { EnvHttpProxyAgent } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
// or
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent({ httpProxy: 'my.proxy.server:8080', httpsProxy: 'my.proxy.server:8443', noProxy: 'localhost' })
|
||||
```
|
||||
|
||||
#### Example - EnvHttpProxyAgent instantiation
|
||||
|
||||
This will instantiate the EnvHttpProxyAgent. It will not do anything until registered as the agent to use with requests.
|
||||
|
||||
```js
|
||||
import { EnvHttpProxyAgent } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
```
|
||||
|
||||
#### Example - Basic Proxy Fetch with global agent dispatcher
|
||||
|
||||
```js
|
||||
import { setGlobalDispatcher, fetch, EnvHttpProxyAgent } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
setGlobalDispatcher(envHttpProxyAgent)
|
||||
|
||||
const { status, json } = await fetch('http://localhost:3000/foo')
|
||||
|
||||
console.log('response received', status) // response received 200
|
||||
|
||||
const data = await json() // data { foo: "bar" }
|
||||
```
|
||||
|
||||
#### Example - Basic Proxy Request with global agent dispatcher
|
||||
|
||||
```js
|
||||
import { setGlobalDispatcher, request, EnvHttpProxyAgent } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
setGlobalDispatcher(envHttpProxyAgent)
|
||||
|
||||
const { statusCode, body } = await request('http://localhost:3000/foo')
|
||||
|
||||
console.log('response received', statusCode) // response received 200
|
||||
|
||||
for await (const data of body) {
|
||||
console.log('data', data.toString('utf8')) // data foo
|
||||
}
|
||||
```
|
||||
|
||||
#### Example - Basic Proxy Request with local agent dispatcher
|
||||
|
||||
```js
|
||||
import { EnvHttpProxyAgent, request } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
|
||||
const {
|
||||
statusCode,
|
||||
body
|
||||
} = await request('http://localhost:3000/foo', { dispatcher: envHttpProxyAgent })
|
||||
|
||||
console.log('response received', statusCode) // response received 200
|
||||
|
||||
for await (const data of body) {
|
||||
console.log('data', data.toString('utf8')) // data foo
|
||||
}
|
||||
```
|
||||
|
||||
#### Example - Basic Proxy Fetch with local agent dispatcher
|
||||
|
||||
```js
|
||||
import { EnvHttpProxyAgent, fetch } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
|
||||
const {
|
||||
status,
|
||||
json
|
||||
} = await fetch('http://localhost:3000/foo', { dispatcher: envHttpProxyAgent })
|
||||
|
||||
console.log('response received', status) // response received 200
|
||||
|
||||
const data = await json() // data { foo: "bar" }
|
||||
```
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `EnvHttpProxyAgent.close([callback])`
|
||||
|
||||
Implements [`Dispatcher.close([callback])`](Dispatcher.md#dispatcherclosecallback-promise).
|
||||
|
||||
### `EnvHttpProxyAgent.destroy([error, callback])`
|
||||
|
||||
Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
|
||||
|
||||
### `EnvHttpProxyAgent.dispatch(options, handler: AgentDispatchOptions)`
|
||||
|
||||
Implements [`Dispatcher.dispatch(options, handler)`](Dispatcher.md#dispatcherdispatchoptions-handler).
|
||||
|
||||
#### Parameter: `AgentDispatchOptions`
|
||||
|
||||
Extends: [`DispatchOptions`](Dispatcher.md#parameter-dispatchoptions)
|
||||
|
||||
* **origin** `string | URL`
|
||||
* **maxRedirections** `Integer`.
|
||||
|
||||
Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
|
||||
|
||||
### `EnvHttpProxyAgent.connect(options[, callback])`
|
||||
|
||||
See [`Dispatcher.connect(options[, callback])`](Dispatcher.md#dispatcherconnectoptions-callback).
|
||||
|
||||
### `EnvHttpProxyAgent.dispatch(options, handler)`
|
||||
|
||||
Implements [`Dispatcher.dispatch(options, handler)`](Dispatcher.md#dispatcherdispatchoptions-handler).
|
||||
|
||||
### `EnvHttpProxyAgent.pipeline(options, handler)`
|
||||
|
||||
See [`Dispatcher.pipeline(options, handler)`](Dispatcher.md#dispatcherpipelineoptions-handler).
|
||||
|
||||
### `EnvHttpProxyAgent.request(options[, callback])`
|
||||
|
||||
See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
|
||||
|
||||
### `EnvHttpProxyAgent.stream(options, factory[, callback])`
|
||||
|
||||
See [`Dispatcher.stream(options, factory[, callback])`](Dispatcher.md#dispatcherstreamoptions-factory-callback).
|
||||
|
||||
### `EnvHttpProxyAgent.upgrade(options[, callback])`
|
||||
|
||||
See [`Dispatcher.upgrade(options[, callback])`](Dispatcher.md#dispatcherupgradeoptions-callback).
|
||||
Generated
Vendored
+2
@@ -26,6 +26,8 @@ import { errors } from 'undici'
|
||||
| `ResponseContentLengthMismatchError` | `UND_ERR_RES_CONTENT_LENGTH_MISMATCH` | response body does not match content-length header |
|
||||
| `InformationalError` | `UND_ERR_INFO` | expected error with reason |
|
||||
| `ResponseExceededMaxSizeError` | `UND_ERR_RES_EXCEEDED_MAX_SIZE` | response body exceed the max size allowed |
|
||||
| `SecureProxyConnectionError` | `UND_ERR_PRX_TLS` | tls connection to a proxy failed |
|
||||
| `MessageSizeExceededError` | `UND_ERR_WS_MESSAGE_SIZE_EXCEEDED` | WebSocket decompressed message exceeded the maximum allowed size |
|
||||
|
||||
### `SocketError`
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
# EventSource
|
||||
|
||||
> ⚠️ Warning: the EventSource API is experimental.
|
||||
|
||||
Undici exposes a WHATWG spec-compliant implementation of [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)
|
||||
for [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events).
|
||||
|
||||
## Instantiating EventSource
|
||||
|
||||
Undici exports a EventSource class. You can instantiate the EventSource as
|
||||
follows:
|
||||
|
||||
```mjs
|
||||
import { EventSource } from 'undici'
|
||||
|
||||
const eventSource = new EventSource('http://localhost:3000')
|
||||
eventSource.onmessage = (event) => {
|
||||
console.log(event.data)
|
||||
}
|
||||
```
|
||||
|
||||
## Using a custom Dispatcher
|
||||
|
||||
undici allows you to set your own Dispatcher in the EventSource constructor.
|
||||
|
||||
An example which allows you to modify the request headers is:
|
||||
|
||||
```mjs
|
||||
import { EventSource, Agent } from 'undici'
|
||||
|
||||
class CustomHeaderAgent extends Agent {
|
||||
dispatch (opts) {
|
||||
opts.headers['x-custom-header'] = 'hello world'
|
||||
return super.dispatch(...arguments)
|
||||
}
|
||||
}
|
||||
|
||||
const eventSource = new EventSource('http://localhost:3000', {
|
||||
dispatcher: new CustomHeaderAgent()
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
More information about the EventSource API can be found on
|
||||
[MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# Fetch
|
||||
|
||||
Undici exposes a fetch() method starts the process of fetching a resource from the network.
|
||||
|
||||
Documentation and examples can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/fetch).
|
||||
|
||||
## FormData
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/FormData).
|
||||
|
||||
If any parameters are passed to the FormData constructor other than `undefined`, an error will be thrown. Other parameters are ignored.
|
||||
|
||||
## Response
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Response)
|
||||
|
||||
## Request
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Request)
|
||||
|
||||
## Header
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Headers)
|
||||
|
||||
# Body Mixins
|
||||
|
||||
`Response` and `Request` body inherit body mixin methods. These methods include:
|
||||
|
||||
- [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
|
||||
- [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
|
||||
- [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
|
||||
- [`.formData()`](https://fetch.spec.whatwg.org/#dom-body-formdata)
|
||||
- [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
|
||||
- [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
|
||||
|
||||
There is an ongoing discussion regarding `.formData()` and its usefulness and performance in server environments. It is recommended to use a dedicated library for parsing `multipart/form-data` bodies, such as [Busboy](https://www.npmjs.com/package/busboy) or [@fastify/busboy](https://www.npmjs.com/package/@fastify/busboy).
|
||||
|
||||
These libraries can be interfaced with fetch with the following example code:
|
||||
|
||||
```mjs
|
||||
import { Busboy } from '@fastify/busboy'
|
||||
import { Readable } from 'node:stream'
|
||||
|
||||
const response = await fetch('...')
|
||||
const busboy = new Busboy({
|
||||
headers: {
|
||||
'content-type': response.headers.get('content-type')
|
||||
}
|
||||
})
|
||||
|
||||
Readable.fromWeb(response.body).pipe(busboy)
|
||||
```
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user