@guanriyue/decurl/codec

@guanriyue/decurl/codec 用于定义 URL search params 的字段规则。它关注的是:URL key 如何映射到业务值,业务值又如何被序列化回 URLSearchParams。

Decode 可以是普通函数,也可以使用 @guanriyue/decurl/decode 提供的 primitives。

import { createURLSearchParamsCodec, defineFields, field } from '@guanriyue/decurl/codec';

field

field(definition) 用于固化单个 FieldCodec 的类型。最简 codec 可以只是普通对象;但推荐使用 field,让 TypeScript 更稳定地保留 modedefaultValuedecodeencode 等信息。

import { field } from '@guanriyue/decurl/codec';

const keyword = field({
  decode: (value: string) => {
    const nextValue = value.trim();
    return nextValue.length > 0 ? nextValue : undefined;
  },
});

常用属性:

属性必填类型说明
decode(value: string | string[]) => TValue | null | undefined从 URL 原始值解析业务值;实际输入由 mode 决定。
mode'single' | 'multi'默认是 singlemulti 使用 URLSearchParams.getAll(name) 读取同名的多个值。
namestring | readonly string[]URL key。数组第一个值是 canonical key,后续值是 legacy alias。
encode(value: NonNullable<TValue>) => string | string[] | null | undefined自定义业务值如何写回 URL;返回类型由 mode 决定。
defaultValueNonNullable<TValue>key 缺失、decode 失败、decode 返回空值时采用的默认值。
eq(left: NonNullable<TValue>, right: NonNullable<TValue>) => boolean判断前后值是否相等。

更多设计说明见 FieldCodec 定义

defineFields

defineFields(fields) 用于定义一组 Search Fields,并为没有显式 name 的字段使用对象 key 作为 URL key。

import { defineFields, field } from '@guanriyue/decurl/codec';

const searchFields = defineFields({
  keyword: field({
    name: ['keyword', 'q'],
    decode: (value: string) => value.trim() || undefined,
  }),
  view: field({
    decode: (value: string) => {
      return value === 'list' || value === 'grid' ? value : undefined;
    },
    defaultValue: 'list',
  }),
});

如果字段上写了多个 name,第一个是 canonical key,后续是 legacy alias。更多说明见 Search Fields

createURLSearchParamsCodec

createURLSearchParamsCodec(fields) 创建 { decode, encode }

方法说明
decode(searchParams)URLSearchParams 解析成业务对象。
encode(values, options?)把业务对象序列化为新的 URLSearchParams
import { createURLSearchParamsCodec, defineFields, field } from '@guanriyue/decurl/codec';

const fields = defineFields({
  page: field({
    name: ['page', 'p'],
    decode: (value: string) => {
      const page = Number(value);
      return Number.isInteger(page) && page >= 1 ? page : undefined;
    },
    defaultValue: 1,
  }),
});

const codec = createURLSearchParamsCodec(fields);

const values = codec.decode(new URLSearchParams('?p=2'));
const nextSearch = codec.encode({ page: 3 }, { base: '?p=2&keyword=router' });

encode(values, options?) 的常用选项:

选项类型说明
baseURLSearchParams | string基于已有 search params 做 patch,未触碰字段会保留。
preserveDefaultboolean写入 default value 时是否保留 canonical key。默认删除对应 key。

Types

类型说明
FieldCodec<TValue>单个 field 的 codec union。
NamedFieldCodec<TValue>已经拥有确定 name 的 field codec。
RecordCodecSearch Fields 的基础 record 类型。
InferFieldValue<TCodec>从单个 field codec 推导 value 类型。
InferFieldValues<TFields>从 Search Fields 推导 values object 类型。