Skip to content

Commit

Permalink
Better buildNormalizedParams()
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanoverna committed Mar 19, 2024
1 parent d694fed commit c9d8043
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 32 deletions.
24 changes: 12 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"rome": "^11.0.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.7.0",
"typescript": "^4.6.3",
"typescript": "^5.4.2",
"dotenv": "^16.4.1"
},
"homepage": "https://github.com/datocms/js-rest-api-clients",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { buildNormalizedParams } from '../buildNormalizedParams';

describe('URLQueryParams', () => {
describe('buildNormalizedParams', () => {
it('encodes complex params', async () => {
expect(buildNormalizedParams({ foo: 0 })).toMatchInlineSnapshot(`
[
Expand Down
61 changes: 43 additions & 18 deletions packages/rest-client-utils/src/buildNormalizedParams.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,58 @@
const ARRAY_INDEX = '__ARRAY_INDEX__';

function buildKey(path: string[]) {
return path.reduce(
(result, chunk, index) => (index === 0 ? chunk : `${result}[${chunk}]`),
(result, chunk, index) =>
index === 0
? chunk
: chunk === ARRAY_INDEX
? `${result}[]`
: `${result}[${chunk}]`,
'',
);
}

function serializeValue(value: unknown) {
if (typeof value === 'number' || typeof value === 'string') {
return value.toString();
}

if (value === true) {
return 'true';
}

if (value === false) {
return 'false';
}

throw `Don't know how to serialize param value ${JSON.stringify(value)}`;
}

export function buildNormalizedParams(
input: Record<string, unknown>,
value: unknown,
path: string[] = [],
): [string, string][] {
const result: [string, string][] = [];

for (const [key, value] of Object.entries(input)) {
if (typeof value === 'number' || typeof value === 'string') {
result.push([buildKey([...path, key]), value.toString()]);
} else if (value === true) {
result.push([buildKey([...path, key]), 'true']);
} else if (value === false) {
result.push([buildKey([...path, key]), 'false']);
} else if (typeof value === 'object') {
if (Array.isArray(value)) {
for (const innerValue of value) {
result.push([`${buildKey([...path, key])}[]`, innerValue.toString()]);
if (
typeof value === 'number' ||
typeof value === 'string' ||
typeof value === 'boolean'
) {
result.push([buildKey(path), serializeValue(value)]);
} else if (typeof value === 'object') {
if (Array.isArray(value)) {
for (const innerValue of value as unknown[]) {
for (const param of buildNormalizedParams(innerValue, [
...path,
ARRAY_INDEX,
])) {
result.push(param);
}
} else if (value) {
for (const param of buildNormalizedParams(
value as Record<string, unknown>,
[...path, key],
)) {
}
} else if (value) {
for (const [key, innerValue] of Object.entries(value)) {
for (const param of buildNormalizedParams(innerValue, [...path, key])) {
result.push(param);
}
}
Expand Down

0 comments on commit c9d8043

Please sign in to comment.