summaryrefslogtreecommitdiffhomepage
path: root/packages/sdk/js/src/gen/core/params.ts
diff options
context:
space:
mode:
authorDax <[email protected]>2025-07-31 01:00:29 -0400
committerGitHub <[email protected]>2025-07-31 01:00:29 -0400
commit33cef075d228e80aefb44671ec68e1989c2855a8 (patch)
treed43a5c1bcc40d4d938eacccfd923c80301706cf1 /packages/sdk/js/src/gen/core/params.ts
parentb09ebf464552f3899120b22c7a8572669000a554 (diff)
downloadopencode-33cef075d228e80aefb44671ec68e1989c2855a8.tar.gz
opencode-33cef075d228e80aefb44671ec68e1989c2855a8.zip
ci: new publish method (#1451)
Diffstat (limited to 'packages/sdk/js/src/gen/core/params.ts')
-rw-r--r--packages/sdk/js/src/gen/core/params.ts151
1 files changed, 151 insertions, 0 deletions
diff --git a/packages/sdk/js/src/gen/core/params.ts b/packages/sdk/js/src/gen/core/params.ts
new file mode 100644
index 000000000..ba35263d8
--- /dev/null
+++ b/packages/sdk/js/src/gen/core/params.ts
@@ -0,0 +1,151 @@
+type Slot = 'body' | 'headers' | 'path' | 'query';
+
+export type Field =
+ | {
+ in: Exclude<Slot, 'body'>;
+ /**
+ * Field name. This is the name we want the user to see and use.
+ */
+ key: string;
+ /**
+ * Field mapped name. This is the name we want to use in the request.
+ * If omitted, we use the same value as `key`.
+ */
+ map?: string;
+ }
+ | {
+ in: Extract<Slot, 'body'>;
+ /**
+ * Key isn't required for bodies.
+ */
+ key?: string;
+ map?: string;
+ };
+
+export interface Fields {
+ allowExtra?: Partial<Record<Slot, boolean>>;
+ args?: ReadonlyArray<Field>;
+}
+
+export type FieldsConfig = ReadonlyArray<Field | Fields>;
+
+const extraPrefixesMap: Record<string, Slot> = {
+ $body_: 'body',
+ $headers_: 'headers',
+ $path_: 'path',
+ $query_: 'query',
+};
+const extraPrefixes = Object.entries(extraPrefixesMap);
+
+type KeyMap = Map<
+ string,
+ {
+ in: Slot;
+ map?: string;
+ }
+>;
+
+const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
+ if (!map) {
+ map = new Map();
+ }
+
+ for (const config of fields) {
+ if ('in' in config) {
+ if (config.key) {
+ map.set(config.key, {
+ in: config.in,
+ map: config.map,
+ });
+ }
+ } else if (config.args) {
+ buildKeyMap(config.args, map);
+ }
+ }
+
+ return map;
+};
+
+interface Params {
+ body: unknown;
+ headers: Record<string, unknown>;
+ path: Record<string, unknown>;
+ query: Record<string, unknown>;
+}
+
+const stripEmptySlots = (params: Params) => {
+ for (const [slot, value] of Object.entries(params)) {
+ if (value && typeof value === 'object' && !Object.keys(value).length) {
+ delete params[slot as Slot];
+ }
+ }
+};
+
+export const buildClientParams = (
+ args: ReadonlyArray<unknown>,
+ fields: FieldsConfig,
+) => {
+ const params: Params = {
+ body: {},
+ headers: {},
+ path: {},
+ query: {},
+ };
+
+ const map = buildKeyMap(fields);
+
+ let config: FieldsConfig[number] | undefined;
+
+ for (const [index, arg] of args.entries()) {
+ if (fields[index]) {
+ config = fields[index];
+ }
+
+ if (!config) {
+ continue;
+ }
+
+ if ('in' in config) {
+ if (config.key) {
+ const field = map.get(config.key)!;
+ const name = field.map || config.key;
+ (params[field.in] as Record<string, unknown>)[name] = arg;
+ } else {
+ params.body = arg;
+ }
+ } else {
+ for (const [key, value] of Object.entries(arg ?? {})) {
+ const field = map.get(key);
+
+ if (field) {
+ const name = field.map || key;
+ (params[field.in] as Record<string, unknown>)[name] = value;
+ } else {
+ const extra = extraPrefixes.find(([prefix]) =>
+ key.startsWith(prefix),
+ );
+
+ if (extra) {
+ const [prefix, slot] = extra;
+ (params[slot] as Record<string, unknown>)[
+ key.slice(prefix.length)
+ ] = value;
+ } else {
+ for (const [slot, allowed] of Object.entries(
+ config.allowExtra ?? {},
+ )) {
+ if (allowed) {
+ (params[slot as Slot] as Record<string, unknown>)[key] = value;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ stripEmptySlots(params);
+
+ return params;
+};