@scalar/api-client 3.10.4 → 3.11.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/style.css +16 -11
  3. package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
  4. package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
  5. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +9 -0
  6. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
  7. package/dist/v2/blocks/operation-block/helpers/send-request.d.ts +7 -1
  8. package/dist/v2/blocks/operation-block/helpers/send-request.d.ts.map +1 -1
  9. package/dist/v2/blocks/operation-block/helpers/send-request.js +2 -2
  10. package/dist/v2/blocks/operation-block/helpers/send-request.js.map +1 -1
  11. package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts.map +1 -1
  12. package/dist/v2/blocks/request-block/RequestBlock.vue.js +1 -1
  13. package/dist/v2/blocks/request-block/RequestBlock.vue.js.map +1 -1
  14. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js +46 -9
  15. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  16. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts +4 -0
  17. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts.map +1 -1
  18. package/dist/v2/blocks/request-block/components/RequestParams.vue.js.map +1 -1
  19. package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js.map +1 -1
  20. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts +3 -11
  21. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts.map +1 -1
  22. package/dist/v2/blocks/request-block/components/RequestTable.vue.js +1 -1
  23. package/dist/v2/blocks/request-block/components/RequestTable.vue.js.map +1 -1
  24. package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js.map +1 -1
  25. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts +8 -10
  26. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
  27. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
  28. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +27 -11
  29. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
  30. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.d.ts +9 -6
  31. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.d.ts.map +1 -1
  32. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js +31 -4
  33. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js.map +1 -1
  34. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts +4 -0
  35. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts.map +1 -1
  36. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js +78 -5
  37. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js.map +1 -1
  38. package/dist/v2/constants.js +1 -1
  39. package/dist/v2/features/modal/Modal.vue.js.map +1 -1
  40. package/dist/v2/features/modal/Modal.vue.script.js +1 -1
  41. package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
  42. package/dist/vue-styles.css +10 -10
  43. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"RequestTableRow.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestTableRow.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIcon } from '@scalar/components/icon'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarIconGlobe, ScalarIconTrash } from '@scalar/icons'\nimport type { ApiReferenceEvents } from '@scalar/workspace-store/events'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n ParameterObject,\n SchemaObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, watch } from 'vue'\n\nimport { getFileName } from '@/v2/blocks/request-block/helpers/files'\nimport { validateParameter } from '@/v2/blocks/request-block/helpers/validate-parameter'\nimport { CodeInputLite } from '@/v2/components/code-input'\nimport {\n DataTableCell,\n DataTableCheckbox,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nimport RequestTableTooltip from './RequestTableTooltip.vue'\n\nexport type TableRow = {\n /** The parameter or field name/key */\n name: string\n /** The parameter value, can be a string, file, or null */\n value: string | File | null\n /** Optional description for the parameter */\n description?: string\n /** Optional route for global parameters (e.g., cookies shared across workspace) */\n globalRoute?: ApiReferenceEvents['ui:navigate']\n /** Whether the parameter is disabled/inactive */\n isDisabled?: boolean\n /** OpenAPI schema object with type, validation rules, examples, etc. */\n schema?: SchemaObject\n /** Whether the parameter is required */\n isRequired?: boolean\n /**\n * Whether the parameter is readonly and can not be modifies directly\n * User can still override the parameter which is going to show up with the linethrough style\n */\n isReadonly?: boolean\n /** Whether the parameter is overridden later on */\n isOverridden?: boolean\n /** Track the original parameter so we can update it */\n originalParameter?: ParameterObject\n /** Path to a value inside the original parameter example for expanded object parameters */\n sourceParameterValuePath?: string[]\n}\n\nconst {\n data,\n environment,\n hasCheckboxDisabled,\n invalidParams,\n showUploadButton,\n} = defineProps<{\n data: TableRow\n hasCheckboxDisabled?: boolean\n invalidParams?: Set<string>\n label?: string\n environment: XScalarEnvironment\n showUploadButton?: boolean\n}>()\n\nconst emit = defineEmits<{\n (\n e: 'upsertRow',\n payload: { name: string; value: string | File; isDisabled: boolean },\n ): void\n (e: 'deleteRow'): void\n (e: 'uploadFile'): void\n (e: 'removeFile'): void\n (e: 'navigate', route: NonNullable<TableRow['globalRoute']>): void\n}>()\n\n/**\n * Track local state for the row\n *\n * Now this is required because of the way we get default values from the schema.\n * If we have a default value in data.value, then we update isDisabled to true. We lose the default value since now\n * we have an example where value: ''. This is why we need to track the local state and update all of the params at the\n * same time.\n */\nconst name = ref<string>(data.name ?? '')\nconst value = ref<string | File>(unpackProxyObject(data.value) ?? '')\nconst isDisabled = ref<boolean>(data.isDisabled ?? false)\n\n// Keep the above state synced with the data prop\nwatch(\n () => data.name,\n (newName) => (name.value = newName ?? ''),\n)\nwatch(\n () => data.value,\n (newValue) => (value.value = unpackProxyObject(newValue) ?? ''),\n)\nwatch(\n () => data.isDisabled,\n (newIsDisabled) => (isDisabled.value = newIsDisabled ?? false),\n)\n\n/** Check if the value is a File instance */\nconst isFile = computed(() => value.value instanceof File)\n\n/** Display value handles File instances and shows filename instead */\nconst displayValue = computed(\n () =>\n (isFile.value\n ? getFileName(value.value as File)\n : (value.value as string)) ?? '',\n)\n\nconst defaultValue = computed(() => data.schema?.default as string)\n\n/** See if we can extract enum values from the schema */\nconst enumValue = computed<string[]>(() => {\n if (!data.schema) {\n return []\n }\n\n // Grab the enum from the schema\n if (data.schema.enum) {\n return data.schema.enum.map((item) => String(item))\n }\n\n // Grab the enum from the items schema\n if ('items' in data.schema) {\n const resolved = resolve.schema(data.schema.items)\n if (resolved?.enum) {\n return resolved.enum.map((item) => String(item))\n }\n }\n\n return []\n})\n\nconst typeValue = computed(() =>\n data.schema && 'type' in data.schema ? data.schema.type : undefined,\n)\n\nconst validationResult = computed(() =>\n validateParameter(data.schema, value.value),\n)\n\n/** Handle row updates while preserving existing properties */\nconst handleUpdateRow = (\n payload: Partial<{ name: string; value: string; isDisabled: boolean }>,\n): void => {\n // Update our local state\n if (payload.name !== undefined) {\n name.value = payload.name\n }\n if (payload.value !== undefined) {\n value.value = payload.value\n }\n\n // Is disabled should always be false unless you explicitly set it to true\n isDisabled.value = payload.isDisabled ?? false\n\n // Emit all of the local state\n emit('upsertRow', {\n name: name.value,\n value: value.value,\n isDisabled: isDisabled.value,\n })\n}\n</script>\n\n<template>\n <DataTableRow\n :id=\"data.name\"\n :class=\"{\n alert: validationResult.ok === false,\n error: validationResult.ok === false && invalidParams?.has(data.name),\n }\">\n <DataTableCheckbox\n class=\"!border-r\"\n :disabled=\"hasCheckboxDisabled ?? false\"\n :modelValue=\"!isDisabled\"\n @update:modelValue=\"(v) => handleUpdateRow({ isDisabled: !v })\" />\n\n <!-- Name -->\n <DataTableCell>\n <CodeInputLite\n :aria-label=\"`${label} Key`\"\n :disabled=\"data.isReadonly\"\n :environment=\"environment\"\n :modelValue=\"name\"\n placeholder=\"Key\"\n :required=\"Boolean(data.isRequired)\"\n @navigate=\"(route) => emit('navigate', route)\"\n @update:modelValue=\"(v) => handleUpdateRow({ name: v })\" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInputLite\n :aria-label=\"`${label} Value`\"\n class=\"pr-6 group-hover:pr-10 group-has-[.code-input-lite__editor:focus]:pr-10\"\n :default=\"defaultValue\"\n :disabled=\"data.isReadonly\"\n :enum=\"enumValue\"\n :environment=\"environment\"\n :examples=\"\n data.schema?.examples?.map((example) => String(example)) ?? []\n \"\n :linethrough=\"data.isOverridden\"\n :modelValue=\"displayValue\"\n placeholder=\"Value\"\n :type=\"typeValue\"\n withFakeData\n @navigate=\"(route) => emit('navigate', route)\"\n @update:modelValue=\"(v) => handleUpdateRow({ value: v })\">\n <template #icon>\n <ScalarButton\n v-if=\"\n Boolean(data.name || value) &&\n !data.isRequired &&\n data.isReadonly !== true\n \"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 z-context -mr-0.5 hidden h-fit rounded p-1 group-hover:flex group-has-[.code-input-lite__editor:focus]:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"emit('deleteRow')\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n\n <ScalarIconButton\n v-if=\"data.globalRoute !== undefined\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 z-context -mr-0.5 h-fit\"\n :icon=\"ScalarIconGlobe\"\n label=\"Global cookies are shared across the whole workspace. Click to navigate.\"\n size=\"xs\"\n tooltip=\"top\"\n variant=\"ghost\"\n @click=\"emit('navigate', data.globalRoute)\" />\n\n <RequestTableTooltip\n v-if=\"data.isReadonly\"\n description=\"This is a readonly property and you can not modify it! If you want to change it you have to override it or disable it using the checkbox\"\n :value=\"null\" />\n <RequestTableTooltip\n v-else-if=\"data.schema\"\n :description=\"data.description\"\n :schema=\"data.schema\"\n :value />\n </template>\n </CodeInputLite>\n </DataTableCell>\n\n <!-- File upload -->\n <DataTableCell\n v-if=\"showUploadButton\"\n class=\"group/upload flex items-center justify-center whitespace-nowrap\">\n <template v-if=\"isFile\">\n <div\n class=\"text-c-2 filemask flex w-full max-w-[100%] items-center justify-center overflow-hidden p-1\">\n <span>{{ displayValue }}</span>\n </div>\n <button\n class=\"bg-b-2 mt-1 block rounded p-0.5 text-center text-xs font-medium md:pointer-events-none md:absolute md:inset-x-1 md:top-1/2 md:mt-0 md:-translate-y-1/2 md:opacity-0 md:group-hover/upload:pointer-events-auto md:group-hover/upload:opacity-100\"\n type=\"button\"\n @click=\"emit('removeFile')\">\n Delete\n </button>\n </template>\n <template v-else>\n <div class=\"p-0.5\">\n <ScalarButton\n class=\"bg-b-2 hover:bg-b-3 text-c-2 h-fit border-0 py-px shadow-none\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"emit('uploadFile')\">\n <span>Select File</span>\n <ScalarIcon\n class=\"ml-1\"\n icon=\"Upload\"\n size=\"xs\"\n thickness=\"2.5\" />\n </ScalarButton>\n </div>\n </template>\n </DataTableCell>\n </DataTableRow>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqEA,MAAM,OAAO;;;;;;;;;EAmBb,MAAM,OAAO,IAAY,QAAA,KAAK,QAAQ,GAAE;EACxC,MAAM,QAAQ,IAAmB,kBAAkB,QAAA,KAAK,MAAM,IAAI,GAAE;EACpE,MAAM,aAAa,IAAa,QAAA,KAAK,cAAc,MAAK;AAGxD,cACQ,QAAA,KAAK,OACV,YAAa,KAAK,QAAQ,WAAW,GACxC;AACA,cACQ,QAAA,KAAK,QACV,aAAc,MAAM,QAAQ,kBAAkB,SAAS,IAAI,GAC9D;AACA,cACQ,QAAA,KAAK,aACV,kBAAmB,WAAW,QAAQ,iBAAiB,MAC1D;;EAGA,MAAM,SAAS,eAAe,MAAM,iBAAiB,KAAI;;EAGzD,MAAM,eAAe,gBAEhB,OAAO,QACJ,YAAY,MAAM,MAAa,GAC9B,MAAM,UAAqB,GACpC;EAEA,MAAM,eAAe,eAAe,QAAA,KAAK,QAAQ,QAAiB;;EAGlE,MAAM,YAAY,eAAyB;AACzC,OAAI,CAAC,QAAA,KAAK,OACR,QAAO,EAAC;AAIV,OAAI,QAAA,KAAK,OAAO,KACd,QAAO,QAAA,KAAK,OAAO,KAAK,KAAK,SAAS,OAAO,KAAK,CAAA;AAIpD,OAAI,WAAW,QAAA,KAAK,QAAQ;IAC1B,MAAM,WAAW,QAAQ,OAAO,QAAA,KAAK,OAAO,MAAK;AACjD,QAAI,UAAU,KACZ,QAAO,SAAS,KAAK,KAAK,SAAS,OAAO,KAAK,CAAA;;AAInD,UAAO,EAAC;IACT;EAED,MAAM,YAAY,eAChB,QAAA,KAAK,UAAU,UAAU,QAAA,KAAK,SAAS,QAAA,KAAK,OAAO,OAAO,KAAA,EAC5D;EAEA,MAAM,mBAAmB,eACvB,kBAAkB,QAAA,KAAK,QAAQ,MAAM,MAAM,CAC7C;;EAGA,MAAM,mBACJ,YACS;AAET,OAAI,QAAQ,SAAS,KAAA,EACnB,MAAK,QAAQ,QAAQ;AAEvB,OAAI,QAAQ,UAAU,KAAA,EACpB,OAAM,QAAQ,QAAQ;AAIxB,cAAW,QAAQ,QAAQ,cAAc;AAGzC,QAAK,aAAa;IAChB,MAAM,KAAK;IACX,OAAO,MAAM;IACb,YAAY,WAAW;IACxB,CAAA;;;uBAKD,YAkHe,MAAA,qBAAA,EAAA;IAjHZ,IAAI,QAAA,KAAK;IACT,OAAK,eAAA;YAAiB,iBAAA,MAAiB,OAAE;YAAyB,iBAAA,MAAiB,OAAE,SAAc,QAAA,eAAe,IAAI,QAAA,KAAK,KAAI;;;2BAQ5D;KAJpE,YAIoE,MAAA,0BAAA,EAAA;MAHlE,OAAM;MACL,UAAU,QAAA,uBAAmB;MAC7B,YAAU,CAAG,WAAA;MACb,uBAAiB,OAAA,OAAA,OAAA,MAAG,MAAM,gBAAe,EAAA,YAAA,CAAgB,GAAC,CAAA;;KAG7D,YAUgB,MAAA,sBAAA,EAAA,MAAA;6BAD+C,CAR7D,YAQ6D,MAAA,sBAAA,EAAA;OAP1D,cAAU,GAAK,QAAA,MAAK;OACpB,UAAU,QAAA,KAAK;OACf,aAAa,QAAA;OACb,YAAY,KAAA;OACb,aAAY;OACX,UAAU,QAAQ,QAAA,KAAK,WAAU;OACjC,YAAQ,OAAA,OAAA,OAAA,MAAG,UAAU,KAAI,YAAa,MAAK;OAC3C,uBAAiB,OAAA,OAAA,OAAA,MAAG,MAAM,gBAAe,EAAA,MAAS,GAAC,CAAA;;;;;;;;;;KAIxD,YAqDgB,MAAA,sBAAA,EAAA,MAAA;6BADE,CAnDhB,YAmDgB,MAAA,sBAAA,EAAA;OAlDb,cAAU,GAAK,QAAA,MAAK;OACrB,OAAM;OACL,SAAS,aAAA;OACT,UAAU,QAAA,KAAK;OACf,MAAM,UAAA;OACN,aAAa,QAAA;OACb,UAAqB,QAAA,KAAK,QAAQ,UAAU,KAAK,YAAY,OAAO,QAAO,CAAA,IAAA,EAAA;OAG3E,aAAa,QAAA,KAAK;OAClB,YAAY,aAAA;OACb,aAAY;OACX,MAAM,UAAA;OACP,cAAA;OACC,YAAQ,OAAA,OAAA,OAAA,MAAG,UAAU,KAAI,YAAa,MAAK;OAC3C,uBAAiB,OAAA,OAAA,OAAA,MAAG,MAAM,gBAAe,EAAA,OAAU,GAAC,CAAA;;OAC1C,MAAI,cAYE;QAVQ,QAAQ,QAAA,KAAK,QAAQ,MAAA,MAAK,IAAA,CAAoB,QAAA,KAAK,cAA4B,QAAA,KAAK,eAAU,QAAA,WAAA,EADrH,YAWe,MAAA,aAAA,EAAA;;SALb,OAAM;SACN,MAAK;SACL,SAAQ;SACP,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,YAAA;;gCACwB,CAApC,YAAoC,MAAA,gBAAA,EAAA,EAAnB,OAAM,YAAU,CAAA,CAAA,CAAA;;;QAI3B,QAAA,KAAK,gBAAgB,KAAA,KAAA,WAAA,EAD7B,YAQgD,MAAA,iBAAA,EAAA;;SAN9C,OAAM;SACL,MAAM,MAAA,gBAAe;SACtB,OAAM;SACN,MAAK;SACL,SAAQ;SACR,SAAQ;SACP,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,YAAa,QAAA,KAAK,YAAW;;QAGnC,QAAA,KAAK,cAAA,WAAA,EADb,YAGkB,6BAAA;;SADhB,aAAY;SACX,OAAO;cAEG,QAAA,KAAK,UAAA,WAAA,EADlB,YAIW,6BAAA;;SAFR,aAAa,QAAA,KAAK;SAClB,QAAQ,QAAA,KAAK;SACb,OAAA,MAAA;;;;;;;;;;;;;;;;;;;;;KAOD,QAAA,oBAAA,WAAA,EADR,YA+BgB,MAAA,sBAAA,EAAA;;MA7Bd,OAAM;;6BAYK,CAXK,OAAA,SAAA,WAAA,EAAhB,mBAWW,UAAA,EAAA,KAAA,GAAA,EAAA,CAVT,mBAGM,OAHN,YAGM,CADJ,mBAA+B,QAAA,MAAA,gBAAtB,aAAA,MAAY,EAAA,EAAA,CAAA,CAAA,EAEvB,mBAKS,UAAA;OAJP,OAAM;OACN,MAAK;OACJ,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,aAAA;SAAgB,WAE9B,CAAA,EAAA,GAAA,KAAA,WAAA,EAGA,mBAaM,OAbN,YAaM,CAZJ,YAWe,MAAA,aAAA,EAAA;OAVb,OAAM;OACN,MAAK;OACL,SAAQ;OACP,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,aAAA;;8BACY,CAAA,OAAA,OAAA,OAAA,KAAxB,mBAAwB,QAAA,MAAlB,eAAW,GAAA,GACjB,YAIoB,MAAA,WAAA,EAAA;QAHlB,OAAM;QACN,MAAK;QACL,MAAK;QACL,WAAU"}
1
+ {"version":3,"file":"RequestTableRow.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestTableRow.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIcon } from '@scalar/components/icon'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarIconGlobe, ScalarIconTrash } from '@scalar/icons'\nimport type { ApiReferenceEvents } from '@scalar/workspace-store/events'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n ParameterObject,\n SchemaObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, watch } from 'vue'\n\nimport { getFileName } from '@/v2/blocks/request-block/helpers/files'\nimport { validateParameter } from '@/v2/blocks/request-block/helpers/validate-parameter'\nimport { CodeInputLite } from '@/v2/components/code-input'\nimport {\n DataTableCell,\n DataTableCheckbox,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nimport RequestTableTooltip from './RequestTableTooltip.vue'\n\nexport type TableRow = {\n /** The parameter or field name/key */\n name: string\n /** The parameter value, can be a string, file, or null */\n value: string | File | null\n /** Optional description for the parameter */\n description?: string\n /** Optional route for global parameters (e.g., cookies shared across workspace) */\n globalRoute?: ApiReferenceEvents['ui:navigate']\n /** Whether the parameter is disabled/inactive */\n isDisabled?: boolean\n /** OpenAPI schema object with type, validation rules, examples, etc. */\n schema?: SchemaObject\n /** Whether the parameter is required */\n isRequired?: boolean\n /**\n * Whether the parameter is readonly and can not be modifies directly\n * User can still override the parameter which is going to show up with the linethrough style\n */\n isReadonly?: boolean\n /** Whether the parameter is overridden later on */\n isOverridden?: boolean\n /** Track the original parameter so we can update it */\n originalParameter?: ParameterObject\n /** Path to a value inside the original parameter example for expanded object parameters */\n sourceParameterValuePath?: string[]\n}\n\nexport type TableRowUpsertPayload = {\n name: string\n value: string | File\n isDisabled: boolean\n shouldRenameExpandedRow?: boolean\n}\n\nconst {\n data,\n environment,\n hasCheckboxDisabled,\n invalidParams,\n showUploadButton,\n} = defineProps<{\n data: TableRow\n hasCheckboxDisabled?: boolean\n invalidParams?: Set<string>\n label?: string\n environment: XScalarEnvironment\n showUploadButton?: boolean\n}>()\n\nconst emit = defineEmits<{\n (e: 'upsertRow', payload: TableRowUpsertPayload): void\n (e: 'deleteRow'): void\n (e: 'uploadFile'): void\n (e: 'removeFile'): void\n (e: 'navigate', route: NonNullable<TableRow['globalRoute']>): void\n}>()\n\n/**\n * Track local state for the row\n *\n * Now this is required because of the way we get default values from the schema.\n * If we have a default value in data.value, then we update isDisabled to true. We lose the default value since now\n * we have an example where value: ''. This is why we need to track the local state and update all of the params at the\n * same time.\n */\nconst name = ref<string>(data.name ?? '')\nconst value = ref<string | File>(unpackProxyObject(data.value) ?? '')\nconst isDisabled = ref<boolean>(data.isDisabled ?? false)\n\n// Keep the above state synced with the data prop\nwatch(\n () => data.name,\n (newName) => (name.value = newName ?? ''),\n)\nwatch(\n () => data.value,\n (newValue) => (value.value = unpackProxyObject(newValue) ?? ''),\n)\nwatch(\n () => data.isDisabled,\n (newIsDisabled) => (isDisabled.value = newIsDisabled ?? false),\n)\n\n/** Check if the value is a File instance */\nconst isFile = computed(() => value.value instanceof File)\n\n/** Display value handles File instances and shows filename instead */\nconst displayValue = computed(\n () =>\n (isFile.value\n ? getFileName(value.value as File)\n : (value.value as string)) ?? '',\n)\n\nconst defaultValue = computed(() => data.schema?.default as string)\n\n/** See if we can extract enum values from the schema */\nconst enumValue = computed<string[]>(() => {\n if (!data.schema) {\n return []\n }\n\n // Grab the enum from the schema\n if (data.schema.enum) {\n return data.schema.enum.map((item) => String(item))\n }\n\n // Grab the enum from the items schema\n if ('items' in data.schema) {\n const resolved = resolve.schema(data.schema.items)\n if (resolved?.enum) {\n return resolved.enum.map((item) => String(item))\n }\n }\n\n return []\n})\n\nconst typeValue = computed(() =>\n data.schema && 'type' in data.schema ? data.schema.type : undefined,\n)\n\nconst validationResult = computed(() =>\n validateParameter(data.schema, value.value),\n)\n\n/** Handle row updates while preserving existing properties */\nconst handleUpdateRow = (\n payload: Partial<{ name: string; value: string; isDisabled: boolean }>,\n options: { shouldRenameExpandedRow?: boolean } = {},\n): void => {\n // Update our local state\n if (payload.name !== undefined) {\n name.value = payload.name\n }\n if (payload.value !== undefined) {\n value.value = payload.value\n }\n\n // Is disabled should always be false unless you explicitly set it to true\n isDisabled.value = payload.isDisabled ?? false\n\n if (\n payload.name !== undefined &&\n data.sourceParameterValuePath &&\n !options.shouldRenameExpandedRow\n ) {\n return\n }\n\n // Emit all of the local state\n emit('upsertRow', {\n name: name.value,\n value: value.value,\n isDisabled: isDisabled.value,\n ...(options.shouldRenameExpandedRow\n ? { shouldRenameExpandedRow: true }\n : {}),\n })\n}\n\n/**\n * Commit a key edit when the input loses focus. Expanded-object rows defer their rename to blur (see\n * handleUpdateRow), so we only emit when the key actually changed — focusing and blurring the field\n * without typing should not re-emit the row or silently reset its disabled state. The current\n * disabled state is passed through so a renamed row keeps it.\n */\nconst handleKeyBlur = (newName: string): void => {\n if (newName === data.name) {\n return\n }\n\n handleUpdateRow(\n { name: newName, isDisabled: isDisabled.value },\n { shouldRenameExpandedRow: Boolean(data.sourceParameterValuePath) },\n )\n}\n</script>\n\n<template>\n <DataTableRow\n :id=\"data.name\"\n :class=\"{\n alert: validationResult.ok === false,\n error: validationResult.ok === false && invalidParams?.has(data.name),\n }\">\n <DataTableCheckbox\n class=\"!border-r\"\n :disabled=\"hasCheckboxDisabled ?? false\"\n :modelValue=\"!isDisabled\"\n @update:modelValue=\"(v) => handleUpdateRow({ isDisabled: !v })\" />\n\n <!-- Name -->\n <DataTableCell>\n <CodeInputLite\n :aria-label=\"`${label} Key`\"\n :disabled=\"data.isReadonly\"\n :environment=\"environment\"\n :modelValue=\"name\"\n placeholder=\"Key\"\n :required=\"Boolean(data.isRequired)\"\n @blur=\"(v) => handleKeyBlur(v)\"\n @navigate=\"(route) => emit('navigate', route)\"\n @update:modelValue=\"(v) => handleUpdateRow({ name: v })\" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInputLite\n :aria-label=\"`${label} Value`\"\n class=\"pr-6 group-hover:pr-10 group-has-[.code-input-lite__editor:focus]:pr-10\"\n :default=\"defaultValue\"\n :disabled=\"data.isReadonly\"\n :enum=\"enumValue\"\n :environment=\"environment\"\n :examples=\"\n data.schema?.examples?.map((example) => String(example)) ?? []\n \"\n :linethrough=\"data.isOverridden\"\n :modelValue=\"displayValue\"\n placeholder=\"Value\"\n :type=\"typeValue\"\n withFakeData\n @navigate=\"(route) => emit('navigate', route)\"\n @update:modelValue=\"(v) => handleUpdateRow({ value: v })\">\n <template #icon>\n <ScalarButton\n v-if=\"\n Boolean(data.name || value) &&\n !data.isRequired &&\n data.isReadonly !== true\n \"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 z-context -mr-0.5 hidden h-fit rounded p-1 group-hover:flex group-has-[.code-input-lite__editor:focus]:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"emit('deleteRow')\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n\n <ScalarIconButton\n v-if=\"data.globalRoute !== undefined\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 z-context -mr-0.5 h-fit\"\n :icon=\"ScalarIconGlobe\"\n label=\"Global cookies are shared across the whole workspace. Click to navigate.\"\n size=\"xs\"\n tooltip=\"top\"\n variant=\"ghost\"\n @click=\"emit('navigate', data.globalRoute)\" />\n\n <RequestTableTooltip\n v-if=\"data.isReadonly\"\n description=\"This is a readonly property and you can not modify it! If you want to change it you have to override it or disable it using the checkbox\"\n :value=\"null\" />\n <RequestTableTooltip\n v-else-if=\"data.schema\"\n :description=\"data.description\"\n :schema=\"data.schema\"\n :value />\n </template>\n </CodeInputLite>\n </DataTableCell>\n\n <!-- File upload -->\n <DataTableCell\n v-if=\"showUploadButton\"\n class=\"group/upload flex items-center justify-center whitespace-nowrap\">\n <template v-if=\"isFile\">\n <div\n class=\"text-c-2 filemask flex w-full max-w-[100%] items-center justify-center overflow-hidden p-1\">\n <span>{{ displayValue }}</span>\n </div>\n <button\n class=\"bg-b-2 mt-1 block rounded p-0.5 text-center text-xs font-medium md:pointer-events-none md:absolute md:inset-x-1 md:top-1/2 md:mt-0 md:-translate-y-1/2 md:opacity-0 md:group-hover/upload:pointer-events-auto md:group-hover/upload:opacity-100\"\n type=\"button\"\n @click=\"emit('removeFile')\">\n Delete\n </button>\n </template>\n <template v-else>\n <div class=\"p-0.5\">\n <ScalarButton\n class=\"bg-b-2 hover:bg-b-3 text-c-2 h-fit border-0 py-px shadow-none\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"emit('uploadFile')\">\n <span>Select File</span>\n <ScalarIcon\n class=\"ml-1\"\n icon=\"Upload\"\n size=\"xs\"\n thickness=\"2.5\" />\n </ScalarButton>\n </div>\n </template>\n </DataTableCell>\n </DataTableRow>\n</template>\n"],"mappings":"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"}
@@ -1,22 +1,25 @@
1
1
  import type { OperationExampleMeta, WorkspaceEventBus } from '@scalar/workspace-store/events';
2
2
  import type { TableRow } from '../../../../v2/blocks/request-block/components/RequestTableRow.vue.js';
3
3
  type ParameterType = 'path' | 'cookie' | 'header' | 'query';
4
+ type ParameterUpsertPayload = {
5
+ name: string;
6
+ value: string;
7
+ isDisabled: boolean;
8
+ shouldRenameExpandedRow?: boolean;
9
+ };
4
10
  /** Create parameter event handlers for a given type */
5
- export declare const createParameterHandlers: (type: ParameterType, eventBus: WorkspaceEventBus, meta: OperationExampleMeta, { context, defaultParameters, globalParameters, onDeleteExpandedRow, }: {
11
+ export declare const createParameterHandlers: (type: ParameterType, eventBus: WorkspaceEventBus, meta: OperationExampleMeta, { context, defaultParameters, globalParameters, onDeleteExpandedRow, onRenameExpandedRow, }: {
6
12
  context: TableRow[];
7
13
  defaultParameters?: number;
8
14
  globalParameters?: number;
9
15
  onDeleteExpandedRow?: (row: TableRow) => void;
16
+ onRenameExpandedRow?: (row: TableRow, newValuePath: string[]) => void;
10
17
  }) => {
11
18
  delete: (payload: {
12
19
  index: number;
13
20
  }) => void;
14
21
  deleteAll: () => void;
15
- upsert: (index: number, payload: {
16
- name: string;
17
- value: string;
18
- isDisabled: boolean;
19
- }) => void;
22
+ upsert: (index: number, payload: ParameterUpsertPayload) => void;
20
23
  };
21
24
  export {};
22
25
  //# sourceMappingURL=create-parameter-handlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-parameter-handlers.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-handlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAE7F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0DAA0D,CAAA;AAExF,KAAK,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;AAmC3D,uDAAuD;AACvD,eAAO,MAAM,uBAAuB,GAClC,MAAM,aAAa,EACnB,UAAU,iBAAiB,EAC3B,MAAM,oBAAoB,EAC1B,wEAKG;IACD,OAAO,EAAE,QAAQ,EAAE,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAA;CAC9C;sBAKmB;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE;;oBAuCnB,MAAM,WAAW;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE;CAoCxF,CAAA"}
1
+ {"version":3,"file":"create-parameter-handlers.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-handlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAE7F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0DAA0D,CAAA;AAExF,KAAK,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE3D,KAAK,sBAAsB,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,OAAO,CAAA;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC,CAAA;AA0ED,uDAAuD;AACvD,eAAO,MAAM,uBAAuB,GAClC,MAAM,aAAa,EACnB,UAAU,iBAAiB,EAC3B,MAAM,oBAAoB,EAC1B,6FAMG;IACD,OAAO,EAAE,QAAQ,EAAE,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAA;IAC7C,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;CACtE;sBAKmB;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE;;oBAuCnB,MAAM,WAAW,sBAAsB;CA+C1D,CAAA"}
@@ -1,14 +1,35 @@
1
1
  import { setValueAtPath } from "@scalar/helpers/object/set-value-at-path";
2
2
  //#region src/v2/blocks/request-block/helpers/create-parameter-handlers.ts
3
3
  var isEmptyValue = (value) => value === void 0 || value === null || value === "";
4
+ /** Parse a parameter key like `filter[a][b]` into its path segments `['filter', 'a', 'b']`. */
5
+ var parseBracketKey = (name) => {
6
+ const segments = [];
7
+ const head = name.match(/^[^[\]]*/)?.[0] ?? "";
8
+ if (head) segments.push(head);
9
+ for (const match of name.matchAll(/\[([^\]]*)\]/g)) segments.push(match[1] ?? "");
10
+ return segments;
11
+ };
12
+ /**
13
+ * Derives the value path for an edited expanded row from the key the user typed, so renaming a
14
+ * property actually moves the value to the new key instead of being dropped. deepObject rows are
15
+ * prefixed with the parent parameter name (`filter[a]`), which we strip to get the path inside the
16
+ * value. Falls back to the row's original path when the typed name cannot be parsed.
17
+ */
18
+ var getEditedValuePath = (typedName, parameterName, fallback) => {
19
+ const segments = parseBracketKey(typedName);
20
+ if (segments.length === 0) return fallback;
21
+ if (parameterName && segments[0] === parameterName && segments.length > 1) return segments.slice(1);
22
+ return segments;
23
+ };
4
24
  var getExpandedObjectPayload = (row, context, payload) => {
5
25
  const value = {};
6
26
  for (const contextRow of context) {
7
27
  if (contextRow.originalParameter !== row.originalParameter || !contextRow.sourceParameterValuePath) continue;
8
28
  if (contextRow === row && !payload) continue;
9
- const nextValue = contextRow === row ? payload?.value : contextRow.value;
29
+ const isEditedRow = contextRow === row && payload !== void 0;
30
+ const nextValue = isEditedRow ? payload.value : contextRow.value;
10
31
  if (isEmptyValue(nextValue)) continue;
11
- setValueAtPath(value, contextRow.sourceParameterValuePath, nextValue);
32
+ setValueAtPath(value, isEditedRow ? payload.shouldRenameExpandedRow ? getEditedValuePath(payload.name, row.originalParameter?.name, contextRow.sourceParameterValuePath) : contextRow.sourceParameterValuePath : contextRow.sourceParameterValuePath, nextValue);
12
33
  }
13
34
  return {
14
35
  name: row.originalParameter?.name ?? payload?.name ?? row.name,
@@ -17,7 +38,7 @@ var getExpandedObjectPayload = (row, context, payload) => {
17
38
  };
18
39
  };
19
40
  /** Create parameter event handlers for a given type */
20
- var createParameterHandlers = (type, eventBus, meta, { context, defaultParameters = 0, globalParameters = 0, onDeleteExpandedRow }) => {
41
+ var createParameterHandlers = (type, eventBus, meta, { context, defaultParameters = 0, globalParameters = 0, onDeleteExpandedRow, onRenameExpandedRow }) => {
21
42
  const offset = defaultParameters + globalParameters;
22
43
  return {
23
44
  delete: (payload) => {
@@ -43,6 +64,7 @@ var createParameterHandlers = (type, eventBus, meta, { context, defaultParameter
43
64
  }),
44
65
  upsert: (index, payload) => {
45
66
  const row = context[index];
67
+ const { shouldRenameExpandedRow, ...parameterPayload } = payload;
46
68
  if (index < defaultParameters + globalParameters) {
47
69
  const extraParameterType = index < defaultParameters ? "default" : "global";
48
70
  return eventBus.emit("operation:update:extra-parameters", {
@@ -56,7 +78,12 @@ var createParameterHandlers = (type, eventBus, meta, { context, defaultParameter
56
78
  });
57
79
  }
58
80
  if (index >= offset) {
59
- const nextPayload = row?.sourceParameterValuePath && row.originalParameter ? getExpandedObjectPayload(row, context, payload) : payload;
81
+ const isExpandedRow = Boolean(row?.sourceParameterValuePath && row.originalParameter);
82
+ if (isExpandedRow && row && shouldRenameExpandedRow && payload.name !== row.name) {
83
+ const newValuePath = getEditedValuePath(payload.name, row.originalParameter?.name, row.sourceParameterValuePath ?? []);
84
+ onRenameExpandedRow?.(row, newValuePath);
85
+ }
86
+ const nextPayload = isExpandedRow && row ? getExpandedObjectPayload(row, context, payload) : parameterPayload;
60
87
  return eventBus.emit("operation:upsert:parameter", {
61
88
  type,
62
89
  payload: nextPayload,
@@ -1 +1 @@
1
- {"version":3,"file":"create-parameter-handlers.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-handlers.ts"],"sourcesContent":["import { setValueAtPath } from '@scalar/helpers/object/set-value-at-path'\nimport type { OperationExampleMeta, WorkspaceEventBus } from '@scalar/workspace-store/events'\n\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\n\ntype ParameterType = 'path' | 'cookie' | 'header' | 'query'\n\nconst isEmptyValue = (value: unknown): boolean => value === undefined || value === null || value === ''\n\nconst getExpandedObjectPayload = (\n row: TableRow,\n context: TableRow[],\n payload?: { name: string; value: string; isDisabled: boolean },\n): { name: string; value: Record<string, unknown>; isDisabled: boolean } => {\n const value: Record<string, unknown> = {}\n\n for (const contextRow of context) {\n if (contextRow.originalParameter !== row.originalParameter || !contextRow.sourceParameterValuePath) {\n continue\n }\n\n if (contextRow === row && !payload) {\n continue\n }\n\n const nextValue = contextRow === row ? payload?.value : contextRow.value\n if (isEmptyValue(nextValue)) {\n continue\n }\n\n setValueAtPath(value, contextRow.sourceParameterValuePath, nextValue)\n }\n\n return {\n name: row.originalParameter?.name ?? payload?.name ?? row.name,\n value,\n isDisabled: payload?.isDisabled ?? row.isDisabled ?? false,\n }\n}\n\n/** Create parameter event handlers for a given type */\nexport const createParameterHandlers = (\n type: ParameterType,\n eventBus: WorkspaceEventBus,\n meta: OperationExampleMeta,\n {\n context,\n defaultParameters = 0,\n globalParameters = 0,\n onDeleteExpandedRow,\n }: {\n context: TableRow[]\n defaultParameters?: number\n globalParameters?: number\n onDeleteExpandedRow?: (row: TableRow) => void\n },\n) => {\n const offset = defaultParameters + globalParameters\n\n return {\n delete: (payload: { index: number }) => {\n const row = context[payload.index]\n if (!row?.originalParameter) {\n return\n }\n\n if (row.sourceParameterValuePath) {\n onDeleteExpandedRow?.(row)\n\n return eventBus.emit(\n 'operation:upsert:parameter',\n {\n type,\n payload: getExpandedObjectPayload(row, context),\n originalParameter: row.originalParameter,\n meta,\n },\n {\n skipUnpackProxy: true,\n },\n )\n }\n\n eventBus.emit(\n 'operation:delete:parameter',\n {\n originalParameter: row.originalParameter,\n meta,\n },\n {\n skipUnpackProxy: true,\n },\n )\n },\n deleteAll: () =>\n eventBus.emit('operation:delete-all:parameters', {\n type,\n meta,\n }),\n upsert: (index: number, payload: { name: string; value: string; isDisabled: boolean }) => {\n const row = context[index]\n\n if (index < defaultParameters + globalParameters) {\n const extraParameterType = index < defaultParameters ? 'default' : 'global'\n\n return eventBus.emit('operation:update:extra-parameters', {\n type: extraParameterType,\n in: type,\n meta: { ...meta, name: row?.name?.toLowerCase?.() ?? 'NON_VALID' },\n payload: { isDisabled: payload.isDisabled ?? false },\n })\n }\n\n if (index >= offset) {\n const nextPayload =\n row?.sourceParameterValuePath && row.originalParameter\n ? getExpandedObjectPayload(row, context, payload)\n : payload\n\n return eventBus.emit(\n 'operation:upsert:parameter',\n {\n type,\n payload: nextPayload,\n originalParameter: row?.originalParameter ?? null,\n meta,\n },\n {\n skipUnpackProxy: true,\n debounceKey: `update:parameter-${type}-${index - offset}`,\n },\n )\n }\n },\n }\n}\n"],"mappings":";;AAOA,IAAM,gBAAgB,UAA4B,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU;AAErG,IAAM,4BACJ,KACA,SACA,YAC0E;CAC1E,MAAM,QAAiC,EAAE;AAEzC,MAAK,MAAM,cAAc,SAAS;AAChC,MAAI,WAAW,sBAAsB,IAAI,qBAAqB,CAAC,WAAW,yBACxE;AAGF,MAAI,eAAe,OAAO,CAAC,QACzB;EAGF,MAAM,YAAY,eAAe,MAAM,SAAS,QAAQ,WAAW;AACnE,MAAI,aAAa,UAAU,CACzB;AAGF,iBAAe,OAAO,WAAW,0BAA0B,UAAU;;AAGvE,QAAO;EACL,MAAM,IAAI,mBAAmB,QAAQ,SAAS,QAAQ,IAAI;EAC1D;EACA,YAAY,SAAS,cAAc,IAAI,cAAc;EACtD;;;AAIH,IAAa,2BACX,MACA,UACA,MACA,EACE,SACA,oBAAoB,GACpB,mBAAmB,GACnB,0BAOC;CACH,MAAM,SAAS,oBAAoB;AAEnC,QAAO;EACL,SAAS,YAA+B;GACtC,MAAM,MAAM,QAAQ,QAAQ;AAC5B,OAAI,CAAC,KAAK,kBACR;AAGF,OAAI,IAAI,0BAA0B;AAChC,0BAAsB,IAAI;AAE1B,WAAO,SAAS,KACd,8BACA;KACE;KACA,SAAS,yBAAyB,KAAK,QAAQ;KAC/C,mBAAmB,IAAI;KACvB;KACD,EACD,EACE,iBAAiB,MAClB,CACF;;AAGH,YAAS,KACP,8BACA;IACE,mBAAmB,IAAI;IACvB;IACD,EACD,EACE,iBAAiB,MAClB,CACF;;EAEH,iBACE,SAAS,KAAK,mCAAmC;GAC/C;GACA;GACD,CAAC;EACJ,SAAS,OAAe,YAAkE;GACxF,MAAM,MAAM,QAAQ;AAEpB,OAAI,QAAQ,oBAAoB,kBAAkB;IAChD,MAAM,qBAAqB,QAAQ,oBAAoB,YAAY;AAEnE,WAAO,SAAS,KAAK,qCAAqC;KACxD,MAAM;KACN,IAAI;KACJ,MAAM;MAAE,GAAG;MAAM,MAAM,KAAK,MAAM,eAAe,IAAI;MAAa;KAClE,SAAS,EAAE,YAAY,QAAQ,cAAc,OAAO;KACrD,CAAC;;AAGJ,OAAI,SAAS,QAAQ;IACnB,MAAM,cACJ,KAAK,4BAA4B,IAAI,oBACjC,yBAAyB,KAAK,SAAS,QAAQ,GAC/C;AAEN,WAAO,SAAS,KACd,8BACA;KACE;KACA,SAAS;KACT,mBAAmB,KAAK,qBAAqB;KAC7C;KACD,EACD;KACE,iBAAiB;KACjB,aAAa,oBAAoB,KAAK,GAAG,QAAQ;KAClD,CACF;;;EAGN"}
1
+ {"version":3,"file":"create-parameter-handlers.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-handlers.ts"],"sourcesContent":["import { setValueAtPath } from '@scalar/helpers/object/set-value-at-path'\nimport type { OperationExampleMeta, WorkspaceEventBus } from '@scalar/workspace-store/events'\n\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\n\ntype ParameterType = 'path' | 'cookie' | 'header' | 'query'\n\ntype ParameterUpsertPayload = {\n name: string\n value: string\n isDisabled: boolean\n shouldRenameExpandedRow?: boolean\n}\n\nconst isEmptyValue = (value: unknown): boolean => value === undefined || value === null || value === ''\n\n/** Parse a parameter key like `filter[a][b]` into its path segments `['filter', 'a', 'b']`. */\nconst parseBracketKey = (name: string): string[] => {\n const segments: string[] = []\n const head = name.match(/^[^[\\]]*/)?.[0] ?? ''\n if (head) {\n segments.push(head)\n }\n for (const match of name.matchAll(/\\[([^\\]]*)\\]/g)) {\n segments.push(match[1] ?? '')\n }\n return segments\n}\n\n/**\n * Derives the value path for an edited expanded row from the key the user typed, so renaming a\n * property actually moves the value to the new key instead of being dropped. deepObject rows are\n * prefixed with the parent parameter name (`filter[a]`), which we strip to get the path inside the\n * value. Falls back to the row's original path when the typed name cannot be parsed.\n */\nconst getEditedValuePath = (typedName: string, parameterName: string | undefined, fallback: string[]): string[] => {\n const segments = parseBracketKey(typedName)\n if (segments.length === 0) {\n return fallback\n }\n if (parameterName && segments[0] === parameterName && segments.length > 1) {\n return segments.slice(1)\n }\n return segments\n}\n\nconst getExpandedObjectPayload = (\n row: TableRow,\n context: TableRow[],\n payload?: ParameterUpsertPayload,\n): { name: string; value: Record<string, unknown>; isDisabled: boolean } => {\n const value: Record<string, unknown> = {}\n\n for (const contextRow of context) {\n if (contextRow.originalParameter !== row.originalParameter || !contextRow.sourceParameterValuePath) {\n continue\n }\n\n if (contextRow === row && !payload) {\n continue\n }\n\n const isEditedRow = contextRow === row && payload !== undefined\n const nextValue = isEditedRow ? payload.value : contextRow.value\n if (isEmptyValue(nextValue)) {\n continue\n }\n\n // Key edits are debounced while the user is still typing. Only committed key edits can move\n // the value to a new object path; regular value updates keep the stable source path.\n const path = isEditedRow\n ? payload.shouldRenameExpandedRow\n ? getEditedValuePath(payload.name, row.originalParameter?.name, contextRow.sourceParameterValuePath)\n : contextRow.sourceParameterValuePath\n : contextRow.sourceParameterValuePath\n\n setValueAtPath(value, path, nextValue)\n }\n\n return {\n name: row.originalParameter?.name ?? payload?.name ?? row.name,\n value,\n isDisabled: payload?.isDisabled ?? row.isDisabled ?? false,\n }\n}\n\n/** Create parameter event handlers for a given type */\nexport const createParameterHandlers = (\n type: ParameterType,\n eventBus: WorkspaceEventBus,\n meta: OperationExampleMeta,\n {\n context,\n defaultParameters = 0,\n globalParameters = 0,\n onDeleteExpandedRow,\n onRenameExpandedRow,\n }: {\n context: TableRow[]\n defaultParameters?: number\n globalParameters?: number\n onDeleteExpandedRow?: (row: TableRow) => void\n onRenameExpandedRow?: (row: TableRow, newValuePath: string[]) => void\n },\n) => {\n const offset = defaultParameters + globalParameters\n\n return {\n delete: (payload: { index: number }) => {\n const row = context[payload.index]\n if (!row?.originalParameter) {\n return\n }\n\n if (row.sourceParameterValuePath) {\n onDeleteExpandedRow?.(row)\n\n return eventBus.emit(\n 'operation:upsert:parameter',\n {\n type,\n payload: getExpandedObjectPayload(row, context),\n originalParameter: row.originalParameter,\n meta,\n },\n {\n skipUnpackProxy: true,\n },\n )\n }\n\n eventBus.emit(\n 'operation:delete:parameter',\n {\n originalParameter: row.originalParameter,\n meta,\n },\n {\n skipUnpackProxy: true,\n },\n )\n },\n deleteAll: () =>\n eventBus.emit('operation:delete-all:parameters', {\n type,\n meta,\n }),\n upsert: (index: number, payload: ParameterUpsertPayload) => {\n const row = context[index]\n const { shouldRenameExpandedRow, ...parameterPayload } = payload\n\n if (index < defaultParameters + globalParameters) {\n const extraParameterType = index < defaultParameters ? 'default' : 'global'\n\n return eventBus.emit('operation:update:extra-parameters', {\n type: extraParameterType,\n in: type,\n meta: { ...meta, name: row?.name?.toLowerCase?.() ?? 'NON_VALID' },\n payload: { isDisabled: payload.isDisabled ?? false },\n })\n }\n\n if (index >= offset) {\n const isExpandedRow = Boolean(row?.sourceParameterValuePath && row.originalParameter)\n\n // When the key of an expanded row changes, report the new value path so the row keeps its\n // original slot (rendered in place of the old schema property) instead of jumping to the end.\n if (isExpandedRow && row && shouldRenameExpandedRow && payload.name !== row.name) {\n const newValuePath = getEditedValuePath(\n payload.name,\n row.originalParameter?.name,\n row.sourceParameterValuePath ?? [],\n )\n onRenameExpandedRow?.(row, newValuePath)\n }\n\n const nextPayload = isExpandedRow && row ? getExpandedObjectPayload(row, context, payload) : parameterPayload\n\n return eventBus.emit(\n 'operation:upsert:parameter',\n {\n type,\n payload: nextPayload,\n originalParameter: row?.originalParameter ?? null,\n meta,\n },\n {\n skipUnpackProxy: true,\n debounceKey: `update:parameter-${type}-${index - offset}`,\n },\n )\n }\n },\n }\n}\n"],"mappings":"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"}
@@ -10,5 +10,9 @@ import type { TableRow } from '../components/RequestTableRow.vue.js';
10
10
  */
11
11
  export declare const createParameterRows: (parameter: ParameterObject, exampleKey: string, options?: {
12
12
  hiddenValuePaths?: readonly string[][];
13
+ renamedValuePaths?: readonly {
14
+ from: string[];
15
+ to: string[];
16
+ }[];
13
17
  }) => TableRow[];
14
18
  //# sourceMappingURL=create-parameter-rows.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-parameter-rows.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-rows.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,8DAA8D,CAAA;AAGrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAA;AA0MjE;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAC9B,WAAW,eAAe,EAC1B,YAAY,MAAM,EAClB,UAAS;IAAE,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,CAAA;CAAO,KACvD,QAAQ,EAmCV,CAAA"}
1
+ {"version":3,"file":"create-parameter-rows.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-rows.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,8DAA8D,CAAA;AAGrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAA;AAiUjE;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAC9B,WAAW,eAAe,EAC1B,YAAY,MAAM,EAClB,UAAS;IACP,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,CAAA;IACtC,iBAAiB,CAAC,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,EAAE,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;CAC3D,KACL,QAAQ,EAmDV,CAAA"}
@@ -3,6 +3,7 @@ import { getParameterSchema } from "./get-parameter-schema.js";
3
3
  import { getValueAtPath } from "@scalar/helpers/object/get-value-at-path";
4
4
  import { deSerializeParameter, getExample } from "@scalar/workspace-store/request-example";
5
5
  import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
6
+ import { isObject } from "@scalar/helpers/object/is-object";
6
7
  import { isObjectSchema } from "@scalar/workspace-store/schemas/v3.1/strict/type-guards";
7
8
  //#region src/v2/blocks/request-block/helpers/create-parameter-rows.ts
8
9
  var isParameterWithSchema = (parameter) => "schema" in parameter && parameter.schema !== void 0;
@@ -50,6 +51,11 @@ var toTableRow = ({ parameter, name, value, description, schema, isRequired, isD
50
51
  originalParameter: parameter,
51
52
  sourceParameterValuePath
52
53
  });
54
+ /**
55
+ * Builds the row name for an expanded property at a given value path. deepObject rows mirror the
56
+ * wire format (`parent[a][b]`); form-style explode uses the bare top-level key.
57
+ */
58
+ var getExpandedRowName = (parameter, path, mode) => mode === "deepObject" ? `${parameter.name}${path.map((segment) => `[${segment}]`).join("")}` : path[0] ?? "";
53
59
  /** Build the single-row representation used when a parameter is not expanded. */
54
60
  var toSingleParameterRow = (parameter, schema, value, isDisabled) => toTableRow({
55
61
  parameter,
@@ -71,7 +77,7 @@ var toSingleParameterRow = (parameter, schema, value, isDisabled) => toTableRow(
71
77
  * `pathPrefix` tracks the path inside the parent parameter value so the handler can later
72
78
  * reassemble all sibling rows back into a single object payload.
73
79
  */
74
- var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefix, mode, isDisabled, hiddenValuePaths }) => {
80
+ var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefix, mode, isDisabled, hiddenValuePaths, renamedValuePaths, renameTargetPaths }) => {
75
81
  if (!schema.properties) return [];
76
82
  const requiredProperties = new Set(schema.required ?? []);
77
83
  return Object.entries(schema.properties).flatMap(([propertyName, propertySchema]) => {
@@ -79,7 +85,23 @@ var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefi
79
85
  if (!resolvedPropertySchema) return [];
80
86
  const path = [...pathPrefix, propertyName];
81
87
  const name = namePrefix ? `${namePrefix}[${propertyName}]` : propertyName;
82
- if (hiddenValuePaths.has(toPathKey(path))) return [];
88
+ const renamedTo = renamedValuePaths.get(toPathKey(path));
89
+ const effectivePath = renamedTo ?? path;
90
+ if (hiddenValuePaths.has(toPathKey(effectivePath))) return [];
91
+ if (renamedTo) {
92
+ const renamedValue = getValueAtPath(value, renamedTo);
93
+ return [toTableRow({
94
+ parameter,
95
+ name: getExpandedRowName(parameter, renamedTo, mode),
96
+ value: renamedValue === void 0 ? getValueAtPath(value, path) : renamedValue,
97
+ description: parameter.description,
98
+ schema: void 0,
99
+ isRequired: false,
100
+ isDisabled,
101
+ sourceParameterValuePath: renamedTo
102
+ })];
103
+ }
104
+ if (renameTargetPaths.has(toPathKey(path))) return [];
83
105
  if (mode === "deepObject" && isObjectSchema(resolvedPropertySchema) && Boolean(resolvedPropertySchema.properties)) return getExpandedPropertyRows({
84
106
  parameter,
85
107
  schema: resolvedPropertySchema,
@@ -88,7 +110,9 @@ var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefi
88
110
  namePrefix: name,
89
111
  mode,
90
112
  isDisabled,
91
- hiddenValuePaths
113
+ hiddenValuePaths,
114
+ renamedValuePaths,
115
+ renameTargetPaths
92
116
  });
93
117
  return [toTableRow({
94
118
  parameter,
@@ -103,6 +127,42 @@ var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefi
103
127
  });
104
128
  };
105
129
  /**
130
+ * Collects the leaf paths of an object value. In `form` mode only the top-level keys are leaves
131
+ * (form-style explode does not flatten nested objects); in `deepObject` mode we recurse into nested
132
+ * objects, mirroring how the rows and serialization are built.
133
+ */
134
+ var collectValueLeafPaths = (value, mode) => {
135
+ if (!isObject(value)) return [];
136
+ const paths = [];
137
+ const walk = (node, prefix) => {
138
+ for (const [key, val] of Object.entries(node)) {
139
+ const path = [...prefix, key];
140
+ if (mode === "deepObject" && isObject(val)) walk(val, path);
141
+ else paths.push(path);
142
+ }
143
+ };
144
+ walk(value, []);
145
+ return paths;
146
+ };
147
+ /**
148
+ * Builds rows for value paths that the schema does not describe. This keeps user-edited keys (for
149
+ * example a property that was renamed in the table) visible instead of snapping back to the
150
+ * schema-derived rows on the next render.
151
+ */
152
+ var getUnmappedValueRows = ({ parameter, value, schemaRows, mode, isDisabled, renamedValuePaths }) => {
153
+ const seen = new Set([...schemaRows.map((row) => toPathKey(row.sourceParameterValuePath ?? [])), ...renamedValuePaths.keys()]);
154
+ return collectValueLeafPaths(value, mode).filter((path) => !seen.has(toPathKey(path))).map((path) => toTableRow({
155
+ parameter,
156
+ name: getExpandedRowName(parameter, path, mode),
157
+ value: getValueAtPath(value, path),
158
+ description: parameter.description,
159
+ schema: void 0,
160
+ isRequired: false,
161
+ isDisabled,
162
+ sourceParameterValuePath: path
163
+ }));
164
+ };
165
+ /**
106
166
  * Turns a single OpenAPI parameter into one or more table rows.
107
167
  *
108
168
  * For object-typed query parameters with `form`/`explode: true` (the default) or `deepObject`
@@ -119,7 +179,9 @@ var createParameterRows = (parameter, exampleKey, options = {}) => {
119
179
  const value = example?.value === void 0 ? void 0 : deSerializeParameter(example.value, parameter);
120
180
  if (!schema.properties) return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)];
121
181
  const hiddenValuePaths = new Set(options.hiddenValuePaths?.map(toPathKey) ?? []);
122
- return getExpandedPropertyRows({
182
+ const renamedValuePaths = new Map((options.renamedValuePaths ?? []).map(({ from, to }) => [toPathKey(from), to]));
183
+ const renameTargetPaths = new Set((options.renamedValuePaths ?? []).map(({ to }) => toPathKey(to)));
184
+ const rows = getExpandedPropertyRows({
123
185
  parameter,
124
186
  schema,
125
187
  value,
@@ -127,8 +189,19 @@ var createParameterRows = (parameter, exampleKey, options = {}) => {
127
189
  namePrefix: mode === "deepObject" ? parameter.name : "",
128
190
  mode,
129
191
  isDisabled,
130
- hiddenValuePaths
192
+ hiddenValuePaths,
193
+ renamedValuePaths,
194
+ renameTargetPaths
195
+ });
196
+ const unmappedRows = getUnmappedValueRows({
197
+ parameter,
198
+ value,
199
+ schemaRows: rows,
200
+ mode,
201
+ isDisabled,
202
+ renamedValuePaths
131
203
  });
204
+ return [...rows, ...unmappedRows];
132
205
  };
133
206
  //#endregion
134
207
  export { createParameterRows };
@@ -1 +1 @@
1
- {"version":3,"file":"create-parameter-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-rows.ts"],"sourcesContent":["import { getValueAtPath } from '@scalar/helpers/object/get-value-at-path'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { deSerializeParameter, getExample } from '@scalar/workspace-store/request-example'\nimport type {\n ParameterObject,\n ParameterWithSchemaObject,\n ReferenceType,\n SchemaObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\nimport type { TableRow } from '../components/RequestTableRow.vue'\nimport { getParameterSchema } from './get-parameter-schema'\nimport { isParamDisabled } from './is-param-disabled'\n\ntype ParameterWithRequiredSchema = ParameterWithSchemaObject & {\n schema: ReferenceType<SchemaObject>\n}\n\n/** Serialization mode for object-typed query parameters that we expand into multiple rows. */\ntype ExpansionMode = 'form' | 'deepObject'\n\nconst isParameterWithSchema = (parameter: ParameterObject): parameter is ParameterWithRequiredSchema =>\n 'schema' in parameter && parameter.schema !== undefined\n\nconst resolveSchema = (schema: unknown): SchemaObject | undefined => {\n const resolvedSchema = getResolvedRef(schema as SchemaObject | { '$ref': string; '$ref-value': SchemaObject })\n\n return resolvedSchema as SchemaObject | undefined\n}\n\n/**\n * Resolves the OpenAPI serialization style and explode flag for a parameter, falling back to the\n * spec defaults (style: 'form', explode: true when style is 'form').\n */\nconst getParameterStyleAndExplode = (parameter: ParameterObject): { style: string; explode: boolean } => {\n const style = 'style' in parameter && parameter.style ? parameter.style : 'form'\n const explode = 'explode' in parameter && parameter.explode !== undefined ? parameter.explode : style === 'form'\n\n return { style, explode }\n}\n\n/**\n * Decides whether an object-typed query parameter should be expanded into one row per property,\n * and which expansion mode to use. Returns null when the parameter should stay as a single row\n * (non-query, non-object schema, or a serialization style we do not expand).\n */\nconst getExpansionMode = (parameter: ParameterObject, schema: SchemaObject | undefined): ExpansionMode | null => {\n if (parameter.in !== 'query' || !isParameterWithSchema(parameter) || !schema || !isObjectSchema(schema)) {\n return null\n }\n\n const { style, explode } = getParameterStyleAndExplode(parameter)\n if (!explode) {\n return null\n }\n\n if (style === 'form') {\n return 'form'\n }\n if (style === 'deepObject') {\n return 'deepObject'\n }\n\n return null\n}\n\nconst toTableValue = (value: unknown): string => {\n if (value === undefined || value === null) {\n return ''\n }\n\n if (Array.isArray(value)) {\n return value.join(',')\n }\n\n if (typeof value === 'object') {\n return JSON.stringify(value)\n }\n\n return String(value)\n}\n\nconst toPathKey = (path: readonly string[]): string => path.join('\\u0000')\n\nconst toTableRow = ({\n parameter,\n name,\n value,\n description,\n schema,\n isRequired,\n isDisabled,\n sourceParameterValuePath,\n}: {\n parameter: ParameterObject\n name: string\n value: unknown\n description: string | undefined\n schema: SchemaObject | undefined\n isRequired: boolean | undefined\n isDisabled: boolean\n sourceParameterValuePath?: string[]\n}): TableRow => ({\n name,\n value: toTableValue(value),\n description,\n schema,\n isRequired,\n isDisabled,\n originalParameter: parameter,\n sourceParameterValuePath,\n})\n\n/** Build the single-row representation used when a parameter is not expanded. */\nconst toSingleParameterRow = (\n parameter: ParameterObject,\n schema: SchemaObject | undefined,\n value: unknown,\n isDisabled: boolean,\n): TableRow =>\n toTableRow({\n parameter,\n name: parameter.name,\n value,\n description: parameter.description,\n schema,\n isRequired: parameter.required,\n isDisabled,\n })\n\n/**\n * Walks an object schema and produces one row per property.\n *\n * - In `form` mode (the OpenAPI default for query parameters) only the top-level properties are\n * flattened, and each row is named after the property itself (`status`).\n * - In `deepObject` mode we recurse into nested objects and emit bracketed names that mirror the\n * serialization on the wire (`filter[user][id]`).\n *\n * `pathPrefix` tracks the path inside the parent parameter value so the handler can later\n * reassemble all sibling rows back into a single object payload.\n */\nconst getExpandedPropertyRows = ({\n parameter,\n schema,\n value,\n pathPrefix,\n namePrefix,\n mode,\n isDisabled,\n hiddenValuePaths,\n}: {\n parameter: ParameterObject\n schema: Extract<SchemaObject, { type: 'object' }>\n value: unknown\n pathPrefix: string[]\n namePrefix: string\n mode: ExpansionMode\n isDisabled: boolean\n hiddenValuePaths: ReadonlySet<string>\n}): TableRow[] => {\n if (!schema.properties) {\n return []\n }\n\n const requiredProperties = new Set(schema.required ?? [])\n\n return Object.entries(schema.properties).flatMap(([propertyName, propertySchema]) => {\n const resolvedPropertySchema = resolveSchema(propertySchema)\n if (!resolvedPropertySchema) {\n return []\n }\n\n const path = [...pathPrefix, propertyName]\n const name = namePrefix ? `${namePrefix}[${propertyName}]` : propertyName\n\n if (hiddenValuePaths.has(toPathKey(path))) {\n return []\n }\n\n // Only deepObject style recurses into nested objects. The OpenAPI 3.1 spec says form-style\n // explode flattens only the top-level properties.\n const shouldRecurse =\n mode === 'deepObject' && isObjectSchema(resolvedPropertySchema) && Boolean(resolvedPropertySchema.properties)\n\n if (shouldRecurse) {\n return getExpandedPropertyRows({\n parameter,\n schema: resolvedPropertySchema,\n value,\n pathPrefix: path,\n namePrefix: name,\n mode,\n isDisabled,\n hiddenValuePaths,\n })\n }\n\n return [\n toTableRow({\n parameter,\n name,\n value: getValueAtPath(value, path),\n description: resolvedPropertySchema.description ?? parameter.description,\n schema: resolvedPropertySchema,\n isRequired: requiredProperties.has(propertyName),\n isDisabled,\n sourceParameterValuePath: path,\n }),\n ]\n })\n}\n\n/**\n * Turns a single OpenAPI parameter into one or more table rows.\n *\n * For object-typed query parameters with `form`/`explode: true` (the default) or `deepObject`\n * serialization, each property becomes its own row so the user can edit them individually,\n * matching how tools like Postman present the same parameter. Every other parameter passes\n * through as a single row.\n */\nexport const createParameterRows = (\n parameter: ParameterObject,\n exampleKey: string,\n options: { hiddenValuePaths?: readonly string[][] } = {},\n): TableRow[] => {\n const example = getExample(parameter, exampleKey, undefined)\n const isDisabled = isParamDisabled(parameter, example)\n const schema = getParameterSchema(parameter)\n const mode = getExpansionMode(parameter, schema)\n\n // Non-expandable parameters: render as a single row.\n if (mode === null || !schema || !isObjectSchema(schema)) {\n return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)]\n }\n\n // Expand into per-property rows. The deserialized value is used so existing per-property values\n // can be displayed in the table even when the example arrives as a serialized string.\n const value = example?.value === undefined ? undefined : deSerializeParameter(example.value, parameter)\n\n // Fall back to a single row only when the schema has no properties to expand.\n if (!schema.properties) {\n return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)]\n }\n\n const hiddenValuePaths = new Set(options.hiddenValuePaths?.map(toPathKey) ?? [])\n\n const rows = getExpandedPropertyRows({\n parameter,\n schema,\n value,\n pathPrefix: [],\n // deepObject names every row with a `parent[child]` prefix; form-style names use bare property names.\n namePrefix: mode === 'deepObject' ? parameter.name : '',\n mode,\n isDisabled,\n hiddenValuePaths,\n })\n\n return rows\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create-parameter-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-rows.ts"],"sourcesContent":["import { getValueAtPath } from '@scalar/helpers/object/get-value-at-path'\nimport { isObject } from '@scalar/helpers/object/is-object'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { deSerializeParameter, getExample } from '@scalar/workspace-store/request-example'\nimport type {\n ParameterObject,\n ParameterWithSchemaObject,\n ReferenceType,\n SchemaObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\nimport type { TableRow } from '../components/RequestTableRow.vue'\nimport { getParameterSchema } from './get-parameter-schema'\nimport { isParamDisabled } from './is-param-disabled'\n\ntype ParameterWithRequiredSchema = ParameterWithSchemaObject & {\n schema: ReferenceType<SchemaObject>\n}\n\n/** Serialization mode for object-typed query parameters that we expand into multiple rows. */\ntype ExpansionMode = 'form' | 'deepObject'\n\nconst isParameterWithSchema = (parameter: ParameterObject): parameter is ParameterWithRequiredSchema =>\n 'schema' in parameter && parameter.schema !== undefined\n\nconst resolveSchema = (schema: unknown): SchemaObject | undefined => {\n const resolvedSchema = getResolvedRef(schema as SchemaObject | { '$ref': string; '$ref-value': SchemaObject })\n\n return resolvedSchema as SchemaObject | undefined\n}\n\n/**\n * Resolves the OpenAPI serialization style and explode flag for a parameter, falling back to the\n * spec defaults (style: 'form', explode: true when style is 'form').\n */\nconst getParameterStyleAndExplode = (parameter: ParameterObject): { style: string; explode: boolean } => {\n const style = 'style' in parameter && parameter.style ? parameter.style : 'form'\n const explode = 'explode' in parameter && parameter.explode !== undefined ? parameter.explode : style === 'form'\n\n return { style, explode }\n}\n\n/**\n * Decides whether an object-typed query parameter should be expanded into one row per property,\n * and which expansion mode to use. Returns null when the parameter should stay as a single row\n * (non-query, non-object schema, or a serialization style we do not expand).\n */\nconst getExpansionMode = (parameter: ParameterObject, schema: SchemaObject | undefined): ExpansionMode | null => {\n if (parameter.in !== 'query' || !isParameterWithSchema(parameter) || !schema || !isObjectSchema(schema)) {\n return null\n }\n\n const { style, explode } = getParameterStyleAndExplode(parameter)\n if (!explode) {\n return null\n }\n\n if (style === 'form') {\n return 'form'\n }\n if (style === 'deepObject') {\n return 'deepObject'\n }\n\n return null\n}\n\nconst toTableValue = (value: unknown): string => {\n if (value === undefined || value === null) {\n return ''\n }\n\n if (Array.isArray(value)) {\n return value.join(',')\n }\n\n if (typeof value === 'object') {\n return JSON.stringify(value)\n }\n\n return String(value)\n}\n\nconst toPathKey = (path: readonly string[]): string => path.join('\\u0000')\n\nconst toTableRow = ({\n parameter,\n name,\n value,\n description,\n schema,\n isRequired,\n isDisabled,\n sourceParameterValuePath,\n}: {\n parameter: ParameterObject\n name: string\n value: unknown\n description: string | undefined\n schema: SchemaObject | undefined\n isRequired: boolean | undefined\n isDisabled: boolean\n sourceParameterValuePath?: string[]\n}): TableRow => ({\n name,\n value: toTableValue(value),\n description,\n schema,\n isRequired,\n isDisabled,\n originalParameter: parameter,\n sourceParameterValuePath,\n})\n\n/**\n * Builds the row name for an expanded property at a given value path. deepObject rows mirror the\n * wire format (`parent[a][b]`); form-style explode uses the bare top-level key.\n */\nconst getExpandedRowName = (parameter: ParameterObject, path: string[], mode: ExpansionMode): string =>\n mode === 'deepObject' ? `${parameter.name}${path.map((segment) => `[${segment}]`).join('')}` : (path[0] ?? '')\n\n/** Build the single-row representation used when a parameter is not expanded. */\nconst toSingleParameterRow = (\n parameter: ParameterObject,\n schema: SchemaObject | undefined,\n value: unknown,\n isDisabled: boolean,\n): TableRow =>\n toTableRow({\n parameter,\n name: parameter.name,\n value,\n description: parameter.description,\n schema,\n isRequired: parameter.required,\n isDisabled,\n })\n\n/**\n * Walks an object schema and produces one row per property.\n *\n * - In `form` mode (the OpenAPI default for query parameters) only the top-level properties are\n * flattened, and each row is named after the property itself (`status`).\n * - In `deepObject` mode we recurse into nested objects and emit bracketed names that mirror the\n * serialization on the wire (`filter[user][id]`).\n *\n * `pathPrefix` tracks the path inside the parent parameter value so the handler can later\n * reassemble all sibling rows back into a single object payload.\n */\nconst getExpandedPropertyRows = ({\n parameter,\n schema,\n value,\n pathPrefix,\n namePrefix,\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n}: {\n parameter: ParameterObject\n schema: Extract<SchemaObject, { type: 'object' }>\n value: unknown\n pathPrefix: string[]\n namePrefix: string\n mode: ExpansionMode\n isDisabled: boolean\n hiddenValuePaths: ReadonlySet<string>\n renamedValuePaths: ReadonlyMap<string, string[]>\n renameTargetPaths: ReadonlySet<string>\n}): TableRow[] => {\n if (!schema.properties) {\n return []\n }\n\n const requiredProperties = new Set(schema.required ?? [])\n\n return Object.entries(schema.properties).flatMap(([propertyName, propertySchema]) => {\n const resolvedPropertySchema = resolveSchema(propertySchema)\n if (!resolvedPropertySchema) {\n return []\n }\n\n const path = [...pathPrefix, propertyName]\n const name = namePrefix ? `${namePrefix}[${propertyName}]` : propertyName\n\n // When this property was renamed, the value lives at the typed key instead of the schema path.\n // Keep the row in its original slot so it does not jump to the end of the table.\n const renamedTo = renamedValuePaths.get(toPathKey(path))\n const effectivePath = renamedTo ?? path\n\n if (hiddenValuePaths.has(toPathKey(effectivePath))) {\n return []\n }\n\n if (renamedTo) {\n // The value move is debounced, so until it lands the value still sits at the old schema path.\n // Fall back to it so the renamed row shows its value immediately instead of flickering empty.\n const renamedValue = getValueAtPath(value, renamedTo)\n\n return [\n toTableRow({\n parameter,\n name: getExpandedRowName(parameter, renamedTo, mode),\n value: renamedValue === undefined ? getValueAtPath(value, path) : renamedValue,\n description: parameter.description,\n // The renamed key no longer maps to the schema property, so it carries no schema.\n schema: undefined,\n isRequired: false,\n isDisabled,\n sourceParameterValuePath: renamedTo,\n }),\n ]\n }\n\n // Another property was renamed onto this path (for example \"a\" renamed to an existing \"b\").\n // The renamed row already occupies this slot, so skip the schema-derived row to avoid rendering\n // two rows for the same value path.\n if (renameTargetPaths.has(toPathKey(path))) {\n return []\n }\n\n // Only deepObject style recurses into nested objects. The OpenAPI 3.1 spec says form-style\n // explode flattens only the top-level properties.\n const shouldRecurse =\n mode === 'deepObject' && isObjectSchema(resolvedPropertySchema) && Boolean(resolvedPropertySchema.properties)\n\n if (shouldRecurse) {\n return getExpandedPropertyRows({\n parameter,\n schema: resolvedPropertySchema,\n value,\n pathPrefix: path,\n namePrefix: name,\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n })\n }\n\n return [\n toTableRow({\n parameter,\n name,\n value: getValueAtPath(value, path),\n description: resolvedPropertySchema.description ?? parameter.description,\n schema: resolvedPropertySchema,\n isRequired: requiredProperties.has(propertyName),\n isDisabled,\n sourceParameterValuePath: path,\n }),\n ]\n })\n}\n\n/**\n * Collects the leaf paths of an object value. In `form` mode only the top-level keys are leaves\n * (form-style explode does not flatten nested objects); in `deepObject` mode we recurse into nested\n * objects, mirroring how the rows and serialization are built.\n */\nconst collectValueLeafPaths = (value: unknown, mode: ExpansionMode): string[][] => {\n if (!isObject(value)) {\n return []\n }\n\n const paths: string[][] = []\n\n const walk = (node: Record<string, unknown>, prefix: string[]): void => {\n for (const [key, val] of Object.entries(node)) {\n const path = [...prefix, key]\n\n if (mode === 'deepObject' && isObject(val)) {\n walk(val, path)\n } else {\n paths.push(path)\n }\n }\n }\n\n walk(value, [])\n\n return paths\n}\n\n/**\n * Builds rows for value paths that the schema does not describe. This keeps user-edited keys (for\n * example a property that was renamed in the table) visible instead of snapping back to the\n * schema-derived rows on the next render.\n */\nconst getUnmappedValueRows = ({\n parameter,\n value,\n schemaRows,\n mode,\n isDisabled,\n renamedValuePaths,\n}: {\n parameter: ParameterObject\n value: unknown\n schemaRows: TableRow[]\n mode: ExpansionMode\n isDisabled: boolean\n renamedValuePaths: ReadonlyMap<string, string[]>\n}): TableRow[] => {\n // Skip the renamed-away source paths too: the value move is debounced, so the old key lingers in\n // the value for a moment and would otherwise flash as a duplicate row next to the renamed one.\n const seen = new Set([\n ...schemaRows.map((row) => toPathKey(row.sourceParameterValuePath ?? [])),\n ...renamedValuePaths.keys(),\n ])\n\n // These rows always render: a key that carries a value should stay visible. The hidden-path set\n // only suppresses empty schema suggestions, so it is intentionally not applied here.\n return collectValueLeafPaths(value, mode)\n .filter((path) => !seen.has(toPathKey(path)))\n .map((path) =>\n toTableRow({\n parameter,\n name: getExpandedRowName(parameter, path, mode),\n value: getValueAtPath(value, path),\n description: parameter.description,\n schema: undefined,\n isRequired: false,\n isDisabled,\n sourceParameterValuePath: path,\n }),\n )\n}\n\n/**\n * Turns a single OpenAPI parameter into one or more table rows.\n *\n * For object-typed query parameters with `form`/`explode: true` (the default) or `deepObject`\n * serialization, each property becomes its own row so the user can edit them individually,\n * matching how tools like Postman present the same parameter. Every other parameter passes\n * through as a single row.\n */\nexport const createParameterRows = (\n parameter: ParameterObject,\n exampleKey: string,\n options: {\n hiddenValuePaths?: readonly string[][]\n renamedValuePaths?: readonly { from: string[]; to: string[] }[]\n } = {},\n): TableRow[] => {\n const example = getExample(parameter, exampleKey, undefined)\n const isDisabled = isParamDisabled(parameter, example)\n const schema = getParameterSchema(parameter)\n const mode = getExpansionMode(parameter, schema)\n\n // Non-expandable parameters: render as a single row.\n if (mode === null || !schema || !isObjectSchema(schema)) {\n return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)]\n }\n\n // Expand into per-property rows. The deserialized value is used so existing per-property values\n // can be displayed in the table even when the example arrives as a serialized string.\n const value = example?.value === undefined ? undefined : deSerializeParameter(example.value, parameter)\n\n // Fall back to a single row only when the schema has no properties to expand.\n if (!schema.properties) {\n return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)]\n }\n\n const hiddenValuePaths = new Set(options.hiddenValuePaths?.map(toPathKey) ?? [])\n const renamedValuePaths = new Map((options.renamedValuePaths ?? []).map(({ from, to }) => [toPathKey(from), to]))\n // Paths a property was renamed onto, used to suppress the colliding schema-derived row.\n const renameTargetPaths = new Set((options.renamedValuePaths ?? []).map(({ to }) => toPathKey(to)))\n\n const rows = getExpandedPropertyRows({\n parameter,\n schema,\n value,\n pathPrefix: [],\n // deepObject names every row with a `parent[child]` prefix; form-style names use bare property names.\n namePrefix: mode === 'deepObject' ? parameter.name : '',\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n })\n\n // Surface keys present in the value but not in the schema (for example a renamed property) so the\n // edited key keeps showing up instead of snapping back to the schema-derived rows.\n const unmappedRows = getUnmappedValueRows({\n parameter,\n value,\n schemaRows: rows,\n mode,\n isDisabled,\n renamedValuePaths,\n })\n\n return [...rows, ...unmappedRows]\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  //#region src/v2/constants.ts
2
2
  /** The version number taken from the package.json. Consumers can override at build time via define (e.g. OVERRIDE_PACKAGE_VERSION: JSON.stringify('1.2.3')). */
3
- var APP_VERSION = typeof OVERRIDE_PACKAGE_VERSION !== "undefined" ? OVERRIDE_PACKAGE_VERSION : "3.10.4";
3
+ var APP_VERSION = typeof OVERRIDE_PACKAGE_VERSION !== "undefined" ? OVERRIDE_PACKAGE_VERSION : "3.11.0";
4
4
  //#endregion
5
5
  export { APP_VERSION };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.vue.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.id ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Modal.vue.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.name ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":""}
@@ -110,7 +110,7 @@ var Modal_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
110
110
  activeWorkspace,
111
111
  class: "flex-1",
112
112
  document: __props.document.value,
113
- documentSlug: __props.document.value["x-scalar-navigation"]?.id ?? "",
113
+ documentSlug: __props.document.value["x-scalar-navigation"]?.name ?? "",
114
114
  environment: environment.value,
115
115
  eventBus: __props.eventBus,
116
116
  exampleName: __props.exampleName?.value,
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.vue.script.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.id ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4EA,MAAM,kBAAuC;GAC3C,OAAO;GACP,IAAI;GACN;;EAGA,MAAM,gBAAgB,IAAI,MAAK;;AAG/B,wBAAsB;GACpB,UAAO,QAAA;GACP;GACA,iCAA8B,QAAA;GAC9B,cAAW,QAAA;GACX,YAAS,QAAA;GACT,OAAO,QAAA;GACR,CAAA;;AAGD,mBAAiB,QAAA,UAAU,eAAe,CAAC,QAAA,WAAW,KAAI;;EAG1D,MAAM,gBAAgB;AACpB,WAAA,SAAS,KAAK,2BAA0B;;EAG1C,MAAM,WAAW,oBAAoB;AACnC,OAAI,OAAO,WAAW,YACpB,QAAO,OAAO,SAAS;AAEzB,UAAO;IACR;AAED,cACQ,QAAA,WAAW,OAChB,SAAS;AAER,YAAS,QAAQ;AAEjB,OAAI,CAAC,KACH,UAAQ;IAGd;AAGA,wBAAsB,SAAS,CAAA;;EAG/B,MAAM,wBAAwB;;EAG9B,MAAM,eAAe,eAEjB,QAAA,gBAAgB,YAAY,6BAC5B,sBACJ;;EAGA,MAAM,4BAA4B,UAChC,QAAA,gBAAgB,OAAO,0BAA0B,MAAK;;;;;;EAOxD,MAAM,cAAc,eACZ,qBAAqB,QAAA,gBAAgB,QAAA,SAAS,MAAM,CAAC,YAC7D;AAEA,WAAa;GACX;GACA;GACD,CAAA;;uBAIC,YA8CuB,8BAAA,EA9CA,YAAA,QAAA,YAAU,EAAA;2BAEf,CAAhB,YAAgB,MAAA,aAAA,CAAA,EAIR,QAAA,SAAS,SAAS,QAAA,MAAM,SAAS,QAAA,QAAQ,SAAA,WAAA,EADjD,mBAkCO,QAlCP,YAkCO;KA/BL,YAEoD,MAAA,sBAAA,EAAA;kBADzC,cAAA;iFAAa,QAAA;MACtB,OAAM;;oBACR,YAYoD,MAAA,gBAAA,EAAA;MAV1C,cAAc,aAAA;mFAAY,QAAA,SAUZ,yBAAA;MATJ;MAClB,OAAM;MACL,WAAS,CAAG,QAAA,SAAS,MAAK;MAC1B,UAAA,QAAA;MACA,mBAAa;MACd,QAAO;MACN,cAAc,QAAA,aAAa;MAC3B,YAAY,EAAE;MACd,cAAY,QAAA,aAAa;;;;;;;kBAVlB,cAAA,MAAa,CAAA,CAAA;KAYvB,YAcoB,mBAAA;MAbA;MAClB,OAAM;MACL,UAAU,QAAA,SAAS;MACnB,cAAc,QAAA,SAAS,MAAK,wBAAyB,MAAE;MACvD,aAAA,YAAA;MACA,UAAA,QAAA;MACA,aAAa,QAAA,aAAa;MAC3B,QAAO;MACN,QAAQ,QAAA,QAAQ;MAChB,SAAA,QAAA;MACA,MAAM,QAAA,MAAM;MACZ,SAAA,QAAA;MACA,iCAAiC,QAAA,gCAAgC;MACjE,gBAAA,QAAA;;;;;;;;;;;;;;wBAGL,mBAIM,OAJN,YAIM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAkD,QAAA,EAA5C,OAAM,YAAU,EAAC,wBAAoB,GAAA,CAAA,EAAA,CAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"Modal.vue.script.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.name ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4EA,MAAM,kBAAuC;GAC3C,OAAO;GACP,IAAI;GACN;;EAGA,MAAM,gBAAgB,IAAI,MAAK;;AAG/B,wBAAsB;GACpB,UAAO,QAAA;GACP;GACA,iCAA8B,QAAA;GAC9B,cAAW,QAAA;GACX,YAAS,QAAA;GACT,OAAO,QAAA;GACR,CAAA;;AAGD,mBAAiB,QAAA,UAAU,eAAe,CAAC,QAAA,WAAW,KAAI;;EAG1D,MAAM,gBAAgB;AACpB,WAAA,SAAS,KAAK,2BAA0B;;EAG1C,MAAM,WAAW,oBAAoB;AACnC,OAAI,OAAO,WAAW,YACpB,QAAO,OAAO,SAAS;AAEzB,UAAO;IACR;AAED,cACQ,QAAA,WAAW,OAChB,SAAS;AAER,YAAS,QAAQ;AAEjB,OAAI,CAAC,KACH,UAAQ;IAGd;AAGA,wBAAsB,SAAS,CAAA;;EAG/B,MAAM,wBAAwB;;EAG9B,MAAM,eAAe,eAEjB,QAAA,gBAAgB,YAAY,6BAC5B,sBACJ;;EAGA,MAAM,4BAA4B,UAChC,QAAA,gBAAgB,OAAO,0BAA0B,MAAK;;;;;;EAOxD,MAAM,cAAc,eACZ,qBAAqB,QAAA,gBAAgB,QAAA,SAAS,MAAM,CAAC,YAC7D;AAEA,WAAa;GACX;GACA;GACD,CAAA;;uBAIC,YA8CuB,8BAAA,EA9CA,YAAA,QAAA,YAAU,EAAA;2BAEf,CAAhB,YAAgB,MAAA,aAAA,CAAA,EAIR,QAAA,SAAS,SAAS,QAAA,MAAM,SAAS,QAAA,QAAQ,SAAA,WAAA,EADjD,mBAkCO,QAlCP,YAkCO;KA/BL,YAEoD,MAAA,sBAAA,EAAA;kBADzC,cAAA;iFAAa,QAAA;MACtB,OAAM;;oBACR,YAYoD,MAAA,gBAAA,EAAA;MAV1C,cAAc,aAAA;mFAAY,QAAA,SAUZ,yBAAA;MATJ;MAClB,OAAM;MACL,WAAS,CAAG,QAAA,SAAS,MAAK;MAC1B,UAAA,QAAA;MACA,mBAAa;MACd,QAAO;MACN,cAAc,QAAA,aAAa;MAC3B,YAAY,EAAE;MACd,cAAY,QAAA,aAAa;;;;;;;kBAVlB,cAAA,MAAa,CAAA,CAAA;KAYvB,YAcoB,mBAAA;MAbA;MAClB,OAAM;MACL,UAAU,QAAA,SAAS;MACnB,cAAc,QAAA,SAAS,MAAK,wBAAyB,QAAI;MACzD,aAAA,YAAA;MACA,UAAA,QAAA;MACA,aAAa,QAAA,aAAa;MAC3B,QAAO;MACN,QAAQ,QAAA,QAAQ;MAChB,SAAA,QAAA;MACA,MAAM,QAAA,MAAM;MACZ,SAAA,QAAA;MACA,iCAAiC,QAAA,gCAAgC;MACjE,gBAAA,QAAA;;;;;;;;;;;;;;wBAGL,mBAIM,OAJN,YAIM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAkD,QAAA,EAA5C,OAAM,YAAU,EAAC,wBAAoB,GAAA,CAAA,EAAA,CAAA,EAAA,CAAA"}