@4cloudguru/pipeline-task-ado 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +27 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +27 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ Modules move here one family at a time, smallest first, so the migration pattern
|
|
|
42
42
|
is proven on something harmless before anything security-bearing moves:
|
|
43
43
|
|
|
44
44
|
- [x] `getBoolInputDefaultTrue` — fail-closed boolean input
|
|
45
|
-
- [
|
|
45
|
+
- [x] `http-client` — proxy-aware, HTTPS-pinned client wiring over `-core`
|
|
46
46
|
- [ ] `registry-version-resolver`
|
|
47
47
|
- [ ] `https-client`
|
|
48
48
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var task_js = require('azure-pipelines-task-lib/task.js');
|
|
4
|
+
var undici = require('undici');
|
|
5
|
+
var pipelineTaskCore = require('@4cloudguru/pipeline-task-core');
|
|
4
6
|
|
|
5
7
|
// src/input/bool-input.ts
|
|
6
8
|
function getBoolInputDefaultTrue(name) {
|
|
7
9
|
const raw = task_js.getInput(name, false);
|
|
8
10
|
return raw === void 0 || raw.trim() === "" ? true : raw.trim().toLowerCase() !== "false";
|
|
9
11
|
}
|
|
12
|
+
function buildAdoFetchOptions() {
|
|
13
|
+
const resolved = pipelineTaskCore.resolveProxy(task_js.getHttpProxyConfiguration());
|
|
14
|
+
if (!resolved) return {};
|
|
15
|
+
for (const secret of resolved.secrets) {
|
|
16
|
+
task_js.setSecret(secret);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
// @ts-expect-error Node's fetch accepts an undici dispatcher at runtime.
|
|
20
|
+
dispatcher: new undici.ProxyAgent(resolved.proxyUrl)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function createAdoHttpClient(options) {
|
|
24
|
+
return pipelineTaskCore.createHttpClient({
|
|
25
|
+
// Re-evaluated per attempt, so a proxy change between retries is picked up.
|
|
26
|
+
fetchOptions: buildAdoFetchOptions,
|
|
27
|
+
// Passed by reference rather than wrapped: a forwarding lambda would be an
|
|
28
|
+
// extra function no test can meaningfully reach, and task-lib's debug does
|
|
29
|
+
// not close over `this`.
|
|
30
|
+
debug: task_js.debug,
|
|
31
|
+
messages: options.messages,
|
|
32
|
+
...options.redirectPolicy ? { redirectPolicy: options.redirectPolicy } : {}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
10
35
|
|
|
36
|
+
exports.buildAdoFetchOptions = buildAdoFetchOptions;
|
|
37
|
+
exports.createAdoHttpClient = createAdoHttpClient;
|
|
11
38
|
exports.getBoolInputDefaultTrue = getBoolInputDefaultTrue;
|
|
12
39
|
//# sourceMappingURL=index.cjs.map
|
|
13
40
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/input/bool-input.ts"],"names":["getInput"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/input/bool-input.ts","../src/http/ado-http.ts"],"names":["getInput","resolveProxy","getHttpProxyConfiguration","setSecret","ProxyAgent","createHttpClient","debug"],"mappings":";;;;;;;AAYO,SAAS,wBAAwB,IAAA,EAAuB;AAC7D,EAAA,MAAM,GAAA,GAAMA,gBAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AAChC,EAAA,OAAO,GAAA,KAAQ,MAAA,IAAa,GAAA,CAAI,IAAA,EAAK,KAAM,EAAA,GAAK,IAAA,GAAO,GAAA,CAAI,IAAA,EAAK,CAAE,WAAA,EAAY,KAAM,OAAA;AACtF;ACOO,SAAS,oBAAA,GAAoC;AAClD,EAAA,MAAM,QAAA,GAAWC,6BAAA,CAAaC,iCAAA,EAA2B,CAAA;AACzD,EAAA,IAAI,CAAC,QAAA,EAAU,OAAO,EAAC;AAEvB,EAAA,KAAA,MAAW,MAAA,IAAU,SAAS,OAAA,EAAS;AACrC,IAAAC,iBAAA,CAAU,MAAM,CAAA;AAAA,EAClB;AAEA,EAAA,OAAO;AAAA;AAAA,IAEL,UAAA,EAAY,IAAIC,iBAAA,CAAW,QAAA,CAAS,QAAQ;AAAA,GAC9C;AACF;AAmBO,SAAS,oBAAoB,OAAA,EAA2C;AAC7E,EAAA,OAAOC,iCAAA,CAAiB;AAAA;AAAA,IAEtB,YAAA,EAAc,oBAAA;AAAA;AAAA;AAAA;AAAA,WAIdC,aAAA;AAAA,IACA,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,GAAI,QAAQ,cAAA,GAAiB,EAAE,gBAAgB,OAAA,CAAQ,cAAA,KAAmB;AAAC,GAC5E,CAAA;AACH","file":"index.cjs","sourcesContent":["// The `.js` extension is load-bearing: azure-pipelines-task-lib is CommonJS with\n// no `exports` map, so under ESM resolution the extensionless subpath does not\n// resolve at all (ERR_MODULE_NOT_FOUND). CJS is unaffected either way.\nimport { getInput } from 'azure-pipelines-task-lib/task.js'\n\n/**\n * Reads a boolean input whose intended default is TRUE (fail-closed). It reads the\n * raw input rather than getBoolInput(name, false) so the default still holds on an\n * agent that does not materialize task.json defaultValues into the input env var\n * (where getBoolInput would silently return false): unset/empty -> true; any value\n * other than \"false\" (case-insensitive) -> true.\n */\nexport function getBoolInputDefaultTrue(name: string): boolean {\n const raw = getInput(name, false)\n return raw === undefined || raw.trim() === '' ? true : raw.trim().toLowerCase() !== 'false'\n}\n","import { debug, getHttpProxyConfiguration, setSecret } from 'azure-pipelines-task-lib/task.js'\nimport { ProxyAgent } from 'undici'\nimport {\n createHttpClient,\n resolveProxy,\n type HttpClient,\n type HttpMessages,\n type RedirectPolicy,\n} from '@4cloudguru/pipeline-task-core'\n\n/**\n * Per-attempt fetch init carrying the agent's proxy.\n *\n * The ordering is the security property, not an implementation detail: the\n * agent's masker matches registered literals rather than derivations of them,\n * and resolveProxy returns every spelling of the credential it produced —\n * including the percent-encoded form the dispatcher URL actually embeds, and\n * any userinfo already inside Agent.ProxyUrl. All of them must be registered\n * BEFORE proxyUrl is handed to a dispatcher or interpolated into a message.\n * resolveProxy cannot do it itself; the package it lives in does not import\n * the task lib. That obligation is the reason this function exists here.\n */\nexport function buildAdoFetchOptions(): RequestInit {\n const resolved = resolveProxy(getHttpProxyConfiguration())\n if (!resolved) return {}\n\n for (const secret of resolved.secrets) {\n setSecret(secret)\n }\n\n return {\n // @ts-expect-error Node's fetch accepts an undici dispatcher at runtime.\n dispatcher: new ProxyAgent(resolved.proxyUrl),\n }\n}\n\nexport interface AdoHttpClientOptions {\n /**\n * Failure text. Kept a parameter because it is the one genuinely per-task\n * part: the strings come from each task's own resource file via tasks.loc,\n * and \"registry request failed\" is wrong on a releases.hashicorp.com fetch.\n */\n messages: HttpMessages\n /**\n * Defaults to the core client's own same-host rule. Pass\n * anyRedirectPolicy(sameHostOnly, githubAssetRedirects) only for callers that\n * really do fetch GitHub release assets — enabling it estate-wide widens the\n * redirect surface for callers that never need it.\n */\n redirectPolicy?: RedirectPolicy\n}\n\n/** An HTTPS-pinned client wired to this agent's proxy, debug channel and text. */\nexport function createAdoHttpClient(options: AdoHttpClientOptions): HttpClient {\n return createHttpClient({\n // Re-evaluated per attempt, so a proxy change between retries is picked up.\n fetchOptions: buildAdoFetchOptions,\n // Passed by reference rather than wrapped: a forwarding lambda would be an\n // extra function no test can meaningfully reach, and task-lib's debug does\n // not close over `this`.\n debug,\n messages: options.messages,\n ...(options.redirectPolicy ? { redirectPolicy: options.redirectPolicy } : {}),\n })\n}\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { HttpMessages, RedirectPolicy, HttpClient } from '@4cloudguru/pipeline-task-core';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Reads a boolean input whose intended default is TRUE (fail-closed). It reads the
|
|
3
5
|
* raw input rather than getBoolInput(name, false) so the default still holds on an
|
|
@@ -7,4 +9,35 @@
|
|
|
7
9
|
*/
|
|
8
10
|
declare function getBoolInputDefaultTrue(name: string): boolean;
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Per-attempt fetch init carrying the agent's proxy.
|
|
14
|
+
*
|
|
15
|
+
* The ordering is the security property, not an implementation detail: the
|
|
16
|
+
* agent's masker matches registered literals rather than derivations of them,
|
|
17
|
+
* and resolveProxy returns every spelling of the credential it produced —
|
|
18
|
+
* including the percent-encoded form the dispatcher URL actually embeds, and
|
|
19
|
+
* any userinfo already inside Agent.ProxyUrl. All of them must be registered
|
|
20
|
+
* BEFORE proxyUrl is handed to a dispatcher or interpolated into a message.
|
|
21
|
+
* resolveProxy cannot do it itself; the package it lives in does not import
|
|
22
|
+
* the task lib. That obligation is the reason this function exists here.
|
|
23
|
+
*/
|
|
24
|
+
declare function buildAdoFetchOptions(): RequestInit;
|
|
25
|
+
interface AdoHttpClientOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Failure text. Kept a parameter because it is the one genuinely per-task
|
|
28
|
+
* part: the strings come from each task's own resource file via tasks.loc,
|
|
29
|
+
* and "registry request failed" is wrong on a releases.hashicorp.com fetch.
|
|
30
|
+
*/
|
|
31
|
+
messages: HttpMessages;
|
|
32
|
+
/**
|
|
33
|
+
* Defaults to the core client's own same-host rule. Pass
|
|
34
|
+
* anyRedirectPolicy(sameHostOnly, githubAssetRedirects) only for callers that
|
|
35
|
+
* really do fetch GitHub release assets — enabling it estate-wide widens the
|
|
36
|
+
* redirect surface for callers that never need it.
|
|
37
|
+
*/
|
|
38
|
+
redirectPolicy?: RedirectPolicy;
|
|
39
|
+
}
|
|
40
|
+
/** An HTTPS-pinned client wired to this agent's proxy, debug channel and text. */
|
|
41
|
+
declare function createAdoHttpClient(options: AdoHttpClientOptions): HttpClient;
|
|
42
|
+
|
|
43
|
+
export { type AdoHttpClientOptions, buildAdoFetchOptions, createAdoHttpClient, getBoolInputDefaultTrue };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { HttpMessages, RedirectPolicy, HttpClient } from '@4cloudguru/pipeline-task-core';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Reads a boolean input whose intended default is TRUE (fail-closed). It reads the
|
|
3
5
|
* raw input rather than getBoolInput(name, false) so the default still holds on an
|
|
@@ -7,4 +9,35 @@
|
|
|
7
9
|
*/
|
|
8
10
|
declare function getBoolInputDefaultTrue(name: string): boolean;
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Per-attempt fetch init carrying the agent's proxy.
|
|
14
|
+
*
|
|
15
|
+
* The ordering is the security property, not an implementation detail: the
|
|
16
|
+
* agent's masker matches registered literals rather than derivations of them,
|
|
17
|
+
* and resolveProxy returns every spelling of the credential it produced —
|
|
18
|
+
* including the percent-encoded form the dispatcher URL actually embeds, and
|
|
19
|
+
* any userinfo already inside Agent.ProxyUrl. All of them must be registered
|
|
20
|
+
* BEFORE proxyUrl is handed to a dispatcher or interpolated into a message.
|
|
21
|
+
* resolveProxy cannot do it itself; the package it lives in does not import
|
|
22
|
+
* the task lib. That obligation is the reason this function exists here.
|
|
23
|
+
*/
|
|
24
|
+
declare function buildAdoFetchOptions(): RequestInit;
|
|
25
|
+
interface AdoHttpClientOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Failure text. Kept a parameter because it is the one genuinely per-task
|
|
28
|
+
* part: the strings come from each task's own resource file via tasks.loc,
|
|
29
|
+
* and "registry request failed" is wrong on a releases.hashicorp.com fetch.
|
|
30
|
+
*/
|
|
31
|
+
messages: HttpMessages;
|
|
32
|
+
/**
|
|
33
|
+
* Defaults to the core client's own same-host rule. Pass
|
|
34
|
+
* anyRedirectPolicy(sameHostOnly, githubAssetRedirects) only for callers that
|
|
35
|
+
* really do fetch GitHub release assets — enabling it estate-wide widens the
|
|
36
|
+
* redirect surface for callers that never need it.
|
|
37
|
+
*/
|
|
38
|
+
redirectPolicy?: RedirectPolicy;
|
|
39
|
+
}
|
|
40
|
+
/** An HTTPS-pinned client wired to this agent's proxy, debug channel and text. */
|
|
41
|
+
declare function createAdoHttpClient(options: AdoHttpClientOptions): HttpClient;
|
|
42
|
+
|
|
43
|
+
export { type AdoHttpClientOptions, buildAdoFetchOptions, createAdoHttpClient, getBoolInputDefaultTrue };
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
|
-
import { getInput } from 'azure-pipelines-task-lib/task.js';
|
|
1
|
+
import { getInput, getHttpProxyConfiguration, setSecret, debug } from 'azure-pipelines-task-lib/task.js';
|
|
2
|
+
import { ProxyAgent } from 'undici';
|
|
3
|
+
import { resolveProxy, createHttpClient } from '@4cloudguru/pipeline-task-core';
|
|
2
4
|
|
|
3
5
|
// src/input/bool-input.ts
|
|
4
6
|
function getBoolInputDefaultTrue(name) {
|
|
5
7
|
const raw = getInput(name, false);
|
|
6
8
|
return raw === void 0 || raw.trim() === "" ? true : raw.trim().toLowerCase() !== "false";
|
|
7
9
|
}
|
|
10
|
+
function buildAdoFetchOptions() {
|
|
11
|
+
const resolved = resolveProxy(getHttpProxyConfiguration());
|
|
12
|
+
if (!resolved) return {};
|
|
13
|
+
for (const secret of resolved.secrets) {
|
|
14
|
+
setSecret(secret);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
// @ts-expect-error Node's fetch accepts an undici dispatcher at runtime.
|
|
18
|
+
dispatcher: new ProxyAgent(resolved.proxyUrl)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function createAdoHttpClient(options) {
|
|
22
|
+
return createHttpClient({
|
|
23
|
+
// Re-evaluated per attempt, so a proxy change between retries is picked up.
|
|
24
|
+
fetchOptions: buildAdoFetchOptions,
|
|
25
|
+
// Passed by reference rather than wrapped: a forwarding lambda would be an
|
|
26
|
+
// extra function no test can meaningfully reach, and task-lib's debug does
|
|
27
|
+
// not close over `this`.
|
|
28
|
+
debug,
|
|
29
|
+
messages: options.messages,
|
|
30
|
+
...options.redirectPolicy ? { redirectPolicy: options.redirectPolicy } : {}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
8
33
|
|
|
9
|
-
export { getBoolInputDefaultTrue };
|
|
34
|
+
export { buildAdoFetchOptions, createAdoHttpClient, getBoolInputDefaultTrue };
|
|
10
35
|
//# sourceMappingURL=index.js.map
|
|
11
36
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/input/bool-input.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/input/bool-input.ts","../src/http/ado-http.ts"],"names":[],"mappings":";;;;;AAYO,SAAS,wBAAwB,IAAA,EAAuB;AAC7D,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AAChC,EAAA,OAAO,GAAA,KAAQ,MAAA,IAAa,GAAA,CAAI,IAAA,EAAK,KAAM,EAAA,GAAK,IAAA,GAAO,GAAA,CAAI,IAAA,EAAK,CAAE,WAAA,EAAY,KAAM,OAAA;AACtF;ACOO,SAAS,oBAAA,GAAoC;AAClD,EAAA,MAAM,QAAA,GAAW,YAAA,CAAa,yBAAA,EAA2B,CAAA;AACzD,EAAA,IAAI,CAAC,QAAA,EAAU,OAAO,EAAC;AAEvB,EAAA,KAAA,MAAW,MAAA,IAAU,SAAS,OAAA,EAAS;AACrC,IAAA,SAAA,CAAU,MAAM,CAAA;AAAA,EAClB;AAEA,EAAA,OAAO;AAAA;AAAA,IAEL,UAAA,EAAY,IAAI,UAAA,CAAW,QAAA,CAAS,QAAQ;AAAA,GAC9C;AACF;AAmBO,SAAS,oBAAoB,OAAA,EAA2C;AAC7E,EAAA,OAAO,gBAAA,CAAiB;AAAA;AAAA,IAEtB,YAAA,EAAc,oBAAA;AAAA;AAAA;AAAA;AAAA,IAId,KAAA;AAAA,IACA,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,GAAI,QAAQ,cAAA,GAAiB,EAAE,gBAAgB,OAAA,CAAQ,cAAA,KAAmB;AAAC,GAC5E,CAAA;AACH","file":"index.js","sourcesContent":["// The `.js` extension is load-bearing: azure-pipelines-task-lib is CommonJS with\n// no `exports` map, so under ESM resolution the extensionless subpath does not\n// resolve at all (ERR_MODULE_NOT_FOUND). CJS is unaffected either way.\nimport { getInput } from 'azure-pipelines-task-lib/task.js'\n\n/**\n * Reads a boolean input whose intended default is TRUE (fail-closed). It reads the\n * raw input rather than getBoolInput(name, false) so the default still holds on an\n * agent that does not materialize task.json defaultValues into the input env var\n * (where getBoolInput would silently return false): unset/empty -> true; any value\n * other than \"false\" (case-insensitive) -> true.\n */\nexport function getBoolInputDefaultTrue(name: string): boolean {\n const raw = getInput(name, false)\n return raw === undefined || raw.trim() === '' ? true : raw.trim().toLowerCase() !== 'false'\n}\n","import { debug, getHttpProxyConfiguration, setSecret } from 'azure-pipelines-task-lib/task.js'\nimport { ProxyAgent } from 'undici'\nimport {\n createHttpClient,\n resolveProxy,\n type HttpClient,\n type HttpMessages,\n type RedirectPolicy,\n} from '@4cloudguru/pipeline-task-core'\n\n/**\n * Per-attempt fetch init carrying the agent's proxy.\n *\n * The ordering is the security property, not an implementation detail: the\n * agent's masker matches registered literals rather than derivations of them,\n * and resolveProxy returns every spelling of the credential it produced —\n * including the percent-encoded form the dispatcher URL actually embeds, and\n * any userinfo already inside Agent.ProxyUrl. All of them must be registered\n * BEFORE proxyUrl is handed to a dispatcher or interpolated into a message.\n * resolveProxy cannot do it itself; the package it lives in does not import\n * the task lib. That obligation is the reason this function exists here.\n */\nexport function buildAdoFetchOptions(): RequestInit {\n const resolved = resolveProxy(getHttpProxyConfiguration())\n if (!resolved) return {}\n\n for (const secret of resolved.secrets) {\n setSecret(secret)\n }\n\n return {\n // @ts-expect-error Node's fetch accepts an undici dispatcher at runtime.\n dispatcher: new ProxyAgent(resolved.proxyUrl),\n }\n}\n\nexport interface AdoHttpClientOptions {\n /**\n * Failure text. Kept a parameter because it is the one genuinely per-task\n * part: the strings come from each task's own resource file via tasks.loc,\n * and \"registry request failed\" is wrong on a releases.hashicorp.com fetch.\n */\n messages: HttpMessages\n /**\n * Defaults to the core client's own same-host rule. Pass\n * anyRedirectPolicy(sameHostOnly, githubAssetRedirects) only for callers that\n * really do fetch GitHub release assets — enabling it estate-wide widens the\n * redirect surface for callers that never need it.\n */\n redirectPolicy?: RedirectPolicy\n}\n\n/** An HTTPS-pinned client wired to this agent's proxy, debug channel and text. */\nexport function createAdoHttpClient(options: AdoHttpClientOptions): HttpClient {\n return createHttpClient({\n // Re-evaluated per attempt, so a proxy change between retries is picked up.\n fetchOptions: buildAdoFetchOptions,\n // Passed by reference rather than wrapped: a forwarding lambda would be an\n // extra function no test can meaningfully reach, and task-lib's debug does\n // not close over `this`.\n debug,\n messages: options.messages,\n ...(options.redirectPolicy ? { redirectPolicy: options.redirectPolicy } : {}),\n })\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4cloudguru/pipeline-task-ado",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Azure DevOps-specific task primitives shared by the Azure Pipelines task extensions.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"private": false,
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"prettier": "3.9.6",
|
|
70
70
|
"tsup": "^8.3.5",
|
|
71
71
|
"typescript": "^5.9.3",
|
|
72
|
-
"undici": "^
|
|
72
|
+
"undici": "^8.10.0",
|
|
73
73
|
"vitest": "^4.1.7"
|
|
74
74
|
}
|
|
75
75
|
}
|