refactor(api): restructure types and exports with barrel files

- Split forge_proxy.types.ts into contract.types.ts and io.types.ts
- Add barrel exports for core/, providers/, utils/, typescript/
- Restrict untyped and core helpers to root proxy only
- Add key, schema, endpoint to intermediate proxy types
- Disable rollupTypes for barrel compatibility
This commit is contained in:
melvinchia3636
2026-06-21 12:45:02 +08:00
parent 43e618a383
commit 22569bbc32
13 changed files with 2591 additions and 2364 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -68,7 +68,7 @@ function createForgeProxyInternal<T>(
return () => `[ForgeProxy: ${pathArray.join('/')}]`
}
if (prop === 'untyped') {
if (pathArray.length === 0 && prop === 'untyped') {
return <TOutput = any, TBody = any, TQuery = any>(url: string) =>
new ForgeEndpoint<UntypedEndpointType<TOutput, TBody, TQuery>>(
getResolvedHost(),
@@ -82,7 +82,7 @@ function createForgeProxyInternal<T>(
return createGetMediaHelper(getResolvedHost())
}
if (prop in CORE_HELPERS) {
if (pathArray.length === 0 && prop in CORE_HELPERS) {
return createCoreHelper(
getResolvedHost(),
prop as keyof typeof CORE_HELPERS

View File

@@ -2,10 +2,7 @@
import type { UseMutationOptions, UseQueryOptions } from '@tanstack/react-query'
import { z } from 'zod'
import type {
InferRawInput,
InferRawOutput
} from '../typescript/forge_proxy.types'
import type { InferRawInput, InferRawOutput } from '../typescript'
import {
createEncryptionSession,
decryptResponse,

View File

@@ -0,0 +1,3 @@
export * from './createForgeProxy'
export * from './forgeEndpoint'
export * from './registry'

View File

@@ -1,23 +1,7 @@
export * from './core/createForgeProxy'
export * from './core'
export * from './core/forgeEndpoint'
export * from './providers'
export * from './core/registry'
export * from './utils'
export * from './typescript/forge_proxy.types'
export * from './providers/APIEndpointProvider'
export * from './providers/APIOnlineStatusProvider'
export * from './providers/EncryptionProvider'
export * from './providers/SocketProvider'
export * from './providers/AuthProvider'
export * from './utils/encryption'
export * from './utils/fetchAPI'
export * from './utils/usePromiseLoading'
export * from './typescript'

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
type RefObject,
createContext,
@@ -11,7 +12,7 @@ import {
import { contract } from '../../contract'
import { createForgeProxy } from '../core/createForgeProxy'
import type { InferOutput, ProxyTree } from '../typescript/forge_proxy.types'
import type { InferOutput, ProxyTree } from '../typescript'
const _forgeAPI = createForgeProxy(contract)

View File

@@ -0,0 +1,5 @@
export * from './APIEndpointProvider'
export * from './APIOnlineStatusProvider'
export * from './AuthProvider'
export * from './EncryptionProvider'
export * from './SocketProvider'

View File

@@ -0,0 +1,86 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { FromSchema } from "json-schema-to-ts";
import type { ZodTypeAny } from "zod";
type KnownKeys<T> = {
[K in keyof T]: string extends K
? never
: number extends K
? never
: symbol extends K
? never
: K
}[keyof T]
export type OmitIndexSignature<T> = T extends object
? T extends Array<any>
? T
: [KnownKeys<T>] extends [never]
? { [K in keyof T]: OmitIndexSignature<T[K]> }
: {
[K in keyof T as string extends K
? never
: number extends K
? never
: symbol extends K
? never
: K]: OmitIndexSignature<T[K]>
}
: T
export type InferFromJSONSchema<T> = 0 extends 1 & T
? any
: T extends undefined
? undefined
: T extends boolean
? undefined
: T extends object
? OmitIndexSignature<FromSchema<T>>
: undefined
export type InferContractInput<T> = 0 extends 1 & T
? any
: T extends {
readonly input?: {
readonly query?: infer Q
readonly body?: infer B
}
}
? {
body: B extends ZodTypeAny
? B
: B extends object
? InferFromJSONSchema<B>
: undefined
query: Q extends ZodTypeAny
? Q
: Q extends object
? InferFromJSONSchema<Q>
: undefined
}
: {
body: undefined
query: undefined
}
export type InferContractOutput<T> = 0 extends 1 & T
? any
: T extends {
readonly output: infer O
}
? O extends { readonly OK: infer OKSchema }
? InferFromJSONSchema<OKSchema>
: O extends { readonly CREATED: infer CreatedSchema }
? InferFromJSONSchema<CreatedSchema>
: any
: never
export type InferContractMedia<T> = 0 extends 1 & T
? any
: T extends {
readonly media?: infer M
}
? M extends undefined
? null
: M
: null

View File

@@ -1,226 +1,64 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { FromSchema } from 'json-schema-to-ts'
import type z from 'zod'
import type { ZodIntersection, ZodObject, ZodRawShape, ZodTypeAny } from 'zod'
import type { ForgeEndpoint } from '../core/forgeEndpoint'
import type { CoreHelperReturnTypes } from '../core/helpers/config'
type ZodObjectOrIntersection =
| ZodObject<ZodRawShape>
| ZodIntersection<ZodTypeAny, ZodTypeAny>
type KnownKeys<T> = {
[K in keyof T]: string extends K
? never
: number extends K
? never
: symbol extends K
? never
: K
}[keyof T]
export type OmitIndexSignature<T> = T extends object
? T extends Array<any>
? T
: [KnownKeys<T>] extends [never]
? { [K in keyof T]: OmitIndexSignature<T[K]> }
: {
[K in keyof T as string extends K
? never
: number extends K
? never
: symbol extends K
? never
: K]: OmitIndexSignature<T[K]>
}
: T
export type InferFromJSONSchema<T> = 0 extends 1 & T
? any
: T extends undefined
? undefined
: T extends boolean
? undefined
: T extends object
? OmitIndexSignature<FromSchema<T>>
: undefined
export type InferContractInput<T> = 0 extends 1 & T
? any
: T extends {
readonly input?: {
readonly query?: infer Q
readonly body?: infer B
}
}
? {
body: B extends ZodTypeAny
? B
: B extends object
? InferFromJSONSchema<B>
: undefined
query: Q extends ZodTypeAny
? Q
: Q extends object
? InferFromJSONSchema<Q>
: undefined
}
: {
body: undefined
query: undefined
}
export type InferContractOutput<T> = 0 extends 1 & T
? any
: T extends {
readonly output: infer O
}
? O extends { readonly OK: infer OKSchema }
? InferFromJSONSchema<OKSchema>
: O extends { readonly CREATED: infer CreatedSchema }
? InferFromJSONSchema<CreatedSchema>
: any
: never
export type InferContractMedia<T> = 0 extends 1 & T
? any
: T extends {
readonly media?: infer M
}
? M extends undefined
? null
: M
: null
/**
* Infers the input TypeScript type from a Forge endpoint config object.
* Uses embedded Zod schema definitions to produce a plain object type.
*/
export type InferRawInput<T> = T extends {
__isForgeContract: true
__input: infer I
__media: infer M
}
? I extends {
body?: infer B
query?: infer Q
}
? {
body: M extends null
? B extends ZodObjectOrIntersection
? z.input<B>
: B
: (B extends ZodObjectOrIntersection
? z.input<B>
: B extends undefined
? {}
: B) & {
[K in keyof M]: M[K] extends { multiple: true }
? M[K] extends { optional: true }
? File[] | undefined
: File[]
: M[K] extends { optional: true }
? File | string | undefined
: File | string
}
query: Q extends ZodObjectOrIntersection ? z.input<Q> : Q
}
: never
: never
/**
* Infers the output (response) TypeScript type from a Forge endpoint config object.
*/
export type InferRawOutput<T> = T extends {
__isForgeContract: true
__output: infer O
}
? O
: never
/**
* Extracts the input schema type from a `ForgeEndpoint` instance.
*/
export type InferInput<T extends ForgeEndpoint<any>> = T['__type'] extends {
__isForgeContract: true
__input: infer I
__media: infer M
}
? I extends {
body?: infer B
query?: infer Q
}
? {
body: M extends null
? B extends ZodObjectOrIntersection
? z.input<B>
: B
: (B extends ZodObjectOrIntersection
? z.input<B>
: B extends undefined
? {}
: B) & {
[K in keyof M]: {
__type: 'media'
config: M[K]
}
}
query: Q extends ZodObjectOrIntersection ? z.input<Q> : Q
}
: never
: never
/**
* Extracts the output (response) type from a `ForgeEndpoint` instance.
*/
export type InferOutput<T extends ForgeEndpoint<any>> = T['__type'] extends {
__isForgeContract: true
__output: infer O
}
? O
: never
import type {
InferContractInput,
InferContractMedia,
InferContractOutput
} from './contract.types'
/**
* Constructs a deeply-nested proxy tree from a server route schema.
* Each endpoint becomes a `ForgeEndpoint`, nested groups become more `ProxyTree`.
*/
export type ProxyTree<T> = 0 extends 1 & T
? {
[K: string]: any
} & {
untyped: <TOutput = any, TBody = any, TQuery = any>(
url: string
) => ForgeEndpoint<UntypedEndpointType<TOutput, TBody, TQuery>>
getMedia: (params: {
collectionId: string
recordId: string
fieldId: string
thumb?: string
token?: string
}) => string
} & CoreHelperReturnTypes
: {
[K in keyof T]: T[K] extends { readonly method: string }
? ForgeEndpoint<{
__isForgeContract: true
__input: InferContractInput<T[K]>
__output: InferContractOutput<T[K]>
__media: InferContractMedia<T[K]>
}>
: ProxyTree<T[K]>
} & {
untyped: <TOutput = any, TBody = any, TQuery = any>(
url: string
) => ForgeEndpoint<UntypedEndpointType<TOutput, TBody, TQuery>>
getMedia: (params: {
collectionId: string
recordId: string
fieldId: string
thumb?: string
token?: string
}) => string
} & CoreHelperReturnTypes
type ProxyTreeLeaf = {
getMedia: (params: {
collectionId: string
recordId: string
fieldId: string
thumb?: string
token?: string
}) => string
key: (string | Record<string, any> | null)[]
schema: { query?: z.ZodTypeAny; body?: z.ZodTypeAny }
endpoint: string
}
type ProxyTreeRootLeaf = ProxyTreeLeaf & {
untyped: <TOutput = any, TBody = any, TQuery = any>(
url: string
) => ForgeEndpoint<UntypedEndpointType<TOutput, TBody, TQuery>>
}
type ProxyTreeInternal<T> = {
[K in keyof T]: T[K] extends { readonly method: string }
? ForgeEndpoint<{
__isForgeContract: true
__input: InferContractInput<T[K]>
__output: InferContractOutput<T[K]>
__media: InferContractMedia<T[K]>
}>
: ProxyTreeInternal<T[K]>
} & ProxyTreeLeaf
/** ProxyTree falls back to `AnyProxyTree` without strict typing when the contract is untyped (`any`). */
type IsAny<T> = 0 extends 1 & T ? true : false
type AnyProxyTree = {
[K: string]: any
} & ProxyTreeRootLeaf &
CoreHelperReturnTypes
type TypedProxyTree<T> = ProxyTreeInternal<T> &
ProxyTreeRootLeaf &
CoreHelperReturnTypes
export type ProxyTree<T> =
IsAny<T> extends true ? AnyProxyTree : TypedProxyTree<T>
/**
* Helper type for creating untyped endpoints.

View File

@@ -0,0 +1,5 @@
export * from './io.types'
export * from './contract.types'
export * from './forge_proxy.types'

View File

@@ -0,0 +1,103 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-empty-object-type */
import type {
ZodIntersection,
ZodObject,
ZodRawShape,
ZodTypeAny,
z
} from 'zod'
import type { ForgeEndpoint } from '../core/forgeEndpoint'
type ZodObjectOrIntersection =
| ZodObject<ZodRawShape>
| ZodIntersection<ZodTypeAny, ZodTypeAny>
/**
* Infers the input TypeScript type from a Forge endpoint config object.
* Uses embedded Zod schema definitions to produce a plain object type.
*/
export type InferRawInput<T> = T extends {
__isForgeContract: true
__input: infer I
__media: infer M
}
? I extends {
body?: infer B
query?: infer Q
}
? {
body: M extends null
? B extends ZodObjectOrIntersection
? z.input<B>
: B
: (B extends ZodObjectOrIntersection
? z.input<B>
: B extends undefined
? {}
: B) & {
[K in keyof M]: M[K] extends { multiple: true }
? M[K] extends { optional: true }
? File[] | undefined
: File[]
: M[K] extends { optional: true }
? File | string | undefined
: File | string
}
query: Q extends ZodObjectOrIntersection ? z.input<Q> : Q
}
: never
: never
/**
* Infers the output (response) TypeScript type from a Forge endpoint config object.
*/
export type InferRawOutput<T> = T extends {
__isForgeContract: true
__output: infer O
}
? O
: never
/**
* Extracts the input schema type from a `ForgeEndpoint` instance.
*/
export type InferInput<T extends ForgeEndpoint<any>> = T['__type'] extends {
__isForgeContract: true
__input: infer I
__media: infer M
}
? I extends {
body?: infer B
query?: infer Q
}
? {
body: M extends null
? B extends ZodObjectOrIntersection
? z.input<B>
: B
: (B extends ZodObjectOrIntersection
? z.input<B>
: B extends undefined
? {}
: B) & {
[K in keyof M]: {
__type: 'media'
config: M[K]
}
}
query: Q extends ZodObjectOrIntersection ? z.input<Q> : Q
}
: never
: never
/**
* Extracts the output (response) type from a `ForgeEndpoint` instance.
*/
export type InferOutput<T extends ForgeEndpoint<any>> = T['__type'] extends {
__isForgeContract: true
__output: infer O
}
? O
: never

View File

@@ -0,0 +1,3 @@
export * from './encryption'
export * from './fetchAPI'
export * from './usePromiseLoading'

View File

@@ -7,7 +7,9 @@ export default defineConfig({
plugins: [
react(),
dts({
rollupTypes: true
rollupTypes: false,
entryRoot: resolve(__dirname, 'src'),
outDir: resolve(__dirname, 'dist')
})
],
resolve: {