@revenexx/integrations-node-sdk 1.6.0 → 1.8.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.
@@ -14,15 +14,23 @@ function extractCredentialManifests(credentials) {
14
14
 
15
15
  // src/manifest.ts
16
16
  var MANIFEST_VERSION = "v0-draft";
17
+ var PACKAGE_ICON = /^lucide:[a-z0-9]+(-[a-z0-9]+)*$/;
18
+ var PHP_TRIM = /^[ \t\n\r\0\v]+|[ \t\n\r\0\v]+$/g;
19
+ function packageIconProblem(icon) {
20
+ if (icon === void 0 || PACKAGE_ICON.test(icon)) return void 0;
21
+ return `package.json "revenexx.icon" must be a Lucide icon name such as "lucide:bell", got "${icon}".`;
22
+ }
17
23
  function parsePackageMeta(raw) {
18
24
  const obj = raw && typeof raw === "object" ? raw : {};
19
25
  const str = (v) => typeof v === "string" ? v.trim() : "";
20
26
  const revenexx = obj.revenexx && typeof obj.revenexx === "object" ? obj.revenexx : {};
21
27
  const displayName = str(revenexx.displayName);
28
+ const icon = typeof revenexx.icon === "string" ? revenexx.icon.replace(PHP_TRIM, "") : "";
22
29
  return {
23
30
  name: str(obj.name),
24
31
  version: str(obj.version),
25
- displayName: displayName !== "" ? displayName : void 0
32
+ displayName: displayName !== "" ? displayName : void 0,
33
+ icon: icon !== "" ? icon : void 0
26
34
  };
27
35
  }
28
36
  function buildManifest(nodes, credentials = [], templates = []) {
@@ -45,6 +53,7 @@ export {
45
53
  extractCredentialManifest,
46
54
  extractCredentialManifests,
47
55
  MANIFEST_VERSION,
56
+ packageIconProblem,
48
57
  parsePackageMeta,
49
58
  buildManifest
50
59
  };
package/dist/cli.cjs CHANGED
@@ -93,15 +93,23 @@ function extractCredentialManifests(credentials) {
93
93
 
94
94
  // src/manifest.ts
95
95
  var MANIFEST_VERSION = "v0-draft";
96
+ var PACKAGE_ICON = /^lucide:[a-z0-9]+(-[a-z0-9]+)*$/;
97
+ var PHP_TRIM = /^[ \t\n\r\0\v]+|[ \t\n\r\0\v]+$/g;
98
+ function packageIconProblem(icon) {
99
+ if (icon === void 0 || PACKAGE_ICON.test(icon)) return void 0;
100
+ return `package.json "revenexx.icon" must be a Lucide icon name such as "lucide:bell", got "${icon}".`;
101
+ }
96
102
  function parsePackageMeta(raw) {
97
103
  const obj = raw && typeof raw === "object" ? raw : {};
98
104
  const str = (v) => typeof v === "string" ? v.trim() : "";
99
105
  const revenexx = obj.revenexx && typeof obj.revenexx === "object" ? obj.revenexx : {};
100
106
  const displayName = str(revenexx.displayName);
107
+ const icon = typeof revenexx.icon === "string" ? revenexx.icon.replace(PHP_TRIM, "") : "";
101
108
  return {
102
109
  name: str(obj.name),
103
110
  version: str(obj.version),
104
- displayName: displayName !== "" ? displayName : void 0
111
+ displayName: displayName !== "" ? displayName : void 0,
112
+ icon: icon !== "" ? icon : void 0
105
113
  };
106
114
  }
107
115
  function buildManifest(nodes, credentials = [], templates = []) {
@@ -136,6 +144,14 @@ function readPackageJson(root) {
136
144
  }
137
145
  }
138
146
  async function runManifest() {
147
+ const pkg = readPackageJson(projectRoot);
148
+ const meta = parsePackageMeta(pkg);
149
+ const iconProblem = packageIconProblem(meta.icon);
150
+ if (iconProblem) fail(iconProblem);
151
+ const declaredIcon = pkg?.revenexx?.icon;
152
+ if (declaredIcon != null && typeof declaredIcon !== "string") {
153
+ console.warn('\u26A0 package.json "revenexx.icon" is not text \u2014 the folder will show no icon.');
154
+ }
139
155
  const distEntry = (0, import_node_path2.resolve)(projectRoot, "dist", "index.js");
140
156
  if (!fs2.existsSync(distEntry)) {
141
157
  fail("dist/index.js is missing. Run the build (tsup) before `rvnxx-nodes manifest`.");
@@ -152,7 +168,6 @@ async function runManifest() {
152
168
  }
153
169
  const credentials = mod.CREDENTIALS ?? [];
154
170
  const templates = mod.TEMPLATES ?? [];
155
- const meta = parsePackageMeta(readPackageJson(projectRoot));
156
171
  const hasPackage = meta.name !== "" && meta.version !== "";
157
172
  if (hasPackage && !meta.displayName) {
158
173
  console.warn(
package/dist/cli.js CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  buildManifest,
4
+ packageIconProblem,
4
5
  parsePackageMeta
5
- } from "./chunk-WB3BYMLA.js";
6
+ } from "./chunk-5BCAXRU3.js";
6
7
 
7
8
  // src/cli.ts
8
9
  import * as fs2 from "fs";
@@ -76,6 +77,14 @@ function readPackageJson(root) {
76
77
  }
77
78
  }
78
79
  async function runManifest() {
80
+ const pkg = readPackageJson(projectRoot);
81
+ const meta = parsePackageMeta(pkg);
82
+ const iconProblem = packageIconProblem(meta.icon);
83
+ if (iconProblem) fail(iconProblem);
84
+ const declaredIcon = pkg?.revenexx?.icon;
85
+ if (declaredIcon != null && typeof declaredIcon !== "string") {
86
+ console.warn('\u26A0 package.json "revenexx.icon" is not text \u2014 the folder will show no icon.');
87
+ }
79
88
  const distEntry = resolve2(projectRoot, "dist", "index.js");
80
89
  if (!fs2.existsSync(distEntry)) {
81
90
  fail("dist/index.js is missing. Run the build (tsup) before `rvnxx-nodes manifest`.");
@@ -92,7 +101,6 @@ async function runManifest() {
92
101
  }
93
102
  const credentials = mod.CREDENTIALS ?? [];
94
103
  const templates = mod.TEMPLATES ?? [];
95
- const meta = parsePackageMeta(readPackageJson(projectRoot));
96
104
  const hasPackage = meta.name !== "" && meta.version !== "";
97
105
  if (hasPackage && !meta.displayName) {
98
106
  console.warn(
package/dist/index.cjs CHANGED
@@ -61,6 +61,7 @@ __export(index_exports, {
61
61
  extractCredentialManifests: () => extractCredentialManifests,
62
62
  extractManifest: () => extractManifest,
63
63
  extractManifests: () => extractManifests,
64
+ headerCrossesOrigin: () => headerCrossesOrigin,
64
65
  httpErrorResult: () => httpErrorResult,
65
66
  isBlockedAddress: () => isBlockedAddress,
66
67
  isNodeWithIteration: () => isNodeWithIteration,
@@ -69,6 +70,7 @@ __export(index_exports, {
69
70
  maxBytesConfigField: () => maxBytesConfigField,
70
71
  normalizeCredentialType: () => normalizeCredentialType,
71
72
  normalizeLocalized: () => normalizeLocalized,
73
+ packageIconProblem: () => packageIconProblem,
72
74
  parsePackageMeta: () => parsePackageMeta,
73
75
  readArrayBuffer: () => readArrayBuffer,
74
76
  readJsonOrText: () => readJsonOrText,
@@ -474,6 +476,26 @@ var DEFAULT_TIMEOUT_MS = 3e4;
474
476
  var MAX_TIMEOUT_MS = 12e4;
475
477
  var MAX_REDIRECTS = 5;
476
478
  var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
479
+ var CROSS_ORIGIN_SAFE_HEADERS = /* @__PURE__ */ new Set([
480
+ "accept",
481
+ "accept-encoding",
482
+ "accept-language",
483
+ "content-encoding",
484
+ "content-language",
485
+ "content-type",
486
+ "idempotency-key",
487
+ "if-match",
488
+ "if-modified-since",
489
+ "if-none-match",
490
+ "if-range",
491
+ "if-unmodified-since",
492
+ "range",
493
+ "soapaction",
494
+ "user-agent"
495
+ ]);
496
+ function headerCrossesOrigin(name) {
497
+ return CROSS_ORIGIN_SAFE_HEADERS.has(name.trim().toLowerCase());
498
+ }
477
499
  var DEFAULT_RETRY_ATTEMPTS = 0;
478
500
  var MAX_RETRY_ATTEMPTS = 5;
479
501
  var DEFAULT_RETRY_DELAY_MS = 1e3;
@@ -556,9 +578,9 @@ async function guardedFetch(url, fetchOptions, ctxSignal, effectiveMs) {
556
578
  headers.delete("content-length");
557
579
  }
558
580
  if (nextUrl.origin !== base.origin) {
559
- headers.delete("authorization");
560
- headers.delete("cookie");
561
- headers.delete("proxy-authorization");
581
+ for (const name of [...headers.keys()]) {
582
+ if (!headerCrossesOrigin(name)) headers.delete(name);
583
+ }
562
584
  }
563
585
  currentUrl = nextUrl;
564
586
  currentInit = { ...currentInit, method, body, headers, redirect: "manual" };
@@ -791,15 +813,23 @@ async function withRetry(fn, policy, hooks) {
791
813
 
792
814
  // src/manifest.ts
793
815
  var MANIFEST_VERSION = "v0-draft";
816
+ var PACKAGE_ICON = /^lucide:[a-z0-9]+(-[a-z0-9]+)*$/;
817
+ var PHP_TRIM = /^[ \t\n\r\0\v]+|[ \t\n\r\0\v]+$/g;
818
+ function packageIconProblem(icon) {
819
+ if (icon === void 0 || PACKAGE_ICON.test(icon)) return void 0;
820
+ return `package.json "revenexx.icon" must be a Lucide icon name such as "lucide:bell", got "${icon}".`;
821
+ }
794
822
  function parsePackageMeta(raw) {
795
823
  const obj = raw && typeof raw === "object" ? raw : {};
796
824
  const str = (v) => typeof v === "string" ? v.trim() : "";
797
825
  const revenexx = obj.revenexx && typeof obj.revenexx === "object" ? obj.revenexx : {};
798
826
  const displayName = str(revenexx.displayName);
827
+ const icon = typeof revenexx.icon === "string" ? revenexx.icon.replace(PHP_TRIM, "") : "";
799
828
  return {
800
829
  name: str(obj.name),
801
830
  version: str(obj.version),
802
- displayName: displayName !== "" ? displayName : void 0
831
+ displayName: displayName !== "" ? displayName : void 0,
832
+ icon: icon !== "" ? icon : void 0
803
833
  };
804
834
  }
805
835
  function buildManifest(nodes, credentials = [], templates = []) {
@@ -1106,6 +1136,7 @@ function base64Url(buf) {
1106
1136
  extractCredentialManifests,
1107
1137
  extractManifest,
1108
1138
  extractManifests,
1139
+ headerCrossesOrigin,
1109
1140
  httpErrorResult,
1110
1141
  isBlockedAddress,
1111
1142
  isNodeWithIteration,
@@ -1114,6 +1145,7 @@ function base64Url(buf) {
1114
1145
  maxBytesConfigField,
1115
1146
  normalizeCredentialType,
1116
1147
  normalizeLocalized,
1148
+ packageIconProblem,
1117
1149
  parsePackageMeta,
1118
1150
  readArrayBuffer,
1119
1151
  readJsonOrText,
package/dist/index.d.cts CHANGED
@@ -771,6 +771,18 @@ declare const DEFAULT_TIMEOUT_MS = 30000;
771
771
  declare const MAX_TIMEOUT_MS = 120000;
772
772
  /** Maximum number of redirect hops `safeFetch` follows before giving up. */
773
773
  declare const MAX_REDIRECTS = 5;
774
+ /**
775
+ * Whether a request header with this name goes on to the next hop when
776
+ * {@link safeFetch} follows a redirect to another origin — `true` for `Accept`,
777
+ * `Accept-Encoding`, `Accept-Language`, `Content-Encoding`, `Content-Language`,
778
+ * `Content-Type`, `Idempotency-Key`, `If-Match`, `If-Modified-Since`,
779
+ * `If-None-Match`, `If-Range`, `If-Unmodified-Since`, `Range`, `SOAPAction` and
780
+ * `User-Agent`, in any case, and `false` for every other name. The keep-list is by
781
+ * name, so it can only keep a secret out of the headers it drops: a credential
782
+ * whose header name the author chooses must refuse a name this answers `true`
783
+ * for, or its key would cross with the harmless headers.
784
+ */
785
+ declare function headerCrossesOrigin(name: string): boolean;
774
786
  declare const DEFAULT_RETRY_ATTEMPTS = 0;
775
787
  declare const MAX_RETRY_ATTEMPTS = 5;
776
788
  declare const DEFAULT_RETRY_DELAY_MS = 1000;
@@ -1023,9 +1035,10 @@ interface NodeManifest {
1023
1035
  * The registry-relevant fields of a node package's `package.json`, as read by
1024
1036
  * the CLI. `name`/`version` identify the package; `displayName` is the
1025
1037
  * human-readable bundle label shown in the editor's node palette (e.g.
1026
- * „Business Central"). All three are read straight from `package.json` by the
1027
- * integrations server on upload — the CLI reads them only to warn about a
1028
- * missing label and to annotate the manifest log line.
1038
+ * „Business Central"); `icon` marks its folder there. All four are read straight
1039
+ * from `package.json` by the integrations server on upload — the CLI reads them
1040
+ * only to warn about a missing label, to annotate the manifest log line, and to
1041
+ * stop on an icon the server would refuse.
1029
1042
  *
1030
1043
  * The label lives under a namespaced `revenexx` group in `package.json`
1031
1044
  * (`{ "revenexx": { "displayName": "…" } }`), not a bespoke top-level key, so
@@ -1036,14 +1049,34 @@ interface NodePackageMeta {
1036
1049
  version: string;
1037
1050
  /** Human-readable bundle label (e.g. „Business Central"); optional. */
1038
1051
  displayName?: string;
1052
+ /**
1053
+ * The glyph that marks the package's folder in the studio's palette, as
1054
+ * `lucide:<kebab-name>` (e.g. `lucide:bell`); optional. Declared by a package
1055
+ * holding several services, which has no one vendor logo to mark its folder
1056
+ * with — a package that is one vendor leaves it out. Trimmed, and a value that
1057
+ * is not a string counts as none, as the server reads it; whether it is well
1058
+ * formed is {@link packageIconProblem}'s question.
1059
+ */
1060
+ icon?: string;
1039
1061
  }
1062
+ /**
1063
+ * Why a declared `revenexx.icon` would be refused by the registry, or
1064
+ * `undefined` when it is fine (or absent). Lets the build stop where the author
1065
+ * can still fix it, rather than at upload. Takes the icon as
1066
+ * {@link parsePackageMeta} returns it — trimmed as the registry trims it; an
1067
+ * untrimmed raw value can be refused here although the registry accepts it.
1068
+ */
1069
+ declare function packageIconProblem(icon: string | undefined): string | undefined;
1040
1070
  /**
1041
1071
  * Extracts {@link NodePackageMeta} from parsed `package.json` contents, keeping
1042
1072
  * only the registry-relevant fields and coercing anything malformed to a safe
1043
- * shape. All three fields are trimmed; a blank or whitespace-only value becomes
1044
- * `''` (`name`/`version`) or `undefined` (`displayName`, matching how the server
1045
- * treats it), so whitespace can't masquerade as a present value in tooling.
1046
- * The bundle label is read from the `revenexx` group (`revenexx.displayName`).
1073
+ * shape. All four fields are trimmed — the icon of ASCII whitespace only, as the
1074
+ * server's PHP `trim()` does, so a pasted no-break space is refused here as it
1075
+ * is there rather than trimmed away; a blank or whitespace-only value becomes
1076
+ * `''` (`name`/`version`) or `undefined` (`displayName`, `icon`, matching how the
1077
+ * server treats them), so whitespace can't masquerade as a present value in
1078
+ * tooling. The bundle label and the folder icon are read from the `revenexx`
1079
+ * group (`revenexx.displayName`, `revenexx.icon`).
1047
1080
  * Does not validate that `name`/`version` are present — the integrations server
1048
1081
  * enforces that on upload; this is a typed, lenient read for tooling.
1049
1082
  */
@@ -1218,4 +1251,4 @@ declare abstract class OAuth2AuthCodeCredential extends BaseCredential implement
1218
1251
  test(_ctx: ICredentialContext, config: Config): Promise<ICredentialTestResult>;
1219
1252
  }
1220
1253
 
1221
- export { ApiKeyCredential, BaseCredential, BasicAuthCredential, type ConfigType, type CredentialAuthKind, type CredentialFieldType, DEFAULT_MAX_RESPONSE_BYTES, DEFAULT_RETRY_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, type DataType, type IConfigField, type IConfigFieldBase, type IConfigOption, type IConfigValidation, type ICredential, type ICredentialContext, type ICredentialDescription, type ICredentialField, type ICredentialOAuthAuthorize, type ICredentialResolveResult, type ICredentialTestResult, type IImage, type IInputPort, type INode, type INodeAuthorContext, type INodeContext, type INodeDescription, type INodeResult, type INodeState, type INodeWithIteration, type IOutputField, type IOutputPort, type IShowIfCondition, type ITemplateDescription, type ITemplateTrigger, type ImageCategory, type LocalizedString, type LookupAddress, type LookupFn, MANIFEST_VERSION, MAX_REDIRECTS, MAX_RESPONSE_BYTES, MAX_RETRY_ATTEMPTS, MAX_TIMEOUT_MS, type NodeCategory, NodeError, type NodeErrorOutput, type NodeManifest, type NodePackageMeta, OAuth2AuthCodeCredential, OAuth2ClientCredentialsCredential, type OAuthTokenResponse, OPERATORS, type Operator, type OutputKind, type RetryHooks, type RetryPolicy, RetryableError, type SafeFetchOptions, type SafeFetchRetry, SimpleValueCredential, type TemplateLevel, type TemplateTriggerType, VALUELESS_OPERATORS, assertPublicUrl, backoffDelay, buildManifest, clampResponseBytes, errorPort, errorResult, evaluate, extractCredentialManifest, extractCredentialManifests, extractManifest, extractManifests, httpErrorResult, isBlockedAddress, isNodeWithIteration, isOAuthAuthorizeCredential, isOperator, maxBytesConfigField, normalizeCredentialType, normalizeLocalized, parsePackageMeta, readArrayBuffer, readJsonOrText, readText, retryConfigFields, safeFetch, settingApplies, sleepWithSignal, takesValue, timeoutConfigField, toErrorOutput, toErrorResult, withRetry };
1254
+ export { ApiKeyCredential, BaseCredential, BasicAuthCredential, type ConfigType, type CredentialAuthKind, type CredentialFieldType, DEFAULT_MAX_RESPONSE_BYTES, DEFAULT_RETRY_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, type DataType, type IConfigField, type IConfigFieldBase, type IConfigOption, type IConfigValidation, type ICredential, type ICredentialContext, type ICredentialDescription, type ICredentialField, type ICredentialOAuthAuthorize, type ICredentialResolveResult, type ICredentialTestResult, type IImage, type IInputPort, type INode, type INodeAuthorContext, type INodeContext, type INodeDescription, type INodeResult, type INodeState, type INodeWithIteration, type IOutputField, type IOutputPort, type IShowIfCondition, type ITemplateDescription, type ITemplateTrigger, type ImageCategory, type LocalizedString, type LookupAddress, type LookupFn, MANIFEST_VERSION, MAX_REDIRECTS, MAX_RESPONSE_BYTES, MAX_RETRY_ATTEMPTS, MAX_TIMEOUT_MS, type NodeCategory, NodeError, type NodeErrorOutput, type NodeManifest, type NodePackageMeta, OAuth2AuthCodeCredential, OAuth2ClientCredentialsCredential, type OAuthTokenResponse, OPERATORS, type Operator, type OutputKind, type RetryHooks, type RetryPolicy, RetryableError, type SafeFetchOptions, type SafeFetchRetry, SimpleValueCredential, type TemplateLevel, type TemplateTriggerType, VALUELESS_OPERATORS, assertPublicUrl, backoffDelay, buildManifest, clampResponseBytes, errorPort, errorResult, evaluate, extractCredentialManifest, extractCredentialManifests, extractManifest, extractManifests, headerCrossesOrigin, httpErrorResult, isBlockedAddress, isNodeWithIteration, isOAuthAuthorizeCredential, isOperator, maxBytesConfigField, normalizeCredentialType, normalizeLocalized, packageIconProblem, parsePackageMeta, readArrayBuffer, readJsonOrText, readText, retryConfigFields, safeFetch, settingApplies, sleepWithSignal, takesValue, timeoutConfigField, toErrorOutput, toErrorResult, withRetry };
package/dist/index.d.ts CHANGED
@@ -771,6 +771,18 @@ declare const DEFAULT_TIMEOUT_MS = 30000;
771
771
  declare const MAX_TIMEOUT_MS = 120000;
772
772
  /** Maximum number of redirect hops `safeFetch` follows before giving up. */
773
773
  declare const MAX_REDIRECTS = 5;
774
+ /**
775
+ * Whether a request header with this name goes on to the next hop when
776
+ * {@link safeFetch} follows a redirect to another origin — `true` for `Accept`,
777
+ * `Accept-Encoding`, `Accept-Language`, `Content-Encoding`, `Content-Language`,
778
+ * `Content-Type`, `Idempotency-Key`, `If-Match`, `If-Modified-Since`,
779
+ * `If-None-Match`, `If-Range`, `If-Unmodified-Since`, `Range`, `SOAPAction` and
780
+ * `User-Agent`, in any case, and `false` for every other name. The keep-list is by
781
+ * name, so it can only keep a secret out of the headers it drops: a credential
782
+ * whose header name the author chooses must refuse a name this answers `true`
783
+ * for, or its key would cross with the harmless headers.
784
+ */
785
+ declare function headerCrossesOrigin(name: string): boolean;
774
786
  declare const DEFAULT_RETRY_ATTEMPTS = 0;
775
787
  declare const MAX_RETRY_ATTEMPTS = 5;
776
788
  declare const DEFAULT_RETRY_DELAY_MS = 1000;
@@ -1023,9 +1035,10 @@ interface NodeManifest {
1023
1035
  * The registry-relevant fields of a node package's `package.json`, as read by
1024
1036
  * the CLI. `name`/`version` identify the package; `displayName` is the
1025
1037
  * human-readable bundle label shown in the editor's node palette (e.g.
1026
- * „Business Central"). All three are read straight from `package.json` by the
1027
- * integrations server on upload — the CLI reads them only to warn about a
1028
- * missing label and to annotate the manifest log line.
1038
+ * „Business Central"); `icon` marks its folder there. All four are read straight
1039
+ * from `package.json` by the integrations server on upload — the CLI reads them
1040
+ * only to warn about a missing label, to annotate the manifest log line, and to
1041
+ * stop on an icon the server would refuse.
1029
1042
  *
1030
1043
  * The label lives under a namespaced `revenexx` group in `package.json`
1031
1044
  * (`{ "revenexx": { "displayName": "…" } }`), not a bespoke top-level key, so
@@ -1036,14 +1049,34 @@ interface NodePackageMeta {
1036
1049
  version: string;
1037
1050
  /** Human-readable bundle label (e.g. „Business Central"); optional. */
1038
1051
  displayName?: string;
1052
+ /**
1053
+ * The glyph that marks the package's folder in the studio's palette, as
1054
+ * `lucide:<kebab-name>` (e.g. `lucide:bell`); optional. Declared by a package
1055
+ * holding several services, which has no one vendor logo to mark its folder
1056
+ * with — a package that is one vendor leaves it out. Trimmed, and a value that
1057
+ * is not a string counts as none, as the server reads it; whether it is well
1058
+ * formed is {@link packageIconProblem}'s question.
1059
+ */
1060
+ icon?: string;
1039
1061
  }
1062
+ /**
1063
+ * Why a declared `revenexx.icon` would be refused by the registry, or
1064
+ * `undefined` when it is fine (or absent). Lets the build stop where the author
1065
+ * can still fix it, rather than at upload. Takes the icon as
1066
+ * {@link parsePackageMeta} returns it — trimmed as the registry trims it; an
1067
+ * untrimmed raw value can be refused here although the registry accepts it.
1068
+ */
1069
+ declare function packageIconProblem(icon: string | undefined): string | undefined;
1040
1070
  /**
1041
1071
  * Extracts {@link NodePackageMeta} from parsed `package.json` contents, keeping
1042
1072
  * only the registry-relevant fields and coercing anything malformed to a safe
1043
- * shape. All three fields are trimmed; a blank or whitespace-only value becomes
1044
- * `''` (`name`/`version`) or `undefined` (`displayName`, matching how the server
1045
- * treats it), so whitespace can't masquerade as a present value in tooling.
1046
- * The bundle label is read from the `revenexx` group (`revenexx.displayName`).
1073
+ * shape. All four fields are trimmed — the icon of ASCII whitespace only, as the
1074
+ * server's PHP `trim()` does, so a pasted no-break space is refused here as it
1075
+ * is there rather than trimmed away; a blank or whitespace-only value becomes
1076
+ * `''` (`name`/`version`) or `undefined` (`displayName`, `icon`, matching how the
1077
+ * server treats them), so whitespace can't masquerade as a present value in
1078
+ * tooling. The bundle label and the folder icon are read from the `revenexx`
1079
+ * group (`revenexx.displayName`, `revenexx.icon`).
1047
1080
  * Does not validate that `name`/`version` are present — the integrations server
1048
1081
  * enforces that on upload; this is a typed, lenient read for tooling.
1049
1082
  */
@@ -1218,4 +1251,4 @@ declare abstract class OAuth2AuthCodeCredential extends BaseCredential implement
1218
1251
  test(_ctx: ICredentialContext, config: Config): Promise<ICredentialTestResult>;
1219
1252
  }
1220
1253
 
1221
- export { ApiKeyCredential, BaseCredential, BasicAuthCredential, type ConfigType, type CredentialAuthKind, type CredentialFieldType, DEFAULT_MAX_RESPONSE_BYTES, DEFAULT_RETRY_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, type DataType, type IConfigField, type IConfigFieldBase, type IConfigOption, type IConfigValidation, type ICredential, type ICredentialContext, type ICredentialDescription, type ICredentialField, type ICredentialOAuthAuthorize, type ICredentialResolveResult, type ICredentialTestResult, type IImage, type IInputPort, type INode, type INodeAuthorContext, type INodeContext, type INodeDescription, type INodeResult, type INodeState, type INodeWithIteration, type IOutputField, type IOutputPort, type IShowIfCondition, type ITemplateDescription, type ITemplateTrigger, type ImageCategory, type LocalizedString, type LookupAddress, type LookupFn, MANIFEST_VERSION, MAX_REDIRECTS, MAX_RESPONSE_BYTES, MAX_RETRY_ATTEMPTS, MAX_TIMEOUT_MS, type NodeCategory, NodeError, type NodeErrorOutput, type NodeManifest, type NodePackageMeta, OAuth2AuthCodeCredential, OAuth2ClientCredentialsCredential, type OAuthTokenResponse, OPERATORS, type Operator, type OutputKind, type RetryHooks, type RetryPolicy, RetryableError, type SafeFetchOptions, type SafeFetchRetry, SimpleValueCredential, type TemplateLevel, type TemplateTriggerType, VALUELESS_OPERATORS, assertPublicUrl, backoffDelay, buildManifest, clampResponseBytes, errorPort, errorResult, evaluate, extractCredentialManifest, extractCredentialManifests, extractManifest, extractManifests, httpErrorResult, isBlockedAddress, isNodeWithIteration, isOAuthAuthorizeCredential, isOperator, maxBytesConfigField, normalizeCredentialType, normalizeLocalized, parsePackageMeta, readArrayBuffer, readJsonOrText, readText, retryConfigFields, safeFetch, settingApplies, sleepWithSignal, takesValue, timeoutConfigField, toErrorOutput, toErrorResult, withRetry };
1254
+ export { ApiKeyCredential, BaseCredential, BasicAuthCredential, type ConfigType, type CredentialAuthKind, type CredentialFieldType, DEFAULT_MAX_RESPONSE_BYTES, DEFAULT_RETRY_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, type DataType, type IConfigField, type IConfigFieldBase, type IConfigOption, type IConfigValidation, type ICredential, type ICredentialContext, type ICredentialDescription, type ICredentialField, type ICredentialOAuthAuthorize, type ICredentialResolveResult, type ICredentialTestResult, type IImage, type IInputPort, type INode, type INodeAuthorContext, type INodeContext, type INodeDescription, type INodeResult, type INodeState, type INodeWithIteration, type IOutputField, type IOutputPort, type IShowIfCondition, type ITemplateDescription, type ITemplateTrigger, type ImageCategory, type LocalizedString, type LookupAddress, type LookupFn, MANIFEST_VERSION, MAX_REDIRECTS, MAX_RESPONSE_BYTES, MAX_RETRY_ATTEMPTS, MAX_TIMEOUT_MS, type NodeCategory, NodeError, type NodeErrorOutput, type NodeManifest, type NodePackageMeta, OAuth2AuthCodeCredential, OAuth2ClientCredentialsCredential, type OAuthTokenResponse, OPERATORS, type Operator, type OutputKind, type RetryHooks, type RetryPolicy, RetryableError, type SafeFetchOptions, type SafeFetchRetry, SimpleValueCredential, type TemplateLevel, type TemplateTriggerType, VALUELESS_OPERATORS, assertPublicUrl, backoffDelay, buildManifest, clampResponseBytes, errorPort, errorResult, evaluate, extractCredentialManifest, extractCredentialManifests, extractManifest, extractManifests, headerCrossesOrigin, httpErrorResult, isBlockedAddress, isNodeWithIteration, isOAuthAuthorizeCredential, isOperator, maxBytesConfigField, normalizeCredentialType, normalizeLocalized, packageIconProblem, parsePackageMeta, readArrayBuffer, readJsonOrText, readText, retryConfigFields, safeFetch, settingApplies, sleepWithSignal, takesValue, timeoutConfigField, toErrorOutput, toErrorResult, withRetry };
package/dist/index.js CHANGED
@@ -5,8 +5,9 @@ import {
5
5
  extractCredentialManifests,
6
6
  extractManifest,
7
7
  extractManifests,
8
+ packageIconProblem,
8
9
  parsePackageMeta
9
- } from "./chunk-WB3BYMLA.js";
10
+ } from "./chunk-5BCAXRU3.js";
10
11
 
11
12
  // src/types.ts
12
13
  function isNodeWithIteration(node) {
@@ -383,6 +384,26 @@ var DEFAULT_TIMEOUT_MS = 3e4;
383
384
  var MAX_TIMEOUT_MS = 12e4;
384
385
  var MAX_REDIRECTS = 5;
385
386
  var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
387
+ var CROSS_ORIGIN_SAFE_HEADERS = /* @__PURE__ */ new Set([
388
+ "accept",
389
+ "accept-encoding",
390
+ "accept-language",
391
+ "content-encoding",
392
+ "content-language",
393
+ "content-type",
394
+ "idempotency-key",
395
+ "if-match",
396
+ "if-modified-since",
397
+ "if-none-match",
398
+ "if-range",
399
+ "if-unmodified-since",
400
+ "range",
401
+ "soapaction",
402
+ "user-agent"
403
+ ]);
404
+ function headerCrossesOrigin(name) {
405
+ return CROSS_ORIGIN_SAFE_HEADERS.has(name.trim().toLowerCase());
406
+ }
386
407
  var DEFAULT_RETRY_ATTEMPTS = 0;
387
408
  var MAX_RETRY_ATTEMPTS = 5;
388
409
  var DEFAULT_RETRY_DELAY_MS = 1e3;
@@ -465,9 +486,9 @@ async function guardedFetch(url, fetchOptions, ctxSignal, effectiveMs) {
465
486
  headers.delete("content-length");
466
487
  }
467
488
  if (nextUrl.origin !== base.origin) {
468
- headers.delete("authorization");
469
- headers.delete("cookie");
470
- headers.delete("proxy-authorization");
489
+ for (const name of [...headers.keys()]) {
490
+ if (!headerCrossesOrigin(name)) headers.delete(name);
491
+ }
471
492
  }
472
493
  currentUrl = nextUrl;
473
494
  currentInit = { ...currentInit, method, body, headers, redirect: "manual" };
@@ -987,6 +1008,7 @@ export {
987
1008
  extractCredentialManifests,
988
1009
  extractManifest,
989
1010
  extractManifests,
1011
+ headerCrossesOrigin,
990
1012
  httpErrorResult,
991
1013
  isBlockedAddress,
992
1014
  isNodeWithIteration,
@@ -995,6 +1017,7 @@ export {
995
1017
  maxBytesConfigField,
996
1018
  normalizeCredentialType,
997
1019
  normalizeLocalized,
1020
+ packageIconProblem,
998
1021
  parsePackageMeta,
999
1022
  readArrayBuffer,
1000
1023
  readJsonOrText,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revenexx/integrations-node-sdk",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "TypeScript interfaces and utilities for Revenexx integration nodes",
5
5
  "license": "MIT",
6
6
  "author": "revenexx GmbH",