@scalar/api-client 3.10.4 → 3.12.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 (151) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/plugins/posthog/sanitize-event-payload.d.ts.map +1 -1
  3. package/dist/plugins/posthog/sanitize-event-payload.js +1 -0
  4. package/dist/plugins/posthog/sanitize-event-payload.js.map +1 -1
  5. package/dist/style.css +25 -74
  6. package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
  7. package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
  8. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +10 -1
  9. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
  10. package/dist/v2/blocks/operation-block/helpers/send-request.d.ts +7 -1
  11. package/dist/v2/blocks/operation-block/helpers/send-request.d.ts.map +1 -1
  12. package/dist/v2/blocks/operation-block/helpers/send-request.js +2 -2
  13. package/dist/v2/blocks/operation-block/helpers/send-request.js.map +1 -1
  14. package/dist/v2/blocks/operation-block/helpers/validate-path-parameters.d.ts.map +1 -1
  15. package/dist/v2/blocks/operation-block/helpers/validate-path-parameters.js +1 -2
  16. package/dist/v2/blocks/operation-block/helpers/validate-path-parameters.js.map +1 -1
  17. package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts +1 -1
  18. package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts.map +1 -1
  19. package/dist/v2/blocks/request-block/RequestBlock.vue.js +1 -1
  20. package/dist/v2/blocks/request-block/RequestBlock.vue.js.map +1 -1
  21. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js +48 -11
  22. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  23. package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.d.ts +2 -2
  24. package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.d.ts.map +1 -1
  25. package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.js.map +1 -1
  26. package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.script.js +2 -6
  27. package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.script.js.map +1 -1
  28. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts +4 -0
  29. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts.map +1 -1
  30. package/dist/v2/blocks/request-block/components/RequestParams.vue.js.map +1 -1
  31. package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js.map +1 -1
  32. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts +3 -11
  33. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts.map +1 -1
  34. package/dist/v2/blocks/request-block/components/RequestTable.vue.js +1 -1
  35. package/dist/v2/blocks/request-block/components/RequestTable.vue.js.map +1 -1
  36. package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js.map +1 -1
  37. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts +8 -10
  38. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
  39. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
  40. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +27 -11
  41. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
  42. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.d.ts +9 -6
  43. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.d.ts.map +1 -1
  44. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js +45 -4
  45. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js.map +1 -1
  46. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts +4 -0
  47. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts.map +1 -1
  48. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js +94 -10
  49. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js.map +1 -1
  50. package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js +1 -1
  51. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js +1 -1
  52. package/dist/v2/components/data-table/DataTableInput.vue.d.ts +1 -1
  53. package/dist/v2/components/data-table/DataTableInput.vue.d.ts.map +1 -1
  54. package/dist/v2/constants.js +1 -1
  55. package/dist/v2/features/modal/Modal.vue.js.map +1 -1
  56. package/dist/v2/features/modal/Modal.vue.script.js +1 -1
  57. package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
  58. package/dist/v2/features/modal/helpers/create-api-client-modal.js +1 -1
  59. package/dist/v2/features/operation/Operation.vue.script.js +1 -1
  60. package/dist/v2/workspace-events.d.ts.map +1 -1
  61. package/dist/v2/workspace-events.js +1 -0
  62. package/dist/v2/workspace-events.js.map +1 -1
  63. package/dist/vue-styles.css +10 -52
  64. package/package.json +13 -24
  65. package/dist/v2/blocks/operation-code-sample/components/ExamplePicker.vue.d.ts +0 -16
  66. package/dist/v2/blocks/operation-code-sample/components/ExamplePicker.vue.d.ts.map +0 -1
  67. package/dist/v2/blocks/operation-code-sample/components/ExamplePicker.vue.js +0 -7
  68. package/dist/v2/blocks/operation-code-sample/components/ExamplePicker.vue.js.map +0 -1
  69. package/dist/v2/blocks/operation-code-sample/components/ExamplePicker.vue.script.js +0 -53
  70. package/dist/v2/blocks/operation-code-sample/components/ExamplePicker.vue.script.js.map +0 -1
  71. package/dist/v2/blocks/operation-code-sample/components/HttpMethod.vue.d.ts +0 -26
  72. package/dist/v2/blocks/operation-code-sample/components/HttpMethod.vue.d.ts.map +0 -1
  73. package/dist/v2/blocks/operation-code-sample/components/HttpMethod.vue.js +0 -7
  74. package/dist/v2/blocks/operation-code-sample/components/HttpMethod.vue.js.map +0 -1
  75. package/dist/v2/blocks/operation-code-sample/components/HttpMethod.vue.script.js +0 -33
  76. package/dist/v2/blocks/operation-code-sample/components/HttpMethod.vue.script.js.map +0 -1
  77. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.d.ts +0 -141
  78. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.d.ts.map +0 -1
  79. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js +0 -9
  80. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js.map +0 -1
  81. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js +0 -272
  82. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js.map +0 -1
  83. package/dist/v2/blocks/operation-code-sample/helpers/filter-clients-by-query.d.ts +0 -9
  84. package/dist/v2/blocks/operation-code-sample/helpers/filter-clients-by-query.d.ts.map +0 -1
  85. package/dist/v2/blocks/operation-code-sample/helpers/filter-clients-by-query.js +0 -37
  86. package/dist/v2/blocks/operation-code-sample/helpers/filter-clients-by-query.js.map +0 -1
  87. package/dist/v2/blocks/operation-code-sample/helpers/find-client.d.ts +0 -41
  88. package/dist/v2/blocks/operation-code-sample/helpers/find-client.d.ts.map +0 -1
  89. package/dist/v2/blocks/operation-code-sample/helpers/find-client.js +0 -48
  90. package/dist/v2/blocks/operation-code-sample/helpers/find-client.js.map +0 -1
  91. package/dist/v2/blocks/operation-code-sample/helpers/format-language.d.ts +0 -8
  92. package/dist/v2/blocks/operation-code-sample/helpers/format-language.d.ts.map +0 -1
  93. package/dist/v2/blocks/operation-code-sample/helpers/format-language.js +0 -70
  94. package/dist/v2/blocks/operation-code-sample/helpers/format-language.js.map +0 -1
  95. package/dist/v2/blocks/operation-code-sample/helpers/generate-client-options.d.ts +0 -30
  96. package/dist/v2/blocks/operation-code-sample/helpers/generate-client-options.d.ts.map +0 -1
  97. package/dist/v2/blocks/operation-code-sample/helpers/generate-client-options.js +0 -63
  98. package/dist/v2/blocks/operation-code-sample/helpers/generate-client-options.js.map +0 -1
  99. package/dist/v2/blocks/operation-code-sample/helpers/generate-code-snippet.d.ts +0 -39
  100. package/dist/v2/blocks/operation-code-sample/helpers/generate-code-snippet.d.ts.map +0 -1
  101. package/dist/v2/blocks/operation-code-sample/helpers/generate-code-snippet.js +0 -38
  102. package/dist/v2/blocks/operation-code-sample/helpers/generate-code-snippet.js.map +0 -1
  103. package/dist/v2/blocks/operation-code-sample/helpers/get-clients.d.ts +0 -13
  104. package/dist/v2/blocks/operation-code-sample/helpers/get-clients.d.ts.map +0 -1
  105. package/dist/v2/blocks/operation-code-sample/helpers/get-clients.js +0 -37
  106. package/dist/v2/blocks/operation-code-sample/helpers/get-clients.js.map +0 -1
  107. package/dist/v2/blocks/operation-code-sample/helpers/get-custom-code-samples.d.ts +0 -45
  108. package/dist/v2/blocks/operation-code-sample/helpers/get-custom-code-samples.d.ts.map +0 -1
  109. package/dist/v2/blocks/operation-code-sample/helpers/get-custom-code-samples.js +0 -84
  110. package/dist/v2/blocks/operation-code-sample/helpers/get-custom-code-samples.js.map +0 -1
  111. package/dist/v2/blocks/operation-code-sample/helpers/get-resolved-ref-deep.d.ts +0 -27
  112. package/dist/v2/blocks/operation-code-sample/helpers/get-resolved-ref-deep.d.ts.map +0 -1
  113. package/dist/v2/blocks/operation-code-sample/helpers/get-resolved-ref-deep.js +0 -41
  114. package/dist/v2/blocks/operation-code-sample/helpers/get-resolved-ref-deep.js.map +0 -1
  115. package/dist/v2/blocks/operation-code-sample/helpers/get-secrets.d.ts +0 -4
  116. package/dist/v2/blocks/operation-code-sample/helpers/get-secrets.d.ts.map +0 -1
  117. package/dist/v2/blocks/operation-code-sample/helpers/get-secrets.js +0 -18
  118. package/dist/v2/blocks/operation-code-sample/helpers/get-secrets.js.map +0 -1
  119. package/dist/v2/blocks/operation-code-sample/helpers/get-snippet.d.ts +0 -8
  120. package/dist/v2/blocks/operation-code-sample/helpers/get-snippet.d.ts.map +0 -1
  121. package/dist/v2/blocks/operation-code-sample/helpers/get-snippet.js +0 -38
  122. package/dist/v2/blocks/operation-code-sample/helpers/get-snippet.js.map +0 -1
  123. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/operation-to-har.d.ts +0 -72
  124. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/operation-to-har.d.ts.map +0 -1
  125. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/operation-to-har.js +0 -114
  126. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/operation-to-har.js.map +0 -1
  127. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.d.ts +0 -13
  128. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.d.ts.map +0 -1
  129. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.js +0 -196
  130. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.js.map +0 -1
  131. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-parameters.d.ts +0 -24
  132. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-parameters.d.ts.map +0 -1
  133. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-parameters.js +0 -237
  134. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-parameters.js.map +0 -1
  135. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-security-schemes.d.ts +0 -15
  136. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-security-schemes.d.ts.map +0 -1
  137. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-security-schemes.js +0 -65
  138. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-security-schemes.js.map +0 -1
  139. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-server-url.d.ts +0 -6
  140. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-server-url.d.ts.map +0 -1
  141. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-server-url.js +0 -19
  142. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-server-url.js.map +0 -1
  143. package/dist/v2/blocks/operation-code-sample/index.d.ts +0 -9
  144. package/dist/v2/blocks/operation-code-sample/index.d.ts.map +0 -1
  145. package/dist/v2/blocks/operation-code-sample/index.js +0 -8
  146. package/dist/v2/blocks/operation-code-sample/types.d.ts +0 -46
  147. package/dist/v2/blocks/operation-code-sample/types.d.ts.map +0 -1
  148. package/dist/v2/blocks/request-block/helpers/is-param-disabled.d.ts +0 -13
  149. package/dist/v2/blocks/request-block/helpers/is-param-disabled.d.ts.map +0 -1
  150. package/dist/v2/blocks/request-block/helpers/is-param-disabled.js +0 -21
  151. package/dist/v2/blocks/request-block/helpers/is-param-disabled.js.map +0 -1
@@ -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'\nimport { deSerializeSchemaValue } from '@scalar/workspace-store/request-example'\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/**\n * Whether a row name carries the display-only deepObject array marker (`filters[id][in][]`). The\n * marker is only ever appended after a real path bracket, so it always shows up as `][]`. That lets\n * us tell it apart from a genuinely empty key: an interior empty (`filters[][in]`) or a lone empty\n * group (`filters[]`, value path `['']`) is not a marker and keeps its segment.\n */\nconst hasArrayMarker = (name: string): boolean => name.endsWith('][]')\n\n/** Parse a parameter key like `filter[a][b]` into its path segments `['filter', 'a', 'b']`. */\nconst parseBracketKey = (name: string): string[] => {\n // Strip the trailing array marker first. The trailing brackets on a deepObject array leaf are\n // display-only, not part of the value path — keeping them would add a bogus empty key that drops\n // the value on write-back and corrupts rename tracking.\n const withoutArrayMarker = hasArrayMarker(name) ? name.slice(0, -2) : name\n\n const segments: string[] = []\n const head = withoutArrayMarker.match(/^[^[\\]]*/)?.[0] ?? ''\n if (head) {\n segments.push(head)\n }\n for (const match of withoutArrayMarker.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 // Only deepObject leaves use the comma-to-array coercion below. The trailing-bracket array\n // convention (`key[]=1&key[]=2`) is deepObject-specific, and deepObject leaves never carry a\n // meaningful comma. Form-style object parameters can (e.g. Spring `sort=username,asc`), so they\n // keep their leaves verbatim.\n const parameter = row.originalParameter\n const isDeepObjectParameter = Boolean(parameter && 'style' in parameter && parameter.style === 'deepObject')\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 // Rows always hold the string the user sees, so a deepObject array leaf arrives comma-joined\n // (\"1,2\"). Coerce it back to an array before storing — otherwise deepObject serialization\n // re-collapses it into a single `key[in]=1,2` entry instead of repeating `key[in][]=1&key[in][]=2`.\n //\n // The display-only `][]` marker is the authoritative array signal: a leaf gets it whenever its\n // schema OR its stored value is an array, so it must win over a non-array property schema, which\n // would otherwise skip the coercion and serialize the array comma-joined. A committed rename\n // re-derives the marker from the freshly typed name, since the row's `schema` and `name` still\n // describe the old key — renaming an array leaf to a scalar key must not store a one-element array.\n // Non-array leaves fall back to the property schema so object leaves still coerce; renamed rows\n // have no reliable schema, so they rely on the marker alone.\n const isCommittedRename = isEditedRow && Boolean(payload.shouldRenameExpandedRow)\n const hasArrayLeafMarker = hasArrayMarker(isCommittedRename ? payload.name : contextRow.name)\n const leafSchema = hasArrayLeafMarker\n ? ({ type: 'array' } as const)\n : isCommittedRename\n ? undefined\n : contextRow.schema\n const leafValue = isDeepObjectParameter && leafSchema ? deSerializeSchemaValue(nextValue, leafSchema) : nextValue\n\n setValueAtPath(value, path, leafValue)\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;AAqVjE;;;;;;;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"}
@@ -1,9 +1,9 @@
1
- import { isParamDisabled } from "./is-param-disabled.js";
2
1
  import { getParameterSchema } from "./get-parameter-schema.js";
3
2
  import { getValueAtPath } from "@scalar/helpers/object/get-value-at-path";
4
- import { deSerializeParameter, getExample } from "@scalar/workspace-store/request-example";
3
+ import { deSerializeParameter, getExample, isParamDisabled } from "@scalar/workspace-store/request-example";
5
4
  import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
6
- import { isObjectSchema } from "@scalar/workspace-store/schemas/v3.1/strict/type-guards";
5
+ import { isObject } from "@scalar/helpers/object/is-object";
6
+ import { isArraySchema, isObjectSchema } from "@scalar/workspace-store/schemas/v3.1/strict/type-guards";
7
7
  //#region src/v2/blocks/request-block/helpers/create-parameter-rows.ts
8
8
  var isParameterWithSchema = (parameter) => "schema" in parameter && parameter.schema !== void 0;
9
9
  var resolveSchema = (schema) => {
@@ -50,6 +50,18 @@ var toTableRow = ({ parameter, name, value, description, schema, isRequired, isD
50
50
  originalParameter: parameter,
51
51
  sourceParameterValuePath
52
52
  });
53
+ /**
54
+ * Builds the row name for an expanded property at a given value path. deepObject rows mirror the
55
+ * wire format (`parent[a][b]`); form-style explode uses the bare top-level key.
56
+ */
57
+ var getExpandedRowName = (parameter, path, mode) => mode === "deepObject" ? `${parameter.name}${path.map((segment) => `[${segment}]`).join("")}` : path[0] ?? "";
58
+ /**
59
+ * Appends the display-only trailing `[]` to deepObject array leaves so the name matches the
60
+ * serialized `parent[ids][]=1&parent[ids][]=2` form. The bracket is display-only — the row's
61
+ * `sourceParameterValuePath` stays bracket-free. It also lets write-back recognize the leaf as an
62
+ * array even on renamed and unmapped rows, which carry no schema.
63
+ */
64
+ var withArrayBracket = (name, mode, isArray) => mode === "deepObject" && isArray ? `${name}[]` : name;
53
65
  /** Build the single-row representation used when a parameter is not expanded. */
54
66
  var toSingleParameterRow = (parameter, schema, value, isDisabled) => toTableRow({
55
67
  parameter,
@@ -71,7 +83,7 @@ var toSingleParameterRow = (parameter, schema, value, isDisabled) => toTableRow(
71
83
  * `pathPrefix` tracks the path inside the parent parameter value so the handler can later
72
84
  * reassemble all sibling rows back into a single object payload.
73
85
  */
74
- var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefix, mode, isDisabled, hiddenValuePaths }) => {
86
+ var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefix, mode, isDisabled, hiddenValuePaths, renamedValuePaths, renameTargetPaths }) => {
75
87
  if (!schema.properties) return [];
76
88
  const requiredProperties = new Set(schema.required ?? []);
77
89
  return Object.entries(schema.properties).flatMap(([propertyName, propertySchema]) => {
@@ -79,7 +91,24 @@ var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefi
79
91
  if (!resolvedPropertySchema) return [];
80
92
  const path = [...pathPrefix, propertyName];
81
93
  const name = namePrefix ? `${namePrefix}[${propertyName}]` : propertyName;
82
- if (hiddenValuePaths.has(toPathKey(path))) return [];
94
+ const renamedTo = renamedValuePaths.get(toPathKey(path));
95
+ const effectivePath = renamedTo ?? path;
96
+ if (hiddenValuePaths.has(toPathKey(effectivePath))) return [];
97
+ if (renamedTo) {
98
+ const renamedValue = getValueAtPath(value, renamedTo);
99
+ const effectiveValue = renamedValue === void 0 ? getValueAtPath(value, path) : renamedValue;
100
+ return [toTableRow({
101
+ parameter,
102
+ name: withArrayBracket(getExpandedRowName(parameter, renamedTo, mode), mode, Array.isArray(effectiveValue)),
103
+ value: effectiveValue,
104
+ description: parameter.description,
105
+ schema: void 0,
106
+ isRequired: false,
107
+ isDisabled,
108
+ sourceParameterValuePath: renamedTo
109
+ })];
110
+ }
111
+ if (renameTargetPaths.has(toPathKey(path))) return [];
83
112
  if (mode === "deepObject" && isObjectSchema(resolvedPropertySchema) && Boolean(resolvedPropertySchema.properties)) return getExpandedPropertyRows({
84
113
  parameter,
85
114
  schema: resolvedPropertySchema,
@@ -88,12 +117,15 @@ var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefi
88
117
  namePrefix: name,
89
118
  mode,
90
119
  isDisabled,
91
- hiddenValuePaths
120
+ hiddenValuePaths,
121
+ renamedValuePaths,
122
+ renameTargetPaths
92
123
  });
124
+ const leafValue = getValueAtPath(value, path);
93
125
  return [toTableRow({
94
126
  parameter,
95
- name,
96
- value: getValueAtPath(value, path),
127
+ name: withArrayBracket(name, mode, isArraySchema(resolvedPropertySchema) || Array.isArray(leafValue)),
128
+ value: leafValue,
97
129
  description: resolvedPropertySchema.description ?? parameter.description,
98
130
  schema: resolvedPropertySchema,
99
131
  isRequired: requiredProperties.has(propertyName),
@@ -103,6 +135,45 @@ var getExpandedPropertyRows = ({ parameter, schema, value, pathPrefix, namePrefi
103
135
  });
104
136
  };
105
137
  /**
138
+ * Collects the leaf paths of an object value. In `form` mode only the top-level keys are leaves
139
+ * (form-style explode does not flatten nested objects); in `deepObject` mode we recurse into nested
140
+ * objects, mirroring how the rows and serialization are built.
141
+ */
142
+ var collectValueLeafPaths = (value, mode) => {
143
+ if (!isObject(value)) return [];
144
+ const paths = [];
145
+ const walk = (node, prefix) => {
146
+ for (const [key, val] of Object.entries(node)) {
147
+ const path = [...prefix, key];
148
+ if (mode === "deepObject" && isObject(val)) walk(val, path);
149
+ else paths.push(path);
150
+ }
151
+ };
152
+ walk(value, []);
153
+ return paths;
154
+ };
155
+ /**
156
+ * Builds rows for value paths that the schema does not describe. This keeps user-edited keys (for
157
+ * example a property that was renamed in the table) visible instead of snapping back to the
158
+ * schema-derived rows on the next render.
159
+ */
160
+ var getUnmappedValueRows = ({ parameter, value, schemaRows, mode, isDisabled, renamedValuePaths }) => {
161
+ const seen = new Set([...schemaRows.map((row) => toPathKey(row.sourceParameterValuePath ?? [])), ...renamedValuePaths.keys()]);
162
+ return collectValueLeafPaths(value, mode).filter((path) => !seen.has(toPathKey(path))).map((path) => {
163
+ const leafValue = getValueAtPath(value, path);
164
+ return toTableRow({
165
+ parameter,
166
+ name: withArrayBracket(getExpandedRowName(parameter, path, mode), mode, Array.isArray(leafValue)),
167
+ value: leafValue,
168
+ description: parameter.description,
169
+ schema: void 0,
170
+ isRequired: false,
171
+ isDisabled,
172
+ sourceParameterValuePath: path
173
+ });
174
+ });
175
+ };
176
+ /**
106
177
  * Turns a single OpenAPI parameter into one or more table rows.
107
178
  *
108
179
  * For object-typed query parameters with `form`/`explode: true` (the default) or `deepObject`
@@ -119,7 +190,9 @@ var createParameterRows = (parameter, exampleKey, options = {}) => {
119
190
  const value = example?.value === void 0 ? void 0 : deSerializeParameter(example.value, parameter);
120
191
  if (!schema.properties) return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)];
121
192
  const hiddenValuePaths = new Set(options.hiddenValuePaths?.map(toPathKey) ?? []);
122
- return getExpandedPropertyRows({
193
+ const renamedValuePaths = new Map((options.renamedValuePaths ?? []).map(({ from, to }) => [toPathKey(from), to]));
194
+ const renameTargetPaths = new Set((options.renamedValuePaths ?? []).map(({ to }) => toPathKey(to)));
195
+ const rows = getExpandedPropertyRows({
123
196
  parameter,
124
197
  schema,
125
198
  value,
@@ -127,8 +200,19 @@ var createParameterRows = (parameter, exampleKey, options = {}) => {
127
200
  namePrefix: mode === "deepObject" ? parameter.name : "",
128
201
  mode,
129
202
  isDisabled,
130
- hiddenValuePaths
203
+ hiddenValuePaths,
204
+ renamedValuePaths,
205
+ renameTargetPaths
206
+ });
207
+ const unmappedRows = getUnmappedValueRows({
208
+ parameter,
209
+ value,
210
+ schemaRows: rows,
211
+ mode,
212
+ isDisabled,
213
+ renamedValuePaths
131
214
  });
215
+ return [...rows, ...unmappedRows];
132
216
  };
133
217
  //#endregion
134
218
  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, isParamDisabled } 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 { isArraySchema, 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'\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/**\n * Appends the display-only trailing `[]` to deepObject array leaves so the name matches the\n * serialized `parent[ids][]=1&parent[ids][]=2` form. The bracket is display-only — the row's\n * `sourceParameterValuePath` stays bracket-free. It also lets write-back recognize the leaf as an\n * array even on renamed and unmapped rows, which carry no schema.\n */\nconst withArrayBracket = (name: string, mode: ExpansionMode, isArray: boolean): string =>\n mode === 'deepObject' && isArray ? `${name}[]` : name\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 const effectiveValue = renamedValue === undefined ? getValueAtPath(value, path) : renamedValue\n\n return [\n toTableRow({\n parameter,\n // The renamed key carries no schema, so the value's array-ness drives the `[]` marker.\n name: withArrayBracket(getExpandedRowName(parameter, renamedTo, mode), mode, Array.isArray(effectiveValue)),\n value: effectiveValue,\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 const leafValue = getValueAtPath(value, path)\n\n // deepObject array values serialize with the trailing-bracket convention\n // (filter[ids][]=1&filter[ids][]=2), so mirror that in the displayed name. We base this on the\n // resolved value too, since the schema can be a composition (anyOf) that hides the array type.\n const displayName = withArrayBracket(name, mode, isArraySchema(resolvedPropertySchema) || Array.isArray(leafValue))\n\n return [\n toTableRow({\n parameter,\n name: displayName,\n value: leafValue,\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 const leafValue = getValueAtPath(value, path)\n\n return toTableRow({\n parameter,\n // No schema describes these rows, so the value's array-ness drives the `[]` marker.\n name: withArrayBracket(getExpandedRowName(parameter, path, mode), mode, Array.isArray(leafValue)),\n value: leafValue,\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
  import { objectEntries } from "@scalar/helpers/object/object-entries";
2
- import { isObject } from "@scalar/helpers/object/is-object";
3
2
  import { resolve } from "@scalar/workspace-store/resolve";
3
+ import { isObject } from "@scalar/helpers/object/is-object";
4
4
  import { isObjectSchema } from "@scalar/workspace-store/schemas/v3.1/strict/type-guards";
5
5
  //#region src/v2/blocks/request-block/helpers/get-form-body-rows.ts
6
6
  var stringifyValue = (value) => {
@@ -1,10 +1,10 @@
1
1
  import { getOAuthCallbackData } from "./oauth-callback.js";
2
2
  import { getServerVariables } from "@scalar/workspace-store/request-example";
3
3
  import { makeUrlAbsolute } from "@scalar/helpers/url/make-url-absolute";
4
- import { encode, fromUint8Array } from "js-base64";
5
4
  import { replaceEnvVariables, replacePathVariables } from "@scalar/helpers/regex/replace-variables";
6
5
  import { isRelativePath } from "@scalar/helpers/url/is-relative-path";
7
6
  import { shouldUseProxy } from "@scalar/helpers/url/redirect-to-proxy";
7
+ import { encode, fromUint8Array } from "js-base64";
8
8
  //#region src/v2/blocks/scalar-auth-selector-block/helpers/oauth.ts
9
9
  var authorizationCodeUsesPkcePublicClient = (flowType, flow) => {
10
10
  if (flowType !== "authorizationCode") return false;
@@ -36,8 +36,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
36
36
  onInputBlur?: (() => any) | undefined;
37
37
  }>, {
38
38
  required: boolean;
39
- readOnly: boolean;
40
39
  withFakeData: boolean;
40
+ readOnly: boolean;
41
41
  canAddCustomEnumValue: boolean;
42
42
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
43
43
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -1 +1 @@
1
- {"version":3,"file":"DataTableInput.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/data-table/DataTableInput.vue"],"names":[],"mappings":"AAkLA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAGnH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAM/C,KAAK,WAAW,GAAG;IACf,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,sEAAsE;IACtE,cAAc,CAAC,EAAE,YAAY,GAAG,SAAS,CAAA;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,0EAA0E;IAC1E,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,EAAE,kBAAkB,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,4FAA4F;IAC5F,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAC;AAiVJ,QAAA,IAAI,OAAO,IAAU,EAAuB,QAAQ,IAAW,EAAE,QAAQ,IAAY,CAAE;AACvF,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC5C;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,GAC7C;IAAE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAO7C,QAAA,MAAM,UAAU;;;;;;;;;;;cAtWD,OAAO;cAIP,OAAO;kBAKH,OAAO;2BANE,OAAO;6EAuWjC,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"DataTableInput.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/data-table/DataTableInput.vue"],"names":[],"mappings":"AAkLA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAGnH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAM/C,KAAK,WAAW,GAAG;IACf,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,sEAAsE;IACtE,cAAc,CAAC,EAAE,YAAY,GAAG,SAAS,CAAA;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,0EAA0E;IAC1E,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,EAAE,kBAAkB,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,4FAA4F;IAC5F,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAC;AAiVJ,QAAA,IAAI,OAAO,IAAU,EAAuB,QAAQ,IAAW,EAAE,QAAQ,IAAY,CAAE;AACvF,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC5C;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,GAC7C;IAAE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAO7C,QAAA,MAAM,UAAU;;;;;;;;;;;cAtWD,OAAO;kBASH,OAAO;cALX,OAAO;2BADM,OAAO;6EAuWjC,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -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.12.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"}
@@ -4,8 +4,8 @@ import Modal_default from "../Modal.vue.js";
4
4
  import { computed, createApp, isRef, reactive, ref, toValue, watch } from "vue";
5
5
  import { useModal } from "@scalar/components/modal";
6
6
  import { subscribePluginEvents } from "@scalar/oas-utils/helpers";
7
- import { createWorkspaceEventBus } from "@scalar/workspace-store/events";
8
7
  import { isOpenApiDocument } from "@scalar/workspace-store/schemas/type-guards";
8
+ import { createWorkspaceEventBus } from "@scalar/workspace-store/events";
9
9
  //#region src/v2/features/modal/helpers/create-api-client-modal.ts
10
10
  /**
11
11
  * Monotonic counter used to give every modal Vue app a unique `idPrefix`.
@@ -1,5 +1,5 @@
1
- import { APP_VERSION } from "../../constants.js";
2
1
  import OperationBlock_default from "../../blocks/operation-block/OperationBlock.vue.js";
2
+ import { APP_VERSION } from "../../constants.js";
3
3
  import { mapHiddenClientsConfig } from "../modal/helpers/map-hidden-clients-config.js";
4
4
  import { computed, createBlock, createElementBlock, createElementVNode, defineComponent, openBlock, toValue, unref } from "vue";
5
5
  import { getActiveProxyUrl, getRequestExampleContext } from "@scalar/workspace-store/request-example";
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-events.d.ts","sourceRoot":"","sources":["../../src/v2/workspace-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAkB,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAE3G,OAAO,EAAE,KAAK,GAAG,EAAY,MAAM,KAAK,CAAA;AAExC,KAAK,IAAI,CAAC,CAAC,SAAS,MAAM,kBAAkB,IAAI,OAAO,CAAC;IACtD,eAAe,EAAE,CACf,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAC3B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAA;IAClF,cAAc,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACzE,CAAC,CAAA;AAEF,KAAK,KAAK,GAAG;KACV,GAAG,IAAI,MAAM,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC;CAC9C,CAAA;AA6BD;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAAC,EAC/C,QAAQ,EACR,KAAK,EACL,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,KAAK,EAAE,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;IACjC,KAAK,EAAE,KAAK,CAAA;CACb,QA+TA"}
1
+ {"version":3,"file":"workspace-events.d.ts","sourceRoot":"","sources":["../../src/v2/workspace-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAkB,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAE3G,OAAO,EAAE,KAAK,GAAG,EAAY,MAAM,KAAK,CAAA;AAExC,KAAK,IAAI,CAAC,CAAC,SAAS,MAAM,kBAAkB,IAAI,OAAO,CAAC;IACtD,eAAe,EAAE,CACf,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAC3B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAA;IAClF,cAAc,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACzE,CAAC,CAAA;AAEF,KAAK,KAAK,GAAG;KACV,GAAG,IAAI,MAAM,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC;CAC9C,CAAA;AA6BD;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAAC,EAC/C,QAAQ,EACR,KAAK,EACL,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,KAAK,EAAE,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;IACjC,KAAK,EAAE,KAAK,CAAA;CACb,QAsUA"}
@@ -43,6 +43,7 @@ function initializeWorkspaceEventHandlers({ eventBus, store, hooks }) {
43
43
  eventBus.on("workspace:update:color-mode", (payload) => withHook("workspace:update:color-mode", mutators.value.workspace().workspace.updateColorMode, hooks)(payload));
44
44
  eventBus.on("workspace:update:theme", (payload) => withHook("workspace:update:theme", mutators.value.workspace().workspace.updateTheme, hooks)(payload));
45
45
  eventBus.on("workspace:update:selected-client", (payload) => withHook("workspace:update:selected-client", mutators.value.workspace().workspace.updateSelectedClient, hooks)(payload));
46
+ eventBus.on("workspace:update:selected-example", (payload) => withHook("workspace:update:selected-example", mutators.value.workspace().workspace.updateSelectedExample, hooks)(payload));
46
47
  eventBus.on("workspace:update:active-environment", (payload) => withHook("workspace:update:active-environment", mutators.value.workspace().workspace.updateActiveEnvironment, hooks)(payload));
47
48
  eventBus.on("document:update:extension", (payload) => withHook("document:update:extension", mutators.value.active().document.updateDocumentExtension, hooks)(payload));
48
49
  eventBus.on("document:update:icon", (payload) => withHook("document:update:icon", mutators.value.active().document.updateDocumentIcon, hooks)(payload));