Compare commits

..

2 Commits

Author SHA1 Message Date
Andrew Bastin
65884293be chore: introduce docker buildx for multi-platform build 2023-09-18 21:16:23 +05:30
Andrew Bastin
3cb4861bac chore: pin netlify-cli version on ui deploy script 2023-09-18 20:51:42 +05:30
34 changed files with 124 additions and 388 deletions

View File

@@ -18,6 +18,9 @@ jobs:
- name: Setup QEMU - name: Setup QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub - name: Log in to Docker Hub
uses: docker/login-action@v2 uses: docker/login-action@v2
with: with:

View File

@@ -36,7 +36,7 @@ jobs:
# Deploy the ui site with netlify-cli # Deploy the ui site with netlify-cli
- name: Deploy to Netlify (ui) - name: Deploy to Netlify (ui)
run: npx netlify-cli deploy --dir=packages/hoppscotch-ui/.histoire/dist --prod run: npx netlify-cli@15.11.0 deploy --dir=packages/hoppscotch-ui/.histoire/dist --prod
env: env:
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_UI_SITE_ID }} NETLIFY_SITE_ID: ${{ secrets.NETLIFY_UI_SITE_ID }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}

View File

@@ -14,10 +14,9 @@ import { isHoppCLIError } from "../utils/checks";
export const test = (path: string, options: TestCmdOptions) => async () => { export const test = (path: string, options: TestCmdOptions) => async () => {
try { try {
const delay = options.delay ? parseDelayOption(options.delay) : 0 const delay = options.delay ? parseDelayOption(options.delay) : 0
const envName = options.envName const envs = options.env ? await parseEnvsData(options.env) : <HoppEnvs>{ global: [], selected: [] }
const envs = options.env ? await parseEnvsData(options.env, envName) : <HoppEnvs>{ global: [], selected: [] }
const collections = await parseCollectionData(path) const collections = await parseCollectionData(path)
const report = await collectionsRunner({collections, envs, delay}) const report = await collectionsRunner({collections, envs, delay})
const hasSucceeded = collectionsRunnerResult(report) const hasSucceeded = collectionsRunnerResult(report)
collectionsRunnerExit(hasSucceeded) collectionsRunnerExit(hasSucceeded)

View File

@@ -51,9 +51,6 @@ export const handleError = <T extends HoppErrorCode>(error: HoppError<T>) => {
case "MALFORMED_COLLECTION": case "MALFORMED_COLLECTION":
ERROR_MSG = `${error.path}\n${parseErrorData(error.data)}`; ERROR_MSG = `${error.path}\n${parseErrorData(error.data)}`;
break; break;
case "ENVIRONMENT_NAME_NOT_FOUND":
ERROR_MSG = `\n${parseErrorData(error.data)}`;
break;
case "NO_FILE_PATH": case "NO_FILE_PATH":
ERROR_MSG = `Please provide a hoppscotch-collection file path.`; ERROR_MSG = `Please provide a hoppscotch-collection file path.`;
break; break;

View File

@@ -50,7 +50,6 @@ program
"path to a hoppscotch collection.json file for CI testing" "path to a hoppscotch collection.json file for CI testing"
) )
.option("-e, --env <file_path>", "path to an environment variables json file") .option("-e, --env <file_path>", "path to an environment variables json file")
.option("-eN, --envName <environment_name>","Specific Name of the environment")
.option( .option(
"-d, --delay <delay_in_ms>", "-d, --delay <delay_in_ms>",
"delay in milliseconds(ms) between consecutive requests within a collection" "delay in milliseconds(ms) between consecutive requests within a collection"

View File

@@ -33,5 +33,4 @@ export interface EffectiveHoppRESTRequest extends HoppRESTRequest {
effectiveFinalHeaders: { key: string; value: string; active: boolean }[]; effectiveFinalHeaders: { key: string; value: string; active: boolean }[];
effectiveFinalParams: { key: string; value: string; active: boolean }[]; effectiveFinalParams: { key: string; value: string; active: boolean }[];
effectiveFinalBody: FormData | string | null; effectiveFinalBody: FormData | string | null;
effectiveFinalMaskedURL: string;
} }

View File

@@ -5,46 +5,23 @@ import { readJsonFile } from "../../utils/mutators";
/** /**
* Parses env json file for given path and validates the parsed env json object. * Parses env json file for given path and validates the parsed env json object.
* @param path Path of env.json file to be parsed. * @param path Path of env.json file to be parsed.
* @param envName Name of the environment that should be used. If undefined first environment is used.
* @returns For successful parsing we get HoppEnvs object. * @returns For successful parsing we get HoppEnvs object.
*/ */
export async function parseEnvsData(path: string, envName: string | undefined) { export async function parseEnvsData(path: string) {
const contents = await readJsonFile(path) const contents = await readJsonFile(path)
if(!(contents && typeof contents === "object" && Array.isArray(contents))) {
if(!(contents && typeof contents === "object" && !Array.isArray(contents))) {
throw error({ code: "MALFORMED_ENV_FILE", path, data: null }) throw error({ code: "MALFORMED_ENV_FILE", path, data: null })
} }
const envPairs: Array<HoppEnvPair> = [] const envPairs: Array<HoppEnvPair> = []
const contentEntries = Object.entries(contents) for( const [key,value] of Object.entries(contents)) {
let environmentFound = false; if(typeof value !== "string") {
throw error({ code: "MALFORMED_ENV_FILE", path, data: {value: value} })
}
for(const [key, obj] of contentEntries) { envPairs.push({key, value})
if(!(typeof obj === "object" && "name" in obj && "variables" in obj)) {
throw error({ code: "MALFORMED_ENV_FILE", path, data: { value: obj } })
}
if(envName && envName !== obj.name) {
continue
}
environmentFound = true;
for(const variable of obj.variables) {
if(
!(
typeof variable === "object" &&
"key" in variable &&
"value" in variable &&
"secret" in variable
)
) {
throw error({ code: "MALFORMED_ENV_FILE", path, data: { value: variable } });
}
const { key, value, secret } = variable;
envPairs.push({ key: key, value: value, secret: secret });
}
break
}
if(envName && !environmentFound) {
throw error({ code: "ENVIRONMENT_NAME_NOT_FOUND", data: envName });
} }
return <HoppEnvs>{ global: [], selected: envPairs } return <HoppEnvs>{ global: [], selected: envPairs }
} }

View File

@@ -1,7 +1,6 @@
export type TestCmdOptions = { export type TestCmdOptions = {
env: string | undefined; env: string | undefined;
delay: string | undefined; delay: string | undefined;
envName: string | undefined;
}; };
export type HOPP_ENV_FILE_EXT = "json"; export type HOPP_ENV_FILE_EXT = "json";

View File

@@ -15,7 +15,6 @@ type HoppErrors = {
FILE_NOT_FOUND: HoppErrorPath; FILE_NOT_FOUND: HoppErrorPath;
UNKNOWN_COMMAND: HoppErrorCmd; UNKNOWN_COMMAND: HoppErrorCmd;
MALFORMED_COLLECTION: HoppErrorPath & HoppErrorData; MALFORMED_COLLECTION: HoppErrorPath & HoppErrorData;
ENVIRONMENT_NAME_NOT_FOUND: HoppErrorData;
NO_FILE_PATH: {}; NO_FILE_PATH: {};
PRE_REQUEST_SCRIPT_ERROR: HoppErrorData; PRE_REQUEST_SCRIPT_ERROR: HoppErrorData;
PARSING_ERROR: HoppErrorData; PARSING_ERROR: HoppErrorData;

View File

@@ -7,7 +7,7 @@ export type FormDataEntry = {
value: string | Blob; value: string | Blob;
}; };
export type HoppEnvPair = { key: string; value: string; secret: boolean }; export type HoppEnvPair = { key: string; value: string };
export type HoppEnvs = { export type HoppEnvs = {
global: HoppEnvPair[]; global: HoppEnvPair[];

View File

@@ -1,7 +1,7 @@
import { bold } from "chalk"; import { bold } from "chalk";
import { groupEnd, group, log } from "console"; import { groupEnd, group, log } from "console";
import { handleError } from "../handlers/error"; import { handleError } from "../handlers/error";
import { Method } from "axios"; import { RequestConfig } from "../interfaces/request";
import { RequestRunnerResponse, TestReport } from "../interfaces/response"; import { RequestRunnerResponse, TestReport } from "../interfaces/response";
import { HoppCLIError } from "../types/errors"; import { HoppCLIError } from "../types/errors";
import { import {
@@ -172,12 +172,11 @@ export const printFailedTestsReport = (
export const printRequestRunner = { export const printRequestRunner = {
/** /**
* Request-runner starting message. * Request-runner starting message.
* @param requestMethod Provides request's method * @param requestConfig Provides request's method and url.
* @param maskedURL Provides the URL with secrets masked with asterisks
*/ */
start: (requestMethod: Method | undefined, maskedURL: string) => { start: (requestConfig: RequestConfig) => {
const METHOD = BG_INFO(` ${requestMethod} `); const METHOD = BG_INFO(` ${requestConfig.method} `);
const ENDPOINT = maskedURL; const ENDPOINT = requestConfig.url;
process.stdout.write(`${METHOD} ${ENDPOINT}`); process.stdout.write(`${METHOD} ${ENDPOINT}`);
}, },

View File

@@ -50,9 +50,9 @@ export const preRequestScriptRunner = (
isHoppCLIError(reason) isHoppCLIError(reason)
? reason ? reason
: error({ : error({
code: "PRE_REQUEST_SCRIPT_ERROR", code: "PRE_REQUEST_SCRIPT_ERROR",
data: reason, data: reason,
}) })
) )
); );
@@ -151,12 +151,6 @@ export function getEffectiveRESTRequest(
request.endpoint, request.endpoint,
envVariables envVariables
); );
const maskedEnvVariables = setAllEnvironmentValuesToAsterisk(envVariables)
const _effectiveFinalMaskedURL = parseTemplateStringE(
request.endpoint,
maskedEnvVariables)
if (E.isLeft(_effectiveFinalURL)) { if (E.isLeft(_effectiveFinalURL)) {
return E.left( return E.left(
error({ error({
@@ -166,7 +160,6 @@ export function getEffectiveRESTRequest(
); );
} }
const effectiveFinalURL = _effectiveFinalURL.right; const effectiveFinalURL = _effectiveFinalURL.right;
const effectiveFinalMaskedURL = E.isLeft(_effectiveFinalMaskedURL) ? request.endpoint : _effectiveFinalMaskedURL.right;
return E.right({ return E.right({
...request, ...request,
@@ -174,7 +167,6 @@ export function getEffectiveRESTRequest(
effectiveFinalHeaders, effectiveFinalHeaders,
effectiveFinalParams, effectiveFinalParams,
effectiveFinalBody, effectiveFinalBody,
effectiveFinalMaskedURL,
}); });
} }
@@ -250,15 +242,15 @@ function getFinalBodyFromRequest(
arrayFlatMap((x) => arrayFlatMap((x) =>
x.isFile x.isFile
? x.value.map((v) => ({ ? x.value.map((v) => ({
key: parseTemplateString(x.key, envVariables),
value: v as string | Blob,
}))
: [
{
key: parseTemplateString(x.key, envVariables), key: parseTemplateString(x.key, envVariables),
value: parseTemplateString(x.value, envVariables), value: v as string | Blob,
}, }))
] : [
{
key: parseTemplateString(x.key, envVariables),
value: parseTemplateString(x.value, envVariables),
},
]
), ),
toFormData, toFormData,
E.right E.right
@@ -295,22 +287,3 @@ export const getPreRequestMetrics = (
hasPreReqErrors ? { failed: 1, passed: 0 } : { failed: 0, passed: 1 }, hasPreReqErrors ? { failed: 1, passed: 0 } : { failed: 0, passed: 1 },
(scripts) => <PreRequestMetrics>{ scripts, duration } (scripts) => <PreRequestMetrics>{ scripts, duration }
); );
/**
* Mask all environment values with asterisks
* @param variables Environment variable array
* @returns Environment variable array with masked values
*/
const setAllEnvironmentValuesToAsterisk = (
variables: Environment["variables"]
): Environment["variables"] => {
const envVariables: Environment["variables"] = [];
for (const variable of variables) {
let value = variable.value
if (variable.secret) {
value = "******"
}
envVariables.push({ key: variable.key, secret: variable.secret, value: value })
}
return envVariables
}

View File

@@ -220,7 +220,6 @@ export const processRequest =
effectiveFinalHeaders: [], effectiveFinalHeaders: [],
effectiveFinalParams: [], effectiveFinalParams: [],
effectiveFinalURL: "", effectiveFinalURL: "",
effectiveFinalMaskedURL:"",
}; };
// Executing pre-request-script // Executing pre-request-script
@@ -238,8 +237,8 @@ export const processRequest =
// Creating request-config for request-runner. // Creating request-config for request-runner.
const requestConfig = createRequest(effectiveRequest); const requestConfig = createRequest(effectiveRequest);
printRequestRunner.start(requestConfig.method, effectiveRequest.effectiveFinalMaskedURL); printRequestRunner.start(requestConfig);
// Default value for request-runner's response. // Default value for request-runner's response.
let _requestRunnerRes: RequestRunnerResponse = { let _requestRunnerRes: RequestRunnerResponse = {

View File

@@ -48,8 +48,7 @@
"turn_off": "Ausschalten", "turn_off": "Ausschalten",
"turn_on": "Einschalten", "turn_on": "Einschalten",
"undo": "Rückgängig machen", "undo": "Rückgängig machen",
"yes": "Ja", "yes": "Ja"
"secret": "Als Secret speichern"
}, },
"add": { "add": {
"new": "Neue hinzufügen", "new": "Neue hinzufügen",
@@ -881,4 +880,4 @@
"team": "Team Workspace", "team": "Team Workspace",
"title": "Workspaces" "title": "Workspaces"
} }
} }

View File

@@ -48,8 +48,7 @@
"turn_off": "Turn off", "turn_off": "Turn off",
"turn_on": "Turn on", "turn_on": "Turn on",
"undo": "Undo", "undo": "Undo",
"yes": "Yes", "yes": "Yes"
"secret": "Save as secret"
}, },
"add": { "add": {
"new": "Add new", "new": "Add new",

View File

@@ -96,6 +96,7 @@ declare module 'vue' {
HoppSmartExpand: typeof import('@hoppscotch/ui')['HoppSmartExpand'] HoppSmartExpand: typeof import('@hoppscotch/ui')['HoppSmartExpand']
HoppSmartFileChip: typeof import('@hoppscotch/ui')['HoppSmartFileChip'] HoppSmartFileChip: typeof import('@hoppscotch/ui')['HoppSmartFileChip']
HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput'] HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput']
HoppSmartIntersection: typeof import('@hoppscotch/ui')['HoppSmartIntersection']
HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem'] HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem']
HoppSmartLink: typeof import('@hoppscotch/ui')['HoppSmartLink'] HoppSmartLink: typeof import('@hoppscotch/ui')['HoppSmartLink']
HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal'] HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal']
@@ -142,6 +143,7 @@ declare module 'vue' {
IconLucideAlertTriangle: typeof import('~icons/lucide/alert-triangle')['default'] IconLucideAlertTriangle: typeof import('~icons/lucide/alert-triangle')['default']
IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default'] IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default']
IconLucideArrowUpRight: typeof import('~icons/lucide/arrow-up-right')['default'] IconLucideArrowUpRight: typeof import('~icons/lucide/arrow-up-right')['default']
IconLucideBrush: typeof import('~icons/lucide/brush')['default']
IconLucideCheckCircle: typeof import('~icons/lucide/check-circle')['default'] IconLucideCheckCircle: typeof import('~icons/lucide/check-circle')['default']
IconLucideChevronRight: typeof import('~icons/lucide/chevron-right')['default'] IconLucideChevronRight: typeof import('~icons/lucide/chevron-right')['default']
IconLucideGlobe: typeof import('~icons/lucide/globe')['default'] IconLucideGlobe: typeof import('~icons/lucide/globe')['default']
@@ -151,8 +153,10 @@ declare module 'vue' {
IconLucideLayers: typeof import('~icons/lucide/layers')['default'] IconLucideLayers: typeof import('~icons/lucide/layers')['default']
IconLucideListEnd: typeof import('~icons/lucide/list-end')['default'] IconLucideListEnd: typeof import('~icons/lucide/list-end')['default']
IconLucideMinus: typeof import('~icons/lucide/minus')['default'] IconLucideMinus: typeof import('~icons/lucide/minus')['default']
IconLucideRss: typeof import('~icons/lucide/rss')['default']
IconLucideSearch: typeof import('~icons/lucide/search')['default'] IconLucideSearch: typeof import('~icons/lucide/search')['default']
IconLucideUsers: typeof import('~icons/lucide/users')['default'] IconLucideUsers: typeof import('~icons/lucide/users')['default']
IconLucideVerified: typeof import('~icons/lucide/verified')['default']
InterceptorsExtensionSubtitle: typeof import('./components/interceptors/ExtensionSubtitle.vue')['default'] InterceptorsExtensionSubtitle: typeof import('./components/interceptors/ExtensionSubtitle.vue')['default']
LensesHeadersRenderer: typeof import('./components/lenses/HeadersRenderer.vue')['default'] LensesHeadersRenderer: typeof import('./components/lenses/HeadersRenderer.vue')['default']
LensesHeadersRendererEntry: typeof import('./components/lenses/HeadersRendererEntry.vue')['default'] LensesHeadersRendererEntry: typeof import('./components/lenses/HeadersRendererEntry.vue')['default']

View File

@@ -60,17 +60,7 @@
:placeholder="`${t('count.value', { count: index + 1 })}`" :placeholder="`${t('count.value', { count: index + 1 })}`"
:envs="liveEnvs" :envs="liveEnvs"
:name="'value' + index" :name="'value' + index"
:secret="env.secret"
/> />
<div class="flex">
<HoppButtonSecondary
id="variable"
v-tippy="{ theme: 'tooltip' }"
:title="t('action.secret')"
:icon="env.secret ? IconEyeOff : IconEye"
@click="toggleEnvironmentSecret(index)"
/>
</div>
<div class="flex"> <div class="flex">
<HoppButtonSecondary <HoppButtonSecondary
id="variable" id="variable"
@@ -120,8 +110,6 @@ import IconTrash2 from "~icons/lucide/trash-2"
import IconDone from "~icons/lucide/check" import IconDone from "~icons/lucide/check"
import IconPlus from "~icons/lucide/plus" import IconPlus from "~icons/lucide/plus"
import IconTrash from "~icons/lucide/trash" import IconTrash from "~icons/lucide/trash"
import IconEye from "~icons/lucide/eye"
import IconEyeOff from "~icons/lucide/eye-off"
import { clone } from "lodash-es" import { clone } from "lodash-es"
import { computed, ref, watch } from "vue" import { computed, ref, watch } from "vue"
import * as E from "fp-ts/Either" import * as E from "fp-ts/Either"
@@ -152,7 +140,6 @@ type EnvironmentVariable = {
env: { env: {
key: string key: string
value: string value: string
secret: boolean
} }
} }
@@ -185,7 +172,7 @@ const idTicker = ref(0)
const editingName = ref<string | null>(null) const editingName = ref<string | null>(null)
const vars = ref<EnvironmentVariable[]>([ const vars = ref<EnvironmentVariable[]>([
{ id: idTicker.value++, env: { key: "", value: "", secret: false } }, { id: idTicker.value++, env: { key: "", value: "" } },
]) ])
const clearIcon = refAutoReset<typeof IconTrash2 | typeof IconDone>( const clearIcon = refAutoReset<typeof IconTrash2 | typeof IconDone>(
@@ -216,8 +203,6 @@ const workingEnv = computed(() => {
} }
}) })
const oldEnvironments = ref<string[]>([])
const envList = useReadonlyStream(environments$, []) || props.envVars() const envList = useReadonlyStream(environments$, []) || props.envVars()
const evnExpandError = computed(() => { const evnExpandError = computed(() => {
@@ -249,28 +234,6 @@ const liveEnvs = computed(() => {
} }
}) })
watch(liveEnvs, (newLiveEnv, oldLiveEnv) => {
const oldEnvLength = oldLiveEnv.length
const newEnvLength = newLiveEnv.length
if (oldEnvLength === newEnvLength) {
const _oldEnvironments = []
for (let i = 0; i < newEnvLength; i++) {
const newVar = newLiveEnv[i]
const oldVar = oldLiveEnv[i]
let newValue = ""
if (!newVar.secret) {
newValue = newVar.value
} else if (!oldVar.secret) {
newValue = oldVar.value
} else {
newValue = oldEnvironments.value[i]
}
_oldEnvironments.push(newValue)
}
oldEnvironments.value = _oldEnvironments
}
})
watch( watch(
() => props.show, () => props.show,
(show) => { (show) => {
@@ -299,7 +262,6 @@ const addEnvironmentVariable = () => {
env: { env: {
key: "", key: "",
value: "", value: "",
secret: false,
}, },
}) })
} }
@@ -308,23 +270,12 @@ const removeEnvironmentVariable = (index: number) => {
vars.value.splice(index, 1) vars.value.splice(index, 1)
} }
const toggleEnvironmentSecret = (index: number) => {
vars.value[index].env.secret = !vars.value[index].env.secret
}
const saveEnvironment = () => { const saveEnvironment = () => {
if (!editingName.value) { if (!editingName.value) {
toast.error(`${t("environment.invalid_name")}`) toast.error(`${t("environment.invalid_name")}`)
return return
} }
const _vars = vars.value
for (let i = 0; i < vars.value.length; i++) {
const value = oldEnvironments.value[i]
if (value) {
_vars[i].env.value = value
}
}
vars.value = _vars
const filterdVariables = pipe( const filterdVariables = pipe(
vars.value, vars.value,
A.filterMap( A.filterMap(

View File

@@ -63,17 +63,7 @@
:envs="liveEnvs" :envs="liveEnvs"
:name="'value' + index" :name="'value' + index"
:readonly="isViewer" :readonly="isViewer"
:secret="env.secret"
/> />
<div v-if="!isViewer" class="flex">
<HoppButtonSecondary
id="variable"
v-tippy="{ theme: 'tooltip' }"
:title="t('action.secret')"
:icon="env.secret ? IconEyeOff : IconEye"
@click="toggleEnvironmentSecret(index)"
/>
</div>
<div v-if="!isViewer" class="flex"> <div v-if="!isViewer" class="flex">
<HoppButtonSecondary <HoppButtonSecondary
id="variable" id="variable"
@@ -149,8 +139,6 @@ import IconTrash from "~icons/lucide/trash"
import IconTrash2 from "~icons/lucide/trash-2" import IconTrash2 from "~icons/lucide/trash-2"
import IconDone from "~icons/lucide/check" import IconDone from "~icons/lucide/check"
import IconPlus from "~icons/lucide/plus" import IconPlus from "~icons/lucide/plus"
import IconEye from "~icons/lucide/eye"
import IconEyeOff from "~icons/lucide/eye-off"
import { platform } from "~/platform" import { platform } from "~/platform"
type EnvironmentVariable = { type EnvironmentVariable = {
@@ -158,7 +146,6 @@ type EnvironmentVariable = {
env: { env: {
key: string key: string
value: string value: string
secret: boolean
} }
} }
@@ -195,10 +182,9 @@ const idTicker = ref(0)
const editingName = ref<string | null>(null) const editingName = ref<string | null>(null)
const vars = ref<EnvironmentVariable[]>([ const vars = ref<EnvironmentVariable[]>([
{ id: idTicker.value++, env: { key: "", value: "", secret: false } }, { id: idTicker.value++, env: { key: "", value: "" } },
]) ])
const oldEnvironments = ref<string[]>([])
const clearIcon = refAutoReset<typeof IconTrash2 | typeof IconDone>( const clearIcon = refAutoReset<typeof IconTrash2 | typeof IconDone>(
IconTrash2, IconTrash2,
1000 1000
@@ -226,28 +212,6 @@ const liveEnvs = computed(() => {
} }
}) })
watch(liveEnvs, (newLiveEnv, oldLiveEnv) => {
const oldEnvLength = oldLiveEnv.length
const newEnvLength = newLiveEnv.length
if (oldEnvLength === newEnvLength) {
const _oldEnvironments = []
for (let i = 0; i < newEnvLength; i++) {
const newVar = newLiveEnv[i]
const oldVar = oldLiveEnv[i]
let newValue = ""
if (!newVar.secret) {
newValue = newVar.value
} else if (!oldVar.secret) {
newValue = oldVar.value
} else {
newValue = oldEnvironments.value[i]
}
_oldEnvironments.push(newValue)
}
oldEnvironments.value = _oldEnvironments
}
})
watch( watch(
() => props.show, () => props.show,
(show) => { (show) => {
@@ -256,7 +220,7 @@ watch(
editingName.value = null editingName.value = null
vars.value = pipe( vars.value = pipe(
props.envVars() ?? [], props.envVars() ?? [],
A.map((e: { key: string; value: string; secret: boolean }) => ({ A.map((e: { key: string; value: string }) => ({
id: idTicker.value++, id: idTicker.value++,
env: clone(e), env: clone(e),
})) }))
@@ -265,7 +229,7 @@ watch(
editingName.value = props.editingEnvironment.environment.name ?? null editingName.value = props.editingEnvironment.environment.name ?? null
vars.value = pipe( vars.value = pipe(
props.editingEnvironment.environment.variables ?? [], props.editingEnvironment.environment.variables ?? [],
A.map((e: { key: string; value: string; secret: boolean }) => ({ A.map((e: { key: string; value: string }) => ({
id: idTicker.value++, id: idTicker.value++,
env: clone(e), env: clone(e),
})) }))
@@ -287,7 +251,6 @@ const addEnvironmentVariable = () => {
env: { env: {
key: "", key: "",
value: "", value: "",
secret: false,
}, },
}) })
} }
@@ -296,10 +259,6 @@ const removeEnvironmentVariable = (index: number) => {
vars.value.splice(index, 1) vars.value.splice(index, 1)
} }
const toggleEnvironmentSecret = (index: number) => {
vars.value[index].env.secret = !vars.value[index].env.secret
}
const isLoading = ref(false) const isLoading = ref(false)
const saveEnvironment = async () => { const saveEnvironment = async () => {
@@ -310,15 +269,6 @@ const saveEnvironment = async () => {
return return
} }
const _vars = vars.value
for (let i = 0; i < vars.value.length; i++) {
const value = oldEnvironments.value[i]
if (value) {
_vars[i].env.value = value
}
}
vars.value = _vars
const filterdVariables = pipe( const filterdVariables = pipe(
vars.value, vars.value,
A.filterMap( A.filterMap(

View File

@@ -279,7 +279,6 @@ const globalEnvVars = useReadonlyStream(globalEnv$, []) as Ref<
Array<{ Array<{
key: string key: string
value: string value: string
secret: boolean
}> }>
> >

View File

@@ -48,7 +48,6 @@ type Props = {
env: { env: {
key: string key: string
value: string value: string
secret: boolean
previousValue?: string previousValue?: string
} }
status: Status status: Status

View File

@@ -55,12 +55,7 @@ import {
keymap, keymap,
tooltips, tooltips,
} from "@codemirror/view" } from "@codemirror/view"
import { import { EditorSelection, EditorState, Extension } from "@codemirror/state"
EditorSelection,
EditorState,
Extension,
StateEffect,
} from "@codemirror/state"
import { clone } from "lodash-es" import { clone } from "lodash-es"
import { history, historyKeymap } from "@codemirror/commands" import { history, historyKeymap } from "@codemirror/commands"
import { inputTheme } from "~/helpers/editor/themes/baseTheme" import { inputTheme } from "~/helpers/editor/themes/baseTheme"
@@ -77,17 +72,13 @@ const props = withDefaults(
modelValue?: string modelValue?: string
placeholder?: string placeholder?: string
styles?: string styles?: string
envs?: envs?: { key: string; value: string; source: string }[] | null
| { key: string; value: string; secret: boolean; source: string }[]
| null
focus?: boolean focus?: boolean
selectTextOnMount?: boolean selectTextOnMount?: boolean
environmentHighlights?: boolean environmentHighlights?: boolean
readonly?: boolean readonly?: boolean
autoCompleteSource?: string[] autoCompleteSource?: string[]
inspectionResults?: InspectorResult[] | undefined inspectionResults?: InspectorResult[] | undefined
defaultValue?: string
secret?: boolean
}>(), }>(),
{ {
modelValue: "", modelValue: "",
@@ -100,8 +91,6 @@ const props = withDefaults(
autoCompleteSource: undefined, autoCompleteSource: undefined,
inspectionResult: undefined, inspectionResult: undefined,
inspectionResults: undefined, inspectionResults: undefined,
defaultValue: "",
secret: false,
} }
) )
@@ -115,8 +104,6 @@ const emit = defineEmits<{
(e: "click", ev: any): void (e: "click", ev: any): void
}>() }>()
const asterikedText = computed(() => "*".repeat(props.modelValue.length))
const cachedValue = ref(props.modelValue) const cachedValue = ref(props.modelValue)
const view = ref<EditorView>() const view = ref<EditorView>()
@@ -276,22 +263,6 @@ watch(
} }
) )
const prevModelValue = ref(props.modelValue)
watch(
() => props.secret,
(newValue) => {
let visibleValue = asterikedText.value
if (!newValue) {
visibleValue = prevModelValue.value
} else {
prevModelValue.value = props.modelValue
}
emit("update:modelValue", visibleValue)
updateEditorViewTheme(newValue)
}
)
/** /**
* Used to scroll the active suggestion into view * Used to scroll the active suggestion into view
*/ */
@@ -313,6 +284,7 @@ watch(
() => props.modelValue, () => props.modelValue,
(newVal) => { (newVal) => {
const singleLinedText = newVal.replaceAll("\n", "") const singleLinedText = newVal.replaceAll("\n", "")
const currDoc = view.value?.state.doc const currDoc = view.value?.state.doc
.toJSON() .toJSON()
.join(view.value.state.lineBreak) .join(view.value.state.lineBreak)
@@ -348,7 +320,6 @@ const envVars = computed(() =>
? props.envs.map((x) => ({ ? props.envs.map((x) => ({
key: x.key, key: x.key,
value: x.value, value: x.value,
secret: x.secret,
sourceEnv: x.source, sourceEnv: x.source,
})) }))
: aggregateEnvs.value : aggregateEnvs.value
@@ -383,14 +354,6 @@ function handleTextSelection() {
} }
} }
} }
const updateEditorViewTheme = (readonly: boolean) => {
if (view.value) {
const extensions: Extension = getExtensions(readonly)
view.value.dispatch({
effects: [StateEffect.reconfigure.of(extensions)],
})
}
}
const initView = (el: any) => { const initView = (el: any) => {
// Debounce to prevent double click from selecting the word // Debounce to prevent double click from selecting the word
@@ -401,31 +364,17 @@ const initView = (el: any) => {
el.addEventListener("mouseup", debounceFn) el.addEventListener("mouseup", debounceFn)
el.addEventListener("keyup", debounceFn) el.addEventListener("keyup", debounceFn)
if (props.secret) {
emit("update:modelValue", asterikedText.value)
}
const extensions: Extension = getExtensions(props.readonly || props.secret)
view.value = new EditorView({
parent: el,
state: EditorState.create({
doc: props.modelValue,
extensions,
}),
})
}
const getExtensions = (readonly: boolean): Extension => {
const extensions: Extension = [ const extensions: Extension = [
EditorView.contentAttributes.of({ "aria-label": props.placeholder }), EditorView.contentAttributes.of({ "aria-label": props.placeholder }),
EditorView.contentAttributes.of({ "data-enable-grammarly": "false" }), EditorView.contentAttributes.of({ "data-enable-grammarly": "false" }),
EditorView.updateListener.of((update) => { EditorView.updateListener.of((update) => {
if (readonly) { if (props.readonly) {
update.view.contentDOM.inputMode = "none" update.view.contentDOM.inputMode = "none"
} }
}), }),
EditorState.changeFilter.of(() => !readonly), EditorState.changeFilter.of(() => !props.readonly),
inputTheme, inputTheme,
readonly props.readonly
? EditorView.theme({ ? EditorView.theme({
".cm-content": { ".cm-content": {
caretColor: "var(--secondary-dark-color)", caretColor: "var(--secondary-dark-color)",
@@ -457,7 +406,7 @@ const getExtensions = (readonly: boolean): Extension => {
ViewPlugin.fromClass( ViewPlugin.fromClass(
class { class {
update(update: ViewUpdate) { update(update: ViewUpdate) {
if (readonly) return if (props.readonly) return
if (update.docChanged) { if (update.docChanged) {
const prevValue = clone(cachedValue.value) const prevValue = clone(cachedValue.value)
@@ -469,14 +418,9 @@ const getExtensions = (readonly: boolean): Extension => {
// We do not update the cache directly in this case (to trigger value watcher to dispatch) // We do not update the cache directly in this case (to trigger value watcher to dispatch)
// So, we desync cachedValue a bit so we can trigger updates // So, we desync cachedValue a bit so we can trigger updates
const value = clone(cachedValue.value).replaceAll("\n", "") const value = clone(cachedValue.value).replaceAll("\n", "")
if (props.secret) {
const asterikedValue = "*".repeat(value.length) emit("update:modelValue", value)
emit("update:modelValue", asterikedValue) emit("change", value)
emit("change", asterikedValue)
} else {
emit("update:modelValue", value)
emit("change", value)
}
const pasted = !!update.transactions.find((txn) => const pasted = !!update.transactions.find((txn) =>
txn.isUserEvent("input.paste") txn.isUserEvent("input.paste")
@@ -501,7 +445,14 @@ const getExtensions = (readonly: boolean): Extension => {
history(), history(),
keymap.of([...historyKeymap]), keymap.of([...historyKeymap]),
] ]
return extensions
view.value = new EditorView({
parent: el,
state: EditorState.create({
doc: props.modelValue,
extensions,
}),
})
} }
const triggerTextSelection = () => { const triggerTextSelection = () => {

View File

@@ -66,10 +66,7 @@ const cursorTooltipField = (aggregateEnvs: AggregateEnvironment[]) =>
const envName = tooltipEnv?.sourceEnv ?? "Choose an Environment" const envName = tooltipEnv?.sourceEnv ?? "Choose an Environment"
let envValue = tooltipEnv?.value ?? "Not found" const envValue = tooltipEnv?.value ?? "Not found"
if (tooltipEnv?.secret) {
envValue = "******"
}
const result = parseTemplateStringE(envValue, aggregateEnvs) const result = parseTemplateStringE(envValue, aggregateEnvs)

View File

@@ -2,7 +2,7 @@
"!name": "pw-pre", "!name": "pw-pre",
"pw": { "pw": {
"env": { "env": {
"set": "fn(key: string, value: string, secret: boolean)", "set": "fn(key: string, value: string)",
"get": "fn(key: string) -> string", "get": "fn(key: string) -> string",
"getResolve": "fn(key: string) -> string", "getResolve": "fn(key: string) -> string",
"resolve": "fn(value: string) -> string" "resolve": "fn(value: string) -> string"

View File

@@ -21,7 +21,7 @@
"body": "?" "body": "?"
}, },
"env": { "env": {
"set": "fn(key: string, value: string, secret:boolean)", "set": "fn(key: string, value: string)",
"get": "fn(key: string) -> string", "get": "fn(key: string) -> string",
"getResolve": "fn(key: string) -> string", "getResolve": "fn(key: string) -> string",
"resolve": "fn(value: string) -> string" "resolve": "fn(value: string) -> string"

View File

@@ -186,19 +186,14 @@ const dispatchers = defineDispatchers({
}, },
addEnvironmentVariable( addEnvironmentVariable(
{ environments }: EnvironmentStore, { environments }: EnvironmentStore,
{ { envIndex, key, value }: { envIndex: number; key: string; value: string }
envIndex,
key,
value,
secret,
}: { envIndex: number; key: string; value: string; secret: boolean }
) { ) {
return { return {
environments: environments.map((env, index) => environments: environments.map((env, index) =>
index === envIndex index === envIndex
? { ? {
...env, ...env,
variables: [...env.variables, { key, value, secret }], variables: [...env.variables, { key, value }],
} }
: env : env
), ),
@@ -226,10 +221,7 @@ const dispatchers = defineDispatchers({
{ {
envIndex, envIndex,
vars, vars,
}: { }: { envIndex: number; vars: { key: string; value: string }[] }
envIndex: number
vars: { key: string; value: string; secret: boolean }[]
}
) { ) {
return { return {
environments: environments.map((env, index) => environments: environments.map((env, index) =>
@@ -249,13 +241,11 @@ const dispatchers = defineDispatchers({
variableIndex, variableIndex,
updatedKey, updatedKey,
updatedValue, updatedValue,
updatedSecret,
}: { }: {
envIndex: number envIndex: number
variableIndex: number variableIndex: number
updatedKey: string updatedKey: string
updatedValue: string updatedValue: string
updatedSecret: boolean
} }
) { ) {
return { return {
@@ -265,11 +255,7 @@ const dispatchers = defineDispatchers({
...env, ...env,
variables: env.variables.map((v, vIndex) => variables: env.variables.map((v, vIndex) =>
vIndex === variableIndex vIndex === variableIndex
? { ? { key: updatedKey, value: updatedValue }
key: updatedKey,
value: updatedValue,
secret: updatedSecret,
}
: v : v
), ),
} }
@@ -373,7 +359,6 @@ export const currentEnvironment$: Observable<Environment | undefined> =
export type AggregateEnvironment = { export type AggregateEnvironment = {
key: string key: string
value: string value: string
secret: boolean
sourceEnv: string sourceEnv: string
} }
@@ -388,11 +373,11 @@ export const aggregateEnvs$: Observable<AggregateEnvironment[]> = combineLatest(
map(([selectedEnv, globalVars]) => { map(([selectedEnv, globalVars]) => {
const results: AggregateEnvironment[] = [] const results: AggregateEnvironment[] = []
selectedEnv?.variables.forEach(({ key, value, secret }) => selectedEnv?.variables.forEach(({ key, value }) =>
results.push({ key, value, secret, sourceEnv: selectedEnv.name }) results.push({ key, value, sourceEnv: selectedEnv.name })
) )
globalVars.forEach(({ key, value, secret }) => globalVars.forEach(({ key, value }) =>
results.push({ key, value, secret, sourceEnv: "Global" }) results.push({ key, value, sourceEnv: "Global" })
) )
return results return results
@@ -608,7 +593,7 @@ export function updateEnvironment(envIndex: number, updatedEnv: Environment) {
export function setEnvironmentVariables( export function setEnvironmentVariables(
envIndex: number, envIndex: number,
vars: { key: string; value: string; secret: boolean }[] vars: { key: string; value: string }[]
) { ) {
environmentsStore.dispatch({ environmentsStore.dispatch({
dispatcher: "setEnvironmentVariables", dispatcher: "setEnvironmentVariables",
@@ -621,7 +606,7 @@ export function setEnvironmentVariables(
export function addEnvironmentVariable( export function addEnvironmentVariable(
envIndex: number, envIndex: number,
{ key, value, secret }: { key: string; value: string; secret: boolean } { key, value }: { key: string; value: string }
) { ) {
environmentsStore.dispatch({ environmentsStore.dispatch({
dispatcher: "addEnvironmentVariable", dispatcher: "addEnvironmentVariable",
@@ -629,7 +614,6 @@ export function addEnvironmentVariable(
envIndex, envIndex,
key, key,
value, value,
secret,
}, },
}) })
} }
@@ -650,7 +634,7 @@ export function removeEnvironmentVariable(
export function updateEnvironmentVariable( export function updateEnvironmentVariable(
envIndex: number, envIndex: number,
variableIndex: number, variableIndex: number,
{ key, value, secret }: { key: string; value: string; secret: boolean } { key, value }: { key: string; value: string }
) { ) {
environmentsStore.dispatch({ environmentsStore.dispatch({
dispatcher: "updateEnvironmentVariable", dispatcher: "updateEnvironmentVariable",
@@ -659,7 +643,6 @@ export function updateEnvironmentVariable(
variableIndex, variableIndex,
updatedKey: key, updatedKey: key,
updatedValue: value, updatedValue: value,
updatedSecret: secret,
}, },
}) })
} }

View File

@@ -7,7 +7,6 @@ export type Environment = {
variables: { variables: {
key: string key: string
value: string value: string
secret: boolean
}[] }[]
} }

View File

@@ -11,16 +11,16 @@ describe("execPreRequestScript", () => {
{ {
global: [], global: [],
selected: [ selected: [
{ key: "bob", value: "oldbob", secret: false }, { key: "bob", value: "oldbob" },
{ key: "foo", value: "bar", secret: false }, { key: "foo", value: "bar" },
], ],
} }
)() )()
).resolves.toEqualRight({ ).resolves.toEqualRight({
global: [], global: [],
selected: [ selected: [
{ key: "bob", value: "newbob", secret: false }, { key: "bob", value: "newbob" },
{ key: "foo", value: "bar", secret: false }, { key: "foo", value: "bar" },
], ],
}) })
}) })
@@ -34,8 +34,8 @@ describe("execPreRequestScript", () => {
{ {
global: [], global: [],
selected: [ selected: [
{ key: "bob", value: "oldbob", secret: false }, { key: "bob", value: "oldbob" },
{ key: "foo", value: "bar", secret: false }, { key: "foo", value: "bar" },
], ],
} }
)() )()
@@ -51,8 +51,8 @@ describe("execPreRequestScript", () => {
{ {
global: [], global: [],
selected: [ selected: [
{ key: "bob", value: "oldbob", secret: false }, { key: "bob", value: "oldbob" },
{ key: "foo", value: "bar", secret: false }, { key: "foo", value: "bar" },
], ],
} }
)() )()
@@ -68,8 +68,8 @@ describe("execPreRequestScript", () => {
{ {
global: [], global: [],
selected: [ selected: [
{ key: "bob", value: "oldbob", secret: false }, { key: "bob", value: "oldbob" },
{ key: "foo", value: "bar", secret: false }, { key: "foo", value: "bar" },
], ],
} }
)() )()
@@ -86,7 +86,7 @@ describe("execPreRequestScript", () => {
)() )()
).resolves.toEqualRight({ ).resolves.toEqualRight({
global: [], global: [],
selected: [{ key: "foo", value: "bar", secret: false }], selected: [{ key: "foo", value: "bar" }],
}) })
}) })
}) })

View File

@@ -30,7 +30,6 @@ describe("pw.env.get", () => {
{ {
key: "a", key: "a",
value: "b", value: "b",
secret: false,
}, },
], ],
} }
@@ -59,7 +58,6 @@ describe("pw.env.get", () => {
{ {
key: "a", key: "a",
value: "b", value: "b",
secret: false,
}, },
], ],
selected: [], selected: [],
@@ -113,14 +111,12 @@ describe("pw.env.get", () => {
{ {
key: "a", key: "a",
value: "global val", value: "global val",
secret: false,
}, },
], ],
selected: [ selected: [
{ {
key: "a", key: "a",
value: "selected val", value: "selected val",
secret: false,
}, },
], ],
} }
@@ -150,7 +146,6 @@ describe("pw.env.get", () => {
{ {
key: "a", key: "a",
value: "<<hello>>", value: "<<hello>>",
secret: false,
}, },
], ],
} }

View File

@@ -30,7 +30,6 @@ describe("pw.env.getResolve", () => {
{ {
key: "a", key: "a",
value: "b", value: "b",
secret: false,
}, },
], ],
} }
@@ -59,7 +58,6 @@ describe("pw.env.getResolve", () => {
{ {
key: "a", key: "a",
value: "b", value: "b",
secret: false,
}, },
], ],
selected: [], selected: [],
@@ -113,14 +111,12 @@ describe("pw.env.getResolve", () => {
{ {
key: "a", key: "a",
value: "global val", value: "global val",
secret: false,
}, },
], ],
selected: [ selected: [
{ {
key: "a", key: "a",
value: "selected val", value: "selected val",
secret: false,
}, },
], ],
} }
@@ -150,12 +146,10 @@ describe("pw.env.getResolve", () => {
{ {
key: "a", key: "a",
value: "<<hello>>", value: "<<hello>>",
secret: false,
}, },
{ {
key: "hello", key: "hello",
value: "there", value: "there",
secret: false,
}, },
], ],
} }
@@ -185,12 +179,10 @@ describe("pw.env.getResolve", () => {
{ {
key: "a", key: "a",
value: "<<hello>>", value: "<<hello>>",
secret: false,
}, },
{ {
key: "hello", key: "hello",
value: "<<a>>", value: "<<a>>",
secret: false,
}, },
], ],
} }

View File

@@ -41,7 +41,6 @@ describe("pw.env.resolve", () => {
{ {
key: "hello", key: "hello",
value: "there", value: "there",
secret: false,
}, },
], ],
selected: [], selected: [],
@@ -72,7 +71,6 @@ describe("pw.env.resolve", () => {
{ {
key: "hello", key: "hello",
value: "there", value: "there",
secret: false,
}, },
], ],
} }
@@ -101,14 +99,12 @@ describe("pw.env.resolve", () => {
{ {
key: "hello", key: "hello",
value: "yo", value: "yo",
secret: false,
}, },
], ],
selected: [ selected: [
{ {
key: "hello", key: "hello",
value: "there", value: "there",
secret: false,
}, },
], ],
} }
@@ -138,12 +134,10 @@ describe("pw.env.resolve", () => {
{ {
key: "hello", key: "hello",
value: "<<there>>", value: "<<there>>",
secret: false,
}, },
{ {
key: "there", key: "there",
value: "<<hello>>", value: "<<hello>>",
secret: false,
}, },
], ],
} }

View File

@@ -33,7 +33,6 @@ describe("pw.env.set", () => {
{ {
key: "a", key: "a",
value: "b", value: "b",
secret: false,
}, },
], ],
} }
@@ -44,7 +43,6 @@ describe("pw.env.set", () => {
{ {
key: "a", key: "a",
value: "c", value: "c",
secret: false,
}, },
], ],
}) })
@@ -62,7 +60,6 @@ describe("pw.env.set", () => {
{ {
key: "a", key: "a",
value: "b", value: "b",
secret: false,
}, },
], ],
selected: [], selected: [],
@@ -74,7 +71,6 @@ describe("pw.env.set", () => {
{ {
key: "a", key: "a",
value: "c", value: "c",
secret: false,
}, },
], ],
}) })
@@ -92,14 +88,12 @@ describe("pw.env.set", () => {
{ {
key: "a", key: "a",
value: "b", value: "b",
secret: false,
}, },
], ],
selected: [ selected: [
{ {
key: "a", key: "a",
value: "d", value: "d",
secret: false,
}, },
], ],
} }
@@ -110,14 +104,12 @@ describe("pw.env.set", () => {
{ {
key: "a", key: "a",
value: "b", value: "b",
secret: false,
}, },
], ],
selected: [ selected: [
{ {
key: "a", key: "a",
value: "c", value: "c",
secret: false,
}, },
], ],
}) })
@@ -142,7 +134,6 @@ describe("pw.env.set", () => {
{ {
key: "a", key: "a",
value: "c", value: "c",
secret: false,
}, },
], ],
}) })

View File

@@ -87,32 +87,28 @@ export const execPreRequestScript = (
} }
}) })
const envSetHandle = vm.newFunction( const envSetHandle = vm.newFunction("set", (keyHandle, valueHandle) => {
"set", const key: unknown = vm.dump(keyHandle)
(keyHandle, valueHandle, secretHandle) => { const value: unknown = vm.dump(valueHandle)
const key: unknown = vm.dump(keyHandle)
const value: unknown = vm.dump(valueHandle)
const secret: boolean = vm.dump(secretHandle)
if (typeof key !== "string") {
return {
error: vm.newString("Expected key to be a string"),
}
}
if (typeof value !== "string") {
return {
error: vm.newString("Expected value to be a string"),
}
}
currentEnvs = setEnv(key, value, secret, currentEnvs)
if (typeof key !== "string") {
return { return {
value: vm.undefined, error: vm.newString("Expected key to be a string"),
} }
} }
)
if (typeof value !== "string") {
return {
error: vm.newString("Expected value to be a string"),
}
}
currentEnvs = setEnv(key, value, currentEnvs)
return {
value: vm.undefined,
}
})
const envResolveHandle = vm.newFunction("resolve", (valueHandle) => { const envResolveHandle = vm.newFunction("resolve", (valueHandle) => {
const value: unknown = vm.dump(valueHandle) const value: unknown = vm.dump(valueHandle)

View File

@@ -527,32 +527,28 @@ export const execTestScript = (
} }
) )
const envSetHandle = vm.newFunction( const envSetHandle = vm.newFunction("set", (keyHandle, valueHandle) => {
"set", const key: unknown = vm.dump(keyHandle)
(keyHandle, valueHandle, secretHandle) => { const value: unknown = vm.dump(valueHandle)
const key: unknown = vm.dump(keyHandle)
const value: unknown = vm.dump(valueHandle)
const secret: boolean = vm.dump(secretHandle)
if (typeof key !== "string") {
return {
error: vm.newString("Expected key to be a string"),
}
}
if (typeof value !== "string") {
return {
error: vm.newString("Expected value to be a string"),
}
}
currentEnvs = setEnv(key, value, secret, currentEnvs)
if (typeof key !== "string") {
return { return {
value: vm.undefined, error: vm.newString("Expected key to be a string"),
} }
} }
)
if (typeof value !== "string") {
return {
error: vm.newString("Expected value to be a string"),
}
}
currentEnvs = setEnv(key, value, currentEnvs)
return {
value: vm.undefined,
}
})
const envResolveHandle = vm.newFunction("resolve", (valueHandle) => { const envResolveHandle = vm.newFunction("resolve", (valueHandle) => {
const value: unknown = vm.dump(valueHandle) const value: unknown = vm.dump(valueHandle)

View File

@@ -50,7 +50,6 @@ export function getEnv(envName: string, envs: TestResult["envs"]) {
export function setEnv( export function setEnv(
envName: string, envName: string,
envValue: string, envValue: string,
envSecret: boolean,
envs: TestResult["envs"] envs: TestResult["envs"]
): TestResult["envs"] { ): TestResult["envs"] {
const indexInSelected = envs.selected.findIndex((x) => x.key === envName) const indexInSelected = envs.selected.findIndex((x) => x.key === envName)
@@ -81,7 +80,6 @@ export function setEnv(
envs.selected.push({ envs.selected.push({
key: envName, key: envName,
value: envValue, value: envValue,
secret: envSecret,
}) })
return { return {