export * from 'fast-check' import * as fc from 'fast-check' import type { Force } from '@traversable/registry' import { symbol as Symbol } from '@traversable/registry' import type { Guard } from '@traversable/schema' export interface Arbitrary extends fc.Arbitrary { readonly [Symbol.optional]?: true } export type { typeOf as typeof } type typeOf = S extends fc.Arbitrary ? T : never /** @internal */ const Object_keys = globalThis.Object.keys /** @internal */ const Array_isArray = globalThis.Array.isArray /** @internal */ const isString: Guard = (u): u is never => typeof u === 'string' /** @internal */ const arrayOf : (p: Guard) => Guard = (p) => (u): u is never => Array_isArray(u) && u.every(p) /** @internal */ const has : (k: K, p: Guard) => Guard<{ [P in K]: T }> = (k, p) => (u: unknown): u is never => !!u && typeof u === 'object' && Object.hasOwn(u, k) && p(u[k as never]) const PATTERN = { identifier: /^[$_a-zA-Z][$_a-zA-Z0-9]*$/, } as const export type UniqueArrayDefaults = fc.UniqueArrayConstraintsRecommended export function identifier(constraints?: fc.StringMatchingConstraints): fc.Arbitrary export function identifier(constraints?: fc.StringMatchingConstraints) { return fc.stringMatching(PATTERN.identifier, constraints) //.filter((ident) => !(ident in KEYWORD)) } export const entries : (model: fc.Arbitrary, constraints?: UniqueArrayDefaults) => fc.Arbitrary<[k: string, v: T][]> = (model, constraints) => fc.uniqueArray( fc.tuple(identifier(), model), { ...constraints, selector: ([k]) => k }, ) /** * ### {@link optional `fc.optional`} */ export function optional(model: fc.Arbitrary): Arbitrary export function optional(model: fc.Arbitrary): fc.Arbitrary { (model as any)[Symbol.optional] = true; return model } // /** @internal */ // type Keyword = keyof typeof Keyword // const Keyword = { // break: "break", case: "case", catch: "catch", class: "class", const: "const", // continue: "continue", debugger: "debugger", default: "default", delete: "delete", // do: "do", else: "else", export: "export", extends: "extends", false: "false", // finally: "finally", for: "for", function: "function", if: "if", import: "import", // in: "in", instanceof: "instanceof", new: "new", null: "null", return: "return", // super: "super", switch: "switch", this: "this", throw: "throw", true: "true", // try: "try", typeof: "typeof", var: "var", void: "void", while: "while", // with: "with", let: "let", static: "static", yield: "yield", // } as const satisfies Record