WIP: bootstrap and partial real Solana watcher implementation

This commit is contained in:
2026-08-16 09:17:45 +00:00
commit dc23412c3f
7232 changed files with 1687637 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
1.2.1 / 2017-05-19
==================
* fix: package.json to reduce vulnerabilities (#3)
1.2.0 / 2016-05-21
==================
* feat: warn with stack
1.1.0 / 2016-04-04
==================
* deps: upgrade ms to 0.7.0
1.0.1 / 2014-12-31
==================
* feat(index.js): warn when result is undefined
1.0.0 / 2014-08-14
==================
* init

View File

@@ -0,0 +1,133 @@
import {Connection} from './connection';
import {TransactionSignature} from './transaction';
export class SendTransactionError extends Error {
private signature: TransactionSignature;
private transactionMessage: string;
private transactionLogs: string[] | Promise<string[]> | undefined;
constructor({
action,
signature,
transactionMessage,
logs,
}: {
action: 'send' | 'simulate';
signature: TransactionSignature;
transactionMessage: string;
logs?: string[];
}) {
const maybeLogsOutput = logs
? `Logs: \n${JSON.stringify(logs.slice(-10), null, 2)}. `
: '';
const guideText =
'\nCatch the `SendTransactionError` and call `getLogs()` on it for full details.';
let message: string;
switch (action) {
case 'send':
message =
`Transaction ${signature} resulted in an error. \n` +
`${transactionMessage}. ` +
maybeLogsOutput +
guideText;
break;
case 'simulate':
message =
`Simulation failed. \nMessage: ${transactionMessage}. \n` +
maybeLogsOutput +
guideText;
break;
default: {
message = `Unknown action '${((a: never) => a)(action)}'`;
}
}
super(message);
this.signature = signature;
this.transactionMessage = transactionMessage;
this.transactionLogs = logs ? logs : undefined;
}
get transactionError(): {message: string; logs?: string[]} {
return {
message: this.transactionMessage,
logs: Array.isArray(this.transactionLogs)
? this.transactionLogs
: undefined,
};
}
/* @deprecated Use `await getLogs()` instead */
get logs(): string[] | undefined {
const cachedLogs = this.transactionLogs;
if (
cachedLogs != null &&
typeof cachedLogs === 'object' &&
'then' in cachedLogs
) {
return undefined;
}
return cachedLogs;
}
async getLogs(connection: Connection): Promise<string[]> {
if (!Array.isArray(this.transactionLogs)) {
this.transactionLogs = new Promise((resolve, reject) => {
connection
.getTransaction(this.signature)
.then(tx => {
if (tx && tx.meta && tx.meta.logMessages) {
const logs = tx.meta.logMessages;
this.transactionLogs = logs;
resolve(logs);
} else {
reject(new Error('Log messages not found'));
}
})
.catch(reject);
});
}
return await this.transactionLogs;
}
}
// Keep in sync with client/src/rpc_custom_errors.rs
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
export const SolanaJSONRPCErrorCode = {
JSON_RPC_SERVER_ERROR_BLOCK_CLEANED_UP: -32001,
JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE: -32002,
JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE: -32003,
JSON_RPC_SERVER_ERROR_BLOCK_NOT_AVAILABLE: -32004,
JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY: -32005,
JSON_RPC_SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE: -32006,
JSON_RPC_SERVER_ERROR_SLOT_SKIPPED: -32007,
JSON_RPC_SERVER_ERROR_NO_SNAPSHOT: -32008,
JSON_RPC_SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED: -32009,
JSON_RPC_SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX: -32010,
JSON_RPC_SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE: -32011,
JSON_RPC_SCAN_ERROR: -32012,
JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_LEN_MISMATCH: -32013,
JSON_RPC_SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET: -32014,
JSON_RPC_SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION: -32015,
JSON_RPC_SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED: -32016,
} as const;
export type SolanaJSONRPCErrorCodeEnum =
(typeof SolanaJSONRPCErrorCode)[keyof typeof SolanaJSONRPCErrorCode];
export class SolanaJSONRPCError extends Error {
code: SolanaJSONRPCErrorCodeEnum | unknown;
data?: any;
constructor(
{
code,
message,
data,
}: Readonly<{code: unknown; message: string; data?: any}>,
customMessage?: string,
) {
super(customMessage != null ? `${customMessage}: ${message}` : message);
this.code = code;
this.data = data;
this.name = 'SolanaJSONRPCError';
}
}

View File

@@ -0,0 +1,17 @@
/**
* Audited & minimal JS implementation of elliptic curve cryptography.
* @module
* @example
```js
import { secp256k1, schnorr } from '@noble/curves/secp256k1.js';
import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519.js';
import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448.js';
import { p256, p384, p521 } from '@noble/curves/nist.js';
import { bls12_381 } from '@noble/curves/bls12-381.js';
import { bn254 } from '@noble/curves/bn254.js';
import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/abstract/utils.js';
```
*/
throw new Error('root module cannot be imported: import submodules instead. Check out README');
export {};
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,50 @@
import * as core from "../core/index.js";
import type { ZodType } from "./schemas.js";
export type {
/** @deprecated Use `z.output<T>` instead. */
output as TypeOf,
/** @deprecated Use `z.output<T>` instead. */
output as Infer,
/** @deprecated Use `z.core.$$ZodFirstPartyTypes` instead */
$ZodTypes as ZodFirstPartySchemaTypes, } from "../core/index.js";
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
export declare const ZodIssueCode: {
readonly invalid_type: "invalid_type";
readonly too_big: "too_big";
readonly too_small: "too_small";
readonly invalid_format: "invalid_format";
readonly not_multiple_of: "not_multiple_of";
readonly unrecognized_keys: "unrecognized_keys";
readonly invalid_union: "invalid_union";
readonly invalid_key: "invalid_key";
readonly invalid_element: "invalid_element";
readonly invalid_value: "invalid_value";
readonly custom: "custom";
};
/** @deprecated Use `z.$ZodFlattenedError` */
export type inferFlattenedErrors<T extends core.$ZodType, U = string> = core.$ZodFlattenedError<core.output<T>, U>;
/** @deprecated Use `z.$ZodFormattedError` */
export type inferFormattedError<T extends core.$ZodType<any, any>, U = string> = core.$ZodFormattedError<core.output<T>, U>;
/** Use `z.$brand` instead */
export type BRAND<T extends string | number | symbol = string | number | symbol> = {
[core.$brand]: {
[k in T]: true;
};
};
export { $brand, config } from "../core/index.js";
/** @deprecated Use `z.config(params)` instead. */
export declare function setErrorMap(map: core.$ZodErrorMap): void;
/** @deprecated Use `z.config()` instead. */
export declare function getErrorMap(): core.$ZodErrorMap<core.$ZodIssue> | undefined;
export type {
/** @deprecated Use z.ZodType (without generics) instead. */
ZodType as ZodTypeAny,
/** @deprecated Use `z.ZodType` */
ZodType as ZodSchema,
/** @deprecated Use `z.ZodType` */
ZodType as Schema, };
/** Included for Zod 3 compatibility */
export type ZodRawShape = core.$ZodShape;
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
export declare enum ZodFirstPartyTypeKind {
}

View File

@@ -0,0 +1,81 @@
/**
* @fileoverview SourceCodeVisitor class
* @author Nicholas C. Zakas
*/
"use strict";
//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------
const emptyArray = Object.freeze([]);
//------------------------------------------------------------------------------
// Exports
//------------------------------------------------------------------------------
/**
* A structure to hold a list of functions to call for a given name.
* This is used to allow multiple rules to register functions for a given name
* without having to know about each other.
*/
class SourceCodeVisitor {
/**
* The functions to call for a given name.
* @type {Map<string, Function[]>}
*/
#functions = new Map();
/**
* Adds a function to the list of functions to call for a given name.
* @param {string} name The name of the function to call.
* @param {Function} func The function to call.
* @returns {void}
*/
add(name, func) {
if (this.#functions.has(name)) {
this.#functions.get(name).push(func);
} else {
this.#functions.set(name, [func]);
}
}
/**
* Gets the list of functions to call for a given name.
* @param {string} name The name of the function to call.
* @returns {Function[]} The list of functions to call.
*/
get(name) {
if (this.#functions.has(name)) {
return this.#functions.get(name);
}
return emptyArray;
}
/**
* Iterates over all names and calls the callback with the name.
* @param {(name:string) => void} callback The callback to call for each name.
* @returns {void}
*/
forEachName(callback) {
this.#functions.forEach((funcs, name) => {
callback(name);
});
}
/**
* Calls the functions for a given name with the given arguments.
* @param {string} name The name of the function to call.
* @param {any[]} args The arguments to pass to the function.
* @returns {void}
*/
callSync(name, ...args) {
if (this.#functions.has(name)) {
this.#functions.get(name).forEach(func => func(...args));
}
}
}
module.exports = { SourceCodeVisitor };

View File

@@ -0,0 +1,35 @@
{
"for + if": {
"name": "for + if",
"browser": "Edge 14.14393.0 (Windows 10 0.0.0)",
"suite": "itar-short",
"hz": 258326.20076670017,
"success": true,
"fastest": true,
"rme": 0.01562542930728137,
"rhz": 1,
"sampleSize": 210
},
"while + if": {
"name": "while + if",
"browser": "Edge 14.14393.0 (Windows 10 0.0.0)",
"suite": "itar-short",
"hz": 250131.81743630744,
"success": true,
"fastest": false,
"rme": 0.015426062316980953,
"rhz": 0.9682789306463216,
"sampleSize": 210
},
"array join": {
"name": "array join",
"browser": "Edge 14.14393.0 (Windows 10 0.0.0)",
"suite": "itar-short",
"hz": 257660.10445245806,
"success": true,
"fastest": true,
"rme": 0.012689221094028156,
"rhz": 0.9974214914620926,
"sampleSize": 212
}
}

View File

@@ -0,0 +1,461 @@
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls|https$" }] */
'use strict';
const EventEmitter = require('events');
const http = require('http');
const https = require('https');
const net = require('net');
const tls = require('tls');
const { createHash } = require('crypto');
const PerMessageDeflate = require('./permessage-deflate');
const WebSocket = require('./websocket');
const { format, parse } = require('./extension');
const { GUID, kWebSocket } = require('./constants');
const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
const RUNNING = 0;
const CLOSING = 1;
const CLOSED = 2;
/**
* Class representing a WebSocket server.
*
* @extends EventEmitter
*/
class WebSocketServer extends EventEmitter {
/**
* Create a `WebSocketServer` instance.
*
* @param {Object} options Configuration options
* @param {Number} [options.backlog=511] The maximum length of the queue of
* pending connections
* @param {Boolean} [options.clientTracking=true] Specifies whether or not to
* track clients
* @param {Function} [options.handleProtocols] A hook to handle protocols
* @param {String} [options.host] The hostname where to bind the server
* @param {Number} [options.maxBufferedChunks=262144] The maximum number of
* buffered data chunks
* @param {Number} [options.maxFragments=16384] The maximum number of message
* fragments
* @param {Number} [options.maxPayload=104857600] The maximum allowed message
* size
* @param {Boolean} [options.noServer=false] Enable no server mode
* @param {String} [options.path] Accept only connections matching this path
* @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable
* permessage-deflate
* @param {Number} [options.port] The port where to bind the server
* @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S
* server to use
* @param {Function} [options.verifyClient] A hook to reject connections
* @param {Function} [callback] A listener for the `listening` event
*/
constructor(options, callback) {
super();
options = {
maxBufferedChunks: 256 * 1024,
maxFragments: 16 * 1024,
maxPayload: 100 * 1024 * 1024,
perMessageDeflate: false,
handleProtocols: null,
clientTracking: true,
verifyClient: null,
noServer: false,
backlog: null, // use default (511 as implemented in net.js)
server: null,
host: null,
path: null,
port: null,
...options
};
if (
(options.port == null && !options.server && !options.noServer) ||
(options.port != null && (options.server || options.noServer)) ||
(options.server && options.noServer)
) {
throw new TypeError(
'One and only one of the "port", "server", or "noServer" options ' +
'must be specified'
);
}
if (options.port != null) {
this._server = http.createServer((req, res) => {
const body = http.STATUS_CODES[426];
res.writeHead(426, {
'Content-Length': body.length,
'Content-Type': 'text/plain'
});
res.end(body);
});
this._server.listen(
options.port,
options.host,
options.backlog,
callback
);
} else if (options.server) {
this._server = options.server;
}
if (this._server) {
const emitConnection = this.emit.bind(this, 'connection');
this._removeListeners = addListeners(this._server, {
listening: this.emit.bind(this, 'listening'),
error: this.emit.bind(this, 'error'),
upgrade: (req, socket, head) => {
this.handleUpgrade(req, socket, head, emitConnection);
}
});
}
if (options.perMessageDeflate === true) options.perMessageDeflate = {};
if (options.clientTracking) this.clients = new Set();
this.options = options;
this._state = RUNNING;
}
/**
* Returns the bound address, the address family name, and port of the server
* as reported by the operating system if listening on an IP socket.
* If the server is listening on a pipe or UNIX domain socket, the name is
* returned as a string.
*
* @return {(Object|String|null)} The address of the server
* @public
*/
address() {
if (this.options.noServer) {
throw new Error('The server is operating in "noServer" mode');
}
if (!this._server) return null;
return this._server.address();
}
/**
* Close the server.
*
* @param {Function} [cb] Callback
* @public
*/
close(cb) {
if (cb) this.once('close', cb);
if (this._state === CLOSED) {
process.nextTick(emitClose, this);
return;
}
if (this._state === CLOSING) return;
this._state = CLOSING;
//
// Terminate all associated clients.
//
if (this.clients) {
for (const client of this.clients) client.terminate();
}
const server = this._server;
if (server) {
this._removeListeners();
this._removeListeners = this._server = null;
//
// Close the http server if it was internally created.
//
if (this.options.port != null) {
server.close(emitClose.bind(undefined, this));
return;
}
}
process.nextTick(emitClose, this);
}
/**
* See if a given request should be handled by this server instance.
*
* @param {http.IncomingMessage} req Request object to inspect
* @return {Boolean} `true` if the request is valid, else `false`
* @public
*/
shouldHandle(req) {
if (this.options.path) {
const index = req.url.indexOf('?');
const pathname = index !== -1 ? req.url.slice(0, index) : req.url;
if (pathname !== this.options.path) return false;
}
return true;
}
/**
* Handle a HTTP Upgrade request.
*
* @param {http.IncomingMessage} req The request object
* @param {(net.Socket|tls.Socket)} socket The network socket between the
* server and client
* @param {Buffer} head The first packet of the upgraded stream
* @param {Function} cb Callback
* @public
*/
handleUpgrade(req, socket, head, cb) {
socket.on('error', socketOnError);
const key =
req.headers['sec-websocket-key'] !== undefined
? req.headers['sec-websocket-key'].trim()
: false;
const upgrade = req.headers.upgrade;
const version = +req.headers['sec-websocket-version'];
const extensions = {};
if (
req.method !== 'GET' ||
upgrade === undefined ||
upgrade.toLowerCase() !== 'websocket' ||
!key ||
!keyRegex.test(key) ||
(version !== 8 && version !== 13) ||
!this.shouldHandle(req)
) {
return abortHandshake(socket, 400);
}
if (this.options.perMessageDeflate) {
const perMessageDeflate = new PerMessageDeflate(
this.options.perMessageDeflate,
true,
this.options.maxPayload
);
try {
const offers = parse(req.headers['sec-websocket-extensions']);
if (offers[PerMessageDeflate.extensionName]) {
perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
}
} catch (err) {
return abortHandshake(socket, 400);
}
}
//
// Optionally call external client verification handler.
//
if (this.options.verifyClient) {
const info = {
origin:
req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
secure: !!(req.socket.authorized || req.socket.encrypted),
req
};
if (this.options.verifyClient.length === 2) {
this.options.verifyClient(info, (verified, code, message, headers) => {
if (!verified) {
return abortHandshake(socket, code || 401, message, headers);
}
this.completeUpgrade(key, extensions, req, socket, head, cb);
});
return;
}
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
}
this.completeUpgrade(key, extensions, req, socket, head, cb);
}
/**
* Upgrade the connection to WebSocket.
*
* @param {String} key The value of the `Sec-WebSocket-Key` header
* @param {Object} extensions The accepted extensions
* @param {http.IncomingMessage} req The request object
* @param {(net.Socket|tls.Socket)} socket The network socket between the
* server and client
* @param {Buffer} head The first packet of the upgraded stream
* @param {Function} cb Callback
* @throws {Error} If called more than once with the same socket
* @private
*/
completeUpgrade(key, extensions, req, socket, head, cb) {
//
// Destroy the socket if the client has already sent a FIN packet.
//
if (!socket.readable || !socket.writable) return socket.destroy();
if (socket[kWebSocket]) {
throw new Error(
'server.handleUpgrade() was called more than once with the same ' +
'socket, possibly due to a misconfiguration'
);
}
if (this._state > RUNNING) return abortHandshake(socket, 503);
const digest = createHash('sha1')
.update(key + GUID)
.digest('base64');
const headers = [
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
`Sec-WebSocket-Accept: ${digest}`
];
const ws = new WebSocket(null);
let protocol = req.headers['sec-websocket-protocol'];
if (protocol) {
protocol = protocol.split(',').map(trim);
//
// Optionally call external protocol selection handler.
//
if (this.options.handleProtocols) {
protocol = this.options.handleProtocols(protocol, req);
} else {
protocol = protocol[0];
}
if (protocol) {
headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
ws._protocol = protocol;
}
}
if (extensions[PerMessageDeflate.extensionName]) {
const params = extensions[PerMessageDeflate.extensionName].params;
const value = format({
[PerMessageDeflate.extensionName]: [params]
});
headers.push(`Sec-WebSocket-Extensions: ${value}`);
ws._extensions = extensions;
}
//
// Allow external modification/inspection of handshake headers.
//
this.emit('headers', headers, req);
socket.write(headers.concat('\r\n').join('\r\n'));
socket.removeListener('error', socketOnError);
ws.setSocket(
socket,
head,
this.options.maxPayload,
this.options.maxBufferedChunks,
this.options.maxFragments
);
if (this.clients) {
this.clients.add(ws);
ws.on('close', () => this.clients.delete(ws));
}
cb(ws, req);
}
}
module.exports = WebSocketServer;
/**
* Add event listeners on an `EventEmitter` using a map of <event, listener>
* pairs.
*
* @param {EventEmitter} server The event emitter
* @param {Object.<String, Function>} map The listeners to add
* @return {Function} A function that will remove the added listeners when
* called
* @private
*/
function addListeners(server, map) {
for (const event of Object.keys(map)) server.on(event, map[event]);
return function removeListeners() {
for (const event of Object.keys(map)) {
server.removeListener(event, map[event]);
}
};
}
/**
* Emit a `'close'` event on an `EventEmitter`.
*
* @param {EventEmitter} server The event emitter
* @private
*/
function emitClose(server) {
server._state = CLOSED;
server.emit('close');
}
/**
* Handle premature socket errors.
*
* @private
*/
function socketOnError() {
this.destroy();
}
/**
* Close the connection when preconditions are not fulfilled.
*
* @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request
* @param {Number} code The HTTP response status code
* @param {String} [message] The HTTP response body
* @param {Object} [headers] Additional HTTP response headers
* @private
*/
function abortHandshake(socket, code, message, headers) {
if (socket.writable) {
message = message || http.STATUS_CODES[code];
headers = {
Connection: 'close',
'Content-Type': 'text/html',
'Content-Length': Buffer.byteLength(message),
...headers
};
socket.write(
`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
Object.keys(headers)
.map((h) => `${h}: ${headers[h]}`)
.join('\r\n') +
'\r\n\r\n' +
message
);
}
socket.removeListener('error', socketOnError);
socket.destroy();
}
/**
* Remove whitespace characters from both ends of a string.
*
* @param {String} str The string
* @return {String} A new string representing `str` stripped of whitespace
* characters from both its beginning and end
* @private
*/
function trim(str) {
return str.trim();
}

View File

@@ -0,0 +1,182 @@
'use strict'
const bench = require('fastbench')
const pino = require('../../')
const fs = require('node:fs')
const dest = fs.createWriteStream('/dev/null')
const plog = pino(dest)
delete require.cache[require.resolve('../../')]
const plogDest = require('../../')(pino.destination('/dev/null'))
delete require.cache[require.resolve('../../')]
const plogAsync = require('../../')(pino.destination({ dest: '/dev/null', sync: false }))
const plogChild = plog.child({ a: 'property' })
const plogDestChild = plogDest.child({ a: 'property' })
const plogAsyncChild = plogAsync.child({ a: 'property' })
const plogChildChild = plog.child({ a: 'property' }).child({ sub: 'child' })
const plogDestChildChild = plogDest.child({ a: 'property' }).child({ sub: 'child' })
const plogAsyncChildChild = plogAsync.child({ a: 'property' }).child({ sub: 'child' })
const max = 10
const run = bench([
function benchPino (cb) {
for (var i = 0; i < max; i++) {
plog.info('hello world')
}
setImmediate(cb)
},
function benchPinoDest (cb) {
for (var i = 0; i < max; i++) {
plogDest.info('hello world')
}
setImmediate(cb)
},
function benchPinoExtreme (cb) {
for (var i = 0; i < max; i++) {
plogAsync.info('hello world')
}
setImmediate(cb)
},
function benchPinoObj (cb) {
for (var i = 0; i < max; i++) {
plog.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoDestObj (cb) {
for (var i = 0; i < max; i++) {
plogDest.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoAsyncObj (cb) {
for (var i = 0; i < max; i++) {
plogAsync.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoChild (cb) {
for (var i = 0; i < max; i++) {
plogChild.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoDestChild (cb) {
for (var i = 0; i < max; i++) {
plogDestChild.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoAsyncChild (cb) {
for (var i = 0; i < max; i++) {
plogAsyncChild.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoChildChild (cb) {
for (var i = 0; i < max; i++) {
plogChildChild.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoDestChildChild (cb) {
for (var i = 0; i < max; i++) {
plogDestChildChild.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoAsyncChildChild (cb) {
for (var i = 0; i < max; i++) {
plogAsyncChildChild.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoChildCreation (cb) {
const child = plog.child({ a: 'property' })
for (var i = 0; i < max; i++) {
child.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoDestChildCreation (cb) {
const child = plogDest.child({ a: 'property' })
for (var i = 0; i < max; i++) {
child.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoMulti (cb) {
for (var i = 0; i < max; i++) {
plog.info('hello', 'world')
}
setImmediate(cb)
},
function benchPinoDestMulti (cb) {
for (var i = 0; i < max; i++) {
plogDest.info('hello', 'world')
}
setImmediate(cb)
},
function benchPinoAsyncMulti (cb) {
for (var i = 0; i < max; i++) {
plogAsync.info('hello', 'world')
}
setImmediate(cb)
},
function benchPinoInterpolate (cb) {
for (var i = 0; i < max; i++) {
plog.info('hello %s', 'world')
}
setImmediate(cb)
},
function benchPinoDestInterpolate (cb) {
for (var i = 0; i < max; i++) {
plogDest.info('hello %s', 'world')
}
setImmediate(cb)
},
function benchPinoDestInterpolate (cb) {
for (var i = 0; i < max; i++) {
plogDest.info('hello %s', 'world')
}
setImmediate(cb)
},
function benchPinoInterpolateAll (cb) {
for (var i = 0; i < max; i++) {
plog.info('hello %s %j %d', 'world', { obj: true }, 4)
}
setImmediate(cb)
},
function benchPinoDestInterpolateAll (cb) {
for (var i = 0; i < max; i++) {
plogDest.info('hello %s %j %d', 'world', { obj: true }, 4)
}
setImmediate(cb)
},
function benchPinoAsyncInterpolateAll (cb) {
for (var i = 0; i < max; i++) {
plogAsync.info('hello %s %j %d', 'world', { obj: true }, 4)
}
setImmediate(cb)
},
function benchPinoInterpolateExtra (cb) {
for (var i = 0; i < max; i++) {
plog.info('hello %s %j %d', 'world', { obj: true }, 4, { another: 'obj' })
}
setImmediate(cb)
},
function benchPinoDestInterpolateExtra (cb) {
for (var i = 0; i < max; i++) {
plogDest.info('hello %s %j %d', 'world', { obj: true }, 4, { another: 'obj' })
}
setImmediate(cb)
},
function benchPinoAsyncInterpolateExtra (cb) {
for (var i = 0; i < max; i++) {
plogAsync.info('hello %s %j %d', 'world', { obj: true }, 4, { another: 'obj' })
}
setImmediate(cb)
}
], 10000)
run(run)

View File

@@ -0,0 +1,110 @@
import * as util from "../core/util.js";
const error = () => {
const Sizable = {
string: { unit: "ตัวอักษร", verb: "ควรมี" },
file: { unit: "ไบต์", verb: "ควรมี" },
array: { unit: "รายการ", verb: "ควรมี" },
set: { unit: "รายการ", verb: "ควรมี" },
};
function getSizing(origin) {
return Sizable[origin] ?? null;
}
const FormatDictionary = {
regex: "ข้อมูลที่ป้อน",
email: "ที่อยู่อีเมล",
url: "URL",
emoji: "อิโมจิ",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "วันที่เวลาแบบ ISO",
date: "วันที่แบบ ISO",
time: "เวลาแบบ ISO",
duration: "ช่วงเวลาแบบ ISO",
ipv4: "ที่อยู่ IPv4",
ipv6: "ที่อยู่ IPv6",
cidrv4: "ช่วง IP แบบ IPv4",
cidrv6: "ช่วง IP แบบ IPv6",
base64: "ข้อความแบบ Base64",
base64url: "ข้อความแบบ Base64 สำหรับ URL",
json_string: "ข้อความแบบ JSON",
e164: "เบอร์โทรศัพท์ระหว่างประเทศ (E.164)",
jwt: "โทเคน JWT",
template_literal: "ข้อมูลที่ป้อน",
};
const TypeDictionary = {
nan: "NaN",
number: "ตัวเลข",
array: "อาร์เรย์ (Array)",
null: "ไม่มีค่า (null)",
};
return (issue) => {
switch (issue.code) {
case "invalid_type": {
const expected = TypeDictionary[issue.expected] ?? issue.expected;
const receivedType = util.parsedType(issue.input);
const received = TypeDictionary[receivedType] ?? receivedType;
if (/^[A-Z]/.test(issue.expected)) {
return `ประเภทข้อมูลไม่ถูกต้อง: ควรเป็น instanceof ${issue.expected} แต่ได้รับ ${received}`;
}
return `ประเภทข้อมูลไม่ถูกต้อง: ควรเป็น ${expected} แต่ได้รับ ${received}`;
}
case "invalid_value":
if (issue.values.length === 1)
return `ค่าไม่ถูกต้อง: ควรเป็น ${util.stringifyPrimitive(issue.values[0])}`;
return `ตัวเลือกไม่ถูกต้อง: ควรเป็นหนึ่งใน ${util.joinValues(issue.values, "|")}`;
case "too_big": {
const adj = issue.inclusive ? "ไม่เกิน" : "น้อยกว่า";
const sizing = getSizing(issue.origin);
if (sizing)
return `เกินกำหนด: ${issue.origin ?? "ค่า"} ควรมี${adj} ${issue.maximum.toString()} ${sizing.unit ?? "รายการ"}`;
return `เกินกำหนด: ${issue.origin ?? "ค่า"} ควรมี${adj} ${issue.maximum.toString()}`;
}
case "too_small": {
const adj = issue.inclusive ? "อย่างน้อย" : "มากกว่า";
const sizing = getSizing(issue.origin);
if (sizing) {
return `น้อยกว่ากำหนด: ${issue.origin} ควรมี${adj} ${issue.minimum.toString()} ${sizing.unit}`;
}
return `น้อยกว่ากำหนด: ${issue.origin} ควรมี${adj} ${issue.minimum.toString()}`;
}
case "invalid_format": {
const _issue = issue;
if (_issue.format === "starts_with") {
return `รูปแบบไม่ถูกต้อง: ข้อความต้องขึ้นต้นด้วย "${_issue.prefix}"`;
}
if (_issue.format === "ends_with")
return `รูปแบบไม่ถูกต้อง: ข้อความต้องลงท้ายด้วย "${_issue.suffix}"`;
if (_issue.format === "includes")
return `รูปแบบไม่ถูกต้อง: ข้อความต้องมี "${_issue.includes}" อยู่ในข้อความ`;
if (_issue.format === "regex")
return `รูปแบบไม่ถูกต้อง: ต้องตรงกับรูปแบบที่กำหนด ${_issue.pattern}`;
return `รูปแบบไม่ถูกต้อง: ${FormatDictionary[_issue.format] ?? issue.format}`;
}
case "not_multiple_of":
return `ตัวเลขไม่ถูกต้อง: ต้องเป็นจำนวนที่หารด้วย ${issue.divisor} ได้ลงตัว`;
case "unrecognized_keys":
return `พบคีย์ที่ไม่รู้จัก: ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `คีย์ไม่ถูกต้องใน ${issue.origin}`;
case "invalid_union":
return "ข้อมูลไม่ถูกต้อง: ไม่ตรงกับรูปแบบยูเนียนที่กำหนดไว้";
case "invalid_element":
return `ข้อมูลไม่ถูกต้องใน ${issue.origin}`;
default:
return `ข้อมูลไม่ถูกต้อง`;
}
};
};
export default function () {
return {
localeError: error(),
};
}

View File

@@ -0,0 +1 @@
export { _ as default } from "../esm/_ts_rewrite_relative_import_extension.js";

View File

@@ -0,0 +1,202 @@
/**
* @fileoverview Disallow renaming import, export, and destructured assignments to the same name.
* @author Kai Cataldo
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../types').Rule.RuleModule} */
module.exports = {
meta: {
type: "suggestion",
defaultOptions: [
{
ignoreDestructuring: false,
ignoreImport: false,
ignoreExport: false,
},
],
docs: {
description:
"Disallow renaming import, export, and destructured assignments to the same name",
recommended: false,
url: "https://eslint.org/docs/latest/rules/no-useless-rename",
},
fixable: "code",
schema: [
{
type: "object",
properties: {
ignoreDestructuring: { type: "boolean" },
ignoreImport: { type: "boolean" },
ignoreExport: { type: "boolean" },
},
additionalProperties: false,
},
],
messages: {
unnecessarilyRenamed: "{{type}} {{name}} unnecessarily renamed.",
},
},
create(context) {
const sourceCode = context.sourceCode;
const [{ ignoreDestructuring, ignoreImport, ignoreExport }] =
context.options;
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Reports error for unnecessarily renamed assignments
* @param {ASTNode} node node to report
* @param {ASTNode} initial node with initial name value
* @param {string} type the type of the offending node
* @returns {void}
*/
function reportError(node, initial, type) {
const name =
initial.type === "Identifier" ? initial.name : initial.value;
return context.report({
node,
messageId: "unnecessarilyRenamed",
data: {
name,
type,
},
fix(fixer) {
const replacementNode =
node.type === "Property" ? node.value : node.local;
if (
sourceCode.getCommentsInside(node).length >
sourceCode.getCommentsInside(replacementNode).length
) {
return null;
}
// Don't autofix code such as `({foo: (foo) = a} = obj);`, parens are not allowed in shorthand properties.
if (
replacementNode.type === "AssignmentPattern" &&
astUtils.isParenthesised(
sourceCode,
replacementNode.left,
)
) {
return null;
}
return fixer.replaceText(
node,
sourceCode.getText(replacementNode),
);
},
});
}
/**
* Checks whether a destructured assignment is unnecessarily renamed
* @param {ASTNode} node node to check
* @returns {void}
*/
function checkDestructured(node) {
if (ignoreDestructuring) {
return;
}
for (const property of node.properties) {
/**
* Properties using shorthand syntax and rest elements can not be renamed.
* If the property is computed, we have no idea if a rename is useless or not.
*/
if (
property.type !== "Property" ||
property.shorthand ||
property.computed
) {
continue;
}
const key =
(property.key.type === "Identifier" && property.key.name) ||
(property.key.type === "Literal" && property.key.value);
const renamedKey =
property.value.type === "AssignmentPattern"
? property.value.left.name
: property.value.name;
if (key === renamedKey) {
reportError(
property,
property.key,
"Destructuring assignment",
);
}
}
}
/**
* Checks whether an import is unnecessarily renamed
* @param {ASTNode} node node to check
* @returns {void}
*/
function checkImport(node) {
if (ignoreImport) {
return;
}
if (
node.imported.range[0] !== node.local.range[0] &&
astUtils.getModuleExportName(node.imported) === node.local.name
) {
reportError(node, node.imported, "Import");
}
}
/**
* Checks whether an export is unnecessarily renamed
* @param {ASTNode} node node to check
* @returns {void}
*/
function checkExport(node) {
if (ignoreExport) {
return;
}
if (
node.local.range[0] !== node.exported.range[0] &&
astUtils.getModuleExportName(node.local) ===
astUtils.getModuleExportName(node.exported)
) {
reportError(node, node.local, "Export");
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
ObjectPattern: checkDestructured,
ImportSpecifier: checkImport,
ExportSpecifier: checkExport,
};
},
};

View File

@@ -0,0 +1,548 @@
import { expect, expectTypeOf, test } from "vitest";
import { en } from "zod/locales";
import * as z from "zod/mini";
z.config(en());
const isoDateCodec = z.codec(
z.iso.datetime(), // Input: ISO string (validates to string)
z.date(), // Output: Date object
{
decode: (isoString) => new Date(isoString), // Forward: ISO string → Date
encode: (date) => date.toISOString(), // Backward: Date → ISO string
}
);
test("instanceof", () => {
expect(isoDateCodec instanceof z.ZodMiniCodec).toBe(true);
expect(isoDateCodec instanceof z.ZodMiniPipe).toBe(true);
expect(isoDateCodec instanceof z.ZodMiniType).toBe(true);
expect(isoDateCodec instanceof z.core.$ZodCodec).toBe(true);
expect(isoDateCodec instanceof z.core.$ZodPipe).toBe(true);
expect(isoDateCodec instanceof z.core.$ZodType).toBe(true);
expectTypeOf(isoDateCodec.def).toEqualTypeOf<z.core.$ZodCodecDef<z.ZodMiniISODateTime, z.ZodMiniDate<Date>>>();
});
test("codec basic functionality", () => {
// ISO string -> Date codec using z.iso.datetime() for input validation
const testIsoString = "2024-01-15T10:30:00.000Z";
const testDate = new Date("2024-01-15T10:30:00.000Z");
// Forward decoding (ISO string -> Date)
const decodedResult = z.decode(isoDateCodec, testIsoString);
expect(decodedResult).toBeInstanceOf(Date);
expect(decodedResult.toISOString()).toMatchInlineSnapshot(`"2024-01-15T10:30:00.000Z"`);
// Backward encoding (Date -> ISO string)
const encodedResult = z.encode(isoDateCodec, testDate);
expect(typeof encodedResult).toBe("string");
expect(encodedResult).toMatchInlineSnapshot(`"2024-01-15T10:30:00.000Z"`);
});
test("codec round trip", () => {
const isoDateCodec = z.codec(z.iso.datetime(), z.date(), {
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString(),
});
const original = "2024-12-25T15:45:30.123Z";
const toDate = z.decode(isoDateCodec, original);
const backToString = z.encode(isoDateCodec, toDate);
expect(backToString).toMatchInlineSnapshot(`"2024-12-25T15:45:30.123Z"`);
expect(toDate).toBeInstanceOf(Date);
expect(toDate.getTime()).toMatchInlineSnapshot(`1735141530123`);
});
test("codec with refinement", () => {
const isoDateCodec = z
.codec(z.iso.datetime(), z.date(), {
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString(),
})
.check(z.refine((val) => val.getFullYear() === 2024, { error: "Year must be 2024" }));
// Valid 2024 date
const validDate = z.decode(isoDateCodec, "2024-01-15T10:30:00.000Z");
expect(validDate.getFullYear()).toMatchInlineSnapshot(`2024`);
expect(validDate.getTime()).toMatchInlineSnapshot(`1705314600000`);
// Invalid year should fail safely
const invalidYearResult = z.safeDecode(isoDateCodec, "2023-01-15T10:30:00.000Z");
expect(invalidYearResult.success).toBe(false);
if (!invalidYearResult.success) {
expect(invalidYearResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "custom",
"message": "Year must be 2024",
"path": [],
},
]
`);
}
});
test("safe codec operations", () => {
const isoDateCodec = z.codec(z.iso.datetime(), z.date(), {
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString(),
});
// Safe decode with invalid input
const safeDecodeResult = z.safeDecode(isoDateCodec, "invalid-date");
expect(safeDecodeResult.success).toBe(false);
if (!safeDecodeResult.success) {
expect(safeDecodeResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "invalid_format",
"format": "datetime",
"message": "Invalid ISO datetime",
"origin": "string",
"path": [],
"pattern": "/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/",
},
]
`);
}
// Safe decode with valid input
const safeDecodeValid = z.safeDecode(isoDateCodec, "2024-01-15T10:30:00.000Z");
expect(safeDecodeValid.success).toBe(true);
if (safeDecodeValid.success) {
expect(safeDecodeValid.data).toBeInstanceOf(Date);
expect(safeDecodeValid.data.getTime()).toMatchInlineSnapshot(`1705314600000`);
}
// Safe encode with valid input
const safeEncodeResult = z.safeEncode(isoDateCodec, new Date("2024-01-01"));
expect(safeEncodeResult.success).toBe(true);
if (safeEncodeResult.success) {
expect(safeEncodeResult.data).toMatchInlineSnapshot(`"2024-01-01T00:00:00.000Z"`);
}
});
test("codec with different types", () => {
// String -> Number codec
const stringNumberCodec = z.codec(z.string(), z.number(), {
decode: (str) => Number.parseFloat(str),
encode: (num) => num.toString(),
});
const decodedNumber = z.decode(stringNumberCodec, "42.5");
expect(decodedNumber).toMatchInlineSnapshot(`42.5`);
expect(typeof decodedNumber).toBe("number");
const encodedString = z.encode(stringNumberCodec, 42.5);
expect(encodedString).toMatchInlineSnapshot(`"42.5"`);
expect(typeof encodedString).toBe("string");
});
test("async codec operations", async () => {
const isoDateCodec = z.codec(z.iso.datetime(), z.date(), {
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString(),
});
// Async decode
const decodedResult = await z.decodeAsync(isoDateCodec, "2024-01-15T10:30:00.000Z");
expect(decodedResult).toBeInstanceOf(Date);
expect(decodedResult.getTime()).toMatchInlineSnapshot(`1705314600000`);
// Async encode
const encodedResult = await z.encodeAsync(isoDateCodec, new Date("2024-01-15T10:30:00.000Z"));
expect(typeof encodedResult).toBe("string");
expect(encodedResult).toMatchInlineSnapshot(`"2024-01-15T10:30:00.000Z"`);
// Safe async operations
const safeDecodeResult = await z.safeDecodeAsync(isoDateCodec, "2024-01-15T10:30:00.000Z");
expect(safeDecodeResult.success).toBe(true);
if (safeDecodeResult.success) {
expect(safeDecodeResult.data.getTime()).toMatchInlineSnapshot(`1705314600000`);
}
const safeEncodeResult = await z.safeEncodeAsync(isoDateCodec, new Date("2024-01-15T10:30:00.000Z"));
expect(safeEncodeResult.success).toBe(true);
if (safeEncodeResult.success) {
expect(safeEncodeResult.data).toMatchInlineSnapshot(`"2024-01-15T10:30:00.000Z"`);
}
});
test("codec type inference", () => {
const codec = z.codec(z.string(), z.number(), {
decode: (str) => Number.parseInt(str),
encode: (num) => num.toString(),
});
// These should compile without type errors
const decoded: number = z.decode(codec, "123");
const encoded: string = z.encode(codec, 123);
expect(decoded).toMatchInlineSnapshot(`123`);
expect(encoded).toMatchInlineSnapshot(`"123"`);
});
test("nested codec with object containing codec property", () => {
// Nested schema: object containing a codec as one of its properties, with refinements at all levels
const waypointSchema = z
.object({
name: z.string().check(z.minLength(1, "Waypoint name required")),
difficulty: z.enum(["easy", "medium", "hard"]),
coordinate: z
.codec(
z
.string()
.check(z.regex(/^-?\d+,-?\d+$/, "Must be 'x,y' format")), // Input: coordinate string
z
.object({ x: z.number(), y: z.number() })
.check(z.refine((coord) => coord.x >= 0 && coord.y >= 0, { error: "Coordinates must be non-negative" })), // Output: coordinate object
{
decode: (coordString: string) => {
const [x, y] = coordString.split(",").map(Number);
return { x, y };
},
encode: (coord: { x: number; y: number }) => `${coord.x},${coord.y}`,
}
)
.check(z.refine((coord) => coord.x <= 1000 && coord.y <= 1000, { error: "Coordinates must be within bounds" })),
})
.check(
z.refine((waypoint) => waypoint.difficulty !== "hard" || waypoint.coordinate.x >= 100, {
error: "Hard waypoints must be at least 100 units from origin",
})
);
// Test data
const inputWaypoint = {
name: "Summit Point",
difficulty: "medium" as const,
coordinate: "150,200",
};
// Forward decoding (object with string coordinate -> object with coordinate object)
const decodedWaypoint = z.decode(waypointSchema, inputWaypoint);
expect(decodedWaypoint).toMatchInlineSnapshot(`
{
"coordinate": {
"x": 150,
"y": 200,
},
"difficulty": "medium",
"name": "Summit Point",
}
`);
// Backward encoding (object with coordinate object -> object with string coordinate)
const encodedWaypoint = z.encode(waypointSchema, decodedWaypoint);
expect(encodedWaypoint).toMatchInlineSnapshot(`
{
"coordinate": "150,200",
"difficulty": "medium",
"name": "Summit Point",
}
`);
// Test refinements at all levels
// String validation (empty waypoint name)
const emptyNameResult = z.safeDecode(waypointSchema, {
name: "",
difficulty: "easy",
coordinate: "10,20",
});
expect(emptyNameResult.success).toBe(false);
if (!emptyNameResult.success) {
expect(emptyNameResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"inclusive": true,
"message": "Waypoint name required",
"minimum": 1,
"origin": "string",
"path": [
"name",
],
},
]
`);
}
// Enum validation (invalid difficulty)
const invalidDifficultyResult = z.safeDecode(waypointSchema, {
name: "Test Point",
difficulty: "impossible" as any,
coordinate: "10,20",
});
expect(invalidDifficultyResult.success).toBe(false);
if (!invalidDifficultyResult.success) {
expect(invalidDifficultyResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "invalid_value",
"message": "Invalid option: expected one of "easy"|"medium"|"hard"",
"path": [
"difficulty",
],
"values": [
"easy",
"medium",
"hard",
],
},
]
`);
}
// Codec string format validation (invalid coordinate format)
const invalidFormatResult = z.safeDecode(waypointSchema, {
name: "Test Point",
difficulty: "easy",
coordinate: "invalid",
});
expect(invalidFormatResult.success).toBe(false);
if (!invalidFormatResult.success) {
expect(invalidFormatResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "invalid_format",
"format": "regex",
"message": "Must be 'x,y' format",
"origin": "string",
"path": [
"coordinate",
],
"pattern": "/^-?\\d+,-?\\d+$/",
},
]
`);
}
// Codec object refinement (negative coordinates)
const negativeCoordResult = z.safeDecode(waypointSchema, {
name: "Test Point",
difficulty: "easy",
coordinate: "-5,10",
});
expect(negativeCoordResult.success).toBe(false);
if (!negativeCoordResult.success) {
expect(negativeCoordResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "custom",
"message": "Coordinates must be non-negative",
"path": [
"coordinate",
],
},
]
`);
}
// Codec-level refinement (coordinates out of bounds)
const outOfBoundsResult = z.safeDecode(waypointSchema, {
name: "Test Point",
difficulty: "easy",
coordinate: "1500,2000",
});
expect(outOfBoundsResult.success).toBe(false);
if (!outOfBoundsResult.success) {
expect(outOfBoundsResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "custom",
"message": "Coordinates must be within bounds",
"path": [
"coordinate",
],
},
]
`);
}
// Object-level refinement (hard waypoint too close to origin)
const hardWaypointResult = z.safeDecode(waypointSchema, {
name: "Expert Point",
difficulty: "hard",
coordinate: "50,60", // x < 100, but hard waypoints need x >= 100
});
expect(hardWaypointResult.success).toBe(false);
if (!hardWaypointResult.success) {
expect(hardWaypointResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "custom",
"message": "Hard waypoints must be at least 100 units from origin",
"path": [],
},
]
`);
}
// Round trip test
const roundTripResult = z.encode(waypointSchema, z.decode(waypointSchema, inputWaypoint));
expect(roundTripResult).toMatchInlineSnapshot(`
{
"coordinate": "150,200",
"difficulty": "medium",
"name": "Summit Point",
}
`);
});
test("mutating refinements", () => {
const A = z.codec(z.string(), z.string().check(z.trim()), {
decode: (val) => val,
encode: (val) => val,
});
expect(z.decode(A, " asdf ")).toMatchInlineSnapshot(`"asdf"`);
expect(z.encode(A, " asdf ")).toMatchInlineSnapshot(`"asdf"`);
});
test("codec type enforcement - correct encode/decode signatures", () => {
// Test that codec functions have correct type signatures
const stringToNumberCodec = z.codec(z.string(), z.number(), {
decode: (value: string) => Number(value), // core.output<A> -> core.input<B>
encode: (value: number) => String(value), // core.input<B> -> core.output<A>
});
// These should compile without errors - correct types (async support)
expectTypeOf<(value: string, payload: z.core.ParsePayload<string>) => z.core.util.MaybeAsync<number>>(
stringToNumberCodec.def.transform
).toBeFunction();
expectTypeOf<(value: number, payload: z.core.ParsePayload<number>) => z.core.util.MaybeAsync<string>>(
stringToNumberCodec.def.reverseTransform
).toBeFunction();
// Test that decode parameter type is core.output<A> (string)
const validDecode = (value: string) => Number(value);
expectTypeOf(validDecode).toMatchTypeOf<(value: string) => number>();
// Test that encode parameter type is core.input<B> (number)
const validEncode = (value: number) => String(value);
expectTypeOf(validEncode).toMatchTypeOf<(value: number) => string>();
z.codec(z.string(), z.number(), {
// @ts-expect-error - decode should NOT accept core.input<A> as parameter
decode: (value: never, _payload) => Number(value), // Wrong: should be string, not unknown
encode: (value: number, _payload) => String(value),
});
z.codec(z.string(), z.number(), {
decode: (value: string) => Number(value),
// @ts-expect-error - encode should NOT accept core.output<B> as parameter
encode: (value: never) => String(value), // Wrong: should be number, not unknown
});
z.codec(z.string(), z.number(), {
// @ts-expect-error - decode return type should be core.input<B>
decode: (value: string) => String(value), // Wrong: should return number, not string
encode: (value: number) => String(value),
});
z.codec(z.string(), z.number(), {
decode: (value: string) => Number(value),
// @ts-expect-error - encode return type should be core.output<A>
encode: (value: number) => Number(value), // Wrong: should return string, not number
});
});
test("async codec functionality", async () => {
// Test that async encode/decode functions work properly
const asyncCodec = z.codec(z.string(), z.number(), {
decode: async (str) => {
await new Promise((resolve) => setTimeout(resolve, 1)); // Simulate async work
return Number.parseFloat(str);
},
encode: async (num) => {
await new Promise((resolve) => setTimeout(resolve, 1)); // Simulate async work
return num.toString();
},
});
// Test async decode/encode
const decoded = await z.decodeAsync(asyncCodec, "42.5");
expect(decoded).toBe(42.5);
const encoded = await z.encodeAsync(asyncCodec, 42.5);
expect(encoded).toBe("42.5");
// Test that both sync and async work
const mixedCodec = z.codec(z.string(), z.number(), {
decode: async (str) => Number.parseFloat(str),
encode: (num) => num.toString(), // sync encode
});
const mixedResult = await z.decodeAsync(mixedCodec, "123");
expect(mixedResult).toBe(123);
});
test("codec type enforcement - complex types", () => {
type User = { id: number; name: string };
type UserInput = { id: string; name: string };
const userCodec = z.codec(
z.object({ id: z.string(), name: z.string() }),
z.object({ id: z.number(), name: z.string() }),
{
decode: (input: UserInput) => ({ id: Number(input.id), name: input.name }),
encode: (user: User) => ({ id: String(user.id), name: user.name }),
}
);
// Verify correct types are inferred (async support)
expectTypeOf<(input: UserInput, payload: z.core.ParsePayload<UserInput>) => z.core.util.MaybeAsync<User>>(
userCodec.def.transform
).toBeFunction();
expectTypeOf<(user: User, payload: z.core.ParsePayload<User>) => z.core.util.MaybeAsync<UserInput>>(
userCodec.def.reverseTransform
).toBeFunction();
z.codec(
z.object({
id: z.string(),
name: z.string(),
}),
z.object({ id: z.number(), name: z.string() }),
{
// @ts-expect-error - decode parameter should be UserInput, not User
decode: (input: User) => ({ id: Number(input.id), name: input.name }), // Wrong type
encode: (user: User) => ({ id: String(user.id), name: user.name }),
}
);
z.codec(
z.object({
id: z.string(),
name: z.string(),
}),
z.object({ id: z.number(), name: z.string() }),
{
decode: (input: UserInput) => ({ id: Number(input.id), name: input.name }),
// @ts-expect-error - encode parameter should be User, not UserInput
encode: (user: UserInput) => ({ id: String(user.id), name: user.name }), // Wrong type
}
);
});
test("invertCodec", () => {
const inverted = z.invertCodec(isoDateCodec);
type InvIn = z.input<typeof inverted>;
type InvOut = z.output<typeof inverted>;
expectTypeOf<InvIn>().toEqualTypeOf<Date>();
expectTypeOf<InvOut>().toEqualTypeOf<string>();
const testDate = new Date("2024-01-15T10:30:00.000Z");
expect(z.decode(inverted, testDate)).toBe("2024-01-15T10:30:00.000Z");
const encoded = z.encode(inverted, "2024-01-15T10:30:00.000Z");
expect(encoded).toBeInstanceOf(Date);
expect(encoded.toISOString()).toBe("2024-01-15T10:30:00.000Z");
const doubleInverted = z.invertCodec(z.invertCodec(isoDateCodec));
expect(z.decode(doubleInverted, "2024-01-15T10:30:00.000Z")).toBeInstanceOf(Date);
});

View File

@@ -0,0 +1,60 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// This code was bundled using `deno bundle` and it's not recommended to edit it manually
const canElideFrames = "captureStackTrace" in Error;
class AssertionError extends Error {
message;
get name() {
return "AssertionError";
}
get ok() {
return false;
}
constructor(message = "Unspecified AssertionError", props, ssf){
super(message);
this.message = message;
if (canElideFrames) {
Error.captureStackTrace(this, ssf || AssertionError);
}
for(const key in props){
if (!(key in this)) {
this[key] = props[key];
}
}
}
toJSON(stack) {
return {
...this,
name: this.name,
message: this.message,
ok: false,
stack: stack !== false ? this.stack : undefined
};
}
}
class AssertionResult {
get name() {
return "AssertionResult";
}
get ok() {
return true;
}
constructor(props){
for(const key in props){
if (!(key in this)) {
this[key] = props[key];
}
}
}
toJSON() {
return {
...this,
name: this.name,
ok: this.ok
};
}
}
export { AssertionError as AssertionError };
export { AssertionResult as AssertionResult };

View File

@@ -0,0 +1,283 @@
import { expect, test } from "vitest";
import * as z from "zod/v4";
test("string length", async () => {
try {
await z.string().length(4).parseAsync("asd");
} catch (err) {
// ("String must contain exactly 4 character(s)");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"exact": true,
"inclusive": true,
"message": "Too small: expected string to have >=4 characters",
"minimum": 4,
"origin": "string",
"path": [],
},
]
`);
}
try {
await z.string().length(4).parseAsync("asdaa");
} catch (err) {
// ("String must contain exactly 4 character(s)");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_big",
"exact": true,
"inclusive": true,
"maximum": 4,
"message": "Too big: expected string to have <=4 characters",
"origin": "string",
"path": [],
},
]
`);
}
});
test("string min/max", async () => {
try {
await z.string().min(4).parseAsync("asd");
} catch (err) {
// ("String must contain at least 4 character(s)");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"inclusive": true,
"message": "Too small: expected string to have >=4 characters",
"minimum": 4,
"origin": "string",
"path": [],
},
]
`);
}
});
test("string max", async () => {
try {
await z.string().max(4).parseAsync("aasdfsdfsd");
} catch (err) {
// ("String must contain at most 4 character(s)");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_big",
"inclusive": true,
"maximum": 4,
"message": "Too big: expected string to have <=4 characters",
"origin": "string",
"path": [],
},
]
`);
}
});
test("number min", async () => {
try {
await z.number().min(3).parseAsync(2);
} catch (err) {
// ("Number must be greater than or equal to 3");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"inclusive": true,
"message": "Too small: expected number to be >=3",
"minimum": 3,
"origin": "number",
"path": [],
},
]
`);
}
});
test("number gte", async () => {
try {
await z.number().gte(3).parseAsync(2);
} catch (err) {
// ("Number must be greater than or equal to 3");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"inclusive": true,
"message": "Too small: expected number to be >=3",
"minimum": 3,
"origin": "number",
"path": [],
},
]
`);
}
});
test("number gt", async () => {
try {
await z.number().gt(3).parseAsync(3);
} catch (err) {
// ("Number must be greater than or equal to 3");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"inclusive": false,
"message": "Too small: expected number to be >3",
"minimum": 3,
"origin": "number",
"path": [],
},
]
`);
}
});
test("number max", async () => {
try {
await z.number().max(3).parseAsync(4);
} catch (err) {
// ("Number must be less than or equal to 3");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_big",
"inclusive": true,
"maximum": 3,
"message": "Too big: expected number to be <=3",
"origin": "number",
"path": [],
},
]
`);
}
});
test("number lte", async () => {
try {
await z.number().lte(3).parseAsync(4);
} catch (err) {
// ("Number must be less than or equal to 3");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_big",
"inclusive": true,
"maximum": 3,
"message": "Too big: expected number to be <=3",
"origin": "number",
"path": [],
},
]
`);
}
});
test("number lt", async () => {
try {
await z.number().lt(3).parseAsync(3);
} catch (err) {
// ("Number must be less than or equal to 3");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_big",
"inclusive": false,
"maximum": 3,
"message": "Too big: expected number to be <3",
"origin": "number",
"path": [],
},
]
`);
}
});
test("number nonnegative", async () => {
try {
await z.number().nonnegative().parseAsync(-1);
} catch (err) {
// ("Number must be greater than or equal to 0");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"inclusive": true,
"message": "Too small: expected number to be >=0",
"minimum": 0,
"origin": "number",
"path": [],
},
]
`);
}
});
test("number nonpositive", async () => {
try {
await z.number().nonpositive().parseAsync(1);
} catch (err) {
// ("Number must be less than or equal to 0");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_big",
"inclusive": true,
"maximum": 0,
"message": "Too big: expected number to be <=0",
"origin": "number",
"path": [],
},
]
`);
}
});
test("number negative", async () => {
try {
await z.number().negative().parseAsync(1);
} catch (err) {
// ("Number must be less than 0");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_big",
"inclusive": false,
"maximum": 0,
"message": "Too big: expected number to be <0",
"origin": "number",
"path": [],
},
]
`);
}
});
test("number positive", async () => {
try {
await z.number().positive().parseAsync(-1);
} catch (err) {
// ("Number must be greater than 0");
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"inclusive": false,
"message": "Too small: expected number to be >0",
"minimum": 0,
"origin": "number",
"path": [],
},
]
`);
}
});

View File

@@ -0,0 +1,142 @@
import { Infer, Struct } from '../struct.js';
import { ObjectSchema, ObjectType, AnyStruct, InferStructTuple, UnionToIntersection } from '../utils.js';
/**
* Ensure that any value passes validation.
*/
export declare function any(): Struct<any, null>;
/**
* Ensure that a value is an array and that its elements are of a specific type.
*
* Note: If you omit the element struct, the arrays elements will not be
* iterated at all. This can be helpful for cases where performance is critical,
* and it is preferred to using `array(any())`.
*/
export declare function array<T extends Struct<any>>(Element: T): Struct<Infer<T>[], T>;
export declare function array(): Struct<unknown[], undefined>;
/**
* Ensure that a value is a bigint.
*/
export declare function bigint(): Struct<bigint, null>;
/**
* Ensure that a value is a boolean.
*/
export declare function boolean(): Struct<boolean, null>;
/**
* Ensure that a value is a valid `Date`.
*
* Note: this also ensures that the value is *not* an invalid `Date` object,
* which can occur when parsing a date fails but still returns a `Date`.
*/
export declare function date(): Struct<Date, null>;
/**
* Ensure that a value is one of a set of potential values.
*
* Note: after creating the struct, you can access the definition of the
* potential values as `struct.schema`.
*/
export declare function enums<U extends number, T extends readonly U[]>(values: T): Struct<T[number], {
[K in T[number]]: K;
}>;
export declare function enums<U extends string, T extends readonly U[]>(values: T): Struct<T[number], {
[K in T[number]]: K;
}>;
/**
* Ensure that a value is a function.
*/
export declare function func(): Struct<Function, null>;
/**
* Ensure that a value is an instance of a specific class.
*/
export declare function instance<T extends {
new (...args: any): any;
}>(Class: T): Struct<InstanceType<T>, null>;
/**
* Ensure that a value is an integer.
*/
export declare function integer(): Struct<number, null>;
/**
* Ensure that a value matches all of a set of types.
*/
export declare function intersection<A extends AnyStruct, B extends AnyStruct[]>(Structs: [A, ...B]): Struct<Infer<A> & UnionToIntersection<InferStructTuple<B>[number]>, null>;
/**
* Ensure that a value is an exact value, using `===` for comparison.
*/
export declare function literal<T extends boolean>(constant: T): Struct<T, T>;
export declare function literal<T extends number>(constant: T): Struct<T, T>;
export declare function literal<T extends string>(constant: T): Struct<T, T>;
export declare function literal<T>(constant: T): Struct<T, null>;
/**
* Ensure that a value is a `Map` object, and that its keys and values are of
* specific types.
*/
export declare function map(): Struct<Map<unknown, unknown>, null>;
export declare function map<K, V>(Key: Struct<K>, Value: Struct<V>): Struct<Map<K, V>, null>;
/**
* Ensure that no value ever passes validation.
*/
export declare function never(): Struct<never, null>;
/**
* Augment an existing struct to allow `null` values.
*/
export declare function nullable<T, S>(struct: Struct<T, S>): Struct<T | null, S>;
/**
* Ensure that a value is a number.
*/
export declare function number(): Struct<number, null>;
/**
* Ensure that a value is an object, that is has a known set of properties,
* and that its properties are of specific types.
*
* Note: Unrecognized properties will fail validation.
*/
export declare function object(): Struct<Record<string, unknown>, null>;
export declare function object<S extends ObjectSchema>(schema: S): Struct<ObjectType<S>, S>;
/**
* Augment a struct to allow `undefined` values.
*/
export declare function optional<T, S>(struct: Struct<T, S>): Struct<T | undefined, S>;
/**
* Ensure that a value is an object with keys and values of specific types, but
* without ensuring any specific shape of properties.
*
* Like TypeScript's `Record` utility.
*/
export declare function record<K extends string, V>(Key: Struct<K>, Value: Struct<V>): Struct<Record<K, V>, null>;
/**
* Ensure that a value is a `RegExp`.
*
* Note: this does not test the value against the regular expression! For that
* you need to use the `pattern()` refinement.
*/
export declare function regexp(): Struct<RegExp, null>;
/**
* Ensure that a value is a `Set` object, and that its elements are of a
* specific type.
*/
export declare function set(): Struct<Set<unknown>, null>;
export declare function set<T>(Element: Struct<T>): Struct<Set<T>, null>;
/**
* Ensure that a value is a string.
*/
export declare function string(): Struct<string, null>;
/**
* Ensure that a value is a tuple of a specific length, and that each of its
* elements is of a specific type.
*/
export declare function tuple<A extends AnyStruct, B extends AnyStruct[]>(Structs: [A, ...B]): Struct<[Infer<A>, ...InferStructTuple<B>], null>;
/**
* Ensure that a value has a set of known properties of specific types.
*
* Note: Unrecognized properties are allowed and untouched. This is similar to
* how TypeScript's structural typing works.
*/
export declare function type<S extends ObjectSchema>(schema: S): Struct<ObjectType<S>, S>;
/**
* Ensure that a value matches one of a set of types.
*/
export declare function union<A extends AnyStruct, B extends AnyStruct[]>(Structs: [A, ...B]): Struct<Infer<A> | InferStructTuple<B>[number], null>;
/**
* Ensure that any value passes validation, without widening its type to `any`.
*/
export declare function unknown(): Struct<unknown, null>;
//# sourceMappingURL=types.d.ts.map

View File

@@ -0,0 +1,52 @@
export { default as ar } from "./ar.js";
export { default as az } from "./az.js";
export { default as be } from "./be.js";
export { default as bg } from "./bg.js";
export { default as ca } from "./ca.js";
export { default as cs } from "./cs.js";
export { default as da } from "./da.js";
export { default as de } from "./de.js";
export { default as el } from "./el.js";
export { default as en } from "./en.js";
export { default as eo } from "./eo.js";
export { default as es } from "./es.js";
export { default as fa } from "./fa.js";
export { default as fi } from "./fi.js";
export { default as fr } from "./fr.js";
export { default as frCA } from "./fr-CA.js";
export { default as he } from "./he.js";
export { default as hr } from "./hr.js";
export { default as hu } from "./hu.js";
export { default as hy } from "./hy.js";
export { default as id } from "./id.js";
export { default as is } from "./is.js";
export { default as it } from "./it.js";
export { default as ja } from "./ja.js";
export { default as ka } from "./ka.js";
export { default as kh } from "./kh.js";
export { default as km } from "./km.js";
export { default as ko } from "./ko.js";
export { default as lt } from "./lt.js";
export { default as mk } from "./mk.js";
export { default as ms } from "./ms.js";
export { default as nl } from "./nl.js";
export { default as no } from "./no.js";
export { default as ota } from "./ota.js";
export { default as ps } from "./ps.js";
export { default as pl } from "./pl.js";
export { default as pt } from "./pt.js";
export { default as ro } from "./ro.js";
export { default as ru } from "./ru.js";
export { default as sl } from "./sl.js";
export { default as sv } from "./sv.js";
export { default as ta } from "./ta.js";
export { default as th } from "./th.js";
export { default as tr } from "./tr.js";
export { default as ua } from "./ua.js";
export { default as uk } from "./uk.js";
export { default as ur } from "./ur.js";
export { default as uz } from "./uz.js";
export { default as vi } from "./vi.js";
export { default as zhCN } from "./zh-CN.js";
export { default as zhTW } from "./zh-TW.js";
export { default as yo } from "./yo.js";

View File

@@ -0,0 +1,63 @@
import Benchmark from "benchmark";
import { z } from "zod/v3";
const shortSuite = new Benchmark.Suite("realworld");
const People = z.array(
z.object({
type: z.literal("person"),
hair: z.enum(["blue", "brown"]),
active: z.boolean(),
name: z.string(),
age: z.number().int(),
hobbies: z.array(z.string()),
address: z.object({
street: z.string(),
zip: z.string(),
country: z.string(),
}),
})
);
let i = 0;
function num() {
return ++i;
}
function str() {
return (++i % 100).toString(16);
}
function array<T>(fn: () => T): T[] {
return Array.from({ length: ++i % 10 }, () => fn());
}
const people = Array.from({ length: 100 }, () => {
return {
type: "person",
hair: i % 2 ? "blue" : "brown",
active: !!(i % 2),
name: str(),
age: num(),
hobbies: array(str),
address: {
street: str(),
zip: str(),
country: str(),
},
};
});
shortSuite
.add("valid", () => {
People.parse(people);
})
.on("cycle", (e: Benchmark.Event) => {
console.log(`${(shortSuite as any).name}: ${e.target}`);
});
export default {
suites: [shortSuite],
};

View File

@@ -0,0 +1,13 @@
/**
* @author Toru Nagashima <https://github.com/mysticatea>
*/
"use strict";
/**
* Check whether a given character is a combining mark or not.
* @param {number} codePoint The character code to check.
* @returns {boolean} `true` if the character has the General Category of Combining Mark (M), consisting of `Mc`, `Me`, and `Mn`.
*/
module.exports = function isCombiningCharacter(codePoint) {
return /^\p{M}$/u.test(String.fromCodePoint(codePoint));
};

View File

@@ -0,0 +1,2 @@
import type { LibDefinition } from '../variable';
export declare const es2022_error: LibDefinition;

View File

@@ -0,0 +1,50 @@
type Line = number;
type Column = number;
type Kind = number;
type Name = number;
type Var = number;
type SourcesIndex = number;
type ScopesIndex = number;
type Mix<A, B, O> = (A & O) | (B & O);
export type OriginalScope = Mix<[
Line,
Column,
Line,
Column,
Kind
], [
Line,
Column,
Line,
Column,
Kind,
Name
], {
vars: Var[];
}>;
export type GeneratedRange = Mix<[
Line,
Column,
Line,
Column
], [
Line,
Column,
Line,
Column,
SourcesIndex,
ScopesIndex
], {
callsite: CallSite | null;
bindings: Binding[];
isScope: boolean;
}>;
export type CallSite = [SourcesIndex, Line, Column];
type Binding = BindingExpressionRange[];
export type BindingExpressionRange = [Name] | [Name, Line, Column];
export declare function decodeOriginalScopes(input: string): OriginalScope[];
export declare function encodeOriginalScopes(scopes: OriginalScope[]): string;
export declare function decodeGeneratedRanges(input: string): GeneratedRange[];
export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string;
export {};
//# sourceMappingURL=scopes.d.ts.map

View File

@@ -0,0 +1,17 @@
import { AbstractMessageReader, DataCallback, AbstractMessageWriter, Message, Disposable, ConnectionStrategy, ConnectionOptions, MessageReader, MessageWriter, Logger, MessageConnection } from '../common/api';
export * from '../common/api';
export declare class BrowserMessageReader extends AbstractMessageReader implements MessageReader {
private _onData;
private _messageListener;
constructor(port: MessagePort | Worker | DedicatedWorkerGlobalScope);
listen(callback: DataCallback): Disposable;
}
export declare class BrowserMessageWriter extends AbstractMessageWriter implements MessageWriter {
private port;
private errorCount;
constructor(port: MessagePort | Worker | DedicatedWorkerGlobalScope);
write(msg: Message): Promise<void>;
private handleError;
end(): void;
}
export declare function createMessageConnection(reader: MessageReader, writer: MessageWriter, logger?: Logger, options?: ConnectionStrategy | ConnectionOptions): MessageConnection;

View File

@@ -0,0 +1,16 @@
export * as core from "../core/index.cjs";
export * from "./schemas.cjs";
export * from "./checks.cjs";
export * from "./errors.cjs";
export * from "./parse.cjs";
export * from "./compat.cjs";
export type { infer, output, input } from "../core/index.cjs";
export type { JSONType } from "../core/util.cjs";
export { globalRegistry, type GlobalMeta, registry, config, $output, $input, $brand, clone, regexes, treeifyError, prettifyError, formatError, flattenError, TimePrecision, util, NEVER, } from "../core/index.cjs";
export { toJSONSchema } from "../core/json-schema-processors.cjs";
export { fromJSONSchema } from "./from-json-schema.cjs";
export * as locales from "../locales/index.cjs";
export { ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration } from "./iso.cjs";
export * as iso from "./iso.cjs";
export type { ZodCoercedString, ZodCoercedNumber, ZodCoercedBigInt, ZodCoercedBoolean, ZodCoercedDate, } from "./coerce.cjs";
export * as coerce from "./coerce.cjs";