From 77cb002abec7179d0fea7792fecd193904cd75d5 Mon Sep 17 00:00:00 2001 From: Igor Savin Date: Fri, 24 May 2024 00:03:58 +0300 Subject: [PATCH 1/2] Add message-queue-toolkit/schemas --- packages/core/lib/events/baseEventSchemas.ts | 81 +++----------- packages/core/lib/events/eventTypes.ts | 64 ++--------- .../core/lib/messages/baseMessageSchemas.ts | 102 ++---------------- packages/core/lib/utils/toDateProcessor.ts | 11 +- packages/core/package.json | 1 + packages/schemas/.eslintignore | 4 + packages/schemas/.eslintrc.json | 80 ++++++++++++++ packages/schemas/.prettierrc.json | 9 ++ packages/schemas/index.ts | 5 + .../schemas/lib/events/baseEventSchemas.ts | 68 ++++++++++++ packages/schemas/lib/events/eventTypes.ts | 55 ++++++++++ .../lib/messages/baseMessageSchemas.ts | 98 +++++++++++++++++ .../lib/utils/toDatePreprocessor.spec.ts | 0 packages/schemas/lib/utils/toDateProcessor.ts | 10 ++ packages/schemas/package.json | 62 +++++++++++ packages/schemas/tsconfig.json | 27 +++++ packages/schemas/tsconfig.release.json | 5 + 17 files changed, 455 insertions(+), 227 deletions(-) create mode 100644 packages/schemas/.eslintignore create mode 100644 packages/schemas/.eslintrc.json create mode 100644 packages/schemas/.prettierrc.json create mode 100644 packages/schemas/index.ts create mode 100644 packages/schemas/lib/events/baseEventSchemas.ts create mode 100644 packages/schemas/lib/events/eventTypes.ts create mode 100644 packages/schemas/lib/messages/baseMessageSchemas.ts rename packages/{core => schemas}/lib/utils/toDatePreprocessor.spec.ts (100%) create mode 100644 packages/schemas/lib/utils/toDateProcessor.ts create mode 100644 packages/schemas/package.json create mode 100644 packages/schemas/tsconfig.json create mode 100644 packages/schemas/tsconfig.release.json diff --git a/packages/core/lib/events/baseEventSchemas.ts b/packages/core/lib/events/baseEventSchemas.ts index 4ce3f9e4..6910d36b 100644 --- a/packages/core/lib/events/baseEventSchemas.ts +++ b/packages/core/lib/events/baseEventSchemas.ts @@ -1,69 +1,12 @@ -import type { ZodLiteral, ZodObject, ZodOptional, ZodString } from 'zod' -import z from 'zod' -import type { ZodRawShape } from 'zod/lib/types' - -// Base event fields that are typically autogenerated -export const GENERATED_BASE_EVENT_SCHEMA = z.object({ - id: z.string().describe('event unique identifier'), - timestamp: z.string().datetime().describe('iso 8601 datetime'), -}) - -// Base event fields that are typically autogenerated, marked as optional -export const OPTIONAL_GENERATED_BASE_EVENT_SCHEMA = z.object({ - id: z.string().describe('event unique identifier').optional(), - timestamp: z.string().datetime().describe('iso 8601 datetime').optional(), -}) - -// Base event fields that are always defined manually -export const CORE_EVENT_SCHEMA = z.object({ - type: z.literal('').describe('event type name'), - payload: z.optional(z.object({})).describe('event payload based on type'), -}) - -// Core fields that describe either internal event or external message -export const CONSUMER_BASE_EVENT_SCHEMA = GENERATED_BASE_EVENT_SCHEMA.extend( - CORE_EVENT_SCHEMA.shape, -) -export const PUBLISHER_BASE_EVENT_SCHEMA = OPTIONAL_GENERATED_BASE_EVENT_SCHEMA.extend( - CORE_EVENT_SCHEMA.shape, -) - -export type ConsumerBaseEventType = z.infer -export type PublisherBaseEventType = z.infer -export type CoreEventType = z.infer -export type GeneratedBaseEventType = z.infer - -type ReturnType, Y extends ZodRawShape, Z extends string> = { - consumerSchema: ZodObject<{ - id: ZodString - timestamp: ZodString - type: ZodLiteral - payload: T - }> - - publisherSchema: ZodObject<{ - id: ZodOptional - timestamp: ZodOptional - type: ZodLiteral - payload: T - }> -} - -export function enrichEventSchemaWithBase< - T extends ZodObject, - Y extends ZodRawShape, - Z extends string, ->(type: Z, payloadSchema: T): ReturnType { - const baseSchema = z.object({ - type: z.literal(type), - payload: payloadSchema, - }) - - const consumerSchema = GENERATED_BASE_EVENT_SCHEMA.merge(baseSchema) - const publisherSchema = OPTIONAL_GENERATED_BASE_EVENT_SCHEMA.merge(baseSchema) - - return { - consumerSchema: consumerSchema, - publisherSchema: publisherSchema, - } -} +export { + GENERATED_BASE_EVENT_SCHEMA, + OPTIONAL_GENERATED_BASE_EVENT_SCHEMA, + CORE_EVENT_SCHEMA, + CONSUMER_BASE_EVENT_SCHEMA, + PUBLISHER_BASE_EVENT_SCHEMA, + ConsumerBaseEventType, + PublisherBaseEventType, + CoreEventType, + GeneratedBaseEventType, + enrichEventSchemaWithBase, +} from '@message-queue-toolkit/schemas' diff --git a/packages/core/lib/events/eventTypes.ts b/packages/core/lib/events/eventTypes.ts index 21356d1d..0b586b1d 100644 --- a/packages/core/lib/events/eventTypes.ts +++ b/packages/core/lib/events/eventTypes.ts @@ -1,55 +1,9 @@ -import type { ZodObject, ZodTypeAny } from 'zod' -import type z from 'zod' - -import type { MessageMetadataType } from '../messages/baseMessageSchemas' - -import type { CONSUMER_BASE_EVENT_SCHEMA, PUBLISHER_BASE_EVENT_SCHEMA } from './baseEventSchemas' - -export type EventTypeNames = - CommonEventDefinitionConsumerSchemaType['type'] - -export type CommonEventDefinition = { - consumerSchema: ZodObject< - Omit<(typeof CONSUMER_BASE_EVENT_SCHEMA)['shape'], 'payload'> & { payload: ZodTypeAny } - > - publisherSchema: ZodObject< - Omit<(typeof PUBLISHER_BASE_EVENT_SCHEMA)['shape'], 'payload'> & { payload: ZodTypeAny } - > - schemaVersion?: string -} - -export type CommonEventDefinitionConsumerSchemaType = z.infer< - T['consumerSchema'] -> - -export type CommonEventDefinitionPublisherSchemaType = z.infer< - T['publisherSchema'] -> - -export type EventHandler< - EventDefinitionSchema extends - CommonEventDefinitionConsumerSchemaType = CommonEventDefinitionConsumerSchemaType, - MetadataDefinitionSchema extends Partial = Partial, -> = { - handleEvent( - event: EventDefinitionSchema, - metadata?: MetadataDefinitionSchema, - ): void | Promise -} - -export type AnyEventHandler = EventHandler< - CommonEventDefinitionConsumerSchemaType -> - -export type SingleEventHandler< - EventDefinition extends CommonEventDefinition[], - EventTypeName extends EventTypeNames, -> = EventHandler> - -type EventFromArrayByTypeName< - EventDefinition extends CommonEventDefinition[], - EventTypeName extends EventTypeNames, -> = Extract< - CommonEventDefinitionConsumerSchemaType, - { type: EventTypeName } -> +export { + EventTypeNames, + CommonEventDefinition, + CommonEventDefinitionConsumerSchemaType, + CommonEventDefinitionPublisherSchemaType, + EventHandler, + AnyEventHandler, + SingleEventHandler, +} from '@message-queue-toolkit/schemas' diff --git a/packages/core/lib/messages/baseMessageSchemas.ts b/packages/core/lib/messages/baseMessageSchemas.ts index cec3fec9..45f568c6 100644 --- a/packages/core/lib/messages/baseMessageSchemas.ts +++ b/packages/core/lib/messages/baseMessageSchemas.ts @@ -1,93 +1,9 @@ -import z, { type ZodLiteral, type ZodObject, type ZodOptional, type ZodString } from 'zod' -import type { ZodRawShape } from 'zod/lib/types' - -import { - CONSUMER_BASE_EVENT_SCHEMA, - GENERATED_BASE_EVENT_SCHEMA, - OPTIONAL_GENERATED_BASE_EVENT_SCHEMA, -} from '../events/baseEventSchemas' -import type { CommonEventDefinition } from '../events/eventTypes' - -// External message metadata that describe the context in which the message was created, primarily used for debugging purposes -export const MESSAGE_METADATA_SCHEMA = z - .object({ - schemaVersion: z.string().min(1).describe('message schema version'), - // this is always set to a service that created the message - producedBy: z.string().min(1).describe('app/service that produced the message'), - // this is always propagated within the message chain. For the first message in the chain it is equal to "producedBy" - originatedFrom: z - .string() - .min(1) - .describe('app/service that initiated entire workflow that led to creating this message'), - // this is always propagated within the message chain. - correlationId: z.string().describe('unique identifier passed to all events in workflow chain'), - }) - .describe('external message metadata') - -export const MESSAGE_SCHEMA_EXTENSION = { - // For internal domain events that did not originate within a message chain metadata field can be omitted, producer should then assume it is initiating a new chain - metadata: MESSAGE_METADATA_SCHEMA.optional(), -} - -export const BASE_MESSAGE_SCHEMA = CONSUMER_BASE_EVENT_SCHEMA.extend(MESSAGE_SCHEMA_EXTENSION) - -export type BaseMessageType = z.infer - -export type MessageMetadataType = z.infer - -export type CommonMessageDefinitionSchemaType = z.infer< - T['consumerSchema'] -> - -type ReturnType, Y extends ZodRawShape, Z extends string> = { - consumerSchema: ZodObject<{ - id: ZodString - timestamp: ZodString - type: ZodLiteral - payload: T - metadata: ZodOptional< - ZodObject<{ - schemaVersion: ZodString - producedBy: ZodString - originatedFrom: ZodString - correlationId: ZodString - }> - > - }> - - publisherSchema: ZodObject<{ - id: ZodOptional - timestamp: ZodOptional - type: ZodLiteral - payload: T - metadata: ZodOptional< - ZodObject<{ - schemaVersion: ZodString - producedBy: ZodString - originatedFrom: ZodString - correlationId: ZodString - }> - > - }> -} - -export function enrichMessageSchemaWithBase< - T extends ZodObject, - Y extends ZodRawShape, - Z extends string, ->(type: Z, payloadSchema: T): ReturnType { - const baseSchema = z.object({ - type: z.literal(type), - payload: payloadSchema, - }) - - const consumerSchema = - GENERATED_BASE_EVENT_SCHEMA.merge(baseSchema).extend(MESSAGE_SCHEMA_EXTENSION) - const publisherSchema = - OPTIONAL_GENERATED_BASE_EVENT_SCHEMA.merge(baseSchema).extend(MESSAGE_SCHEMA_EXTENSION) - - return { - consumerSchema: consumerSchema, - publisherSchema: publisherSchema, - } -} +export { + MESSAGE_METADATA_SCHEMA, + MESSAGE_SCHEMA_EXTENSION, + BASE_MESSAGE_SCHEMA, + BaseMessageType, + MessageMetadataType, + CommonMessageDefinitionSchemaType, + enrichMessageSchemaWithBase, +} from '@message-queue-toolkit/schemas' diff --git a/packages/core/lib/utils/toDateProcessor.ts b/packages/core/lib/utils/toDateProcessor.ts index de9778fa..5acae666 100644 --- a/packages/core/lib/utils/toDateProcessor.ts +++ b/packages/core/lib/utils/toDateProcessor.ts @@ -1,10 +1 @@ -export const toDatePreprocessor = (value: unknown) => { - switch (typeof value) { - case 'string': - case 'number': - return new Date(value) - - default: - return value // could not coerce, return the original and face the consequences during validation - } -} +export { toDatePreprocessor } from '@message-queue-toolkit/schemas' diff --git a/packages/core/package.json b/packages/core/package.json index 7c26bbd3..1a4bd361 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -26,6 +26,7 @@ }, "dependencies": { "@lokalise/node-core": "^9.17.0", + "@message-queue-toolkit/schemas": "^1.0.0", "fast-equals": "^5.0.1", "toad-cache": "^3.7.0", "zod": "^3.23.8" diff --git a/packages/schemas/.eslintignore b/packages/schemas/.eslintignore new file mode 100644 index 00000000..dcaed66f --- /dev/null +++ b/packages/schemas/.eslintignore @@ -0,0 +1,4 @@ +node_modules/ +coverage/ +dist/ +vitest.config.mts diff --git a/packages/schemas/.eslintrc.json b/packages/schemas/.eslintrc.json new file mode 100644 index 00000000..a637755b --- /dev/null +++ b/packages/schemas/.eslintrc.json @@ -0,0 +1,80 @@ +{ + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2022, + "sourceType": "module", + "project": "./tsconfig.json" + }, + "ignorePatterns": ["node_modules"], + "plugins": ["@typescript-eslint", "vitest", "import"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:import/recommended", + "plugin:import/typescript", + "plugin:vitest/recommended" + ], + "rules": { + "@typescript-eslint/no-empty-interface": "warn", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-use-before-define": "off", + "@typescript-eslint/no-non-null-assertion": "warn", + "@typescript-eslint/no-var-requires": "off", + "@typescript-eslint/indent": "off", + "@typescript-eslint/restrict-template-expressions": "off", + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-unsafe-member-access": "off", + "@typescript-eslint/no-unsafe-assignment": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/consistent-type-imports": "warn", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_" + } + ], + "@typescript-eslint/member-delimiter-style": [ + "error", + { + "multiline": { + "delimiter": "none", + "requireLast": false + }, + "singleline": { + "delimiter": "comma", + "requireLast": false + } + } + ], + "import/no-default-export": "error", + "import/order": [ + "warn", + { + "alphabetize": { "order": "asc" }, + "newlines-between": "always" + } + ], + "max-lines": ["error", { "max": 600 }], + "max-params": ["error", { "max": 4 }], + "max-statements": ["error", { "max": 15 }], + "complexity": ["error", { "max": 20 }] + }, + "overrides": [ + { + "files": ["test/**/*.ts", "*.test.ts", "*.spec.ts"], + "rules": { + "@typescript-eslint/require-await": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-unsafe-return": "off", + "@typescript-eslint/no-unsafe-assignment": "off", + "@typescript-eslint/no-unsafe-member-access": "off", + "@typescript-eslint/no-unsafe-call": "off", + "max-statements": ["off"] + } + } + ] +} diff --git a/packages/schemas/.prettierrc.json b/packages/schemas/.prettierrc.json new file mode 100644 index 00000000..b59d4dd3 --- /dev/null +++ b/packages/schemas/.prettierrc.json @@ -0,0 +1,9 @@ +{ + "printWidth": 100, + "singleQuote": true, + "bracketSpacing": true, + "semi": false, + "arrowParens": "always", + "endOfLine": "lf", + "trailingComma": "all" +} diff --git a/packages/schemas/index.ts b/packages/schemas/index.ts new file mode 100644 index 00000000..148cc6ba --- /dev/null +++ b/packages/schemas/index.ts @@ -0,0 +1,5 @@ +export { toDatePreprocessor } from './lib/utils/toDateProcessor' + +export * from './lib/events/eventTypes' +export * from './lib/events/baseEventSchemas' +export * from './lib/messages/baseMessageSchemas' diff --git a/packages/schemas/lib/events/baseEventSchemas.ts b/packages/schemas/lib/events/baseEventSchemas.ts new file mode 100644 index 00000000..723151c9 --- /dev/null +++ b/packages/schemas/lib/events/baseEventSchemas.ts @@ -0,0 +1,68 @@ +import type { ZodLiteral, ZodObject, ZodOptional, ZodString, ZodRawShape } from 'zod' +import { z } from 'zod' + +// Base event fields that are typically autogenerated +export const GENERATED_BASE_EVENT_SCHEMA = z.object({ + id: z.string().describe('event unique identifier'), + timestamp: z.string().datetime().describe('iso 8601 datetime'), +}) + +// Base event fields that are typically autogenerated, marked as optional +export const OPTIONAL_GENERATED_BASE_EVENT_SCHEMA = z.object({ + id: z.string().describe('event unique identifier').optional(), + timestamp: z.string().datetime().describe('iso 8601 datetime').optional(), +}) + +// Base event fields that are always defined manually +export const CORE_EVENT_SCHEMA = z.object({ + type: z.literal('').describe('event type name'), + payload: z.optional(z.object({})).describe('event payload based on type'), +}) + +// Core fields that describe either internal event or external message +export const CONSUMER_BASE_EVENT_SCHEMA = GENERATED_BASE_EVENT_SCHEMA.extend( + CORE_EVENT_SCHEMA.shape, +) +export const PUBLISHER_BASE_EVENT_SCHEMA = OPTIONAL_GENERATED_BASE_EVENT_SCHEMA.extend( + CORE_EVENT_SCHEMA.shape, +) + +export type ConsumerBaseEventType = z.infer +export type PublisherBaseEventType = z.infer +export type CoreEventType = z.infer +export type GeneratedBaseEventType = z.infer + +type ReturnType, Y extends ZodRawShape, Z extends string> = { + consumerSchema: ZodObject<{ + id: ZodString + timestamp: ZodString + type: ZodLiteral + payload: T + }> + + publisherSchema: ZodObject<{ + id: ZodOptional + timestamp: ZodOptional + type: ZodLiteral + payload: T + }> +} + +export function enrichEventSchemaWithBase< + T extends ZodObject, + Y extends ZodRawShape, + Z extends string, +>(type: Z, payloadSchema: T): ReturnType { + const baseSchema = z.object({ + type: z.literal(type), + payload: payloadSchema, + }) + + const consumerSchema = GENERATED_BASE_EVENT_SCHEMA.merge(baseSchema) + const publisherSchema = OPTIONAL_GENERATED_BASE_EVENT_SCHEMA.merge(baseSchema) + + return { + consumerSchema: consumerSchema, + publisherSchema: publisherSchema, + } +} diff --git a/packages/schemas/lib/events/eventTypes.ts b/packages/schemas/lib/events/eventTypes.ts new file mode 100644 index 00000000..21356d1d --- /dev/null +++ b/packages/schemas/lib/events/eventTypes.ts @@ -0,0 +1,55 @@ +import type { ZodObject, ZodTypeAny } from 'zod' +import type z from 'zod' + +import type { MessageMetadataType } from '../messages/baseMessageSchemas' + +import type { CONSUMER_BASE_EVENT_SCHEMA, PUBLISHER_BASE_EVENT_SCHEMA } from './baseEventSchemas' + +export type EventTypeNames = + CommonEventDefinitionConsumerSchemaType['type'] + +export type CommonEventDefinition = { + consumerSchema: ZodObject< + Omit<(typeof CONSUMER_BASE_EVENT_SCHEMA)['shape'], 'payload'> & { payload: ZodTypeAny } + > + publisherSchema: ZodObject< + Omit<(typeof PUBLISHER_BASE_EVENT_SCHEMA)['shape'], 'payload'> & { payload: ZodTypeAny } + > + schemaVersion?: string +} + +export type CommonEventDefinitionConsumerSchemaType = z.infer< + T['consumerSchema'] +> + +export type CommonEventDefinitionPublisherSchemaType = z.infer< + T['publisherSchema'] +> + +export type EventHandler< + EventDefinitionSchema extends + CommonEventDefinitionConsumerSchemaType = CommonEventDefinitionConsumerSchemaType, + MetadataDefinitionSchema extends Partial = Partial, +> = { + handleEvent( + event: EventDefinitionSchema, + metadata?: MetadataDefinitionSchema, + ): void | Promise +} + +export type AnyEventHandler = EventHandler< + CommonEventDefinitionConsumerSchemaType +> + +export type SingleEventHandler< + EventDefinition extends CommonEventDefinition[], + EventTypeName extends EventTypeNames, +> = EventHandler> + +type EventFromArrayByTypeName< + EventDefinition extends CommonEventDefinition[], + EventTypeName extends EventTypeNames, +> = Extract< + CommonEventDefinitionConsumerSchemaType, + { type: EventTypeName } +> diff --git a/packages/schemas/lib/messages/baseMessageSchemas.ts b/packages/schemas/lib/messages/baseMessageSchemas.ts new file mode 100644 index 00000000..883673f5 --- /dev/null +++ b/packages/schemas/lib/messages/baseMessageSchemas.ts @@ -0,0 +1,98 @@ +import z, { + type ZodLiteral, + type ZodObject, + type ZodOptional, + type ZodString, + type ZodRawShape, +} from 'zod' + +import { + CONSUMER_BASE_EVENT_SCHEMA, + GENERATED_BASE_EVENT_SCHEMA, + OPTIONAL_GENERATED_BASE_EVENT_SCHEMA, +} from '../events/baseEventSchemas' +import type { CommonEventDefinition } from '../events/eventTypes' + +// External message metadata that describe the context in which the message was created, primarily used for debugging purposes +export const MESSAGE_METADATA_SCHEMA = z + .object({ + schemaVersion: z.string().min(1).describe('message schema version'), + // this is always set to a service that created the message + producedBy: z.string().min(1).describe('app/service that produced the message'), + // this is always propagated within the message chain. For the first message in the chain it is equal to "producedBy" + originatedFrom: z + .string() + .min(1) + .describe('app/service that initiated entire workflow that led to creating this message'), + // this is always propagated within the message chain. + correlationId: z.string().describe('unique identifier passed to all events in workflow chain'), + }) + .describe('external message metadata') + +export const MESSAGE_SCHEMA_EXTENSION = { + // For internal domain events that did not originate within a message chain metadata field can be omitted, producer should then assume it is initiating a new chain + metadata: MESSAGE_METADATA_SCHEMA.optional(), +} + +export const BASE_MESSAGE_SCHEMA = CONSUMER_BASE_EVENT_SCHEMA.extend(MESSAGE_SCHEMA_EXTENSION) + +export type BaseMessageType = z.infer + +export type MessageMetadataType = z.infer + +export type CommonMessageDefinitionSchemaType = z.infer< + T['consumerSchema'] +> + +type ReturnType, Y extends ZodRawShape, Z extends string> = { + consumerSchema: ZodObject<{ + id: ZodString + timestamp: ZodString + type: ZodLiteral + payload: T + metadata: ZodOptional< + ZodObject<{ + schemaVersion: ZodString + producedBy: ZodString + originatedFrom: ZodString + correlationId: ZodString + }> + > + }> + + publisherSchema: ZodObject<{ + id: ZodOptional + timestamp: ZodOptional + type: ZodLiteral + payload: T + metadata: ZodOptional< + ZodObject<{ + schemaVersion: ZodString + producedBy: ZodString + originatedFrom: ZodString + correlationId: ZodString + }> + > + }> +} + +export function enrichMessageSchemaWithBase< + T extends ZodObject, + Y extends ZodRawShape, + Z extends string, +>(type: Z, payloadSchema: T): ReturnType { + const baseSchema = z.object({ + type: z.literal(type), + payload: payloadSchema, + }) + + const consumerSchema = + GENERATED_BASE_EVENT_SCHEMA.merge(baseSchema).extend(MESSAGE_SCHEMA_EXTENSION) + const publisherSchema = + OPTIONAL_GENERATED_BASE_EVENT_SCHEMA.merge(baseSchema).extend(MESSAGE_SCHEMA_EXTENSION) + + return { + consumerSchema: consumerSchema, + publisherSchema: publisherSchema, + } +} diff --git a/packages/core/lib/utils/toDatePreprocessor.spec.ts b/packages/schemas/lib/utils/toDatePreprocessor.spec.ts similarity index 100% rename from packages/core/lib/utils/toDatePreprocessor.spec.ts rename to packages/schemas/lib/utils/toDatePreprocessor.spec.ts diff --git a/packages/schemas/lib/utils/toDateProcessor.ts b/packages/schemas/lib/utils/toDateProcessor.ts new file mode 100644 index 00000000..de9778fa --- /dev/null +++ b/packages/schemas/lib/utils/toDateProcessor.ts @@ -0,0 +1,10 @@ +export const toDatePreprocessor = (value: unknown) => { + switch (typeof value) { + case 'string': + case 'number': + return new Date(value) + + default: + return value // could not coerce, return the original and face the consequences during validation + } +} diff --git a/packages/schemas/package.json b/packages/schemas/package.json new file mode 100644 index 00000000..29cec826 --- /dev/null +++ b/packages/schemas/package.json @@ -0,0 +1,62 @@ +{ + "name": "@message-queue-toolkit/schemas", + "version": "1.0.0", + "private": false, + "license": "MIT", + "description": "Useful utilities, interfaces and base classes for message queue handling. Supports AMQP and SQS with a common abstraction on top currently", + "maintainers": [ + { + "name": "Igor Savin", + "email": "kibertoad@gmail.com" + } + ], + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "del-cli dist && del-cli coverage && tsc", + "build:release": "del-cli dist && npm run lint && tsc --project tsconfig.release.json", + "lint": "eslint . --ext .ts", + "lint:fix": "prettier --write . && eslint . --ext .ts --fix", + "test:coverage": "", + "test:ci": "", + "docker:start:dev": "", + "docker:stop:dev": "", + "prepublishOnly": "npm run build:release" + }, + "peerDependencies": { + "zod": "^3.23.8" + }, + "devDependencies": { + "@types/node": "^20.12.8", + "@typescript-eslint/eslint-plugin": "^7.7.1", + "@typescript-eslint/parser": "^7.7.1", + "del-cli": "^5.1.0", + "eslint": "^8.57.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-vitest": "0.4.1", + "prettier": "^3.2.5", + "typescript": "^5.4.5" + }, + "homepage": "https://github.com/kibertoad/message-queue-toolkit", + "repository": { + "type": "git", + "url": "git://github.com/kibertoad/message-queue-toolkit.git" + }, + "keywords": [ + "message", + "queue", + "queues", + "abstract", + "common", + "utils", + "sqs", + "amqp", + "rabbitmq", + "rabbit" + ], + "files": [ + "README.md", + "LICENSE", + "dist/*" + ] +} diff --git a/packages/schemas/tsconfig.json b/packages/schemas/tsconfig.json new file mode 100644 index 00000000..b9088ab4 --- /dev/null +++ b/packages/schemas/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "outDir": "dist", + "module": "commonjs", + "target": "ES2022", + "lib": ["ES2022", "dom"], + "sourceMap": true, + "declaration": true, + "declarationMap": false, + "types": ["node"], + "strict": true, + "moduleResolution": "node", + "noUnusedLocals": false, + "noUnusedParameters": false, + "noFallthroughCasesInSwitch": true, + "strictNullChecks": true, + "importHelpers": true, + "baseUrl": ".", + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["lib/**/*.ts", "test/**/*.ts", "index.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/schemas/tsconfig.release.json b/packages/schemas/tsconfig.release.json new file mode 100644 index 00000000..93ab99f8 --- /dev/null +++ b/packages/schemas/tsconfig.release.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["lib/**/*.ts", "index.ts"], + "exclude": ["node_modules", "dist", "lib/**/*.spec.ts"] +} From 71f1224c7ab643b5da3b1a3452c8011043229653 Mon Sep 17 00:00:00 2001 From: Igor Savin Date: Fri, 24 May 2024 00:10:02 +0300 Subject: [PATCH 2/2] Adjust coverage --- packages/core/vitest.config.mts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/vitest.config.mts b/packages/core/vitest.config.mts index 25ed77d6..149daacd 100644 --- a/packages/core/vitest.config.mts +++ b/packages/core/vitest.config.mts @@ -19,10 +19,10 @@ export default defineConfig({ reporter: ['text'], all: true, thresholds: { - lines: 35, - functions: 65, - branches: 80, - statements: 35, + lines: 30, + functions: 60, + branches: 75, + statements: 30, }, }, },