@jfdevelops/create-error 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,101 @@
1
+ import { BlueprintContext, BlueprintErrorTemplate, CreateErrorConfig, ErrorFamilyFactory } from "./types.mjs";
2
+ import { StandardSchemaV1 } from "@standard-schema/spec";
3
+
4
+ //#region src/create-error.d.ts
5
+ type ErrorConfigBody<Schema extends StandardSchemaV1, DataConfig extends CreateErrorConfig<Schema>['data'], MessageCallback extends CreateErrorConfig<Schema>['message']> = {
6
+ data: DataConfig;
7
+ message: MessageCallback;
8
+ };
9
+ type ErrorConfigWithProperties<Schema extends StandardSchemaV1, DataConfig extends CreateErrorConfig<Schema>['data'], MessageCallback extends CreateErrorConfig<Schema>['message'], Properties extends object> = ErrorConfigBody<Schema, DataConfig, MessageCallback> & {
10
+ properties(context: BlueprintContext<Schema>): Properties;
11
+ };
12
+ type ErrorConfigWithoutProperties<Schema extends StandardSchemaV1, DataConfig extends CreateErrorConfig<Schema>['data'], MessageCallback extends CreateErrorConfig<Schema>['message']> = ErrorConfigBody<Schema, DataConfig, MessageCallback> & {
13
+ properties?: never;
14
+ };
15
+ type ExactCreateErrorConfig<Schema extends StandardSchemaV1, Config extends object> = {
16
+ definition: Schema;
17
+ } & Config & (StandardSchemaV1.InferOutput<Schema> extends object ? unknown : {
18
+ definition: never;
19
+ });
20
+ type SerializedCreateErrorConfig<Schema extends StandardSchemaV1, Config extends object, Json> = ExactCreateErrorConfig<Schema, Config & {
21
+ toJSON(error: BlueprintErrorTemplate<NoInfer<Config>>): Json;
22
+ }>;
23
+ /**
24
+ * Creates an error family with additional instance properties and typed JSON
25
+ * serialization.
26
+ *
27
+ * @param config Defines the family, its public properties, and its serialized
28
+ * representation.
29
+ * @returns A callable factory with a shared `.Error` base class.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const createApiError = createError({
34
+ * definition: z.object({ code: z.string() }),
35
+ * data: {
36
+ * property: 'context',
37
+ * resolve: ({ input }) => input,
38
+ * },
39
+ * message: ({ data, implementation }) => implementation(data),
40
+ * properties: ({ definition }) => ({ code: definition.code }),
41
+ * toJSON: (error) => ({
42
+ * code: error.code,
43
+ * context: error.context,
44
+ * message: error.message,
45
+ * }),
46
+ * });
47
+ * ```
48
+ */
49
+ declare function createError<const Schema extends StandardSchemaV1, const DataConfig extends CreateErrorConfig<Schema>['data'], const MessageCallback extends CreateErrorConfig<Schema>['message'], const Properties extends object, Json>(config: SerializedCreateErrorConfig<Schema, ErrorConfigWithProperties<Schema, DataConfig, MessageCallback, Properties>, Json>): ErrorFamilyFactory<Schema, typeof config>;
50
+ /**
51
+ * Creates an error family with typed JSON serialization and no additional
52
+ * instance properties.
53
+ *
54
+ * @param config Defines the family and its serialized representation.
55
+ * @returns A callable factory with a shared `.Error` base class.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const createLogError = createError({
60
+ * definition: z.object({ code: z.string() }),
61
+ * data: {
62
+ * property: 'details',
63
+ * resolve: ({ input }) => input,
64
+ * },
65
+ * message: ({ data, implementation }) => implementation(data),
66
+ * toJSON: (error) => ({
67
+ * details: error.details,
68
+ * message: error.message,
69
+ * }),
70
+ * });
71
+ * ```
72
+ */
73
+ declare function createError<const Schema extends StandardSchemaV1, const DataConfig extends CreateErrorConfig<Schema>['data'], const MessageCallback extends CreateErrorConfig<Schema>['message'], Json>(config: SerializedCreateErrorConfig<Schema, ErrorConfigWithoutProperties<Schema, DataConfig, MessageCallback>, Json>): ErrorFamilyFactory<Schema, typeof config>;
74
+ /**
75
+ * Creates a configurable family of strongly typed error classes.
76
+ *
77
+ * Callback execution order is `data.resolve`, optional context validation,
78
+ * `message`, then `properties`. Parsed definition output and constructor data
79
+ * are inferred without explicit generic arguments or `as const`.
80
+ *
81
+ * @param config Defines the family's schema, data lifecycle, message, and
82
+ * optional public properties.
83
+ * @returns A callable factory with a shared `.Error` base class.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * const createRequestError = createError({
88
+ * definition: z.object({ code: z.string() }),
89
+ * data: {
90
+ * property: 'context',
91
+ * resolve: ({ input }) => input,
92
+ * },
93
+ * message: ({ data, implementation }) => implementation(data),
94
+ * properties: ({ definition }) => ({ code: definition.code }),
95
+ * });
96
+ * ```
97
+ */
98
+ declare function createError<const Schema extends StandardSchemaV1, const Config extends Omit<CreateErrorConfig<Schema>, 'definition'>>(config: ExactCreateErrorConfig<Schema, Config>): ErrorFamilyFactory<Schema, typeof config>;
99
+ //#endregion
100
+ export { createError };
101
+ //# sourceMappingURL=create-error.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-error.d.mts","names":[],"sources":["../src/create-error.ts"],"sourcesContent":[],"mappings":";;;;KAWK,+BACY,qCACI,kBAAkB,yCACb,kBAAkB;QAEpC;EALH,OAAA,EAMM,eANS;CACH;KAQZ,yBAPkC,CAAA,eAQtB,gBARsB,EAAA,mBASlB,iBATkB,CASA,MATA,CAAA,CAAA,MAAA,CAAA,EAAA,wBAUb,iBAVa,CAUK,MAVL,CAAA,CAAA,SAAA,CAAA,EAAA,mBAAA,MAAA,CAAA,GAYnC,eAZmC,CAYnB,MAZmB,EAYX,UAZW,EAYC,eAZD,CAAA,GAAA;EAAlB,UAAA,CAAA,OAAA,EAaC,gBAbD,CAakB,MAblB,CAAA,CAAA,EAa4B,UAb5B;CACuB;KAevC,4BAfqB,CAAA,eAgBT,gBAhBS,EAAA,mBAiBL,iBAjBK,CAiBa,MAjBb,CAAA,CAAA,MAAA,CAAA,EAAA,wBAkBA,iBAlBA,CAkBkB,MAlBlB,CAAA,CAAA,SAAA,CAAA,CAAA,GAmBtB,eAnBsB,CAmBN,MAnBM,EAmBE,UAnBF,EAmBc,eAnBd,CAAA,GAAA;EAElB,UAAA,CAAA,EAAA,KAAA;CACG;KAoBN,sBApBqB,CAAA,eAqBT,gBArBS,EAAA,eAAA,MAAA,CAAA,GAAA;EAGrB,UAAA,EAqBS,MArBT;CACY,GAqBb,MArBa,GAAA,CAsBd,gBAAA,CAAiB,WAtBH,CAsBe,MAtBf,CAAA,SAAA,MAAA,GAAA,OAAA,GAAA;EACsB,UAAA,EAAA,KAAA;CAAlB,CAAA;KAyBhB,2BAxBuC,CAAA,eAyB3B,gBAzB2B,EAAA,eAAA,MAAA,EAAA,IAAA,CAAA,GA4BxC,sBA5BwC,CA6B1C,MA7B0C,EA8B1C,MA9B0C,GAAA;EAAlB,MAAA,CAAA,KAAA,EA+BR,sBA/BQ,CA+Be,OA/Bf,CA+BuB,MA/BvB,CAAA,CAAA,CAAA,EA+BkC,IA/BlC;CAEN,CAAA;;;;;;;;AACuC;;;;;;;;;;;AAOxC;;;;;;;AAUY;AAKd,iBAqLD,WArLC,CAAA,qBAsLM,gBAtLN,EAAA,yBAuLU,iBAvLV,CAuL4B,MAvL5B,CAAA,CAAA,MAAA,CAAA,EAAA,8BAwLe,iBAxLf,CAwLiC,MAxLjC,CAAA,CAAA,SAAA,CAAA,EAAA,yBAAA,MAAA,EAAA,IAAA,CAAA,CAAA,MAAA,EA4LP,2BA5LO,CA6Lb,MA7La,EA8Lb,yBA9La,CA+LX,MA/LW,EAgMX,UAhMW,EAiMX,eAjMW,EAkMX,UAlMW,CAAA,EAoMb,IApMa,CAAA,CAAA,EAsMd,kBAtMc,CAsMK,MAtML,EAAA,OAsMoB,MAtMpB,CAAA;;;;;;;;;AAqLjB;;;;;;;;;;;;;;;AAiBqC,iBAyBrB,WAzBqB,CAAA,qBA0Bd,gBA1Bc,EAAA,yBA2BV,iBA3BU,CA2BQ,MA3BR,CAAA,CAAA,MAAA,CAAA,EAAA,8BA4BL,iBA5BK,CA4Ba,MA5Bb,CAAA,CAAA,SAAA,CAAA,EAAA,IAAA,CAAA,CAAA,MAAA,EA+B3B,2BA/B2B,CAgCjC,MAhCiC,EAiCjC,4BAjCiC,CAiCJ,MAjCI,EAiCI,UAjCJ,EAiCgB,eAjChB,CAAA,EAkCjC,IAlCiC,CAAA,CAAA,EAoClC,kBApCkC,CAoCf,MApCe,EAAA,OAoCA,MApCA,CAAA;;;AAyBrC;;;;;;;;;;;;;;;;;AAqCA;;;;;AAIiC,iBAJjB,WAIiB,CAAA,qBAHV,gBAGU,EAAA,qBAFV,IAEU,CAFL,iBAEK,CAFa,MAEb,CAAA,EAAA,YAAA,CAAA,CAAA,CAAA,MAAA,EAAvB,sBAAuB,CAAA,MAAA,EAAQ,MAAR,CAAA,CAAA,EAC9B,kBAD8B,CACX,MADW,EAAA,OACI,MADJ,CAAA"}
@@ -0,0 +1,134 @@
1
+ //#region src/create-error.ts
2
+ const protectedPropertyNames = new Set([
3
+ "name",
4
+ "message",
5
+ "stack",
6
+ "cause",
7
+ "constructor",
8
+ "prototype"
9
+ ]);
10
+ function isObjectLike(value) {
11
+ return value !== null && (typeof value === "object" || typeof value === "function");
12
+ }
13
+ function isPlainObject(value) {
14
+ if (!isObjectLike(value)) return false;
15
+ const prototype = Object.getPrototypeOf(value);
16
+ return prototype === Object.prototype || prototype === null;
17
+ }
18
+ function includeDefinition(argument, definition) {
19
+ if (!isPlainObject(argument)) return argument;
20
+ return {
21
+ ...definition,
22
+ ...argument
23
+ };
24
+ }
25
+ function validateStandardSchema(schema, subject) {
26
+ if (!isObjectLike(schema)) throw new TypeError(`${subject} must be a Standard Schema object`);
27
+ const standard = Reflect.get(schema, "~standard");
28
+ if (!isObjectLike(standard) || Reflect.get(standard, "version") !== 1 || typeof Reflect.get(standard, "vendor") !== "string" || typeof Reflect.get(standard, "validate") !== "function") throw new TypeError(`${subject} must implement Standard Schema V1`);
29
+ }
30
+ function validateBlueprint(config) {
31
+ validateStandardSchema(config.definition, "definition");
32
+ if (typeof config.data.property !== "string" || config.data.property.length === 0) throw new TypeError("data.property must be a non-empty string");
33
+ if (protectedPropertyNames.has(config.data.property)) throw new TypeError(`data.property cannot overwrite protected property "${config.data.property}"`);
34
+ }
35
+ function formatIssuePath(path) {
36
+ if (!path?.length) return "";
37
+ return `${path.map((segment) => typeof segment === "object" ? segment.key : segment).map(String).join(".")}: `;
38
+ }
39
+ function parseSchema(schema, input, subject) {
40
+ const result = schema["~standard"].validate(input);
41
+ if (result instanceof Promise) throw new TypeError(`${subject} schema validation must be synchronous`);
42
+ if (result.issues) {
43
+ const details = result.issues.map((issue) => `${formatIssuePath(issue.path)}${issue.message}`).join("; ");
44
+ throw new TypeError(`Invalid error ${subject}: ${details}`);
45
+ }
46
+ return result.value;
47
+ }
48
+ function parseDefinition(schema, definition) {
49
+ const parsedDefinition = parseSchema(schema, definition, "definition");
50
+ if (!isObjectLike(parsedDefinition)) throw new TypeError("definition schema must produce an object");
51
+ return parsedDefinition;
52
+ }
53
+ function assignProperties(error, properties, dataProperty, data) {
54
+ for (const key of Reflect.ownKeys(properties)) {
55
+ if (typeof key === "string" && protectedPropertyNames.has(key)) throw new TypeError(`Cannot overwrite protected error property "${key}"`);
56
+ const descriptor = Object.getOwnPropertyDescriptor(properties, key);
57
+ if (!descriptor) continue;
58
+ if (key === dataProperty && (!("value" in descriptor) || descriptor.value !== data)) throw new TypeError(`Cannot overwrite resolved data property "${dataProperty}"`);
59
+ Object.defineProperty(error, key, descriptor);
60
+ }
61
+ }
62
+ function createError(config) {
63
+ validateBlueprint(config);
64
+ class FamilyError extends Error {
65
+ static invariant(condition, input, options) {
66
+ if (condition) return;
67
+ const resolvedInput = typeof input === "function" ? input() : input;
68
+ throw new this(resolvedInput, options);
69
+ }
70
+ constructor(message, options) {
71
+ super(message, options);
72
+ const name = new.target.name;
73
+ if (name) this.name = name;
74
+ }
75
+ }
76
+ if (config.toJSON) Object.defineProperty(FamilyError.prototype, "toJSON", {
77
+ configurable: true,
78
+ value: function toJSON() {
79
+ return config.toJSON?.(this);
80
+ },
81
+ writable: true
82
+ });
83
+ function createDefinition(definition) {
84
+ const parsedDefinition = parseDefinition(config.definition, definition);
85
+ function createImplementation(implementation, contextSchema) {
86
+ return class extends FamilyError {
87
+ constructor(input, options) {
88
+ const resolvedData = config.data.resolve({
89
+ definition: parsedDefinition,
90
+ input
91
+ });
92
+ const data = contextSchema ? parseSchema(contextSchema, resolvedData, "context") : resolvedData;
93
+ const implementationWithDefinition = (argument) => implementation(argument === data ? argument : includeDefinition(argument, parsedDefinition));
94
+ const message = config.message({
95
+ data,
96
+ definition: parsedDefinition,
97
+ implementation: implementationWithDefinition
98
+ });
99
+ super(message, options);
100
+ Object.defineProperty(this, config.data.property, {
101
+ configurable: true,
102
+ enumerable: true,
103
+ value: data,
104
+ writable: true
105
+ });
106
+ const properties = config.properties?.({
107
+ data,
108
+ definition: parsedDefinition,
109
+ implementation: implementationWithDefinition
110
+ });
111
+ if (properties) assignProperties(this, properties, config.data.property, data);
112
+ }
113
+ };
114
+ }
115
+ function implement(implementation) {
116
+ return createImplementation(implementation);
117
+ }
118
+ function defineContext(contextSchema) {
119
+ validateStandardSchema(contextSchema, "context");
120
+ return { implement(implementation) {
121
+ return createImplementation(implementation, contextSchema);
122
+ } };
123
+ }
124
+ return {
125
+ defineContext,
126
+ implement
127
+ };
128
+ }
129
+ return Object.assign(createDefinition, { Error: FamilyError });
130
+ }
131
+
132
+ //#endregion
133
+ export { createError };
134
+ //# sourceMappingURL=create-error.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-error.mjs","names":["implementationWithDefinition: RuntimeImplementation"],"sources":["../src/create-error.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec';\r\n\r\nimport type {\r\n BlueprintContext,\r\n BlueprintErrorTemplate,\r\n CreateErrorConfig,\r\n ErrorFamilyFactory,\r\n} from './types.js';\r\n\r\ntype RuntimeImplementation = (argument: unknown) => string;\r\n\r\ntype ErrorConfigBody<\r\n Schema extends StandardSchemaV1,\r\n DataConfig extends CreateErrorConfig<Schema>['data'],\r\n MessageCallback extends CreateErrorConfig<Schema>['message'],\r\n> = {\r\n data: DataConfig;\r\n message: MessageCallback;\r\n};\r\n\r\ntype ErrorConfigWithProperties<\r\n Schema extends StandardSchemaV1,\r\n DataConfig extends CreateErrorConfig<Schema>['data'],\r\n MessageCallback extends CreateErrorConfig<Schema>['message'],\r\n Properties extends object,\r\n> = ErrorConfigBody<Schema, DataConfig, MessageCallback> & {\r\n properties(context: BlueprintContext<Schema>): Properties;\r\n};\r\n\r\ntype ErrorConfigWithoutProperties<\r\n Schema extends StandardSchemaV1,\r\n DataConfig extends CreateErrorConfig<Schema>['data'],\r\n MessageCallback extends CreateErrorConfig<Schema>['message'],\r\n> = ErrorConfigBody<Schema, DataConfig, MessageCallback> & {\r\n properties?: never;\r\n};\r\n\r\ntype ExactCreateErrorConfig<\r\n Schema extends StandardSchemaV1,\r\n Config extends object,\r\n> = {\r\n definition: Schema;\r\n} & Config &\r\n (StandardSchemaV1.InferOutput<Schema> extends object\r\n ? unknown\r\n : { definition: never });\r\n\r\ntype SerializedCreateErrorConfig<\r\n Schema extends StandardSchemaV1,\r\n Config extends object,\r\n Json,\r\n> = ExactCreateErrorConfig<\r\n Schema,\r\n Config & {\r\n toJSON(error: BlueprintErrorTemplate<NoInfer<Config>>): Json;\r\n }\r\n>;\r\n\r\nconst protectedPropertyNames = new Set([\r\n 'name',\r\n 'message',\r\n 'stack',\r\n 'cause',\r\n 'constructor',\r\n 'prototype',\r\n]);\r\n\r\nfunction isObjectLike(value: unknown): value is object {\r\n return (\r\n value !== null && (typeof value === 'object' || typeof value === 'function')\r\n );\r\n}\r\n\r\nfunction isPlainObject(value: unknown): value is Record<PropertyKey, unknown> {\r\n if (!isObjectLike(value)) {\r\n return false;\r\n }\r\n\r\n const prototype = Object.getPrototypeOf(value);\r\n\r\n return prototype === Object.prototype || prototype === null;\r\n}\r\n\r\nfunction includeDefinition(\r\n argument: unknown,\r\n definition: object,\r\n): unknown {\r\n if (!isPlainObject(argument)) {\r\n return argument;\r\n }\r\n\r\n return { ...definition, ...argument };\r\n}\r\n\r\nfunction validateStandardSchema(schema: unknown, subject: string) {\r\n if (!isObjectLike(schema)) {\r\n throw new TypeError(`${subject} must be a Standard Schema object`);\r\n }\r\n\r\n const standard = Reflect.get(schema, '~standard') as unknown;\r\n\r\n if (\r\n !isObjectLike(standard) ||\r\n Reflect.get(standard, 'version') !== 1 ||\r\n typeof Reflect.get(standard, 'vendor') !== 'string' ||\r\n typeof Reflect.get(standard, 'validate') !== 'function'\r\n ) {\r\n throw new TypeError(`${subject} must implement Standard Schema V1`);\r\n }\r\n}\r\n\r\nfunction validateBlueprint(config: CreateErrorConfig<StandardSchemaV1>) {\r\n validateStandardSchema(config.definition, 'definition');\r\n\r\n if (\r\n typeof config.data.property !== 'string' ||\r\n config.data.property.length === 0\r\n ) {\r\n throw new TypeError('data.property must be a non-empty string');\r\n }\r\n\r\n if (protectedPropertyNames.has(config.data.property)) {\r\n throw new TypeError(\r\n `data.property cannot overwrite protected property \"${config.data.property}\"`,\r\n );\r\n }\r\n}\r\n\r\nfunction formatIssuePath(path: StandardSchemaV1.Issue['path']) {\r\n if (!path?.length) {\r\n return '';\r\n }\r\n\r\n const keys = path.map((segment) =>\r\n typeof segment === 'object' ? segment.key : segment,\r\n );\r\n\r\n return `${keys.map(String).join('.')}: `;\r\n}\r\n\r\nfunction parseSchema<Schema extends StandardSchemaV1>(\r\n schema: Schema,\r\n input: StandardSchemaV1.InferInput<Schema>,\r\n subject: string,\r\n) {\r\n const result = schema['~standard'].validate(input);\r\n\r\n if (result instanceof Promise) {\r\n throw new TypeError(`${subject} schema validation must be synchronous`);\r\n }\r\n\r\n if (result.issues) {\r\n const details = result.issues\r\n .map((issue) => `${formatIssuePath(issue.path)}${issue.message}`)\r\n .join('; ');\r\n\r\n throw new TypeError(`Invalid error ${subject}: ${details}`);\r\n }\r\n\r\n return result.value;\r\n}\r\n\r\nfunction parseDefinition<Schema extends StandardSchemaV1>(\r\n schema: Schema,\r\n definition: StandardSchemaV1.InferInput<Schema>,\r\n) {\r\n const parsedDefinition = parseSchema(schema, definition, 'definition');\r\n\r\n if (!isObjectLike(parsedDefinition)) {\r\n throw new TypeError('definition schema must produce an object');\r\n }\r\n\r\n return parsedDefinition;\r\n}\r\n\r\nfunction assignProperties(\r\n error: Error & Record<string, unknown>,\r\n properties: object,\r\n dataProperty: string,\r\n data: unknown,\r\n) {\r\n for (const key of Reflect.ownKeys(properties)) {\r\n if (typeof key === 'string' && protectedPropertyNames.has(key)) {\r\n throw new TypeError(`Cannot overwrite protected error property \"${key}\"`);\r\n }\r\n\r\n const descriptor = Object.getOwnPropertyDescriptor(properties, key);\r\n\r\n if (!descriptor) {\r\n continue;\r\n }\r\n\r\n if (\r\n key === dataProperty &&\r\n (!('value' in descriptor) || descriptor.value !== data)\r\n ) {\r\n throw new TypeError(`Cannot overwrite resolved data property \"${dataProperty}\"`);\r\n }\r\n\r\n Object.defineProperty(error, key, descriptor);\r\n }\r\n}\r\n\r\n/**\r\n * Creates an error family with additional instance properties and typed JSON\r\n * serialization.\r\n *\r\n * @param config Defines the family, its public properties, and its serialized\r\n * representation.\r\n * @returns A callable factory with a shared `.Error` base class.\r\n *\r\n * @example\r\n * ```ts\r\n * const createApiError = createError({\r\n * definition: z.object({ code: z.string() }),\r\n * data: {\r\n * property: 'context',\r\n * resolve: ({ input }) => input,\r\n * },\r\n * message: ({ data, implementation }) => implementation(data),\r\n * properties: ({ definition }) => ({ code: definition.code }),\r\n * toJSON: (error) => ({\r\n * code: error.code,\r\n * context: error.context,\r\n * message: error.message,\r\n * }),\r\n * });\r\n * ```\r\n */\r\nexport function createError<\r\n const Schema extends StandardSchemaV1,\r\n const DataConfig extends CreateErrorConfig<Schema>['data'],\r\n const MessageCallback extends CreateErrorConfig<Schema>['message'],\r\n const Properties extends object,\r\n Json,\r\n>(\r\n config: SerializedCreateErrorConfig<\r\n Schema,\r\n ErrorConfigWithProperties<\r\n Schema,\r\n DataConfig,\r\n MessageCallback,\r\n Properties\r\n >,\r\n Json\r\n >,\r\n): ErrorFamilyFactory<Schema, typeof config>;\r\n\r\n/**\r\n * Creates an error family with typed JSON serialization and no additional\r\n * instance properties.\r\n *\r\n * @param config Defines the family and its serialized representation.\r\n * @returns A callable factory with a shared `.Error` base class.\r\n *\r\n * @example\r\n * ```ts\r\n * const createLogError = createError({\r\n * definition: z.object({ code: z.string() }),\r\n * data: {\r\n * property: 'details',\r\n * resolve: ({ input }) => input,\r\n * },\r\n * message: ({ data, implementation }) => implementation(data),\r\n * toJSON: (error) => ({\r\n * details: error.details,\r\n * message: error.message,\r\n * }),\r\n * });\r\n * ```\r\n */\r\nexport function createError<\r\n const Schema extends StandardSchemaV1,\r\n const DataConfig extends CreateErrorConfig<Schema>['data'],\r\n const MessageCallback extends CreateErrorConfig<Schema>['message'],\r\n Json,\r\n>(\r\n config: SerializedCreateErrorConfig<\r\n Schema,\r\n ErrorConfigWithoutProperties<Schema, DataConfig, MessageCallback>,\r\n Json\r\n >,\r\n): ErrorFamilyFactory<Schema, typeof config>;\r\n\r\n/**\r\n * Creates a configurable family of strongly typed error classes.\r\n *\r\n * Callback execution order is `data.resolve`, optional context validation,\r\n * `message`, then `properties`. Parsed definition output and constructor data\r\n * are inferred without explicit generic arguments or `as const`.\r\n *\r\n * @param config Defines the family's schema, data lifecycle, message, and\r\n * optional public properties.\r\n * @returns A callable factory with a shared `.Error` base class.\r\n *\r\n * @example\r\n * ```ts\r\n * const createRequestError = createError({\r\n * definition: z.object({ code: z.string() }),\r\n * data: {\r\n * property: 'context',\r\n * resolve: ({ input }) => input,\r\n * },\r\n * message: ({ data, implementation }) => implementation(data),\r\n * properties: ({ definition }) => ({ code: definition.code }),\r\n * });\r\n * ```\r\n */\r\nexport function createError<\r\n const Schema extends StandardSchemaV1,\r\n const Config extends Omit<CreateErrorConfig<Schema>, 'definition'>,\r\n>(\r\n config: ExactCreateErrorConfig<Schema, Config>,\r\n): ErrorFamilyFactory<Schema, typeof config>;\r\nexport function createError<\r\n const Schema extends StandardSchemaV1,\r\n const Config extends Omit<CreateErrorConfig<Schema>, 'definition'>,\r\n>(\r\n config: ExactCreateErrorConfig<Schema, Config>,\r\n): ErrorFamilyFactory<Schema, typeof config> {\r\n validateBlueprint(config as CreateErrorConfig<StandardSchemaV1>);\r\n\r\n class FamilyError extends Error {\r\n static invariant<Condition, Input>(\r\n this: new (input: Input, options?: ErrorOptions) => Error,\r\n condition: Condition,\r\n input: Input | (() => Input),\r\n options?: ErrorOptions,\r\n ): asserts condition {\r\n if (condition) {\r\n return;\r\n }\r\n\r\n const resolvedInput =\r\n typeof input === 'function' ? (input as () => Input)() : input;\r\n\r\n throw new this(resolvedInput, options);\r\n }\r\n\r\n constructor(message: string, options?: ErrorOptions) {\r\n super(message, options);\r\n const name = new.target.name;\r\n if (name) {\r\n this.name = name;\r\n }\r\n }\r\n }\r\n\r\n if (config.toJSON) {\r\n Object.defineProperty(FamilyError.prototype, 'toJSON', {\r\n configurable: true,\r\n value: function toJSON(this: Error & Record<string, unknown>) {\r\n return config.toJSON?.(this as never);\r\n },\r\n writable: true,\r\n });\r\n }\r\n\r\n function createDefinition<\r\n const Definition extends StandardSchemaV1.InferInput<Schema>,\r\n >(definition: Definition) {\r\n const parsedDefinition = parseDefinition(config.definition, definition);\r\n\r\n function createImplementation(\r\n implementation: RuntimeImplementation,\r\n contextSchema?: StandardSchemaV1,\r\n ) {\r\n return class extends FamilyError {\r\n constructor(input: unknown, options?: ErrorOptions) {\r\n const resolvedData = config.data.resolve({\r\n definition: parsedDefinition,\r\n input,\r\n } as never);\r\n const data = contextSchema\r\n ? parseSchema(contextSchema, resolvedData, 'context')\r\n : resolvedData;\r\n const implementationWithDefinition: RuntimeImplementation = (\r\n argument,\r\n ) =>\r\n implementation(\r\n argument === data\r\n ? argument\r\n : includeDefinition(argument, parsedDefinition),\r\n );\r\n const message = config.message({\r\n data,\r\n definition: parsedDefinition,\r\n implementation: implementationWithDefinition,\r\n } as never);\r\n\r\n super(message, options);\r\n\r\n Object.defineProperty(this, config.data.property, {\r\n configurable: true,\r\n enumerable: true,\r\n value: data,\r\n writable: true,\r\n });\r\n\r\n const properties = config.properties?.({\r\n data,\r\n definition: parsedDefinition,\r\n implementation: implementationWithDefinition,\r\n } as never);\r\n\r\n if (properties) {\r\n assignProperties(\r\n this as Error & Record<string, unknown>,\r\n properties,\r\n config.data.property,\r\n data,\r\n );\r\n }\r\n }\r\n };\r\n }\r\n\r\n function implement(implementation: RuntimeImplementation) {\r\n return createImplementation(implementation);\r\n }\r\n\r\n function defineContext<ContextSchema extends StandardSchemaV1>(\r\n contextSchema: ContextSchema,\r\n ) {\r\n validateStandardSchema(contextSchema, 'context');\r\n\r\n return {\r\n implement(implementation: RuntimeImplementation) {\r\n return createImplementation(implementation, contextSchema);\r\n },\r\n };\r\n }\r\n\r\n return {\r\n defineContext,\r\n implement,\r\n };\r\n }\r\n\r\n return Object.assign(createDefinition, {\r\n Error: FamilyError,\r\n }) as unknown as ErrorFamilyFactory<Schema, typeof config>;\r\n}\r\n"],"mappings":"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"}
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ const require_create_error = require('./create-error.cjs');
2
+
3
+ exports.createError = require_create_error.createError;
@@ -0,0 +1,3 @@
1
+ import { CreateErrorConfig } from "./types.cjs";
2
+ import { createError } from "./create-error.cjs";
3
+ export { type CreateErrorConfig, createError };
@@ -0,0 +1,3 @@
1
+ import { CreateErrorConfig } from "./types.mjs";
2
+ import { createError } from "./create-error.mjs";
3
+ export { type CreateErrorConfig, createError };
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import { createError } from "./create-error.mjs";
2
+
3
+ export { createError };
@@ -0,0 +1,291 @@
1
+ import { StandardSchemaV1 } from "@standard-schema/spec";
2
+
3
+ //#region src/types.d.ts
4
+ declare const typeSlot: unique symbol;
5
+ /** Marks a blueprint value that is resolved by a later builder stage. */
6
+ type TypeSlot<Kind extends string, Payload = never> = {
7
+ readonly [typeSlot]: {
8
+ readonly kind: Kind;
9
+ readonly payload: Payload;
10
+ };
11
+ };
12
+ type DefinitionInput<Schema extends StandardSchemaV1> = StandardSchemaV1.InferInput<Schema>;
13
+ type DefinitionOutput<Schema extends StandardSchemaV1> = StandardSchemaV1.InferOutput<Schema>;
14
+ type ExactDefinition<Input, Definition> = Input extends object ? Definition & Record<Exclude<keyof Definition, keyof Input>, never> : Definition;
15
+ type DefinitionTemplate<Schema extends StandardSchemaV1> = DefinitionOutput<Schema> extends object ? { readonly [Key in keyof DefinitionOutput<Schema>]: DefinitionOutput<Schema>[Key] & TypeSlot<'definition', Key> } : never;
16
+ type ConcreteDefinition<Schema extends StandardSchemaV1> = DefinitionOutput<Schema> extends object ? { readonly [Key in keyof DefinitionOutput<Schema>]: DefinitionOutput<Schema>[Key] } : never;
17
+ type DataSlot = TypeSlot<'data'>;
18
+ type ImplementationSlot = TypeSlot<'implementation'> & {
19
+ <const Argument$1>(argument: Argument$1): string & TypeSlot<'implementationArgument', Argument$1>;
20
+ };
21
+ /** Values available while an error instance is being created. */
22
+ interface BlueprintContext<Schema extends StandardSchemaV1> {
23
+ /** The parsed definition captured by the concrete error class. */
24
+ definition: DefinitionTemplate<Schema>;
25
+ /** The resolved, and optionally schema-validated, constructor data. */
26
+ data: DataSlot;
27
+ /**
28
+ * Calls the concrete error's implementation with one argument.
29
+ *
30
+ * The argument passed here defines the implementation callback's parameter
31
+ * type. Concrete definition fields are included automatically when the
32
+ * argument is a plain object.
33
+ */
34
+ implementation: ImplementationSlot;
35
+ }
36
+ /** Values available when resolving a concrete error's constructor input. */
37
+ interface ResolveContext<Schema extends StandardSchemaV1> {
38
+ /** The parsed definition captured by the concrete error class. */
39
+ definition: DefinitionTemplate<Schema>;
40
+ /** The value passed to the concrete error constructor. */
41
+ input: object;
42
+ }
43
+ /**
44
+ * Configuration accepted by {@link createError}.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * const config = {
49
+ * definition,
50
+ * data: {
51
+ * property: 'context',
52
+ * resolve: ({ input }) => input,
53
+ * },
54
+ * message: ({ data, implementation }) => implementation(data),
55
+ * } satisfies CreateErrorConfig<typeof definition>;
56
+ * ```
57
+ */
58
+ interface CreateErrorConfig<Schema extends StandardSchemaV1> {
59
+ /**
60
+ * A Standard Schema object that parses every concrete error definition.
61
+ * Validation must be synchronous because class creation is synchronous.
62
+ */
63
+ definition: Schema;
64
+ /**
65
+ * Controls how constructor input becomes the error's stored data.
66
+ *
67
+ * Use `resolve` to normalize input or combine it with the concrete
68
+ * definition. The resulting value is validated by `defineContext`, when
69
+ * present, and then stored under `property` on every error instance.
70
+ *
71
+ * @example Preserve input while adding a definition value
72
+ * ```ts
73
+ * data: {
74
+ * property: 'context',
75
+ * resolve: ({ definition, input }) => ({
76
+ * ...input,
77
+ * scope: definition.scope,
78
+ * }),
79
+ * }
80
+ * ```
81
+ */
82
+ data: {
83
+ /**
84
+ * The public instance property that receives the final resolved data.
85
+ *
86
+ * For example, `property: 'context'` makes `error.context` available.
87
+ */
88
+ property: string;
89
+ /**
90
+ * Converts constructor input into the value used by the error blueprint.
91
+ *
92
+ * This callback runs first. It can return the input unchanged, normalize
93
+ * it, or add values from the concrete definition. Its result becomes the
94
+ * input to the optional context schema.
95
+ */
96
+ resolve(context: ResolveContext<Schema>): unknown;
97
+ };
98
+ /**
99
+ * Creates the native `Error.message` after data resolution and validation.
100
+ */
101
+ message(context: BlueprintContext<Schema>): string;
102
+ /**
103
+ * Creates additional public fields and methods for each error instance.
104
+ *
105
+ * Use this to expose definition values such as `code`, derive fields from
106
+ * resolved data, or attach convenience methods. It does not transform or
107
+ * validate constructor input; use `data.resolve` and `defineContext` for
108
+ * that.
109
+ *
110
+ * @example Expose definition and resolved-data values
111
+ * ```ts
112
+ * properties: ({ definition, data }) => ({
113
+ * code: definition.code,
114
+ * context: data,
115
+ * describe: () => `${definition.code}: ${data.field}`,
116
+ * })
117
+ * ```
118
+ */
119
+ properties?(context: BlueprintContext<Schema>): object;
120
+ /**
121
+ * Serializes every error in the family when `toJSON()` or `JSON.stringify`
122
+ * is called.
123
+ *
124
+ * The callback receives the fully constructed error, including the data
125
+ * property and any fields or methods returned by `properties`.
126
+ *
127
+ * @example Return an API-safe error representation
128
+ * ```ts
129
+ * toJSON: (error) => ({
130
+ * name: error.name,
131
+ * code: error.code,
132
+ * message: error.message,
133
+ * context: error.context,
134
+ * })
135
+ * ```
136
+ */
137
+ toJSON?(error: Error & Record<string, unknown>): unknown;
138
+ }
139
+ type ResolveTemplate<Config> = Config extends {
140
+ data: {
141
+ resolve: (...arguments_: infer _Arguments) => infer Resolved;
142
+ };
143
+ } ? Resolved : never;
144
+ type InjectedDefinitionKeys<Template> = { [Key in keyof Template]: Template[Key] extends TypeSlot<'definition', PropertyKey> ? Key : never }[keyof Template];
145
+ type ConstructorInput<Config, Data> = Data extends readonly unknown[] ? Data : Data extends object ? Omit<Data, Extract<InjectedDefinitionKeys<ResolveTemplate<Config>>, keyof Data>> : Data;
146
+ type ReplaceTuple<Values extends readonly unknown[], Definition, Data, Implementation> = { [Index in keyof Values]: ReplaceTemplate<Values[Index], Definition, Data, Implementation> };
147
+ type ReplaceTemplate<Type, Definition, Data, Implementation> = Type extends TypeSlot<'definition', infer Key> ? Key extends keyof Definition ? Definition[Key] : never : Type extends TypeSlot<'data'> ? Data : Type extends TypeSlot<'implementation'> ? Implementation : Type extends ((...arguments_: infer Arguments) => infer Result) ? (...arguments_: ReplaceTuple<Arguments, Definition, Data, Implementation>) => ReplaceTemplate<Result, Definition, Data, Implementation> : Type extends readonly unknown[] ? ReplaceTuple<Type, Definition, Data, Implementation> : Type extends object ? { [Key in keyof Type]: ReplaceTemplate<Type[Key], Definition, Data, Implementation> } : Type;
148
+ type PropertiesTemplate<Config> = Config extends {
149
+ properties: (...arguments_: infer _Arguments) => infer Properties;
150
+ } ? Properties : object;
151
+ type DataPropertyTemplate<Config> = Config extends {
152
+ data: {
153
+ property: infer Property extends string;
154
+ };
155
+ } ? { [Key in Property]: DataSlot } : object;
156
+ /**
157
+ * The error shape visible to a blueprint's `toJSON` callback.
158
+ *
159
+ * It contains native `Error` fields, the configured data property, and every
160
+ * member returned by `properties`.
161
+ */
162
+ type BlueprintErrorTemplate<Config> = Error & DataPropertyTemplate<Config> & PropertiesTemplate<Config>;
163
+ type InstanceProperties<Config, Definition, Data, Implementation> = ReplaceTemplate<PropertiesTemplate<Config>, Definition, Data, Implementation> & ReplaceTemplate<DataPropertyTemplate<Config>, Definition, Data, Implementation> & Error & (Config extends {
164
+ toJSON: (...arguments_: infer _Arguments) => infer Json;
165
+ } ? {
166
+ toJSON(): ReplaceTemplate<Json, Definition, Data, Implementation>;
167
+ } : object);
168
+ type MessageTemplate<Config> = Config extends {
169
+ message: (...arguments_: infer _Arguments) => infer Message;
170
+ } ? Message : string;
171
+ type ImplementationArgumentWithDefinition<Argument$1, Definition, Data> = Argument$1 extends TypeSlot<'data'> ? Data : ReplaceTemplate<Argument$1, Definition, Data, never> extends infer Resolved ? Argument$1 extends TypeSlot<string, unknown> ? Resolved : Resolved extends readonly unknown[] ? Resolved : Resolved extends ((...arguments_: infer _Arguments) => unknown) ? Resolved : Resolved extends object ? Omit<Definition, keyof Resolved> & Resolved : Resolved : never;
172
+ type ImplementationArgument<Config, Definition, Data> = MessageTemplate<Config> extends TypeSlot<'implementationArgument', infer Argument> ? ImplementationArgumentWithDefinition<Argument, Definition, Data> : never;
173
+ type ImplementationCallback<Config, Definition, Data> = (argument: ImplementationArgument<Config, Definition, Data>) => string;
174
+ type PassedImplementationArgument<Config, Definition, Data> = MessageTemplate<Config> extends TypeSlot<'implementationArgument', infer Argument> ? Argument extends TypeSlot<'data'> ? Data : ReplaceTemplate<Argument, Definition, Data, never> : never;
175
+ type PassedImplementationCallback<Config, Definition, Data> = (argument: PassedImplementationArgument<Config, Definition, Data>) => string;
176
+ interface ErrorClassStatics {
177
+ /**
178
+ * Throws this error class when `condition` is falsy.
179
+ *
180
+ * A function can be supplied as `input` to avoid constructing error data
181
+ * unless the invariant fails. TypeScript narrows `condition` after a
182
+ * successful call.
183
+ *
184
+ * @example
185
+ * ```ts
186
+ * MissingUserError.invariant(
187
+ * user,
188
+ * () => ({ userId }),
189
+ * { cause },
190
+ * );
191
+ *
192
+ * user.id; // narrowed to the truthy branch
193
+ * ```
194
+ */
195
+ invariant<Condition, Input>(this: new (input: Input, options?: ErrorOptions) => Error, condition: Condition, input: Input | (() => Input), options?: ErrorOptions): asserts condition;
196
+ }
197
+ /**
198
+ * The shared native `Error` base created for one blueprint.
199
+ *
200
+ * Use `factory.Error` for family-wide `instanceof` checks or as a public base
201
+ * type for errors created by the same blueprint.
202
+ */
203
+ type FamilyErrorClass = (abstract new (...arguments_: never[]) => Error) & ErrorClassStatics;
204
+ /** An extendable concrete error class produced by a configured factory. */
205
+ interface ConcreteErrorClass<Input, Instance> extends ErrorClassStatics {
206
+ /**
207
+ * Creates an error from family-specific input.
208
+ *
209
+ * Pass native `ErrorOptions` as the second argument to preserve a `cause`.
210
+ */
211
+ new (input: Input, options?: ErrorOptions): Instance;
212
+ }
213
+ type ImplementedErrorClass<Config, Definition, Input, Data> = ConcreteErrorClass<ConstructorInput<Config, Input>, InstanceProperties<Config, Definition, Data, PassedImplementationCallback<Config, Definition, Data>>>;
214
+ type ExtendsNever<Value, OnTrue, OnFalse> = [Value] extends [never] ? OnTrue : OnFalse;
215
+ type BuilderData<Data, InferredData> = ExtendsNever<Data, InferredData, Data>;
216
+ type DefaultBuilderData<Data> = ExtendsNever<Data, unknown, Data>;
217
+ type BuilderInput<Input, Data> = ExtendsNever<Input, Data, Input>;
218
+ type Expand<Type> = Type extends ((...arguments_: infer Arguments) => infer Result) ? (...arguments_: Arguments) => Result : Type;
219
+ /** Captures the final behavior for one concrete error class. */
220
+ interface ImplementationBuilder<Config, Definition, Input = never, Data = never> {
221
+ /**
222
+ * Creates an extendable error class from a message implementation.
223
+ *
224
+ * The callback receives the single argument chosen by the blueprint's call
225
+ * to `implementation(argument)`. When that argument is a plain object, the
226
+ * concrete definition's fields are also available on it.
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * const MissingUserError = createRequestError({
231
+ * code: 'missingUser',
232
+ * }).implement(
233
+ * ({ code, context }) => `${code}: ${context.userId} was not found`,
234
+ * );
235
+ * ```
236
+ */
237
+ implement<InferredData = DefaultBuilderData<Data>>(implementation: Expand<ImplementationCallback<Config, Definition, BuilderData<Data, InferredData>>>): ImplementedErrorClass<Config, Definition, BuilderInput<Input, BuilderData<Data, InferredData>>, BuilderData<Data, InferredData>>;
238
+ }
239
+ /** Configures one concrete error definition before creating its class. */
240
+ interface ErrorDefinitionBuilder<Config, Definition> extends ImplementationBuilder<Config, Definition> {
241
+ /**
242
+ * Validates and optionally transforms resolved data with a Standard Schema.
243
+ *
244
+ * The schema's input becomes the concrete class's constructor input and its
245
+ * output becomes the stored data and implementation value. Validation must
246
+ * be synchronous. After selecting a schema, only `implement` is available.
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * const MissingUserError = createRequestError({ code: 'missingUser' })
251
+ * .defineContext(z.object({ userId: z.string() }))
252
+ * .implement(({ userId }) => `User ${userId} was not found`);
253
+ *
254
+ * new MissingUserError({ userId: 'user_123' });
255
+ * ```
256
+ */
257
+ defineContext<const ContextSchema extends StandardSchemaV1>(context: ContextSchema): ImplementationBuilder<Config, Definition, StandardSchemaV1.InferInput<ContextSchema>, StandardSchemaV1.InferOutput<ContextSchema>>;
258
+ }
259
+ /**
260
+ * A callable factory for creating related, strongly typed error classes.
261
+ *
262
+ * Call it with a concrete definition to receive a builder, or use `.Error` as
263
+ * the common base class for every error produced by this factory.
264
+ */
265
+ type ErrorFamilyFactory<Schema extends StandardSchemaV1, Config> = {
266
+ /**
267
+ * Parses and captures a concrete definition. Definition-derived fields use
268
+ * the schema's output type so transforms remain type-safe.
269
+ *
270
+ * @example
271
+ * ```ts
272
+ * const builder = createRequestError({
273
+ * code: 'missingUser',
274
+ * scope: 'request',
275
+ * });
276
+ * ```
277
+ */
278
+ <const Definition extends DefinitionInput<Schema>>(definition: ExactDefinition<DefinitionInput<Schema>, Definition>): ErrorDefinitionBuilder<Config, ConcreteDefinition<Schema>>;
279
+ /**
280
+ * The shared native `Error` base for every class created by this factory.
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * error instanceof createRequestError.Error;
285
+ * ```
286
+ */
287
+ Error: FamilyErrorClass;
288
+ };
289
+ //#endregion
290
+ export { BlueprintContext, BlueprintErrorTemplate, CreateErrorConfig, ErrorFamilyFactory };
291
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;cAEc;;AAFgD,KAKzD,QAHS,CAAA,aAAuB,MAAA,EAAA,UAAA,KAAA,CAAA,GAAA;EAGhC,UACO,QAAA,CADC,EAAA;IAEM,SAAA,IAAA,EAAA,IAAA;IACG,SAAA,OAAA,EAAA,OAAA;EAFV,CAAA;CAAQ;AAAA,KAMf,eAAA,CAAA,eAA+B,gBAAhB,CAAA,GAClB,gBAAA,CAAiB,UADC,CACU,MADV,CAAA;KAGf,gBAH+B,CAAA,eAGC,gBAHD,CAAA,GAIlC,gBAAA,CAAiB,WAJiB,CAIL,MAJK,CAAA;KAM/B,eALyB,CAAA,KAAA,EAAA,UAAA,CAAA,GAKY,KALZ,SAAA,MAAA,GAM1B,UAN0B,GAMb,MANa,CAMN,OANM,CAAA,MAMQ,UANR,EAAA,MAM0B,KAN1B,CAAA,EAAA,KAAA,CAAA,GAO1B,UAP0B;KASzB,kBATc,CAAA,eASoB,gBATpB,CAAA,GAUjB,gBAViB,CAUA,MAVA,CAAA,SAAA,MAAA,GAAA,mBAAU,MAYE,gBAZF,CAYmB,MAZnB,CAAA,GAY6B,gBAZ7B,CAY8C,MAZ9C,CAAA,CAYsD,GAZtD,CAAA,GAanB,QAbmB,CAAA,YAAA,EAaI,GAbJ,CAAA,EAAA,GAExB,KAAA;KAeA,kBAfgC,CAAA,eAeE,gBAfF,CAAA,GAgBnC,gBAhBmC,CAgBlB,MAhBkB,CAAA,SAAA,MAAA,GAAA,mBACN,MAiBA,gBAjBA,CAiBiB,MAjBjB,CAAA,GAiB2B,gBAjB3B,CAiB4C,MAjB5C,CAAA,CAiBoD,GAjBpD,CAAA,EAA7B,GAAA,KAAA;KAqBG,QAAA,GAAW,QArBc,CAAA,MAAA,CAAA;AAAA,KAuBzB,kBAAA,GAAqB,QArBN,CAAA,gBAAA,CAAA,GAAA;EAAsB,CAAA,gBAAA,CAAA,CAAA,QAAA,EAuB5B,UAvB4B,CAAA,EAAA,MAAA,GAwB5B,QAxB4B,CAAA,wBAAA,EAwBO,UAxBP,CAAA;CACtC;;AAAoD,UA2BvC,gBA3BuC,CAAA,eA2BP,gBA3BO,CAAA,CAAA;EAAhC;EAAP,UAAA,EA6BH,kBA7BG,CA6BgB,MA7BhB,CAAA;EACb;EAAU,IAAA,EA+BN,QA/BM;EAET;;;;;;;EAGqD,cAAA,EAmCxC,kBAnCwC;;;AAChD,UAsCO,cAtCP,CAAA,eAsCqC,gBAtCrC,CAAA,CAAA;EAAQ;EAIb,UAAA,EAoCS,kBApCS,CAoCU,MApCV,CAAA;EAAgB;EACpB,KAAA,EAAA,MAAA;;;;;;;;AAEmE;AAI9D;;;;;;AASxB;;AAEiC,UAuChB,iBAvCgB,CAAA,eAuCiB,gBAvCjB,CAAA,CAAA;EAAnB;;;;EAgBG,UAAA,EA4BH,MA5BiB;EAAgB;;;;AAuB/C;;;;;;;;;;;;AAqFC;AAEoC;EAOrB,IAAA,EAAA;IAAW;;;;;IAMnB,QAAA,EAAA,MAAA;IAAQ;AAAA;;;;;;IAOuB,OAAA,CAAA,OAAA,EAnElB,cAmEkB,CAnEH,MAmEG,CAAA,CAAA,EAAA,OAAA;EAAvB,CAAA;EAAuD;;;EAEjE,OAAA,CAAA,OAAA,EA/Da,gBA+Db,CA/D8B,MA+D9B,CAAA,CAAA,EAAA,MAAA;EAAI;AAAA;;;;;;;;;AAQgC;;;;;;;EAavB,UAAA,EAAA,OAAA,EAjEI,gBAiEJ,CAjEqB,MAiErB,CAAA,CAAA,EAAA,MAAA;EACX;;;;;;;;;;;;;;;;;EAayB,MAAA,EAAA,KAAA,EA5DhB,KA4DgB,GA5DR,MA4DQ,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,EAAA,OAAA;;KAzD5B,eAyD8C,CAAA,MAAA,CAAA,GAzDpB,MAyDoB,SAAA;EAArC,IAAA,EAAA;IACA,OAAA,EAAA,CAAA,GAAA,UAAA,EAAA,KAAA,WAAA,EAAA,GAAA,KAAA,SAAA;EAEkB,CAAA;CACZ,GAAA,QAAA,GAAA,KAAA;KAvDf,sBAuDoB,CAAA,QAAA,CAAA,GAAA,UACL,MAvDJ,QAuDI,GAvDO,QAuDP,CAvDgB,GAuDhB,CAAA,SAvD6B,QAuD7B,CAAA,YAAA,EArDhB,WAqDgB,CAAA,GAnDd,GAmDc,GAAA,KAAA,EACA,CAAA,MAlDZ,QAkDY,CAAA;KAhDf,gBAiDe,CAAA,MAAA,EAAA,IAAA,CAAA,GAjDkB,IAiDlB,SAAA,SAAA,OAAA,EAAA,GAhDhB,IAgDgB,GA/ChB,IA+CgB,SAAA,MAAA,GA9Cd,IA8Cc,CA7CZ,IA6CY,EA5CZ,OA4CY,CA5CJ,sBA4CI,CA5CmB,eA4CnB,CA5CmC,MA4CnC,CAAA,CAAA,EAAA,MA5CmD,IA4CnD,CAAA,CAAA,GA1Cd,IA0Cc;KAxCf,YAoCkC,CAAA,eAAA,SAAA,OAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,cAAA,CAAA,GAAA,YAOvB,MArCE,MAqCF,GArCW,eAqCX,CApCZ,MAoCY,CApCL,KAoCK,CAAA,EAnCZ,UAmCY,EAlCZ,IAkCY,EAjCZ,cAiCY,CAAA,EAAI;AAAA,KA7Bf,eA+BA,CAAA,IAAkB,EAAA,UAAA,EAAA,IAAW,EAAA,cAAM,CAAA,GA9BtC,IA8BsC,SA9BzB,QA8ByB,CAAA,YAAA,EAAA,KAAA,IAAA,CAAA,GAAA,GAAA,SAAA,MA7BhB,UA6BgB,GA5BhC,UA4BgC,CA5BrB,GA4BqB,CAAA,GAAA,KAAA,GA1BlC,IA0BkC,SA1BrB,QA0BqB,CAAA,MAAA,CAAA,GAzBhC,IAyBgC,GAxBhC,IAwBgC,SAxBnB,QAwBmB,CAAA,gBAAA,CAAA,GAvB9B,cAuB8B,GAtB9B,IAsB8B,UAAA,CAAA,GAAA,UAAA,EAAA,KAAA,UAAA,EAAA,GAAA,KAAA,OAAA,IAAA,CAAA,GAAA,UAAA,EApBX,YAoBW,CAnBxB,SAmBwB,EAlBxB,UAkBwB,EAjBxB,IAiBwB,EAhBxB,cAgBwB,CAAA,EAAA,GAdvB,eAcuB,CAdP,MAcO,EAdC,UAcD,EAda,IAcb,EAdmB,cAcnB,CAAA,GAb5B,IAa4B,SAAA,SAAA,OAAA,EAAA,GAZ1B,YAY0B,CAZb,IAYa,EAZP,UAYO,EAZK,IAYL,EAZW,cAYX,CAAA,GAX1B,IAW0B,SAAA,MAAA,GAAA,UAMnC,MAf2B,IAe3B,GAfkC,eAed,CAdL,IAcK,CAdA,GAcA,CAAA,EAbL,UAaK,EAZL,IAYK,EAXL,cAWK,CAAA,EAAW,GARpB,IAQoB;KAN/B,kBASS,CAAA,MAAA,CAAA,GAToB,MASpB,SAAA;EAAW,UAAA,EAAA,CAAA,GAAA,UAAA,EAAA,KAAA,WAAA,EAAA,GAAA,KAAA,WAAA;CAAQ,GAAA,UAAA,GAAA,MAAA;AASjC,KAZK,oBAYO,CAAA,MAAsB,CAAA,GAZE,MAYF,SAAA;EAAW,IAAA,EAAA;IACtB,QAAA,EAAA,KAAA,kBAAA,MAAA;EAArB,CAAA;CACmB,GAAA,UAXP,QAWZ,GAXuB,QAWvB,EAAkB,GAAA,MAAA;AAAS;;;;;;AAG3B,KALU,sBAKV,CAAA,MAAA,CAAA,GAL2C,KAK3C,GAJA,oBAIA,CAJqB,MAIrB,CAAA,GAHA,kBAGA,CAHmB,MAGnB,CAAA;KADG,kBAQsB,CAAA,MAAA,EAAA,UAAA,EAAA,IAAA,EAAA,cAAA,CAAA,GAPzB,eAOyB,CANvB,kBAMuB,CANJ,MAMI,CAAA,EALvB,UAKuB,EAJvB,IAIuB,EAHvB,cAGuB,CAAA,GADvB,eACuB,CAArB,oBAAqB,CAAA,MAAA,CAAA,EACrB,UADqB,EAErB,IAFqB,EAGrB,cAHqB,CAAA,GAKvB,KALuB,GAAA,CAMtB,MANsB,SAAA;EAArB,MAAA,EAAA,CAAA,GAAA,UAAA,EAAA,KAAA,WAAA,EAAA,GAAA,KAAA,KAAA;CACA,GAAA;EACA,MAAA,EAAA,EAQc,eARd,CAQ8B,IAR9B,EAQoC,UARpC,EAQgD,IARhD,EAQsD,cARtD,CAAA;CACA,GAAA,MAAA,CAAA;KAWD,eAfD,CAAA,MAAA,CAAA,GAe2B,MAf3B,SAAA;EAMA,OAAA,EAAA,CAAA,GAAA,UAAA,EAAA,KAAA,WAAA,EAAA,GAAA,KAAA,QAAA;CACC,GAAA,OAAA,GAAA,MAAA;KAcA,oCAV+B,CAAA,UAAA,EAAA,UAAA,EAAA,IAAA,CAAA,GAWlC,UAXkC,SAWjB,QAXiB,CAAA,MAAA,CAAA,GAY9B,IAZ8B,GAa9B,eAb8B,CAad,UAbc,EAaJ,UAbI,EAaQ,IAbR,EAAA,KAAA,CAAA,SAAA,KAAA,SAAA,GAc5B,UAd4B,SAcX,QAdW,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,QAAA,GAAA,QAAA,SAAA,SAAA,OAAA,EAAA,GAAA,QAAA,GAAA,QAAA,UAAA,CAAA,GAAA,UAAA,EAAA,KAAA,WAAA,EAAA,GAAA,OAAA,IAAA,QAAA,GAAA,QAAA,SAAA,MAAA,GAqBpB,IArBoB,CAqBf,UArBe,EAAA,MAqBG,QArBH,CAAA,GAqBe,QArBf,GAAA,QAAA,GAAA,KAAA;KAyB/B,sBAzBqC,CAAA,MAAA,EAAA,UAAA,EAAA,IAAA,CAAA,GA0BxC,eA1BwC,CA0BxB,MA1BwB,CAAA,SA0BR,QA1BQ,CAAA,wBAAA,EAAA,KAAA,SAAA,CAAA,GA8BpC,oCA9BoC,CA8BC,QA9BD,EA8BW,UA9BX,EA8BuB,IA9BvB,CAAA,GAAA,KAAA;KAiCrC,sBAjCiD,CAAA,MAAA,EAAA,UAAA,EAAA,IAAA,CAAA,GAAA,CAAA,QAAA,EAkC1C,sBAlC0C,CAkCnB,MAlCmB,EAkCX,UAlCW,EAkCC,IAlCD,CAAA,EAAA,GAAA,MAAA;KAqCjD,4BArCuD,CAAA,MAAA,EAAA,UAAA,EAAA,IAAA,CAAA,GAsC1D,eAtC0D,CAsC1C,MAtC0C,CAAA,SAsC1B,QAtC0B,CAAA,wBAAA,EAAA,KAAA,SAAA,CAAA,GAAA,QAAA,SA0CrC,QA1CqC,CAAA,MAAA,CAAA,GA2CpD,IA3CoD,GA4CpD,eA5CoD,CA4CpC,QA5CoC,EA4C1B,UA5C0B,EA4Cd,IA5Cc,EAAA,KAAA,CAAA,GAAA,KAAA;KA+CvD,4BA/Ce,CAAA,MAAA,EAAA,UAAA,EAAA,IAAA,CAAA,GAAA,CAAA,QAAA,EAgDR,4BAhDQ,CAgDqB,MAhDrB,EAgD6B,UAhD7B,EAgDyC,IAhDzC,CAAA,EAAA,GAAA,MAAA;UAmDV,iBAAA,CAnDyB;EAI9B;AAAgC;;;;;;;;;;;;;;;AAiBsB;;EAKzD,SAAA,CAAA,SAAA,EAAA,KAAA,CAAA,CAAA,IAAA,EAAA,KAAA,KAAA,EA6CoB,KA7CpB,EAAA,OAAA,CAAA,EA6CqC,YA7CrC,EAAA,GA6CsD,KA7CtD,EAAA,SAAA,EA8Ca,SA9Cb,EAAA,KAAA,EA+CS,KA/CT,GAAA,CAAA,GAAA,GA+CwB,KA/CxB,CAAA,EAAA,OAAA,CAAA,EAgDY,YAhDZ,CAAA,EAAA,QAAA,SAAA;;;;;;;AAIwC;AAIP,KAkDvB,gBAAA,GAlDuB,CAAA,cAAA,GAAA,UAAA,EAAA,KAAA,EAAA,EAAA,GAoD9B,KApD8B,CAAA,GAqDjC,iBArDiC;;UAwDzB,kBAxD6C,CAAA,KAAA,EAAA,QAAA,CAAA,SAwDD,iBAxDC,CAAA;EAA3C;;AAAsB;;;EAIA,KAAA,KAAA,EA0DpB,KA1DoB,EAAA,OAAA,CAAA,EA0DH,YA1DG,CAAA,EA0DY,QA1DZ;;KA6D7B,qBAxDG,CAAA,MAAA,EAAA,UAAA,EAAA,KAAA,EAAA,IAAA,CAAA,GAyDN,kBAzDM,CA0DJ,gBA1DI,CA0Da,MA1Db,EA0DqB,KA1DrB,CAAA,EA2DJ,kBA3DI,CA4DF,MA5DE,EA6DF,UA7DE,EA8DF,IA9DE,EA+DF,4BA/DE,CA+D2B,MA/D3B,EA+DmC,UA/DnC,EA+D+C,IA/D/C,CAAA,CAAA,CAAA;KAmEH,YAlEmB,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,CAAA,GAAA,CAkEqB,KAlErB,CAAA,SAAA,CAAA,KAAA,CAAA,GAmEpB,MAnEoB,GAoEpB,OApEoB;KAsEnB,WAtE6B,CAAA,IAAA,EAAA,YAAA,CAAA,GAsEK,YAtEL,CAsEkB,IAtElB,EAsEwB,YAtExB,EAsEsC,IAtEtC,CAAA;KAwE7B,kBAxEyC,CAAA,IAAA,CAAA,GAwEd,YAxEc,CAwED,IAxEC,EAAA,OAAA,EAwEc,IAxEd,CAAA;KA0EzC,YA1EG,CAAA,KAAA,EAAA,IAAA,CAAA,GA0EyB,YA1EzB,CA0EsC,KA1EtC,EA0E6C,IA1E7C,EA0EmD,KA1EnD,CAAA;KA4EH,MA5EkB,CAAA,IAAA,CAAA,GA4EH,IA5EG,UAAA,CAAA,GAAA,UAAA,EAAA,KAAA,UAAA,EAAA,GAAA,KAAA,OAAA,IAAA,CAAA,GAAA,UAAA,EA6EH,SA7EG,EAAA,GA6EW,MA7EX,GA8EnB,IA9EmB;AAAA;AAIkB,UA6ExB,qBA7EwB,CAAA,MAAA,EAAA,UAAA,EAAA,QAAA,KAAA,EAAA,OAAA,KAAA,CAAA,CAAA;EAAQ;;;;AAAT;;;;;;;;;AAoCxC;AAGoB;;EASW,SAAA,CAAA,eAmDJ,kBAnDI,CAmDe,IAnDf,CAAA,CAAA,CAAA,cAAA,EAoDX,MApDW,CAoDJ,sBApDI,CAqDzB,MArDyB,EAsDzB,UAtDyB,EAuDzB,WAvDyB,CAuDb,IAvDa,EAuDP,YAvDO,CAAA,CAAA,CAAA,CAAA,EAyD1B,qBAzD0B,CA0D3B,MA1D2B,EA2D3B,UA3D2B,EA4D3B,YA5D2B,CA4Dd,KA5Dc,EA4DP,WA5DO,CA4DK,IA5DL,EA4DW,YA5DX,CAAA,CAAA,EA6D3B,WA7D2B,CA6Df,IA7De,EA6DT,YA7DS,CAAA,CAAA;;;AANwC,UAwEtD,sBAxEsD,CAAA,MAAA,EAAA,UAAA,CAAA,SA2E7D,qBA3E6D,CA2EvC,MA3EuC,EA2E/B,UA3E+B,CAAA,CAAA;EASlE;;;;;;;;;;;;;;AACe;;EAWhB,aAAA,CAAA,4BAuEwC,gBAvExC,CAAA,CAAA,OAAA,EAwES,aAxET,CAAA,EAyEC,qBAzED,CA0EA,MA1EA,EA2EA,UA3EA,EA4EA,gBAAA,CAAiB,UA5EjB,CA4E4B,aA5E5B,CAAA,EA6EA,gBAAA,CAAiB,WA7EjB,CA6E6B,aA7E7B,CAAA,CAAA;;;AACO;;;;;AAEwC,KAoFvC,kBApFuC,CAAA,eAoFL,gBApFK,EAAA,MAAA,CAAA,GAAA;EAE9C;;;;;AAAuC;;;;;;AAEC;EAEzB,CAAA,yBA2FQ,eA3FR,CA2FwB,MA3FxB,CAAA,CAAA,CAAA,UAAA,EA4FJ,eA5FI,CA4FY,eA5FZ,CA4F4B,MA5F5B,CAAA,EA4FqC,UA5FrC,CAAA,CAAA,EA6Ff,sBA7Fe,CA6FQ,MA7FR,EA6FgB,kBA7FhB,CA6FmC,MA7FnC,CAAA,CAAA;EACA;;;;AAIpB;;;;EAyBM,KAAA,EAyEG,gBAzEH;CACY"}