@harborclient/sdk 1.0.0 → 1.0.2
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/dist/build/index.d.ts.map +1 -1
- package/dist/build/index.js +10 -1
- package/dist/client.d.ts +2 -2
- package/dist/components/Autocomplete/AutocompleteInput.d.ts +23 -0
- package/dist/components/Autocomplete/AutocompleteInput.d.ts.map +1 -0
- package/dist/components/Autocomplete/AutocompleteInput.js +26 -0
- package/dist/components/Autocomplete/SuggestionList.d.ts +45 -0
- package/dist/components/Autocomplete/SuggestionList.d.ts.map +1 -0
- package/dist/components/Autocomplete/SuggestionList.js +72 -0
- package/dist/components/Autocomplete/index.d.ts +6 -0
- package/dist/components/Autocomplete/index.d.ts.map +1 -0
- package/dist/components/Autocomplete/index.js +3 -0
- package/dist/components/Autocomplete/types.d.ts +19 -0
- package/dist/components/Autocomplete/types.d.ts.map +1 -0
- package/dist/components/Autocomplete/types.js +1 -0
- package/dist/components/Autocomplete/useAutocomplete.d.ts +84 -0
- package/dist/components/Autocomplete/useAutocomplete.d.ts.map +1 -0
- package/dist/components/Autocomplete/useAutocomplete.js +191 -0
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +8 -7
- package/dist/components/KeyValueEditor/index.d.ts +10 -1
- package/dist/components/KeyValueEditor/index.d.ts.map +1 -1
- package/dist/components/KeyValueEditor/index.js +4 -3
- package/dist/components/VariableInput/index.d.ts +6 -1
- package/dist/components/VariableInput/index.d.ts.map +1 -1
- package/dist/components/VariableInput/index.js +19 -3
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/portalToBody.d.ts +2 -1
- package/dist/components/portalToBody.d.ts.map +1 -1
- package/dist/components/portalToBody.js +5 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/runtime/hcBridge.js +0 -3
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/jsx-dev-runtime.d.ts +1 -1
- package/dist/runtime/store.d.ts +6 -1
- package/dist/runtime/store.d.ts.map +1 -1
- package/dist/runtime/store.js +8 -2
- package/dist/runtime/store.ts +11 -3
- package/package.json +3 -2
- package/dist/components/enhanceControl.test.d.ts +0 -2
- package/dist/components/enhanceControl.test.d.ts.map +0 -1
- package/dist/components/enhanceControl.test.js +0 -83
- package/dist/components/utils.test.d.ts +0 -2
- package/dist/components/utils.test.d.ts.map +0 -1
- package/dist/components/utils.test.js +0 -44
- package/dist/http/resolveRequest.test.d.ts +0 -2
- package/dist/http/resolveRequest.test.d.ts.map +0 -1
- package/dist/http/resolveRequest.test.js +0 -41
- package/dist/http/substitute.test.d.ts +0 -2
- package/dist/http/substitute.test.d.ts.map +0 -1
- package/dist/http/substitute.test.js +0 -93
- package/dist/pluginDatabaseApi.test.d.ts +0 -2
- package/dist/pluginDatabaseApi.test.d.ts.map +0 -1
- package/dist/pluginDatabaseApi.test.js +0 -65
- package/dist/runtime/index.test.d.ts +0 -2
- package/dist/runtime/index.test.d.ts.map +0 -1
- package/dist/runtime/index.test.js +0 -41
- package/dist/runtime/index.test.ts +0 -53
- package/dist/runtime-utils.test.d.ts +0 -2
- package/dist/runtime-utils.test.d.ts.map +0 -1
- package/dist/runtime-utils.test.js +0 -177
- package/dist/signing/signing.test.d.ts +0 -2
- package/dist/signing/signing.test.d.ts.map +0 -1
- package/dist/signing/signing.test.js +0 -100
- package/dist/storage/cappedList.test.d.ts +0 -2
- package/dist/storage/cappedList.test.d.ts.map +0 -1
- package/dist/storage/cappedList.test.js +0 -11
- package/dist/storage/validate.test.d.ts +0 -2
- package/dist/storage/validate.test.d.ts.map +0 -1
- package/dist/storage/validate.test.js +0 -78
- package/dist/store.test.d.ts +0 -2
- package/dist/store.test.d.ts.map +0 -1
- package/dist/store.test.js +0 -248
- package/dist/utilities.test.d.ts +0 -2
- package/dist/utilities.test.d.ts.map +0 -1
- package/dist/utilities.test.js +0 -16
- package/dist/variables/dynamic.test.d.ts +0 -2
- package/dist/variables/dynamic.test.d.ts.map +0 -1
- package/dist/variables/dynamic.test.js +0 -60
- package/dist/variables/tokens.test.d.ts +0 -2
- package/dist/variables/tokens.test.d.ts.map +0 -1
- package/dist/variables/tokens.test.js +0 -160
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { JSX, KeyboardEvent } from 'react';
|
|
2
2
|
import type { Variable } from '../../types.js';
|
|
3
|
+
import type { AutocompleteSource } from '../Autocomplete/types.js';
|
|
3
4
|
export interface Props {
|
|
4
5
|
/**
|
|
5
6
|
* Current input value.
|
|
@@ -47,6 +48,10 @@ export interface Props {
|
|
|
47
48
|
* Id of the element that labels this input when using `aria-labelledby`.
|
|
48
49
|
*/
|
|
49
50
|
'aria-labelledby'?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Optional async source for value autocomplete suggestions.
|
|
53
|
+
*/
|
|
54
|
+
source?: AutocompleteSource;
|
|
50
55
|
}
|
|
51
56
|
/**
|
|
52
57
|
* Text input that highlights {{variable}} tokens and shows resolved values on hover.
|
|
@@ -54,5 +59,5 @@ export interface Props {
|
|
|
54
59
|
* Token highlight color (`text-[#32D2E2]`) and the tooltip `app-no-drag` class rely on
|
|
55
60
|
* host styling in HarborClient `styles.css`.
|
|
56
61
|
*/
|
|
57
|
-
export declare function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className, wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy }: Props): JSX.Element;
|
|
62
|
+
export declare function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className, wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, source }: Props): JSX.Element;
|
|
58
63
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/VariableInput/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAc,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/VariableInput/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAc,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAS/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAYnE,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;OAEG;IACH,SAAS,EAAE,QAAQ,EAAE,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAc,EACd,gBAAgB,EAChB,cAAc,EACd,EAAE,EACF,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,MAAM,EACP,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA0SrB"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
2
|
import { useEffect, useId, useMemo, useRef, useState } from '@harborclient/sdk/react';
|
|
3
3
|
import { getDynamicVariableDescription, getVariableTokenAtOffset, getVariableTooltipContent, resolveVariable, tokenizeVariables } from '../../variables/index.js';
|
|
4
|
+
import { SuggestionList } from '../Autocomplete/SuggestionList.js';
|
|
5
|
+
import { useAutocomplete } from '../Autocomplete/useAutocomplete.js';
|
|
4
6
|
import { Input } from '../forms/index.js';
|
|
5
7
|
/**
|
|
6
8
|
* Text input that highlights {{variable}} tokens and shows resolved values on hover.
|
|
@@ -8,13 +10,19 @@ import { Input } from '../forms/index.js';
|
|
|
8
10
|
* Token highlight color (`text-[#32D2E2]`) and the tooltip `app-no-drag` class rely on
|
|
9
11
|
* host styling in HarborClient `styles.css`.
|
|
10
12
|
*/
|
|
11
|
-
export function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className = '', wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy }) {
|
|
13
|
+
export function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className = '', wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, source }) {
|
|
12
14
|
const inputRef = useRef(null);
|
|
13
15
|
const backdropRef = useRef(null);
|
|
14
16
|
const spanRefs = useRef(new Map());
|
|
15
17
|
const hideTimer = useRef(null);
|
|
16
18
|
const [tooltip, setTooltip] = useState(null);
|
|
17
19
|
const tooltipId = useId();
|
|
20
|
+
const { open: autocompleteOpen, items: autocompleteItems, activeIndex: autocompleteActiveIndex, listboxId, onFocus: openAutocomplete, onBlur: closeAutocomplete, onInputKeyDown, selectItem, setActiveIndex, closeSuggestions } = useAutocomplete({
|
|
21
|
+
source,
|
|
22
|
+
value,
|
|
23
|
+
onSelect: onChange,
|
|
24
|
+
anchorRef: inputRef
|
|
25
|
+
});
|
|
18
26
|
/**
|
|
19
27
|
* Splits the input value into plain text and {{variable}} token spans for highlighting.
|
|
20
28
|
*/
|
|
@@ -126,6 +134,9 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
126
134
|
* @param event - Keyboard event from the input.
|
|
127
135
|
*/
|
|
128
136
|
const handleKeyDown = (event) => {
|
|
137
|
+
if (onInputKeyDown(event)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
129
140
|
if (event.key === 'Escape' && tooltip) {
|
|
130
141
|
event.preventDefault();
|
|
131
142
|
setTooltip(null);
|
|
@@ -154,10 +165,15 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
154
165
|
spanRefs.current.set(index, el);
|
|
155
166
|
else
|
|
156
167
|
spanRefs.current.delete(index);
|
|
157
|
-
}, className: "text-[#32D2E2]", children: token.text }, index)) : (_jsx("span", { children: token.text }, index)))) : (_jsx("span", { className: "text-muted", children: placeholder })) }), _jsx(Input, { ref: inputRef, id: id, variant: "plain",
|
|
168
|
+
}, className: "text-[#32D2E2]", children: token.text }, index)) : (_jsx("span", { children: token.text }, index)))) : (_jsx("span", { className: "text-muted", children: placeholder })) }), _jsx(Input, { ref: inputRef, id: id, variant: "plain", role: source ? 'combobox' : undefined, "aria-autocomplete": source ? 'list' : undefined, "aria-expanded": source ? autocompleteOpen : undefined, "aria-controls": source && autocompleteOpen ? listboxId : undefined, "aria-activedescendant": source && autocompleteOpen && autocompleteActiveIndex >= 0
|
|
169
|
+
? `${listboxId}-option-${autocompleteActiveIndex}`
|
|
170
|
+
: undefined, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": tooltip ? tooltipId : undefined, className: `relative w-full min-w-0 border-none bg-transparent px-2 py-1.5 text-[14px] text-transparent caret-text focus-visible:shadow-none ${className}`, type: "text", placeholder: placeholder, value: value, onChange: (e) => {
|
|
158
171
|
onChange(e.target.value);
|
|
159
172
|
queueMicrotask(updateTooltipFromCaret);
|
|
160
|
-
}, onFocus:
|
|
173
|
+
}, onFocus: () => {
|
|
174
|
+
openAutocomplete();
|
|
175
|
+
updateTooltipFromCaret();
|
|
176
|
+
}, onBlur: closeAutocomplete, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onSelect: updateTooltipFromCaret, onClick: updateTooltipFromCaret, onScroll: syncScroll, onMouseMove: handleMouseMove, onMouseLeave: scheduleHide }), source && (_jsx(SuggestionList, { open: autocompleteOpen, items: autocompleteItems, activeIndex: autocompleteActiveIndex, anchorRef: inputRef, listboxId: listboxId, onSelect: selectItem, onActiveIndexChange: setActiveIndex, onClose: closeSuggestions })), tooltip && tooltipContent && (_jsxs("div", { id: tooltipId, role: "tooltip", className: "pointer-events-auto fixed z-50 flex max-w-sm -translate-x-1/2 -translate-y-full flex-col gap-1.5 rounded-md border border-separator bg-surface px-3 py-2 text-[14px] text-text shadow-md", style: { top: tooltip.top - 4, left: tooltip.left }, onMouseEnter: cancelHide, onMouseLeave: () => setTooltip(null), children: [_jsx("span", { className: tooltipContent.muted ? 'text-muted' : undefined, children: tooltipContent.text }), onEditVariable && (_jsx("button", { type: "button", className: "self-start text-[14px] text-accent hover:underline app-no-drag", "aria-label": `Edit value for ${tooltip.key}`, onClick: () => {
|
|
161
177
|
onEditVariable();
|
|
162
178
|
setTooltip(null);
|
|
163
179
|
}, children: "Edit value" }))] }))] }));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { AsyncListState, ErrorRetry, LoadingMessage } from './AsyncListState/index.js';
|
|
2
|
+
export { AutocompleteInput, SuggestionList, useAutocomplete, type AutocompleteInputProps, type AutocompleteSource } from './Autocomplete/index.js';
|
|
2
3
|
export { BusyIndicator } from './BusyIndicator/index.js';
|
|
3
4
|
export type { Props as BusyIndicatorProps } from './BusyIndicator/index.js';
|
|
4
5
|
export { BackButton } from './BackButton/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
package/dist/components/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { AsyncListState, ErrorRetry, LoadingMessage } from './AsyncListState/index.js';
|
|
2
|
+
export { AutocompleteInput, SuggestionList, useAutocomplete } from './Autocomplete/index.js';
|
|
2
3
|
export { BusyIndicator } from './BusyIndicator/index.js';
|
|
3
4
|
export { BackButton } from './BackButton/index.js';
|
|
4
5
|
export { Badge } from './Badge/index.js';
|
|
@@ -4,7 +4,8 @@ import type { ReactNode, ReactPortal } from 'react';
|
|
|
4
4
|
* the sidebar or other overflow-hidden plugin webview containers.
|
|
5
5
|
*
|
|
6
6
|
* @param node - Modal element to render.
|
|
7
|
-
* @returns Portal into document.body
|
|
7
|
+
* @returns Portal into document.body.
|
|
8
|
+
* @throws When `document` is unavailable (SSR, tests, or misconfigured host).
|
|
8
9
|
*/
|
|
9
10
|
export declare function portalToBody(node: ReactNode): ReactPortal;
|
|
10
11
|
//# sourceMappingURL=portalToBody.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portalToBody.d.ts","sourceRoot":"","sources":["../../src/components/portalToBody.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpD
|
|
1
|
+
{"version":3,"file":"portalToBody.d.ts","sourceRoot":"","sources":["../../src/components/portalToBody.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,CAKzD"}
|
|
@@ -4,11 +4,12 @@ import { createPortal } from '@harborclient/sdk/react-dom';
|
|
|
4
4
|
* the sidebar or other overflow-hidden plugin webview containers.
|
|
5
5
|
*
|
|
6
6
|
* @param node - Modal element to render.
|
|
7
|
-
* @returns Portal into document.body
|
|
7
|
+
* @returns Portal into document.body.
|
|
8
|
+
* @throws When `document` is unavailable (SSR, tests, or misconfigured host).
|
|
8
9
|
*/
|
|
9
10
|
export function portalToBody(node) {
|
|
10
|
-
if (typeof document
|
|
11
|
-
|
|
11
|
+
if (typeof document === 'undefined') {
|
|
12
|
+
throw new Error('portalToBody requires a DOM document');
|
|
12
13
|
}
|
|
13
|
-
return node;
|
|
14
|
+
return createPortal(node, document.body);
|
|
14
15
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type * from './types';
|
|
1
|
+
export type * from './types.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAC"}
|
package/dist/main.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { CodeEditorSetup, CodeEditorTheme, Disposable, EchoServerIncomingRequest, EchoServerStartResult, EchoServerStatus, MainPluginContext, PluginHttp, PluginHttpRequest, PluginHttpResponse, PluginIpc, PluginScriptCollectionInit, PluginScriptContext, PluginScriptContextInit, PluginScriptEnvironmentInit, PluginScriptKeyValue, PluginScriptRequestInit, PluginScriptResponseInit, PluginScriptRunResult, PluginScripts, PluginScriptTestResult, PluginServer, PluginStorage, ScriptPhase } from './types';
|
|
1
|
+
export type { CodeEditorSetup, CodeEditorTheme, Disposable, EchoServerIncomingRequest, EchoServerStartResult, EchoServerStatus, MainPluginContext, PluginHttp, PluginHttpRequest, PluginHttpResponse, PluginIpc, PluginScriptCollectionInit, PluginScriptContext, PluginScriptContextInit, PluginScriptEnvironmentInit, PluginScriptKeyValue, PluginScriptRequestInit, PluginScriptResponseInit, PluginScriptRunResult, PluginScripts, PluginScriptTestResult, PluginServer, PluginStorage, ScriptPhase } from './types.js';
|
|
2
2
|
//# sourceMappingURL=main.d.ts.map
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,eAAe,EACf,UAAU,EACV,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,0BAA0B,EAC1B,mBAAmB,EACnB,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,WAAW,EACZ,MAAM,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,eAAe,EACf,UAAU,EACV,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,0BAA0B,EAC1B,mBAAmB,EACnB,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,WAAW,EACZ,MAAM,YAAY,CAAC"}
|
package/dist/runtime/hcBridge.js
CHANGED
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as React from 'react';
|
|
2
|
-
import type { Disposable, PluginContext, ThemeContribution } from '../types';
|
|
2
|
+
import type { Disposable, PluginContext, ThemeContribution } from '../types.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Installs the HarborClient renderer React instance for plugin JSX and hooks.
|
package/dist/runtime/store.d.ts
CHANGED
|
@@ -41,7 +41,8 @@ export interface StorageStore<T> {
|
|
|
41
41
|
*/
|
|
42
42
|
reloadFromStorage(): Promise<void>;
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* Persists to storage, then updates the in-memory snapshot and notifies subscribers.
|
|
45
|
+
* Rejects when persistence fails; the snapshot is left unchanged.
|
|
45
46
|
*
|
|
46
47
|
* @param next - New snapshot value.
|
|
47
48
|
*/
|
|
@@ -93,6 +94,10 @@ export declare function createExternalStore<T>(initial: T): {
|
|
|
93
94
|
/**
|
|
94
95
|
* Creates a storage-backed external store for sharing state across plugin webviews.
|
|
95
96
|
*
|
|
97
|
+
* Hydrates from storage asynchronously on creation. Synchronous {@link StorageStore.getSnapshot}
|
|
98
|
+
* may return `parse(undefined)` until hydration completes; use {@link StorageStore.useValue}
|
|
99
|
+
* or await {@link StorageStore.reloadFromStorage} when you need the persisted value before reading.
|
|
100
|
+
*
|
|
96
101
|
* Separate plugin webviews do not share memory; use {@link syncOnWindowFocus} to
|
|
97
102
|
* reload when another surface writes storage.
|
|
98
103
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/runtime/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAE5C;;OAEG;IACH,WAAW,IAAI,CAAC,CAAC;IAEjB;;OAEG;IACH,QAAQ,IAAI,CAAC,CAAC;IAEd;;OAEG;IACH,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/runtime/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAE5C;;OAEG;IACH,WAAW,IAAI,CAAC,CAAC;IAEjB;;OAEG;IACH,QAAQ,IAAI,CAAC,CAAC;IAEd;;OAEG;IACH,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,4CAA4C;IAC5C,OAAO,EAAE,WAAW,CAAC;IAErB,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IAEZ;;;;;OAKG;IACH,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC;IAE3B;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;IAEjC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG;IAClD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAChD,WAAW,EAAE,MAAM,CAAC,CAAC;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;CAC7B,CAkBA;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAkD5F;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAO1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,wBAAwB,GACjC,UAAU,CA0BZ"}
|
package/dist/runtime/store.js
CHANGED
|
@@ -35,6 +35,10 @@ function defaultEquals(a, b) {
|
|
|
35
35
|
/**
|
|
36
36
|
* Creates a storage-backed external store for sharing state across plugin webviews.
|
|
37
37
|
*
|
|
38
|
+
* Hydrates from storage asynchronously on creation. Synchronous {@link StorageStore.getSnapshot}
|
|
39
|
+
* may return `parse(undefined)` until hydration completes; use {@link StorageStore.useValue}
|
|
40
|
+
* or await {@link StorageStore.reloadFromStorage} when you need the persisted value before reading.
|
|
41
|
+
*
|
|
38
42
|
* Separate plugin webviews do not share memory; use {@link syncOnWindowFocus} to
|
|
39
43
|
* reload when another surface writes storage.
|
|
40
44
|
*
|
|
@@ -58,7 +62,8 @@ export function createStorageStore(options) {
|
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
/**
|
|
61
|
-
*
|
|
65
|
+
* Persists when the value changed, then updates the snapshot and notifies subscribers.
|
|
66
|
+
* Rejects when persistence fails; the snapshot is left unchanged.
|
|
62
67
|
*
|
|
63
68
|
* @param next - New snapshot value.
|
|
64
69
|
*/
|
|
@@ -67,8 +72,8 @@ export function createStorageStore(options) {
|
|
|
67
72
|
if (equals(current, next)) {
|
|
68
73
|
return;
|
|
69
74
|
}
|
|
70
|
-
external.setState(next);
|
|
71
75
|
await storage.set(key, next);
|
|
76
|
+
external.setState(next);
|
|
72
77
|
}
|
|
73
78
|
/**
|
|
74
79
|
* React hook returning the current storage-backed snapshot.
|
|
@@ -76,6 +81,7 @@ export function createStorageStore(options) {
|
|
|
76
81
|
function useValue() {
|
|
77
82
|
return useSyncExternalStore(external.subscribe, external.getSnapshot, external.getSnapshot);
|
|
78
83
|
}
|
|
84
|
+
void reloadFromStorage();
|
|
79
85
|
return {
|
|
80
86
|
subscribe: external.subscribe,
|
|
81
87
|
getSnapshot: external.getSnapshot,
|
package/dist/runtime/store.ts
CHANGED
|
@@ -49,7 +49,8 @@ export interface StorageStore<T> {
|
|
|
49
49
|
reloadFromStorage(): Promise<void>;
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
52
|
+
* Persists to storage, then updates the in-memory snapshot and notifies subscribers.
|
|
53
|
+
* Rejects when persistence fails; the snapshot is left unchanged.
|
|
53
54
|
*
|
|
54
55
|
* @param next - New snapshot value.
|
|
55
56
|
*/
|
|
@@ -137,6 +138,10 @@ function defaultEquals<T>(a: T, b: T): boolean {
|
|
|
137
138
|
/**
|
|
138
139
|
* Creates a storage-backed external store for sharing state across plugin webviews.
|
|
139
140
|
*
|
|
141
|
+
* Hydrates from storage asynchronously on creation. Synchronous {@link StorageStore.getSnapshot}
|
|
142
|
+
* may return `parse(undefined)` until hydration completes; use {@link StorageStore.useValue}
|
|
143
|
+
* or await {@link StorageStore.reloadFromStorage} when you need the persisted value before reading.
|
|
144
|
+
*
|
|
140
145
|
* Separate plugin webviews do not share memory; use {@link syncOnWindowFocus} to
|
|
141
146
|
* reload when another surface writes storage.
|
|
142
147
|
*
|
|
@@ -162,7 +167,8 @@ export function createStorageStore<T>(options: CreateStorageStoreOptions<T>): St
|
|
|
162
167
|
}
|
|
163
168
|
|
|
164
169
|
/**
|
|
165
|
-
*
|
|
170
|
+
* Persists when the value changed, then updates the snapshot and notifies subscribers.
|
|
171
|
+
* Rejects when persistence fails; the snapshot is left unchanged.
|
|
166
172
|
*
|
|
167
173
|
* @param next - New snapshot value.
|
|
168
174
|
*/
|
|
@@ -171,8 +177,8 @@ export function createStorageStore<T>(options: CreateStorageStoreOptions<T>): St
|
|
|
171
177
|
if (equals(current, next)) {
|
|
172
178
|
return;
|
|
173
179
|
}
|
|
174
|
-
external.setState(next);
|
|
175
180
|
await storage.set(key, next);
|
|
181
|
+
external.setState(next);
|
|
176
182
|
}
|
|
177
183
|
|
|
178
184
|
/**
|
|
@@ -182,6 +188,8 @@ export function createStorageStore<T>(options: CreateStorageStoreOptions<T>): St
|
|
|
182
188
|
return useSyncExternalStore(external.subscribe, external.getSnapshot, external.getSnapshot);
|
|
183
189
|
}
|
|
184
190
|
|
|
191
|
+
void reloadFromStorage();
|
|
192
|
+
|
|
185
193
|
return {
|
|
186
194
|
subscribe: external.subscribe,
|
|
187
195
|
getSnapshot: external.getSnapshot,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harborclient/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "TypeScript SDK for HarborClient plugin development.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"harborclient",
|
|
@@ -201,7 +201,8 @@
|
|
|
201
201
|
"vitepress-plugin-mermaid": "^2.0.17"
|
|
202
202
|
},
|
|
203
203
|
"scripts": {
|
|
204
|
-
"build": "tsc -p tsconfig.build.json && node scripts/copy-runtime.mjs",
|
|
204
|
+
"build": "tsc -p tsconfig.build.json && node scripts/copy-runtime.mjs && node scripts/assert-dist-publishable.mjs",
|
|
205
|
+
"attw": "attw --profile esm-only --no-summary",
|
|
205
206
|
"format": "prettier --write .",
|
|
206
207
|
"format:check": "prettier --check .",
|
|
207
208
|
"lint": "eslint --cache .",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"enhanceControl.test.d.ts","sourceRoot":"","sources":["../../src/components/enhanceControl.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from '@jest/globals';
|
|
2
|
-
import { createElement, Fragment, isValidElement } from 'react';
|
|
3
|
-
import { enhanceControl } from './enhanceControl.js';
|
|
4
|
-
/** Stand-in for {@link Input} — function component that forwards props to a native input. */
|
|
5
|
-
function TextInput(props) {
|
|
6
|
-
return createElement('input', { type: 'text', ...props });
|
|
7
|
-
}
|
|
8
|
-
function propsOf(node) {
|
|
9
|
-
if (!isValidElement(node)) {
|
|
10
|
-
throw new Error('Expected a valid React element');
|
|
11
|
-
}
|
|
12
|
-
return node.props;
|
|
13
|
-
}
|
|
14
|
-
describe('enhanceControl', () => {
|
|
15
|
-
it('merges aria-describedby and aria-invalid on a form component', () => {
|
|
16
|
-
const result = enhanceControl(createElement(TextInput), {
|
|
17
|
-
describedBy: 'field-error',
|
|
18
|
-
invalid: true
|
|
19
|
-
});
|
|
20
|
-
expect(propsOf(result)['aria-describedby']).toBe('field-error');
|
|
21
|
-
expect(propsOf(result)['aria-invalid']).toBe(true);
|
|
22
|
-
});
|
|
23
|
-
it('includes description id in aria-describedby without setting aria-invalid', () => {
|
|
24
|
-
const result = enhanceControl(createElement(TextInput), {
|
|
25
|
-
describedBy: 'api-key-description'
|
|
26
|
-
});
|
|
27
|
-
expect(propsOf(result)['aria-describedby']).toBe('api-key-description');
|
|
28
|
-
expect(propsOf(result)['aria-invalid']).toBeUndefined();
|
|
29
|
-
});
|
|
30
|
-
it('merges description and error ids in aria-describedby', () => {
|
|
31
|
-
const result = enhanceControl(createElement(TextInput), {
|
|
32
|
-
describedBy: 'api-key-description api-key-error',
|
|
33
|
-
invalid: true
|
|
34
|
-
});
|
|
35
|
-
expect(propsOf(result)['aria-describedby']).toBe('api-key-description api-key-error');
|
|
36
|
-
expect(propsOf(result)['aria-invalid']).toBe(true);
|
|
37
|
-
});
|
|
38
|
-
it('merges with an existing aria-describedby value', () => {
|
|
39
|
-
const result = enhanceControl(createElement(TextInput, { 'aria-describedby': 'existing' }), {
|
|
40
|
-
describedBy: 'field-error'
|
|
41
|
-
});
|
|
42
|
-
expect(propsOf(result)['aria-describedby']).toBe('existing field-error');
|
|
43
|
-
});
|
|
44
|
-
it('enhances a control wrapped in a div', () => {
|
|
45
|
-
const wrapped = createElement('div', null, createElement(TextInput));
|
|
46
|
-
const result = enhanceControl(wrapped, { describedBy: 'field-error' });
|
|
47
|
-
const inner = propsOf(result).children;
|
|
48
|
-
expect(propsOf(inner)['aria-describedby']).toBe('field-error');
|
|
49
|
-
});
|
|
50
|
-
it('enhances a native input wrapped in a div', () => {
|
|
51
|
-
const wrapped = createElement('div', null, createElement('input', { type: 'text' }));
|
|
52
|
-
const result = enhanceControl(wrapped, { describedBy: 'field-error' });
|
|
53
|
-
const inner = propsOf(result).children;
|
|
54
|
-
expect(propsOf(inner)['aria-describedby']).toBe('field-error');
|
|
55
|
-
});
|
|
56
|
-
it('unwraps a single-element array', () => {
|
|
57
|
-
const result = enhanceControl([createElement(TextInput)], { describedBy: 'field-error' });
|
|
58
|
-
expect(propsOf(result)['aria-describedby']).toBe('field-error');
|
|
59
|
-
});
|
|
60
|
-
it('enhances a control wrapped in a fragment', () => {
|
|
61
|
-
const wrapped = createElement(Fragment, null, createElement(TextInput));
|
|
62
|
-
const result = enhanceControl(wrapped, { describedBy: 'field-error' });
|
|
63
|
-
const inner = propsOf(result).children;
|
|
64
|
-
expect(propsOf(inner)['aria-describedby']).toBe('field-error');
|
|
65
|
-
});
|
|
66
|
-
it('leaves multiple siblings unchanged', () => {
|
|
67
|
-
const child = [createElement(TextInput), createElement('span')];
|
|
68
|
-
const result = enhanceControl(child, { describedBy: 'field-error' });
|
|
69
|
-
expect(result).toBe(child);
|
|
70
|
-
});
|
|
71
|
-
it('sets id when the control has none', () => {
|
|
72
|
-
const result = enhanceControl(createElement('input', { type: 'checkbox' }), {
|
|
73
|
-
id: 'auto-id'
|
|
74
|
-
});
|
|
75
|
-
expect(propsOf(result).id).toBe('auto-id');
|
|
76
|
-
});
|
|
77
|
-
it('preserves an existing id', () => {
|
|
78
|
-
const result = enhanceControl(createElement('input', { id: 'existing-id', type: 'checkbox' }), {
|
|
79
|
-
id: 'auto-id'
|
|
80
|
-
});
|
|
81
|
-
expect(propsOf(result).id).toBe('existing-id');
|
|
82
|
-
});
|
|
83
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../src/components/utils.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from '@jest/globals';
|
|
2
|
-
import { resolveMenuTypeahead, resolveTabListKeyAction } from './utils.js';
|
|
3
|
-
describe('resolveTabListKeyAction', () => {
|
|
4
|
-
it('returns null for unhandled keys', () => {
|
|
5
|
-
expect(resolveTabListKeyAction('Enter', 0, 3)).toBeNull();
|
|
6
|
-
expect(resolveTabListKeyAction('Tab', 1, 3)).toBeNull();
|
|
7
|
-
});
|
|
8
|
-
it('returns null when itemCount is zero', () => {
|
|
9
|
-
expect(resolveTabListKeyAction('ArrowRight', 0, 0)).toBeNull();
|
|
10
|
-
});
|
|
11
|
-
it('moves forward and backward with arrow keys', () => {
|
|
12
|
-
expect(resolveTabListKeyAction('ArrowRight', 0, 3)).toBe(1);
|
|
13
|
-
expect(resolveTabListKeyAction('ArrowDown', 1, 3)).toBe(2);
|
|
14
|
-
expect(resolveTabListKeyAction('ArrowLeft', 0, 3)).toBe(2);
|
|
15
|
-
expect(resolveTabListKeyAction('ArrowUp', 2, 3)).toBe(1);
|
|
16
|
-
});
|
|
17
|
-
it('jumps to first and last enabled items with Home and End', () => {
|
|
18
|
-
expect(resolveTabListKeyAction('Home', 2, 3)).toBe(0);
|
|
19
|
-
expect(resolveTabListKeyAction('End', 0, 3)).toBe(2);
|
|
20
|
-
});
|
|
21
|
-
it('skips disabled indices when navigating', () => {
|
|
22
|
-
expect(resolveTabListKeyAction('ArrowRight', 0, 3, { disabledIndices: [1] })).toBe(2);
|
|
23
|
-
expect(resolveTabListKeyAction('ArrowLeft', 2, 3, { disabledIndices: [1] })).toBe(0);
|
|
24
|
-
expect(resolveTabListKeyAction('Home', 2, 3, { disabledIndices: [0] })).toBe(1);
|
|
25
|
-
expect(resolveTabListKeyAction('End', 0, 3, { disabledIndices: [2] })).toBe(1);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
describe('resolveMenuTypeahead', () => {
|
|
29
|
-
const labels = ['Rename', 'Duplicate', 'Delete'];
|
|
30
|
-
it('returns null for non-printable keys', () => {
|
|
31
|
-
expect(resolveMenuTypeahead(labels, 0, 'Enter', '')).toBeNull();
|
|
32
|
-
expect(resolveMenuTypeahead(labels, 0, ' ', 'd')).toBeNull();
|
|
33
|
-
});
|
|
34
|
-
it('matches the next item whose label starts with the typed prefix', () => {
|
|
35
|
-
expect(resolveMenuTypeahead(labels, 0, 'd', '')).toEqual({ index: 1, buffer: 'd' });
|
|
36
|
-
expect(resolveMenuTypeahead(labels, 1, 'e', 'd')).toEqual({ index: 2, buffer: 'de' });
|
|
37
|
-
});
|
|
38
|
-
it('wraps the search from the current index', () => {
|
|
39
|
-
expect(resolveMenuTypeahead(labels, 2, 'r', '')).toEqual({ index: 0, buffer: 'r' });
|
|
40
|
-
});
|
|
41
|
-
it('returns null when no label matches the prefix', () => {
|
|
42
|
-
expect(resolveMenuTypeahead(labels, 0, 'z', '')).toBeNull();
|
|
43
|
-
});
|
|
44
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolveRequest.test.d.ts","sourceRoot":"","sources":["../../src/http/resolveRequest.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from '@jest/globals';
|
|
2
|
-
import { resolveRequest } from './resolveRequest.js';
|
|
3
|
-
import { substituteVariables } from './substitute.js';
|
|
4
|
-
describe('substituteVariables', () => {
|
|
5
|
-
it('replaces known placeholders', () => {
|
|
6
|
-
expect(substituteVariables('{{host}}/api', { host: 'https://example.com' })).toBe('https://example.com/api');
|
|
7
|
-
});
|
|
8
|
-
});
|
|
9
|
-
describe('resolveRequest', () => {
|
|
10
|
-
it('merges collection auth and variables', () => {
|
|
11
|
-
const context = {
|
|
12
|
-
draft: {
|
|
13
|
-
method: 'POST',
|
|
14
|
-
url: '{{base}}/users',
|
|
15
|
-
params: [{ key: 'page', value: '1', enabled: true }],
|
|
16
|
-
headers: [{ key: 'X-Test', value: '1', enabled: true }],
|
|
17
|
-
body: '{"ok":true}',
|
|
18
|
-
auth: {
|
|
19
|
-
type: 'none',
|
|
20
|
-
basic: { username: '', password: '' },
|
|
21
|
-
bearer: { token: '' }
|
|
22
|
-
},
|
|
23
|
-
body_type: 'json'
|
|
24
|
-
},
|
|
25
|
-
response: null,
|
|
26
|
-
readOnly: true,
|
|
27
|
-
collectionAuth: {
|
|
28
|
-
type: 'bearer',
|
|
29
|
-
basic: { username: '', password: '' },
|
|
30
|
-
bearer: { token: '{{token}}' }
|
|
31
|
-
},
|
|
32
|
-
collectionHeaders: [{ key: 'Accept', value: 'application/json', enabled: true }],
|
|
33
|
-
variables: { base: 'https://api.test', token: 'secret' },
|
|
34
|
-
requestKey: 'POST https://api.test/users'
|
|
35
|
-
};
|
|
36
|
-
const resolved = resolveRequest(context);
|
|
37
|
-
expect(resolved.url).toBe('https://api.test/users?page=1');
|
|
38
|
-
expect(resolved.headers.Authorization).toBe('Bearer secret');
|
|
39
|
-
expect(resolved.headers['Content-Type']).toBe('application/json');
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"substitute.test.d.ts","sourceRoot":"","sources":["../../src/http/substitute.test.ts"],"names":[],"mappings":""}
|