fix(client): add $serialized for response object

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2023-06-10 16:33:12 +08:00
parent 944c571210
commit 3a9e25763e
7 changed files with 62 additions and 30 deletions

View File

@@ -1,6 +1,8 @@
import type { HTTPClient } from '~/core'
import type { IRequestAdapter } from '~/interfaces/adapter'
import { allControllers } from '~/controllers'
import { HTTPClient, RequestError, createClient } from '~/core'
import { IRequestAdapter } from '~/interfaces/adapter'
import { createClient, RequestError } from '~/core'
import { createMockServer } from './e2e-mock-server'
@@ -95,6 +97,12 @@ export const testAdaptor = (adaptor: IRequestAdapter) => {
expect(res).toStrictEqual({ data: 1, fooBar: 'foo' })
expect(res.$raw.data).toStrictEqual({ data: 1, foo_bar: 'foo' })
expect(res.$request).toBeDefined()
expect(res.$serialized).toBeDefined()
expect(res.$serialized.data).toStrictEqual(res.data)
expect(res.$serialized.data).toStrictEqual(res.data)
expect(res.$serialized.fooBar).toStrictEqual(res.fooBar)
// @ts-expect-error
expect(res.$serialized.$request).toBeUndefined()
})
it('should get string payload', async () => {

View File

@@ -1,12 +1,13 @@
import {
import type {
IAdaptorRequestResponseType,
IRequestAdapter,
} from '~/interfaces/adapter'
import { ClientOptions } from '~/interfaces/client'
import { IController } from '~/interfaces/controller'
import { RequestOptions } from '~/interfaces/instance'
import { IRequestHandler, Method } from '~/interfaces/request'
import { Class } from '~/interfaces/types'
import type { ClientOptions } from '~/interfaces/client'
import type { IController } from '~/interfaces/controller'
import type { RequestOptions } from '~/interfaces/instance'
import type { IRequestHandler, Method } from '~/interfaces/request'
import type { Class } from '~/interfaces/types'
import { isPlainObject } from '~/utils'
import { camelcaseKeys } from '~/utils/camelcase-keys'
import { resolveFullPath } from '~/utils/path'
@@ -180,14 +181,17 @@ class HTTPClient<
return null
}
const transform =
const cameledObject =
(Array.isArray(data) || isPlainObject(data)) &&
that.options.transformResponse
? that.options.transformResponse(data)
: data
if (transform && typeof transform === 'object') {
Object.defineProperty(transform, '$raw', {
let nextObject: any = cameledObject
if (cameledObject && typeof cameledObject === 'object') {
nextObject = { ...cameledObject }
Object.defineProperty(nextObject, '$raw', {
get() {
return res
},
@@ -196,8 +200,7 @@ class HTTPClient<
})
// attach request config onto response
Object.defineProperty(transform, '$request', {
Object.defineProperty(nextObject, '$request', {
get() {
return {
url,
@@ -207,9 +210,15 @@ class HTTPClient<
},
enumerable: false,
})
Object.defineProperty(nextObject, '$serialized', {
get() {
return cameledObject
},
})
}
return transform
return nextObject
}
}
route.push(name)

View File

@@ -1,4 +1,4 @@
import { RequestOptions } from './instance'
import type { RequestOptions } from './instance'
type NoStringIndex<T> = { [K in keyof T as string extends K ? never : K]: T[K] }
@@ -70,6 +70,8 @@ type ResponseWrapperType<Response, RawData, T> = {
method: string
[k: string]: string
}
$serialized: T
}
export type ResponseProxyExtraRaw<

View File

@@ -57,6 +57,7 @@
"tsup": "6.7.0",
"umi-request": "1.4.0",
"vitest": "^0.31.4",
"vite": "^4.3.9"
"vite": "^4.3.9",
"form-data": "4.0.0"
}
}

View File

@@ -1,4 +1,4 @@
import { SortOrder } from '~/interfaces/options'
import type { SortOrder } from '~/interfaces/options'
export const isPlainObject = (obj: any) =>
isObject(obj) &&
@@ -40,14 +40,13 @@ export const attachRawFromOneToAnthor = (from: any, to: any) => {
if (!from || !isObject(to)) {
return
}
from.$raw &&
Object.defineProperty(to, '$raw', {
value: { ...from.$raw },
enumerable: false,
})
from.$request &&
Object.defineProperty(to, '$request', {
value: { ...from.$request },
enumerable: false,
})
;['$raw', '$request', '$serialized'].forEach((key) => {
from[key] &&
Object.defineProperty(to, key, {
get() {
return from[key]
},
enumerable: false,
})
})
}

7
pnpm-lock.yaml generated
View File

@@ -424,6 +424,9 @@ importers:
express:
specifier: 4.18.2
version: 4.18.2
form-data:
specifier: 4.0.0
version: 4.0.0
ky:
specifier: 0.33.3
version: 0.33.3
@@ -6709,7 +6712,7 @@ packages:
/lower-case@2.0.2:
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
dependencies:
tslib: 2.5.2
tslib: 2.5.3
dev: false
/lru-cache@5.1.1:
@@ -7187,7 +7190,7 @@ packages:
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
dependencies:
lower-case: 2.0.2
tslib: 2.5.2
tslib: 2.5.3
dev: false
/node-abort-controller@3.1.1:

View File

@@ -2,13 +2,23 @@
import { execSync } from 'child_process'
import fs from 'fs'
import path from 'path'
import { chalk } from 'zx-cjs'
async function main() {
const cwd = process.cwd()
const isRootDir = fs.existsSync(path.resolve(cwd, 'pnpm-workspace.yaml'))
if (!isRootDir) {
console.warn(chalk.yellow('not a root dir, skip init assets'))
return
}
const existAsset = fs.existsSync(path.resolve(cwd, 'assets'))
if (!existAsset) {
const cmd = `npx degit https://github.com/mx-space/assets.git assets`
const cmd = `npx degit https://github.com/mx-space/assets.git ${path.resolve(
cwd,
'assets',
)}`
console.log(cmd)
try {
execSync(cmd)