@desaubv/quik 0.0.7 → 0.0.8

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cron/index.ts","../../src/cron/cron.ts","../../src/cron/exceptions.ts","../../src/core/time.ts","../../src/cron/schedule.ts"],"sourcesContent":["export { Cron, QuikCron } from \"./cron.js\";\r\nexport { Schedule } from \"./schedule.js\";","import cron from \"node-cron\";\r\nimport { type ScheduledTask } from \"node-cron\";\r\n\r\nimport {\r\n CronTaskAlreadyExistsError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n} from \"./exceptions.js\";\r\n\r\nimport { isValidTimeZone } from \"../core/time.js\";\r\nimport type { CronConfig, CronTask, PartialCronConfig } from \"./types.js\";\r\n\r\n// Default configuration \r\nconst defaultConfig: CronConfig = {\r\n language: \"en\",\r\n};\r\n\r\n// Cron Class\r\nclass QuikCron {\r\n private tasks = new Map<string, CronTask>();\r\n private jobs = new Map<string, ScheduledTask>();\r\n\r\n #config: CronConfig = structuredClone(defaultConfig);\r\n\r\n constructor() {\r\n \r\n }\r\n\r\n add(task: CronTask): void {\r\n if (this.tasks.has(task.name)) {\r\n throw new CronTaskAlreadyExistsError(\r\n task.name\r\n );\r\n }\r\n\r\n if (!cron.validate(task.schedule)) {\r\n throw new CronInvalidScheduleError(\r\n task.schedule\r\n );\r\n }\r\n\r\n if (\r\n task.timezone &&\r\n !isValidTimeZone(task.timezone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n task.timezone\r\n );\r\n }\r\n\r\n this.tasks.set(task.name, {\r\n ...task,\r\n });\r\n }\r\n\r\n remove(name: string): boolean {\r\n this.jobs.get(name)?.stop();\r\n this.jobs.delete(name);\r\n\r\n return this.tasks.delete(name);\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.tasks.has(name);\r\n }\r\n\r\n get(name: string): CronTask | undefined {\r\n return this.tasks.get(name);\r\n }\r\n\r\n getTasks(): CronTask[] {\r\n return [...this.tasks.values()];\r\n }\r\n\r\n start(): void {\r\n for (const task of this.tasks.values()) {\r\n if (this.jobs.has(task.name)) {\r\n continue;\r\n }\r\n\r\n const timezone =\r\n task.timezone ?? this.#config.timeZone;\r\n\r\n const options = timezone\r\n ? { timezone }\r\n : {};\r\n\r\n const job = cron.schedule(\r\n task.schedule,\r\n async () => {\r\n try {\r\n await task.task();\r\n } catch (error) {\r\n const exception =\r\n new CronTaskExecutionError(\r\n task.name,\r\n error\r\n );\r\n\r\n this.#config.onError?.(exception);\r\n }\r\n },\r\n options\r\n );\r\n\r\n this.jobs.set(task.name, job);\r\n }\r\n }\r\n\r\n stop(): void {\r\n for (const job of this.jobs.values()) {\r\n job.stop();\r\n }\r\n\r\n this.jobs.clear();\r\n }\r\n\r\n config(): Readonly<CronConfig> {\r\n return Object.freeze(\r\n structuredClone(this.#config)\r\n );\r\n }\r\n\r\n setConfig(config: PartialCronConfig): void {\r\n if (\r\n config.timeZone &&\r\n !isValidTimeZone(config.timeZone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n config.timeZone\r\n );\r\n }\r\n\r\n this.#config = {\r\n ...this.#config,\r\n ...config,\r\n };\r\n }\r\n}\r\n\r\nfunction Cron(): QuikCron {\r\n return new QuikCron();\r\n}\r\n\r\nexport { QuikCron, Cron };\r\n","class CronError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n\r\n this.name = new.target.name;\r\n\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nclass CronTaskAlreadyExistsError extends CronError {\r\n constructor(name: string) {\r\n super(`Cron task \"${name}\" already exists.`);\r\n }\r\n}\r\n\r\nclass CronTaskNotFoundError extends CronError {\r\n constructor(name: string) {\r\n super(`Cron task \"${name}\" was not found.`);\r\n }\r\n}\r\n\r\nclass CronInvalidScheduleError extends CronError {\r\n constructor(schedule: string) {\r\n super(`Invalid cron schedule: \"${schedule}\".`);\r\n }\r\n}\r\n\r\nclass CronInvalidTimeZoneError extends CronError {\r\n constructor(timeZone: string) {\r\n super(`Invalid time zone: \"${timeZone}\".`);\r\n }\r\n}\r\n\r\nclass CronTaskExecutionError extends CronError {\r\n constructor(\r\n name: string,\r\n cause?: unknown\r\n ) {\r\n super(`Cron task \"${name}\" failed to execute.`);\r\n\r\n if (cause !== undefined) {\r\n this.cause = cause;\r\n }\r\n }\r\n}\r\n\r\nexport {\r\n CronError,\r\n CronTaskAlreadyExistsError,\r\n CronTaskNotFoundError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n};\r\n","function dateToString(date: Date, format: string, timeZone?: string): string {\r\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n year: \"numeric\",\r\n month: \"2-digit\",\r\n day: \"2-digit\",\r\n hour: \"2-digit\",\r\n minute: \"2-digit\",\r\n second: \"2-digit\",\r\n hourCycle: \"h23\",\r\n });\r\n\r\n const parts = formatter.formatToParts(date);\r\n const values = Object.fromEntries(\r\n parts\r\n .filter(({ type }) => type !== \"literal\")\r\n .map(({ type, value }) => [type, value])\r\n );\r\n\r\n return format.replace(/(YYYY|MM|DD|hh|mm|ss)/g, (match): string => {\r\n switch (match) {\r\n case \"YYYY\":\r\n return values.year || \"\";\r\n case \"MM\":\r\n return values.month || \"\";\r\n case \"DD\":\r\n return values.day || \"\";\r\n case \"hh\":\r\n return values.hour || \"\";\r\n case \"mm\":\r\n return values.minute || \"\";\r\n case \"ss\":\r\n return values.second || \"\";\r\n default:\r\n return match;\r\n }\r\n });\r\n}\r\n\r\nfunction isValidTimeZone(timeZone: string): boolean {\r\n try {\r\n new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n });\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport { dateToString, isValidTimeZone };\r\n","type Weekday =\r\n | \"sunday\"\r\n | \"monday\"\r\n | \"tuesday\"\r\n | \"wednesday\"\r\n | \"thursday\"\r\n | \"friday\"\r\n | \"saturday\";\r\n\r\ntype ScheduleUnit =\r\n | \"second\"\r\n | \"minute\"\r\n | \"hour\"\r\n | \"day\"\r\n | \"month\";\r\n\r\nconst weekdays: Record<Weekday, number> = {\r\n sunday: 0,\r\n monday: 1,\r\n tuesday: 2,\r\n wednesday: 3,\r\n thursday: 4,\r\n friday: 5,\r\n saturday: 6,\r\n};\r\n\r\nexport class ScheduleBuilder {\r\n #value: number;\r\n\r\n constructor(value = 1) {\r\n if (!Number.isInteger(value) || value < 1) {\r\n throw new RangeError(\r\n \"Schedule value must be a positive integer.\"\r\n );\r\n }\r\n\r\n this.#value = value;\r\n }\r\n\r\n seconds(): string {\r\n return this.#interval(\"second\");\r\n }\r\n\r\n second(): string {\r\n return this.seconds();\r\n }\r\n\r\n minutes(): string {\r\n return this.#interval(\"minute\");\r\n }\r\n\r\n minute(): string {\r\n return this.minutes();\r\n }\r\n\r\n hours(): string {\r\n return this.#interval(\"hour\");\r\n }\r\n\r\n hour(): string {\r\n return this.hours();\r\n }\r\n\r\n days(): string {\r\n return this.#interval(\"day\");\r\n }\r\n\r\n day(): string {\r\n return this.days();\r\n }\r\n\r\n months(): string {\r\n return this.#interval(\"month\");\r\n }\r\n\r\n month(): string {\r\n return this.months();\r\n }\r\n\r\n dayAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * *`;\r\n }\r\n\r\n at(time: string): string {\r\n return this.dayAt(time);\r\n }\r\n\r\n weekdayAt(\r\n weekday: Weekday,\r\n time: string\r\n ): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * ${weekdays[weekday]}`;\r\n }\r\n\r\n sundayAt(time: string): string {\r\n return this.weekdayAt(\"sunday\", time);\r\n }\r\n\r\n mondayAt(time: string): string {\r\n return this.weekdayAt(\"monday\", time);\r\n }\r\n\r\n tuesdayAt(time: string): string {\r\n return this.weekdayAt(\"tuesday\", time);\r\n }\r\n\r\n wednesdayAt(time: string): string {\r\n return this.weekdayAt(\"wednesday\", time);\r\n }\r\n\r\n thursdayAt(time: string): string {\r\n return this.weekdayAt(\"thursday\", time);\r\n }\r\n\r\n fridayAt(time: string): string {\r\n return this.weekdayAt(\"friday\", time);\r\n }\r\n\r\n saturdayAt(time: string): string {\r\n return this.weekdayAt(\"saturday\", time);\r\n }\r\n\r\n weekdaysAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * 1-5`;\r\n }\r\n\r\n weekendsAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * 0,6`;\r\n }\r\n\r\n #interval(unit: ScheduleUnit): string {\r\n switch (unit) {\r\n case \"second\":\r\n return `*/${this.#value} * * * * *`;\r\n\r\n case \"minute\":\r\n return `*/${this.#value} * * * *`;\r\n\r\n case \"hour\":\r\n return `0 */${this.#value} * * *`;\r\n\r\n case \"day\":\r\n return `0 0 */${this.#value} * *`;\r\n\r\n case \"month\":\r\n return `0 0 1 */${this.#value} *`;\r\n }\r\n }\r\n\r\n #parseTime(time: string): [number, number] {\r\n if (!/^\\d{2}:\\d{2}$/.test(time)) {\r\n throw new TypeError(\r\n `Invalid time \"${time}\". Expected HH:mm.`\r\n );\r\n }\r\n\r\n const parts = time.split(\":\");\r\n\r\n const hour = Number(parts[0]);\r\n const minute = Number(parts[1]);\r\n\r\n if (\r\n hour < 0 ||\r\n hour > 23 ||\r\n minute < 0 ||\r\n minute > 59\r\n ) {\r\n throw new RangeError(\r\n `Invalid time \"${time}\".`\r\n );\r\n }\r\n\r\n return [hour, minute];\r\n }\r\n}\r\n\r\nexport class Schedule {\r\n static every(value = 1): ScheduleBuilder {\r\n return new ScheduleBuilder(value);\r\n }\r\n\r\n static at(time: string): string {\r\n return new ScheduleBuilder().at(time);\r\n }\r\n\r\n static weekday(\r\n weekday: Weekday,\r\n time: string\r\n ): string {\r\n return new ScheduleBuilder().weekdayAt(\r\n weekday,\r\n time\r\n );\r\n }\r\n\r\n static weekdaysAt(time: string): string {\r\n return new ScheduleBuilder().weekdaysAt(time);\r\n }\r\n\r\n static weekendsAt(time: string): string {\r\n return new ScheduleBuilder().weekendsAt(time);\r\n }\r\n}"],"mappings":"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","names":["import_node_cron","cron"]}
1
+ {"version":3,"sources":["../../src/cron/index.ts","../../src/cron/cron.ts","../../src/cron/exceptions.ts","../../src/core/time.ts","../../src/cron/schedule.ts"],"sourcesContent":["export { Cron, QuikCron } from \"./cron.js\";\r\nexport { Schedule } from \"./schedule.js\";","import cron from \"node-cron\";\r\nimport { type ScheduledTask } from \"node-cron\";\r\n\r\nimport {\r\n CronTaskAlreadyExistsError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n} from \"./exceptions.js\";\r\n\r\nimport { isValidTimeZone } from \"../core/time.js\";\r\nimport type { CronConfig, CronTask, PartialCronConfig } from \"./types.js\";\r\n\r\n// Default configuration \r\nconst defaultConfig: CronConfig = {\r\n language: \"en\",\r\n};\r\n\r\n// Cron Class\r\nclass QuikCron {\r\n private tasks = new Map<string, CronTask>();\r\n private jobs = new Map<string, ScheduledTask>();\r\n\r\n #config: CronConfig = structuredClone(defaultConfig);\r\n\r\n constructor() {\r\n \r\n }\r\n\r\n add(task: CronTask): void {\r\n if (this.tasks.has(task.name)) {\r\n throw new CronTaskAlreadyExistsError(\r\n task.name\r\n );\r\n }\r\n\r\n if (!cron.validate(task.schedule)) {\r\n throw new CronInvalidScheduleError(\r\n task.schedule\r\n );\r\n }\r\n\r\n if (\r\n task.timezone &&\r\n !isValidTimeZone(task.timezone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n task.timezone\r\n );\r\n }\r\n\r\n this.tasks.set(task.name, {\r\n ...task,\r\n });\r\n }\r\n\r\n remove(name: string): boolean {\r\n this.jobs.get(name)?.stop();\r\n this.jobs.delete(name);\r\n\r\n return this.tasks.delete(name);\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.tasks.has(name);\r\n }\r\n\r\n get(name: string): CronTask | undefined {\r\n return this.tasks.get(name);\r\n }\r\n\r\n getTasks(): CronTask[] {\r\n return [...this.tasks.values()];\r\n }\r\n\r\n start(): void {\r\n for (const task of this.tasks.values()) {\r\n if (this.jobs.has(task.name)) {\r\n continue;\r\n }\r\n\r\n const timezone =\r\n task.timezone ?? this.#config.timeZone;\r\n\r\n const options = timezone\r\n ? { timezone }\r\n : {};\r\n\r\n const job = cron.schedule(\r\n task.schedule,\r\n async () => {\r\n try {\r\n await task.task();\r\n } catch (error) {\r\n const exception =\r\n new CronTaskExecutionError(\r\n task.name,\r\n error\r\n );\r\n\r\n this.#config.onError?.(exception);\r\n }\r\n },\r\n options\r\n );\r\n\r\n this.jobs.set(task.name, job);\r\n }\r\n }\r\n\r\n stop(): void {\r\n for (const job of this.jobs.values()) {\r\n job.stop();\r\n }\r\n\r\n this.jobs.clear();\r\n }\r\n\r\n config(): Readonly<CronConfig> {\r\n return Object.freeze(\r\n structuredClone(this.#config)\r\n );\r\n }\r\n\r\n setConfig(config: PartialCronConfig): void {\r\n if (\r\n config.timeZone &&\r\n !isValidTimeZone(config.timeZone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n config.timeZone\r\n );\r\n }\r\n\r\n this.#config = {\r\n ...this.#config,\r\n ...config,\r\n };\r\n }\r\n}\r\n\r\nfunction Cron(): QuikCron {\r\n return new QuikCron();\r\n}\r\n\r\nexport { QuikCron, Cron };\r\n","class CronError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n\r\n this.name = new.target.name;\r\n\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nclass CronTaskAlreadyExistsError extends CronError {\r\n constructor(name: string) {\r\n super(`Cron task \"${name}\" already exists.`);\r\n }\r\n}\r\n\r\nclass CronTaskNotFoundError extends CronError {\r\n constructor(name: string) {\r\n super(`Cron task \"${name}\" was not found.`);\r\n }\r\n}\r\n\r\nclass CronInvalidScheduleError extends CronError {\r\n constructor(schedule: string) {\r\n super(`Invalid cron schedule: \"${schedule}\".`);\r\n }\r\n}\r\n\r\nclass CronInvalidTimeZoneError extends CronError {\r\n constructor(timeZone: string) {\r\n super(`Invalid time zone: \"${timeZone}\".`);\r\n }\r\n}\r\n\r\nclass CronTaskExecutionError extends CronError {\r\n constructor(\r\n name: string,\r\n cause?: unknown\r\n ) {\r\n super(`Cron task \"${name}\" failed to execute.`);\r\n\r\n if (cause !== undefined) {\r\n this.cause = cause;\r\n }\r\n }\r\n}\r\n\r\nexport {\r\n CronError,\r\n CronTaskAlreadyExistsError,\r\n CronTaskNotFoundError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n};\r\n","function dateToString(date: Date, format: string, timeZone?: string): string {\r\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n year: \"numeric\",\r\n month: \"2-digit\",\r\n day: \"2-digit\",\r\n hour: \"2-digit\",\r\n minute: \"2-digit\",\r\n second: \"2-digit\",\r\n hourCycle: \"h23\",\r\n });\r\n\r\n const parts = formatter.formatToParts(date);\r\n const values = Object.fromEntries(\r\n parts\r\n .filter(({ type }) => type !== \"literal\")\r\n .map(({ type, value }) => [type, value])\r\n );\r\n\r\n return format.replace(/(YYYY|MM|DD|hh|mm|ss)/g, (match): string => {\r\n switch (match) {\r\n case \"YYYY\":\r\n return values.year || \"\";\r\n case \"MM\":\r\n return values.month || \"\";\r\n case \"DD\":\r\n return values.day || \"\";\r\n case \"hh\":\r\n return values.hour || \"\";\r\n case \"mm\":\r\n return values.minute || \"\";\r\n case \"ss\":\r\n return values.second || \"\";\r\n default:\r\n return match;\r\n }\r\n });\r\n}\r\n\r\nfunction isValidTimeZone(timeZone: string): boolean {\r\n try {\r\n new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n });\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport { dateToString, isValidTimeZone };\r\n","type Weekday =\r\n | \"sunday\"\r\n | \"monday\"\r\n | \"tuesday\"\r\n | \"wednesday\"\r\n | \"thursday\"\r\n | \"friday\"\r\n | \"saturday\";\r\n\r\ntype ScheduleUnit =\r\n | \"second\"\r\n | \"minute\"\r\n | \"hour\"\r\n | \"day\"\r\n | \"month\";\r\n\r\nconst weekdays: Record<Weekday, number> = {\r\n sunday: 0,\r\n monday: 1,\r\n tuesday: 2,\r\n wednesday: 3,\r\n thursday: 4,\r\n friday: 5,\r\n saturday: 6,\r\n};\r\n\r\nexport class ScheduleBuilder {\r\n #value: number;\r\n\r\n constructor(value = 1) {\r\n if (!Number.isInteger(value) || value < 1) {\r\n throw new RangeError(\r\n \"Schedule value must be a positive integer.\"\r\n );\r\n }\r\n\r\n this.#value = value;\r\n }\r\n\r\n seconds(): string {\r\n return this.#interval(\"second\");\r\n }\r\n\r\n second(): string {\r\n return this.seconds();\r\n }\r\n\r\n minutes(): string {\r\n return this.#interval(\"minute\");\r\n }\r\n\r\n minute(): string {\r\n return this.minutes();\r\n }\r\n\r\n hours(): string {\r\n return this.#interval(\"hour\");\r\n }\r\n\r\n hour(): string {\r\n return this.hours();\r\n }\r\n\r\n days(): string {\r\n return this.#interval(\"day\");\r\n }\r\n\r\n day(): string {\r\n return this.days();\r\n }\r\n\r\n months(): string {\r\n return this.#interval(\"month\");\r\n }\r\n\r\n month(): string {\r\n return this.months();\r\n }\r\n\r\n dayAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * *`;\r\n }\r\n\r\n at(time: string): string {\r\n return this.dayAt(time);\r\n }\r\n\r\n weekdayAt(\r\n weekday: Weekday,\r\n time: string\r\n ): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * ${weekdays[weekday]}`;\r\n }\r\n\r\n sundayAt(time: string): string {\r\n return this.weekdayAt(\"sunday\", time);\r\n }\r\n\r\n mondayAt(time: string): string {\r\n return this.weekdayAt(\"monday\", time);\r\n }\r\n\r\n tuesdayAt(time: string): string {\r\n return this.weekdayAt(\"tuesday\", time);\r\n }\r\n\r\n wednesdayAt(time: string): string {\r\n return this.weekdayAt(\"wednesday\", time);\r\n }\r\n\r\n thursdayAt(time: string): string {\r\n return this.weekdayAt(\"thursday\", time);\r\n }\r\n\r\n fridayAt(time: string): string {\r\n return this.weekdayAt(\"friday\", time);\r\n }\r\n\r\n saturdayAt(time: string): string {\r\n return this.weekdayAt(\"saturday\", time);\r\n }\r\n\r\n weekdaysAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * 1-5`;\r\n }\r\n\r\n weekendsAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * 0,6`;\r\n }\r\n\r\n #interval(unit: ScheduleUnit): string {\r\n switch (unit) {\r\n case \"second\":\r\n return `*/${this.#value} * * * * *`;\r\n\r\n case \"minute\":\r\n return `*/${this.#value} * * * *`;\r\n\r\n case \"hour\":\r\n return `0 */${this.#value} * * *`;\r\n\r\n case \"day\":\r\n return `0 0 */${this.#value} * *`;\r\n\r\n case \"month\":\r\n return `0 0 1 */${this.#value} *`;\r\n }\r\n }\r\n\r\n #parseTime(time: string): [number, number] {\r\n if (!/^\\d{2}:\\d{2}$/.test(time)) {\r\n throw new TypeError(\r\n `Invalid time \"${time}\". Expected HH:mm.`\r\n );\r\n }\r\n\r\n const parts = time.split(\":\");\r\n\r\n const hour = Number(parts[0]);\r\n const minute = Number(parts[1]);\r\n\r\n if (\r\n hour < 0 ||\r\n hour > 23 ||\r\n minute < 0 ||\r\n minute > 59\r\n ) {\r\n throw new RangeError(\r\n `Invalid time \"${time}\".`\r\n );\r\n }\r\n\r\n return [hour, minute];\r\n }\r\n}\r\n\r\nexport class Schedule {\r\n static every(value = 1): ScheduleBuilder {\r\n return new ScheduleBuilder(value);\r\n }\r\n\r\n static at(time: string): string {\r\n return new ScheduleBuilder().at(time);\r\n }\r\n\r\n static weekday(weekday: Weekday, time: string): string {\r\n return new ScheduleBuilder().weekdayAt(\r\n weekday,\r\n time\r\n );\r\n }\r\n\r\n static weekdaysAt(time: string): string {\r\n return new ScheduleBuilder().weekdaysAt(time);\r\n }\r\n\r\n static weekendsAt(time: string): string {\r\n return new ScheduleBuilder().weekendsAt(time);\r\n }\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uBAAiB;AACjB,IAAAA,oBAAmC;;;ACDnC,IAAM,YAAN,cAAwB,MAAM;AAAA,EAC1B,YAAY,SAAiB;AACzB,UAAM,OAAO;AAEb,SAAK,OAAO,WAAW;AAEvB,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EACpD;AACJ;AAEA,IAAM,6BAAN,cAAyC,UAAU;AAAA,EAC/C,YAAY,MAAc;AACtB,UAAM,cAAc,IAAI,mBAAmB;AAAA,EAC/C;AACJ;AAQA,IAAM,2BAAN,cAAuC,UAAU;AAAA,EAC7C,YAAY,UAAkB;AAC1B,UAAM,2BAA2B,QAAQ,IAAI;AAAA,EACjD;AACJ;AAEA,IAAM,2BAAN,cAAuC,UAAU;AAAA,EAC7C,YAAY,UAAkB;AAC1B,UAAM,uBAAuB,QAAQ,IAAI;AAAA,EAC7C;AACJ;AAEA,IAAM,yBAAN,cAAqC,UAAU;AAAA,EAC3C,YACI,MACA,OACF;AACE,UAAM,cAAc,IAAI,sBAAsB;AAE9C,QAAI,UAAU,QAAW;AACrB,WAAK,QAAQ;AAAA,IACjB;AAAA,EACJ;AACJ;;;ACNA,SAAS,gBAAgB,UAA2B;AAChD,MAAI;AACA,QAAI,KAAK,eAAe,SAAS;AAAA,MAC7B;AAAA,IACJ,CAAC;AAED,WAAO;AAAA,EACX,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;;;AFnCA,IAAM,gBAA4B;AAAA,EAC9B,UAAU;AACd;AAGA,IAAM,WAAN,MAAe;AAAA,EACH,QAAQ,oBAAI,IAAsB;AAAA,EAClC,OAAO,oBAAI,IAA2B;AAAA,EAE9C,UAAsB,gBAAgB,aAAa;AAAA,EAEnD,cAAc;AAAA,EAEd;AAAA,EAEA,IAAI,MAAsB;AACtB,QAAI,KAAK,MAAM,IAAI,KAAK,IAAI,GAAG;AAC3B,YAAM,IAAI;AAAA,QACN,KAAK;AAAA,MACT;AAAA,IACJ;AAEA,QAAI,CAAC,iBAAAC,QAAK,SAAS,KAAK,QAAQ,GAAG;AAC/B,YAAM,IAAI;AAAA,QACN,KAAK;AAAA,MACT;AAAA,IACJ;AAEA,QACI,KAAK,YACL,CAAC,gBAAgB,KAAK,QAAQ,GAChC;AACE,YAAM,IAAI;AAAA,QACN,KAAK;AAAA,MACT;AAAA,IACJ;AAEA,SAAK,MAAM,IAAI,KAAK,MAAM;AAAA,MACtB,GAAG;AAAA,IACP,CAAC;AAAA,EACL;AAAA,EAEA,OAAO,MAAuB;AAC1B,SAAK,KAAK,IAAI,IAAI,GAAG,KAAK;AAC1B,SAAK,KAAK,OAAO,IAAI;AAErB,WAAO,KAAK,MAAM,OAAO,IAAI;AAAA,EACjC;AAAA,EAEA,IAAI,MAAuB;AACvB,WAAO,KAAK,MAAM,IAAI,IAAI;AAAA,EAC9B;AAAA,EAEA,IAAI,MAAoC;AACpC,WAAO,KAAK,MAAM,IAAI,IAAI;AAAA,EAC9B;AAAA,EAEA,WAAuB;AACnB,WAAO,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC;AAAA,EAClC;AAAA,EAEA,QAAc;AACV,eAAW,QAAQ,KAAK,MAAM,OAAO,GAAG;AACpC,UAAI,KAAK,KAAK,IAAI,KAAK,IAAI,GAAG;AAC1B;AAAA,MACJ;AAEA,YAAM,WACF,KAAK,YAAY,KAAK,QAAQ;AAElC,YAAM,UAAU,WACV,EAAE,SAAS,IACX,CAAC;AAEP,YAAM,MAAM,iBAAAA,QAAK;AAAA,QACb,KAAK;AAAA,QACL,YAAY;AACR,cAAI;AACA,kBAAM,KAAK,KAAK;AAAA,UACpB,SAAS,OAAO;AACZ,kBAAM,YACF,IAAI;AAAA,cACA,KAAK;AAAA,cACL;AAAA,YACJ;AAEJ,iBAAK,QAAQ,UAAU,SAAS;AAAA,UACpC;AAAA,QACJ;AAAA,QACA;AAAA,MACJ;AAEA,WAAK,KAAK,IAAI,KAAK,MAAM,GAAG;AAAA,IAChC;AAAA,EACJ;AAAA,EAEA,OAAa;AACT,eAAW,OAAO,KAAK,KAAK,OAAO,GAAG;AAClC,UAAI,KAAK;AAAA,IACb;AAEA,SAAK,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,SAA+B;AAC3B,WAAO,OAAO;AAAA,MACV,gBAAgB,KAAK,OAAO;AAAA,IAChC;AAAA,EACJ;AAAA,EAEA,UAAU,QAAiC;AACvC,QACI,OAAO,YACP,CAAC,gBAAgB,OAAO,QAAQ,GAClC;AACE,YAAM,IAAI;AAAA,QACN,OAAO;AAAA,MACX;AAAA,IACJ;AAEA,SAAK,UAAU;AAAA,MACX,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACP;AAAA,EACJ;AACJ;AAEA,SAAS,OAAiB;AACtB,SAAO,IAAI,SAAS;AACxB;;;AG/HA,IAAM,WAAoC;AAAA,EACtC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,UAAU;AACd;AAEO,IAAM,kBAAN,MAAsB;AAAA,EACzB;AAAA,EAEA,YAAY,QAAQ,GAAG;AACnB,QAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AACvC,YAAM,IAAI;AAAA,QACN;AAAA,MACJ;AAAA,IACJ;AAEA,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,UAAkB;AACd,WAAO,KAAK,UAAU,QAAQ;AAAA,EAClC;AAAA,EAEA,SAAiB;AACb,WAAO,KAAK,QAAQ;AAAA,EACxB;AAAA,EAEA,UAAkB;AACd,WAAO,KAAK,UAAU,QAAQ;AAAA,EAClC;AAAA,EAEA,SAAiB;AACb,WAAO,KAAK,QAAQ;AAAA,EACxB;AAAA,EAEA,QAAgB;AACZ,WAAO,KAAK,UAAU,MAAM;AAAA,EAChC;AAAA,EAEA,OAAe;AACX,WAAO,KAAK,MAAM;AAAA,EACtB;AAAA,EAEA,OAAe;AACX,WAAO,KAAK,UAAU,KAAK;AAAA,EAC/B;AAAA,EAEA,MAAc;AACV,WAAO,KAAK,KAAK;AAAA,EACrB;AAAA,EAEA,SAAiB;AACb,WAAO,KAAK,UAAU,OAAO;AAAA,EACjC;AAAA,EAEA,QAAgB;AACZ,WAAO,KAAK,OAAO;AAAA,EACvB;AAAA,EAEA,MAAM,MAAsB;AACxB,UAAM,CAAC,MAAM,MAAM,IAAI,KAAK,WAAW,IAAI;AAE3C,WAAO,GAAG,MAAM,IAAI,IAAI;AAAA,EAC5B;AAAA,EAEA,GAAG,MAAsB;AACrB,WAAO,KAAK,MAAM,IAAI;AAAA,EAC1B;AAAA,EAEA,UACI,SACA,MACM;AACN,UAAM,CAAC,MAAM,MAAM,IAAI,KAAK,WAAW,IAAI;AAE3C,WAAO,GAAG,MAAM,IAAI,IAAI,QAAQ,SAAS,OAAO,CAAC;AAAA,EACrD;AAAA,EAEA,SAAS,MAAsB;AAC3B,WAAO,KAAK,UAAU,UAAU,IAAI;AAAA,EACxC;AAAA,EAEA,SAAS,MAAsB;AAC3B,WAAO,KAAK,UAAU,UAAU,IAAI;AAAA,EACxC;AAAA,EAEA,UAAU,MAAsB;AAC5B,WAAO,KAAK,UAAU,WAAW,IAAI;AAAA,EACzC;AAAA,EAEA,YAAY,MAAsB;AAC9B,WAAO,KAAK,UAAU,aAAa,IAAI;AAAA,EAC3C;AAAA,EAEA,WAAW,MAAsB;AAC7B,WAAO,KAAK,UAAU,YAAY,IAAI;AAAA,EAC1C;AAAA,EAEA,SAAS,MAAsB;AAC3B,WAAO,KAAK,UAAU,UAAU,IAAI;AAAA,EACxC;AAAA,EAEA,WAAW,MAAsB;AAC7B,WAAO,KAAK,UAAU,YAAY,IAAI;AAAA,EAC1C;AAAA,EAEA,WAAW,MAAsB;AAC7B,UAAM,CAAC,MAAM,MAAM,IAAI,KAAK,WAAW,IAAI;AAE3C,WAAO,GAAG,MAAM,IAAI,IAAI;AAAA,EAC5B;AAAA,EAEA,WAAW,MAAsB;AAC7B,UAAM,CAAC,MAAM,MAAM,IAAI,KAAK,WAAW,IAAI;AAE3C,WAAO,GAAG,MAAM,IAAI,IAAI;AAAA,EAC5B;AAAA,EAEA,UAAU,MAA4B;AAClC,YAAQ,MAAM;AAAA,MACV,KAAK;AACD,eAAO,KAAK,KAAK,MAAM;AAAA,MAE3B,KAAK;AACD,eAAO,KAAK,KAAK,MAAM;AAAA,MAE3B,KAAK;AACD,eAAO,OAAO,KAAK,MAAM;AAAA,MAE7B,KAAK;AACD,eAAO,SAAS,KAAK,MAAM;AAAA,MAE/B,KAAK;AACD,eAAO,WAAW,KAAK,MAAM;AAAA,IACrC;AAAA,EACJ;AAAA,EAEA,WAAW,MAAgC;AACvC,QAAI,CAAC,gBAAgB,KAAK,IAAI,GAAG;AAC7B,YAAM,IAAI;AAAA,QACN,iBAAiB,IAAI;AAAA,MACzB;AAAA,IACJ;AAEA,UAAM,QAAQ,KAAK,MAAM,GAAG;AAE5B,UAAM,OAAO,OAAO,MAAM,CAAC,CAAC;AAC5B,UAAM,SAAS,OAAO,MAAM,CAAC,CAAC;AAE9B,QACI,OAAO,KACP,OAAO,MACP,SAAS,KACT,SAAS,IACX;AACE,YAAM,IAAI;AAAA,QACN,iBAAiB,IAAI;AAAA,MACzB;AAAA,IACJ;AAEA,WAAO,CAAC,MAAM,MAAM;AAAA,EACxB;AACJ;AAEO,IAAM,WAAN,MAAe;AAAA,EAClB,OAAO,MAAM,QAAQ,GAAoB;AACrC,WAAO,IAAI,gBAAgB,KAAK;AAAA,EACpC;AAAA,EAEA,OAAO,GAAG,MAAsB;AAC5B,WAAO,IAAI,gBAAgB,EAAE,GAAG,IAAI;AAAA,EACxC;AAAA,EAEA,OAAO,QAAQ,SAAkB,MAAsB;AACnD,WAAO,IAAI,gBAAgB,EAAE;AAAA,MACzB;AAAA,MACA;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,OAAO,WAAW,MAAsB;AACpC,WAAO,IAAI,gBAAgB,EAAE,WAAW,IAAI;AAAA,EAChD;AAAA,EAEA,OAAO,WAAW,MAAsB;AACpC,WAAO,IAAI,gBAAgB,EAAE,WAAW,IAAI;AAAA,EAChD;AACJ;","names":["import_node_cron","cron"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cron/cron.ts","../../src/cron/exceptions.ts","../../src/core/time.ts","../../src/cron/schedule.ts"],"sourcesContent":["import cron from \"node-cron\";\r\nimport { type ScheduledTask } from \"node-cron\";\r\n\r\nimport {\r\n CronTaskAlreadyExistsError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n} from \"./exceptions.js\";\r\n\r\nimport { isValidTimeZone } from \"../core/time.js\";\r\nimport type { CronConfig, CronTask, PartialCronConfig } from \"./types.js\";\r\n\r\n// Default configuration \r\nconst defaultConfig: CronConfig = {\r\n language: \"en\",\r\n};\r\n\r\n// Cron Class\r\nclass QuikCron {\r\n private tasks = new Map<string, CronTask>();\r\n private jobs = new Map<string, ScheduledTask>();\r\n\r\n #config: CronConfig = structuredClone(defaultConfig);\r\n\r\n constructor() {\r\n \r\n }\r\n\r\n add(task: CronTask): void {\r\n if (this.tasks.has(task.name)) {\r\n throw new CronTaskAlreadyExistsError(\r\n task.name\r\n );\r\n }\r\n\r\n if (!cron.validate(task.schedule)) {\r\n throw new CronInvalidScheduleError(\r\n task.schedule\r\n );\r\n }\r\n\r\n if (\r\n task.timezone &&\r\n !isValidTimeZone(task.timezone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n task.timezone\r\n );\r\n }\r\n\r\n this.tasks.set(task.name, {\r\n ...task,\r\n });\r\n }\r\n\r\n remove(name: string): boolean {\r\n this.jobs.get(name)?.stop();\r\n this.jobs.delete(name);\r\n\r\n return this.tasks.delete(name);\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.tasks.has(name);\r\n }\r\n\r\n get(name: string): CronTask | undefined {\r\n return this.tasks.get(name);\r\n }\r\n\r\n getTasks(): CronTask[] {\r\n return [...this.tasks.values()];\r\n }\r\n\r\n start(): void {\r\n for (const task of this.tasks.values()) {\r\n if (this.jobs.has(task.name)) {\r\n continue;\r\n }\r\n\r\n const timezone =\r\n task.timezone ?? this.#config.timeZone;\r\n\r\n const options = timezone\r\n ? { timezone }\r\n : {};\r\n\r\n const job = cron.schedule(\r\n task.schedule,\r\n async () => {\r\n try {\r\n await task.task();\r\n } catch (error) {\r\n const exception =\r\n new CronTaskExecutionError(\r\n task.name,\r\n error\r\n );\r\n\r\n this.#config.onError?.(exception);\r\n }\r\n },\r\n options\r\n );\r\n\r\n this.jobs.set(task.name, job);\r\n }\r\n }\r\n\r\n stop(): void {\r\n for (const job of this.jobs.values()) {\r\n job.stop();\r\n }\r\n\r\n this.jobs.clear();\r\n }\r\n\r\n config(): Readonly<CronConfig> {\r\n return Object.freeze(\r\n structuredClone(this.#config)\r\n );\r\n }\r\n\r\n setConfig(config: PartialCronConfig): void {\r\n if (\r\n config.timeZone &&\r\n !isValidTimeZone(config.timeZone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n config.timeZone\r\n );\r\n }\r\n\r\n this.#config = {\r\n ...this.#config,\r\n ...config,\r\n };\r\n }\r\n}\r\n\r\nfunction Cron(): QuikCron {\r\n return new QuikCron();\r\n}\r\n\r\nexport { QuikCron, Cron };\r\n","class CronError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n\r\n this.name = new.target.name;\r\n\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nclass CronTaskAlreadyExistsError extends CronError {\r\n constructor(name: string) {\r\n super(`Cron task \"${name}\" already exists.`);\r\n }\r\n}\r\n\r\nclass CronTaskNotFoundError extends CronError {\r\n constructor(name: string) {\r\n super(`Cron task \"${name}\" was not found.`);\r\n }\r\n}\r\n\r\nclass CronInvalidScheduleError extends CronError {\r\n constructor(schedule: string) {\r\n super(`Invalid cron schedule: \"${schedule}\".`);\r\n }\r\n}\r\n\r\nclass CronInvalidTimeZoneError extends CronError {\r\n constructor(timeZone: string) {\r\n super(`Invalid time zone: \"${timeZone}\".`);\r\n }\r\n}\r\n\r\nclass CronTaskExecutionError extends CronError {\r\n constructor(\r\n name: string,\r\n cause?: unknown\r\n ) {\r\n super(`Cron task \"${name}\" failed to execute.`);\r\n\r\n if (cause !== undefined) {\r\n this.cause = cause;\r\n }\r\n }\r\n}\r\n\r\nexport {\r\n CronError,\r\n CronTaskAlreadyExistsError,\r\n CronTaskNotFoundError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n};\r\n","function dateToString(date: Date, format: string, timeZone?: string): string {\r\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n year: \"numeric\",\r\n month: \"2-digit\",\r\n day: \"2-digit\",\r\n hour: \"2-digit\",\r\n minute: \"2-digit\",\r\n second: \"2-digit\",\r\n hourCycle: \"h23\",\r\n });\r\n\r\n const parts = formatter.formatToParts(date);\r\n const values = Object.fromEntries(\r\n parts\r\n .filter(({ type }) => type !== \"literal\")\r\n .map(({ type, value }) => [type, value])\r\n );\r\n\r\n return format.replace(/(YYYY|MM|DD|hh|mm|ss)/g, (match): string => {\r\n switch (match) {\r\n case \"YYYY\":\r\n return values.year || \"\";\r\n case \"MM\":\r\n return values.month || \"\";\r\n case \"DD\":\r\n return values.day || \"\";\r\n case \"hh\":\r\n return values.hour || \"\";\r\n case \"mm\":\r\n return values.minute || \"\";\r\n case \"ss\":\r\n return values.second || \"\";\r\n default:\r\n return match;\r\n }\r\n });\r\n}\r\n\r\nfunction isValidTimeZone(timeZone: string): boolean {\r\n try {\r\n new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n });\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport { dateToString, isValidTimeZone };\r\n","type Weekday =\r\n | \"sunday\"\r\n | \"monday\"\r\n | \"tuesday\"\r\n | \"wednesday\"\r\n | \"thursday\"\r\n | \"friday\"\r\n | \"saturday\";\r\n\r\ntype ScheduleUnit =\r\n | \"second\"\r\n | \"minute\"\r\n | \"hour\"\r\n | \"day\"\r\n | \"month\";\r\n\r\nconst weekdays: Record<Weekday, number> = {\r\n sunday: 0,\r\n monday: 1,\r\n tuesday: 2,\r\n wednesday: 3,\r\n thursday: 4,\r\n friday: 5,\r\n saturday: 6,\r\n};\r\n\r\nexport class ScheduleBuilder {\r\n #value: number;\r\n\r\n constructor(value = 1) {\r\n if (!Number.isInteger(value) || value < 1) {\r\n throw new RangeError(\r\n \"Schedule value must be a positive integer.\"\r\n );\r\n }\r\n\r\n this.#value = value;\r\n }\r\n\r\n seconds(): string {\r\n return this.#interval(\"second\");\r\n }\r\n\r\n second(): string {\r\n return this.seconds();\r\n }\r\n\r\n minutes(): string {\r\n return this.#interval(\"minute\");\r\n }\r\n\r\n minute(): string {\r\n return this.minutes();\r\n }\r\n\r\n hours(): string {\r\n return this.#interval(\"hour\");\r\n }\r\n\r\n hour(): string {\r\n return this.hours();\r\n }\r\n\r\n days(): string {\r\n return this.#interval(\"day\");\r\n }\r\n\r\n day(): string {\r\n return this.days();\r\n }\r\n\r\n months(): string {\r\n return this.#interval(\"month\");\r\n }\r\n\r\n month(): string {\r\n return this.months();\r\n }\r\n\r\n dayAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * *`;\r\n }\r\n\r\n at(time: string): string {\r\n return this.dayAt(time);\r\n }\r\n\r\n weekdayAt(\r\n weekday: Weekday,\r\n time: string\r\n ): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * ${weekdays[weekday]}`;\r\n }\r\n\r\n sundayAt(time: string): string {\r\n return this.weekdayAt(\"sunday\", time);\r\n }\r\n\r\n mondayAt(time: string): string {\r\n return this.weekdayAt(\"monday\", time);\r\n }\r\n\r\n tuesdayAt(time: string): string {\r\n return this.weekdayAt(\"tuesday\", time);\r\n }\r\n\r\n wednesdayAt(time: string): string {\r\n return this.weekdayAt(\"wednesday\", time);\r\n }\r\n\r\n thursdayAt(time: string): string {\r\n return this.weekdayAt(\"thursday\", time);\r\n }\r\n\r\n fridayAt(time: string): string {\r\n return this.weekdayAt(\"friday\", time);\r\n }\r\n\r\n saturdayAt(time: string): string {\r\n return this.weekdayAt(\"saturday\", time);\r\n }\r\n\r\n weekdaysAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * 1-5`;\r\n }\r\n\r\n weekendsAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * 0,6`;\r\n }\r\n\r\n #interval(unit: ScheduleUnit): string {\r\n switch (unit) {\r\n case \"second\":\r\n return `*/${this.#value} * * * * *`;\r\n\r\n case \"minute\":\r\n return `*/${this.#value} * * * *`;\r\n\r\n case \"hour\":\r\n return `0 */${this.#value} * * *`;\r\n\r\n case \"day\":\r\n return `0 0 */${this.#value} * *`;\r\n\r\n case \"month\":\r\n return `0 0 1 */${this.#value} *`;\r\n }\r\n }\r\n\r\n #parseTime(time: string): [number, number] {\r\n if (!/^\\d{2}:\\d{2}$/.test(time)) {\r\n throw new TypeError(\r\n `Invalid time \"${time}\". Expected HH:mm.`\r\n );\r\n }\r\n\r\n const parts = time.split(\":\");\r\n\r\n const hour = Number(parts[0]);\r\n const minute = Number(parts[1]);\r\n\r\n if (\r\n hour < 0 ||\r\n hour > 23 ||\r\n minute < 0 ||\r\n minute > 59\r\n ) {\r\n throw new RangeError(\r\n `Invalid time \"${time}\".`\r\n );\r\n }\r\n\r\n return [hour, minute];\r\n }\r\n}\r\n\r\nexport class Schedule {\r\n static every(value = 1): ScheduleBuilder {\r\n return new ScheduleBuilder(value);\r\n }\r\n\r\n static at(time: string): string {\r\n return new ScheduleBuilder().at(time);\r\n }\r\n\r\n static weekday(\r\n weekday: Weekday,\r\n time: string\r\n ): string {\r\n return new ScheduleBuilder().weekdayAt(\r\n weekday,\r\n time\r\n );\r\n }\r\n\r\n static weekdaysAt(time: string): string {\r\n return new ScheduleBuilder().weekdaysAt(time);\r\n }\r\n\r\n static weekendsAt(time: string): string {\r\n return new ScheduleBuilder().weekendsAt(time);\r\n }\r\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cron/cron.ts","../../src/cron/exceptions.ts","../../src/core/time.ts","../../src/cron/schedule.ts"],"sourcesContent":["import cron from \"node-cron\";\r\nimport { type ScheduledTask } from \"node-cron\";\r\n\r\nimport {\r\n CronTaskAlreadyExistsError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n} from \"./exceptions.js\";\r\n\r\nimport { isValidTimeZone } from \"../core/time.js\";\r\nimport type { CronConfig, CronTask, PartialCronConfig } from \"./types.js\";\r\n\r\n// Default configuration \r\nconst defaultConfig: CronConfig = {\r\n language: \"en\",\r\n};\r\n\r\n// Cron Class\r\nclass QuikCron {\r\n private tasks = new Map<string, CronTask>();\r\n private jobs = new Map<string, ScheduledTask>();\r\n\r\n #config: CronConfig = structuredClone(defaultConfig);\r\n\r\n constructor() {\r\n \r\n }\r\n\r\n add(task: CronTask): void {\r\n if (this.tasks.has(task.name)) {\r\n throw new CronTaskAlreadyExistsError(\r\n task.name\r\n );\r\n }\r\n\r\n if (!cron.validate(task.schedule)) {\r\n throw new CronInvalidScheduleError(\r\n task.schedule\r\n );\r\n }\r\n\r\n if (\r\n task.timezone &&\r\n !isValidTimeZone(task.timezone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n task.timezone\r\n );\r\n }\r\n\r\n this.tasks.set(task.name, {\r\n ...task,\r\n });\r\n }\r\n\r\n remove(name: string): boolean {\r\n this.jobs.get(name)?.stop();\r\n this.jobs.delete(name);\r\n\r\n return this.tasks.delete(name);\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.tasks.has(name);\r\n }\r\n\r\n get(name: string): CronTask | undefined {\r\n return this.tasks.get(name);\r\n }\r\n\r\n getTasks(): CronTask[] {\r\n return [...this.tasks.values()];\r\n }\r\n\r\n start(): void {\r\n for (const task of this.tasks.values()) {\r\n if (this.jobs.has(task.name)) {\r\n continue;\r\n }\r\n\r\n const timezone =\r\n task.timezone ?? this.#config.timeZone;\r\n\r\n const options = timezone\r\n ? { timezone }\r\n : {};\r\n\r\n const job = cron.schedule(\r\n task.schedule,\r\n async () => {\r\n try {\r\n await task.task();\r\n } catch (error) {\r\n const exception =\r\n new CronTaskExecutionError(\r\n task.name,\r\n error\r\n );\r\n\r\n this.#config.onError?.(exception);\r\n }\r\n },\r\n options\r\n );\r\n\r\n this.jobs.set(task.name, job);\r\n }\r\n }\r\n\r\n stop(): void {\r\n for (const job of this.jobs.values()) {\r\n job.stop();\r\n }\r\n\r\n this.jobs.clear();\r\n }\r\n\r\n config(): Readonly<CronConfig> {\r\n return Object.freeze(\r\n structuredClone(this.#config)\r\n );\r\n }\r\n\r\n setConfig(config: PartialCronConfig): void {\r\n if (\r\n config.timeZone &&\r\n !isValidTimeZone(config.timeZone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n config.timeZone\r\n );\r\n }\r\n\r\n this.#config = {\r\n ...this.#config,\r\n ...config,\r\n };\r\n }\r\n}\r\n\r\nfunction Cron(): QuikCron {\r\n return new QuikCron();\r\n}\r\n\r\nexport { QuikCron, Cron };\r\n","class CronError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n\r\n this.name = new.target.name;\r\n\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nclass CronTaskAlreadyExistsError extends CronError {\r\n constructor(name: string) {\r\n super(`Cron task \"${name}\" already exists.`);\r\n }\r\n}\r\n\r\nclass CronTaskNotFoundError extends CronError {\r\n constructor(name: string) {\r\n super(`Cron task \"${name}\" was not found.`);\r\n }\r\n}\r\n\r\nclass CronInvalidScheduleError extends CronError {\r\n constructor(schedule: string) {\r\n super(`Invalid cron schedule: \"${schedule}\".`);\r\n }\r\n}\r\n\r\nclass CronInvalidTimeZoneError extends CronError {\r\n constructor(timeZone: string) {\r\n super(`Invalid time zone: \"${timeZone}\".`);\r\n }\r\n}\r\n\r\nclass CronTaskExecutionError extends CronError {\r\n constructor(\r\n name: string,\r\n cause?: unknown\r\n ) {\r\n super(`Cron task \"${name}\" failed to execute.`);\r\n\r\n if (cause !== undefined) {\r\n this.cause = cause;\r\n }\r\n }\r\n}\r\n\r\nexport {\r\n CronError,\r\n CronTaskAlreadyExistsError,\r\n CronTaskNotFoundError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n};\r\n","function dateToString(date: Date, format: string, timeZone?: string): string {\r\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n year: \"numeric\",\r\n month: \"2-digit\",\r\n day: \"2-digit\",\r\n hour: \"2-digit\",\r\n minute: \"2-digit\",\r\n second: \"2-digit\",\r\n hourCycle: \"h23\",\r\n });\r\n\r\n const parts = formatter.formatToParts(date);\r\n const values = Object.fromEntries(\r\n parts\r\n .filter(({ type }) => type !== \"literal\")\r\n .map(({ type, value }) => [type, value])\r\n );\r\n\r\n return format.replace(/(YYYY|MM|DD|hh|mm|ss)/g, (match): string => {\r\n switch (match) {\r\n case \"YYYY\":\r\n return values.year || \"\";\r\n case \"MM\":\r\n return values.month || \"\";\r\n case \"DD\":\r\n return values.day || \"\";\r\n case \"hh\":\r\n return values.hour || \"\";\r\n case \"mm\":\r\n return values.minute || \"\";\r\n case \"ss\":\r\n return values.second || \"\";\r\n default:\r\n return match;\r\n }\r\n });\r\n}\r\n\r\nfunction isValidTimeZone(timeZone: string): boolean {\r\n try {\r\n new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n });\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport { dateToString, isValidTimeZone };\r\n","type Weekday =\r\n | \"sunday\"\r\n | \"monday\"\r\n | \"tuesday\"\r\n | \"wednesday\"\r\n | \"thursday\"\r\n | \"friday\"\r\n | \"saturday\";\r\n\r\ntype ScheduleUnit =\r\n | \"second\"\r\n | \"minute\"\r\n | \"hour\"\r\n | \"day\"\r\n | \"month\";\r\n\r\nconst weekdays: Record<Weekday, number> = {\r\n sunday: 0,\r\n monday: 1,\r\n tuesday: 2,\r\n wednesday: 3,\r\n thursday: 4,\r\n friday: 5,\r\n saturday: 6,\r\n};\r\n\r\nexport class ScheduleBuilder {\r\n #value: number;\r\n\r\n constructor(value = 1) {\r\n if (!Number.isInteger(value) || value < 1) {\r\n throw new RangeError(\r\n \"Schedule value must be a positive integer.\"\r\n );\r\n }\r\n\r\n this.#value = value;\r\n }\r\n\r\n seconds(): string {\r\n return this.#interval(\"second\");\r\n }\r\n\r\n second(): string {\r\n return this.seconds();\r\n }\r\n\r\n minutes(): string {\r\n return this.#interval(\"minute\");\r\n }\r\n\r\n minute(): string {\r\n return this.minutes();\r\n }\r\n\r\n hours(): string {\r\n return this.#interval(\"hour\");\r\n }\r\n\r\n hour(): string {\r\n return this.hours();\r\n }\r\n\r\n days(): string {\r\n return this.#interval(\"day\");\r\n }\r\n\r\n day(): string {\r\n return this.days();\r\n }\r\n\r\n months(): string {\r\n return this.#interval(\"month\");\r\n }\r\n\r\n month(): string {\r\n return this.months();\r\n }\r\n\r\n dayAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * *`;\r\n }\r\n\r\n at(time: string): string {\r\n return this.dayAt(time);\r\n }\r\n\r\n weekdayAt(\r\n weekday: Weekday,\r\n time: string\r\n ): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * ${weekdays[weekday]}`;\r\n }\r\n\r\n sundayAt(time: string): string {\r\n return this.weekdayAt(\"sunday\", time);\r\n }\r\n\r\n mondayAt(time: string): string {\r\n return this.weekdayAt(\"monday\", time);\r\n }\r\n\r\n tuesdayAt(time: string): string {\r\n return this.weekdayAt(\"tuesday\", time);\r\n }\r\n\r\n wednesdayAt(time: string): string {\r\n return this.weekdayAt(\"wednesday\", time);\r\n }\r\n\r\n thursdayAt(time: string): string {\r\n return this.weekdayAt(\"thursday\", time);\r\n }\r\n\r\n fridayAt(time: string): string {\r\n return this.weekdayAt(\"friday\", time);\r\n }\r\n\r\n saturdayAt(time: string): string {\r\n return this.weekdayAt(\"saturday\", time);\r\n }\r\n\r\n weekdaysAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * 1-5`;\r\n }\r\n\r\n weekendsAt(time: string): string {\r\n const [hour, minute] = this.#parseTime(time);\r\n\r\n return `${minute} ${hour} * * 0,6`;\r\n }\r\n\r\n #interval(unit: ScheduleUnit): string {\r\n switch (unit) {\r\n case \"second\":\r\n return `*/${this.#value} * * * * *`;\r\n\r\n case \"minute\":\r\n return `*/${this.#value} * * * *`;\r\n\r\n case \"hour\":\r\n return `0 */${this.#value} * * *`;\r\n\r\n case \"day\":\r\n return `0 0 */${this.#value} * *`;\r\n\r\n case \"month\":\r\n return `0 0 1 */${this.#value} *`;\r\n }\r\n }\r\n\r\n #parseTime(time: string): [number, number] {\r\n if (!/^\\d{2}:\\d{2}$/.test(time)) {\r\n throw new TypeError(\r\n `Invalid time \"${time}\". Expected HH:mm.`\r\n );\r\n }\r\n\r\n const parts = time.split(\":\");\r\n\r\n const hour = Number(parts[0]);\r\n const minute = Number(parts[1]);\r\n\r\n if (\r\n hour < 0 ||\r\n hour > 23 ||\r\n minute < 0 ||\r\n minute > 59\r\n ) {\r\n throw new RangeError(\r\n `Invalid time \"${time}\".`\r\n );\r\n }\r\n\r\n return [hour, minute];\r\n }\r\n}\r\n\r\nexport class Schedule {\r\n static every(value = 1): ScheduleBuilder {\r\n return new ScheduleBuilder(value);\r\n }\r\n\r\n static at(time: string): string {\r\n return new ScheduleBuilder().at(time);\r\n }\r\n\r\n static weekday(weekday: Weekday, time: string): string {\r\n return new ScheduleBuilder().weekdayAt(\r\n weekday,\r\n time\r\n );\r\n }\r\n\r\n static weekdaysAt(time: string): string {\r\n return new ScheduleBuilder().weekdaysAt(time);\r\n }\r\n\r\n static weekendsAt(time: string): string {\r\n return new ScheduleBuilder().weekendsAt(time);\r\n }\r\n}"],"mappings":"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","names":[]}
@@ -20,10 +20,223 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/http/index.ts
21
21
  var http_exports = {};
22
22
  __export(http_exports, {
23
- Status: () => Status
23
+ Status: () => Status,
24
+ Types: () => Types,
25
+ ValidationException: () => ValidationException,
26
+ Validator: () => Validator
24
27
  });
25
28
  module.exports = __toCommonJS(http_exports);
26
29
 
30
+ // src/http/validatorTypes.ts
31
+ var ArrayType = class {
32
+ type;
33
+ description = "array";
34
+ empty = false;
35
+ constructor(...type) {
36
+ this.type = [...type];
37
+ this.empty = false;
38
+ const types = type.map((t) => t.description);
39
+ this.description = `array(${types.join(" | ")})`;
40
+ }
41
+ canBeEmpty() {
42
+ this.empty = true;
43
+ return this;
44
+ }
45
+ };
46
+ var ObjectType = class {
47
+ fields;
48
+ description = "object";
49
+ constructor(fields) {
50
+ this.fields = fields;
51
+ const names = Object.keys(fields);
52
+ this.description = `object{${names.join(", ")}}`;
53
+ }
54
+ };
55
+ function Array2(...type) {
56
+ return new ArrayType(...type);
57
+ }
58
+ function Struct(fields) {
59
+ return new ObjectType(fields);
60
+ }
61
+ var Types = {
62
+ String: /* @__PURE__ */ Symbol("string"),
63
+ Number: /* @__PURE__ */ Symbol("number"),
64
+ Int: /* @__PURE__ */ Symbol("int"),
65
+ Float: /* @__PURE__ */ Symbol("float"),
66
+ Boolean: /* @__PURE__ */ Symbol("boolean"),
67
+ Object: /* @__PURE__ */ Symbol("object"),
68
+ Null: /* @__PURE__ */ Symbol("null"),
69
+ Array: Array2,
70
+ Struct
71
+ };
72
+
73
+ // src/http/exceptions.ts
74
+ var ValidationException = class extends Error {
75
+ constructor(message) {
76
+ super(message);
77
+ this.name = "ValidationException";
78
+ }
79
+ };
80
+ var RequestBodyUndefinedException = class extends ValidationException {
81
+ constructor() {
82
+ super("Request body is undefined");
83
+ this.name = "RequestBodyUndefinedException";
84
+ }
85
+ };
86
+ var InvalidBodyException = class extends ValidationException {
87
+ constructor() {
88
+ super("Request body must be an object");
89
+ this.name = "InvalidBodyException";
90
+ }
91
+ };
92
+ var RequiredFieldException = class extends ValidationException {
93
+ constructor(field) {
94
+ super(`Field "${field}" is required`);
95
+ this.field = field;
96
+ this.name = "RequiredFieldException";
97
+ }
98
+ field;
99
+ };
100
+ var InvalidTypeException = class extends ValidationException {
101
+ constructor(field, expected, received) {
102
+ super(
103
+ `Field "${field}" must be of type ${expected}, received ${received}`
104
+ );
105
+ this.field = field;
106
+ this.expected = expected;
107
+ this.received = received;
108
+ this.name = "InvalidTypeException";
109
+ }
110
+ field;
111
+ expected;
112
+ received;
113
+ };
114
+ var EmptyArrayException = class extends ValidationException {
115
+ constructor(field) {
116
+ super(`Field "${field}" must not be an empty array`);
117
+ this.field = field;
118
+ this.name = "EmptyArrayException";
119
+ }
120
+ field;
121
+ };
122
+
123
+ // src/http/validador.ts
124
+ var Validator = {
125
+ body(body, fields) {
126
+ if (body === void 0) {
127
+ throw new RequestBodyUndefinedException();
128
+ }
129
+ if (typeof body !== "object" || body === null || Array.isArray(body)) {
130
+ throw new InvalidBodyException();
131
+ }
132
+ return validateObject(body, fields);
133
+ }
134
+ };
135
+ function validateObject(body, fields, parentPath = "") {
136
+ if (typeof body !== "object" || body === null || Array.isArray(body)) {
137
+ throw new InvalidBodyException();
138
+ }
139
+ const bodyData = body;
140
+ const data = {};
141
+ for (const name in fields) {
142
+ const field = fields[name];
143
+ if (!field) {
144
+ continue;
145
+ }
146
+ const fieldPath = parentPath ? `${parentPath}.${name}` : name;
147
+ let value = bodyData[name];
148
+ if (field.required && value === void 0) {
149
+ throw new RequiredFieldException(fieldPath);
150
+ }
151
+ if (value === void 0) {
152
+ continue;
153
+ }
154
+ if (!validateType(field.type, value, fieldPath)) {
155
+ const type = getTypeDescription(field.type);
156
+ throw new InvalidTypeException(
157
+ fieldPath,
158
+ type,
159
+ whatTypeIs(value)
160
+ );
161
+ }
162
+ if (field.validator) {
163
+ const result = field.validator(value);
164
+ if (result instanceof ValidationException) {
165
+ throw result;
166
+ }
167
+ value = result;
168
+ }
169
+ data[name] = value;
170
+ }
171
+ return data;
172
+ }
173
+ function validateType(type, value, fieldName = "") {
174
+ if (Array.isArray(type)) {
175
+ return type.some(
176
+ (t) => validateType(t, value, fieldName)
177
+ );
178
+ }
179
+ if (type instanceof ArrayType) {
180
+ if (!Array.isArray(value)) {
181
+ return false;
182
+ }
183
+ if (!type.empty && value.length === 0) {
184
+ throw new EmptyArrayException(fieldName);
185
+ }
186
+ for (const item of value) {
187
+ if (!validateType(type.type, item, fieldName)) {
188
+ return false;
189
+ }
190
+ }
191
+ return true;
192
+ }
193
+ if (type instanceof ObjectType) {
194
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
195
+ return false;
196
+ }
197
+ validateObject(
198
+ value,
199
+ type.fields,
200
+ fieldName
201
+ );
202
+ return true;
203
+ }
204
+ switch (type?.description) {
205
+ case "null":
206
+ return value === null;
207
+ case "string":
208
+ return typeof value === "string";
209
+ case "number":
210
+ case "float":
211
+ return typeof value === "number";
212
+ case "int":
213
+ return typeof value === "number" && Number.isInteger(value);
214
+ case "boolean":
215
+ return typeof value === "boolean";
216
+ case "object":
217
+ return typeof value === "object" && value !== null && !Array.isArray(value);
218
+ }
219
+ return false;
220
+ }
221
+ function getTypeDescription(type) {
222
+ if (Array.isArray(type)) {
223
+ return type.map((t) => getTypeDescription(t)).join(" | ");
224
+ }
225
+ return type.description || "";
226
+ }
227
+ function whatTypeIs(value) {
228
+ if (typeof value === "number" && Number.isInteger(value)) {
229
+ return "int";
230
+ }
231
+ if (Array.isArray(value)) {
232
+ return "array";
233
+ }
234
+ if (value === null) {
235
+ return "null";
236
+ }
237
+ return typeof value;
238
+ }
239
+
27
240
  // src/http/status.ts
28
241
  var Status = {
29
242
  // 1xx Informational
@@ -94,6 +307,9 @@ var Status = {
94
307
  };
95
308
  // Annotate the CommonJS export names for ESM import in node:
96
309
  0 && (module.exports = {
97
- Status
310
+ Status,
311
+ Types,
312
+ ValidationException,
313
+ Validator
98
314
  });
99
315
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/http/index.ts","../../src/http/status.ts"],"sourcesContent":["export { Status } from \"./status.js\";","const Status = {\r\n // 1xx Informational\r\n CONTINUE: 100,\r\n SWITCHING_PROTOCOLS: 101,\r\n PROCESSING: 102,\r\n EARLY_HINTS: 103,\r\n\r\n // 2xx Success\r\n OK: 200,\r\n CREATED: 201,\r\n ACCEPTED: 202,\r\n NON_AUTHORITATIVE_INFORMATION: 203,\r\n NO_CONTENT: 204,\r\n RESET_CONTENT: 205,\r\n PARTIAL_CONTENT: 206,\r\n MULTI_STATUS: 207,\r\n ALREADY_REPORTED: 208,\r\n IM_USED: 226,\r\n\r\n // 3xx Redirection\r\n MULTIPLE_CHOICES: 300,\r\n MOVED_PERMANENTLY: 301,\r\n FOUND: 302,\r\n SEE_OTHER: 303,\r\n NOT_MODIFIED: 304,\r\n TEMPORARY_REDIRECT: 307,\r\n PERMANENT_REDIRECT: 308,\r\n\r\n // 4xx Client Errors\r\n BAD_REQUEST: 400,\r\n UNAUTHORIZED: 401,\r\n PAYMENT_REQUIRED: 402,\r\n FORBIDDEN: 403,\r\n NOT_FOUND: 404,\r\n METHOD_NOT_ALLOWED: 405,\r\n NOT_ACCEPTABLE: 406,\r\n PROXY_AUTHENTICATION_REQUIRED: 407,\r\n REQUEST_TIMEOUT: 408,\r\n CONFLICT: 409,\r\n GONE: 410,\r\n LENGTH_REQUIRED: 411,\r\n PRECONDITION_FAILED: 412,\r\n PAYLOAD_TOO_LARGE: 413,\r\n URI_TOO_LONG: 414,\r\n UNSUPPORTED_MEDIA_TYPE: 415,\r\n RANGE_NOT_SATISFIABLE: 416,\r\n EXPECTATION_FAILED: 417,\r\n IM_A_TEAPOT: 418,\r\n MISDIRECTED_REQUEST: 421,\r\n UNPROCESSABLE_CONTENT: 422,\r\n LOCKED: 423,\r\n FAILED_DEPENDENCY: 424,\r\n UPGRADE_REQUIRED: 426,\r\n PRECONDITION_REQUIRED: 428,\r\n TOO_MANY_REQUESTS: 429,\r\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\r\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\r\n\r\n // 5xx Server Errors\r\n INTERNAL_SERVER_ERROR: 500,\r\n NOT_IMPLEMENTED: 501,\r\n BAD_GATEWAY: 502,\r\n SERVICE_UNAVAILABLE: 503,\r\n GATEWAY_TIMEOUT: 504,\r\n HTTP_VERSION_NOT_SUPPORTED: 505,\r\n VARIANT_ALSO_NEGOTIATES: 506,\r\n INSUFFICIENT_STORAGE: 507,\r\n LOOP_DETECTED: 508,\r\n NOT_EXTENDED: 510,\r\n NETWORK_AUTHENTICATION_REQUIRED: 511\r\n} as const;\r\n\r\nexport {\r\n Status\r\n};"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAM,SAAS;AAAA;AAAA,EAEX,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,YAAY;AAAA,EACZ,aAAa;AAAA;AAAA,EAGb,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,UAAU;AAAA,EACV,+BAA+B;AAAA,EAC/B,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,SAAS;AAAA;AAAA,EAGT,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,OAAO;AAAA,EACP,WAAW;AAAA,EACX,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,oBAAoB;AAAA;AAAA,EAGpB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,+BAA+B;AAAA,EAC/B,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,QAAQ;AAAA,EACR,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,iCAAiC;AAAA,EACjC,+BAA+B;AAAA;AAAA,EAG/B,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,iCAAiC;AACrC;","names":[]}
1
+ {"version":3,"sources":["../../src/http/index.ts","../../src/http/validatorTypes.ts","../../src/http/exceptions.ts","../../src/http/validador.ts","../../src/http/status.ts"],"sourcesContent":["export { Types } from \"./validatorTypes.js\";\r\n\r\nexport { ValidationException } from \"./exceptions.js\";\r\nexport { Validator } from \"./validador.js\";\r\nexport { Status } from \"./status.js\";\r\n","import type { ValidationException } from \"./exceptions.js\";\r\n\r\nexport class ArrayType {\r\n type: PrimitiveType[];\r\n description = \"array\";\r\n empty: boolean = false;\r\n\r\n constructor(...type: PrimitiveType[]) {\r\n this.type = [...type];\r\n this.empty = false;\r\n\r\n const types = type.map((t) => t.description);\r\n this.description = `array(${types.join(\" | \")})`;\r\n }\r\n\r\n canBeEmpty() {\r\n this.empty = true;\r\n return this;\r\n }\r\n}\r\n\r\nexport type FieldDefinition = {\r\n type: ValidatorType;\r\n required?: boolean;\r\n validator?: (value: unknown) => unknown | ValidationException;\r\n};\r\n\r\nexport type ObjectFields = {\r\n [name: string]: FieldDefinition;\r\n};\r\n\r\nexport class ObjectType {\r\n fields: ObjectFields;\r\n description = \"object\";\r\n\r\n constructor(fields: ObjectFields) {\r\n this.fields = fields;\r\n\r\n const names = Object.keys(fields);\r\n\r\n this.description = `object{${names.join(\", \")}}`;\r\n }\r\n}\r\n\r\nfunction Array(...type: PrimitiveType[]) {\r\n return new ArrayType(...type);\r\n}\r\n\r\nfunction Struct(fields: ObjectFields) {\r\n return new ObjectType(fields);\r\n}\r\n\r\nexport const Types = {\r\n String: Symbol(\"string\"),\r\n Number: Symbol(\"number\"),\r\n Int: Symbol(\"int\"),\r\n Float: Symbol(\"float\"),\r\n Boolean: Symbol(\"boolean\"),\r\n Object: Symbol(\"object\"),\r\n Null: Symbol(\"null\"),\r\n\r\n Array,\r\n Struct,\r\n};\r\n\r\nexport type PrimitiveType =\r\n | typeof Types.String\r\n | typeof Types.Number\r\n | typeof Types.Int\r\n | typeof Types.Float\r\n | typeof Types.Boolean\r\n | typeof Types.Object\r\n | typeof Types.Null;\r\n\r\nexport type MultiType = PrimitiveType[];\r\n\r\nexport type ValidatorType =\r\n | PrimitiveType\r\n | MultiType\r\n | ArrayType\r\n | ObjectType;","class ValidationException extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n\r\n this.name = \"ValidationException\";\r\n }\r\n}\r\n\r\nclass RequestBodyUndefinedException extends ValidationException {\r\n constructor() {\r\n super(\"Request body is undefined\");\r\n\r\n this.name = \"RequestBodyUndefinedException\";\r\n }\r\n}\r\n\r\nclass InvalidBodyException extends ValidationException {\r\n constructor() {\r\n super(\"Request body must be an object\");\r\n\r\n this.name = \"InvalidBodyException\";\r\n }\r\n}\r\n\r\nclass RequiredFieldException extends ValidationException {\r\n constructor(\r\n public readonly field: string,\r\n ) {\r\n super(`Field \"${field}\" is required`);\r\n\r\n this.name = \"RequiredFieldException\";\r\n }\r\n}\r\n\r\nclass InvalidTypeException extends ValidationException {\r\n constructor(\r\n public readonly field: string,\r\n public readonly expected: string | undefined,\r\n public readonly received: string,\r\n ) {\r\n super(\r\n `Field \"${field}\" must be of type ${expected}, received ${received}`,\r\n );\r\n\r\n this.name = \"InvalidTypeException\";\r\n }\r\n}\r\n\r\nclass CustomValidationException extends ValidationException {\r\n constructor(\r\n public readonly field: string,\r\n ) {\r\n super(`Field \"${field}\" failed custom validation`);\r\n\r\n this.name = \"CustomValidationException\";\r\n }\r\n}\r\n\r\nclass EmptyArrayException extends ValidationException {\r\n constructor(\r\n public readonly field: string,\r\n ) {\r\n super(`Field \"${field}\" must not be an empty array`);\r\n\r\n this.name = \"EmptyArrayException\";\r\n }\r\n}\r\n\r\nexport {\r\n ValidationException,\r\n RequestBodyUndefinedException,\r\n InvalidBodyException,\r\n RequiredFieldException,\r\n InvalidTypeException,\r\n CustomValidationException,\r\n EmptyArrayException\r\n}","import {\r\n ValidationException,\r\n RequestBodyUndefinedException,\r\n InvalidBodyException,\r\n RequiredFieldException,\r\n InvalidTypeException,\r\n EmptyArrayException\r\n} from \"./exceptions.js\";\r\n\r\nimport {\r\n ArrayType,\r\n ObjectType,\r\n Types\r\n} from \"./validatorTypes.js\";\r\n\r\nimport type {\r\n ValidatorType,\r\n ObjectFields\r\n} from \"./validatorTypes.js\";\r\n\r\ntype FieldDefinition = {\r\n type: ValidatorType;\r\n required?: boolean;\r\n validator?: (\r\n value: unknown\r\n ) => unknown | ValidationException;\r\n};\r\n\r\ninterface BodyFields {\r\n [name: string]: FieldDefinition;\r\n}\r\n\r\ninterface Body {\r\n [name: string]: unknown;\r\n}\r\n\r\nconst Validator = {\r\n body(body: Body, fields: BodyFields) {\r\n if (body === undefined) {\r\n throw new RequestBodyUndefinedException();\r\n }\r\n\r\n if (\r\n typeof body !== \"object\" ||\r\n body === null ||\r\n Array.isArray(body)\r\n ) {\r\n throw new InvalidBodyException();\r\n }\r\n\r\n return validateObject(body, fields);\r\n }\r\n};\r\n\r\nfunction validateObject(\r\n body: unknown,\r\n fields: ObjectFields,\r\n parentPath = \"\"\r\n): Record<string, unknown> {\r\n\r\n if (\r\n typeof body !== \"object\" ||\r\n body === null ||\r\n Array.isArray(body)\r\n ) {\r\n throw new InvalidBodyException();\r\n }\r\n\r\n const bodyData = body as Record<string, unknown>;\r\n const data: Record<string, unknown> = {};\r\n\r\n for (const name in fields) {\r\n const field = fields[name];\r\n\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n const fieldPath = parentPath\r\n ? `${parentPath}.${name}`\r\n : name;\r\n\r\n let value = bodyData[name];\r\n\r\n // Required field\r\n if (field.required && value === undefined) {\r\n throw new RequiredFieldException(fieldPath);\r\n }\r\n\r\n // Optional field not provided\r\n if (value === undefined) {\r\n continue;\r\n }\r\n\r\n // Validate type\r\n if (!validateType(field.type, value, fieldPath)) {\r\n const type = getTypeDescription(field.type);\r\n\r\n throw new InvalidTypeException(\r\n fieldPath,\r\n type,\r\n whatTypeIs(value)\r\n );\r\n }\r\n\r\n // Custom validator\r\n if (field.validator) {\r\n const result = field.validator(value);\r\n\r\n if (result instanceof ValidationException) {\r\n throw result;\r\n }\r\n\r\n value = result;\r\n }\r\n\r\n data[name] = value;\r\n }\r\n\r\n return data;\r\n}\r\n\r\nfunction validateType(\r\n type: ValidatorType | undefined,\r\n value: unknown,\r\n fieldName = \"\"\r\n): boolean {\r\n\r\n // Multiple types\r\n if (Array.isArray(type)) {\r\n return type.some((t) =>\r\n validateType(t, value, fieldName)\r\n );\r\n }\r\n\r\n // Array\r\n if (type instanceof ArrayType) {\r\n\r\n if (!Array.isArray(value)) {\r\n return false;\r\n }\r\n\r\n if (!type.empty && value.length === 0) {\r\n throw new EmptyArrayException(fieldName);\r\n }\r\n\r\n for (const item of value) {\r\n if (!validateType(type.type, item, fieldName)) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n // Object structure\r\n if (type instanceof ObjectType) {\r\n\r\n if (\r\n typeof value !== \"object\" ||\r\n value === null ||\r\n Array.isArray(value)\r\n ) {\r\n return false;\r\n }\r\n\r\n validateObject(\r\n value,\r\n type.fields,\r\n fieldName\r\n );\r\n\r\n return true;\r\n }\r\n\r\n // Primitive types\r\n switch (type?.description) {\r\n\r\n case \"null\":\r\n return value === null;\r\n\r\n case \"string\":\r\n return typeof value === \"string\";\r\n\r\n case \"number\":\r\n case \"float\":\r\n return typeof value === \"number\";\r\n\r\n case \"int\":\r\n return (\r\n typeof value === \"number\" &&\r\n Number.isInteger(value)\r\n );\r\n\r\n case \"boolean\":\r\n return typeof value === \"boolean\";\r\n\r\n case \"object\":\r\n return (\r\n typeof value === \"object\" &&\r\n value !== null &&\r\n !Array.isArray(value)\r\n );\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction getTypeDescription(\r\n type: ValidatorType\r\n): string {\r\n\r\n if (Array.isArray(type)) {\r\n return type\r\n .map((t) => getTypeDescription(t))\r\n .join(\" | \");\r\n }\r\n\r\n return type.description || \"\";\r\n}\r\n\r\nfunction whatTypeIs(value: unknown): string {\r\n\r\n if (\r\n typeof value === \"number\" &&\r\n Number.isInteger(value)\r\n ) {\r\n return \"int\";\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return \"array\";\r\n }\r\n\r\n if (value === null) {\r\n return \"null\";\r\n }\r\n\r\n return typeof value;\r\n}\r\n\r\nexport {\r\n Validator\r\n};","const Status = {\r\n // 1xx Informational\r\n CONTINUE: 100,\r\n SWITCHING_PROTOCOLS: 101,\r\n PROCESSING: 102,\r\n EARLY_HINTS: 103,\r\n\r\n // 2xx Success\r\n OK: 200,\r\n CREATED: 201,\r\n ACCEPTED: 202,\r\n NON_AUTHORITATIVE_INFORMATION: 203,\r\n NO_CONTENT: 204,\r\n RESET_CONTENT: 205,\r\n PARTIAL_CONTENT: 206,\r\n MULTI_STATUS: 207,\r\n ALREADY_REPORTED: 208,\r\n IM_USED: 226,\r\n\r\n // 3xx Redirection\r\n MULTIPLE_CHOICES: 300,\r\n MOVED_PERMANENTLY: 301,\r\n FOUND: 302,\r\n SEE_OTHER: 303,\r\n NOT_MODIFIED: 304,\r\n TEMPORARY_REDIRECT: 307,\r\n PERMANENT_REDIRECT: 308,\r\n\r\n // 4xx Client Errors\r\n BAD_REQUEST: 400,\r\n UNAUTHORIZED: 401,\r\n PAYMENT_REQUIRED: 402,\r\n FORBIDDEN: 403,\r\n NOT_FOUND: 404,\r\n METHOD_NOT_ALLOWED: 405,\r\n NOT_ACCEPTABLE: 406,\r\n PROXY_AUTHENTICATION_REQUIRED: 407,\r\n REQUEST_TIMEOUT: 408,\r\n CONFLICT: 409,\r\n GONE: 410,\r\n LENGTH_REQUIRED: 411,\r\n PRECONDITION_FAILED: 412,\r\n PAYLOAD_TOO_LARGE: 413,\r\n URI_TOO_LONG: 414,\r\n UNSUPPORTED_MEDIA_TYPE: 415,\r\n RANGE_NOT_SATISFIABLE: 416,\r\n EXPECTATION_FAILED: 417,\r\n IM_A_TEAPOT: 418,\r\n MISDIRECTED_REQUEST: 421,\r\n UNPROCESSABLE_CONTENT: 422,\r\n LOCKED: 423,\r\n FAILED_DEPENDENCY: 424,\r\n UPGRADE_REQUIRED: 426,\r\n PRECONDITION_REQUIRED: 428,\r\n TOO_MANY_REQUESTS: 429,\r\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\r\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\r\n\r\n // 5xx Server Errors\r\n INTERNAL_SERVER_ERROR: 500,\r\n NOT_IMPLEMENTED: 501,\r\n BAD_GATEWAY: 502,\r\n SERVICE_UNAVAILABLE: 503,\r\n GATEWAY_TIMEOUT: 504,\r\n HTTP_VERSION_NOT_SUPPORTED: 505,\r\n VARIANT_ALSO_NEGOTIATES: 506,\r\n INSUFFICIENT_STORAGE: 507,\r\n LOOP_DETECTED: 508,\r\n NOT_EXTENDED: 510,\r\n NETWORK_AUTHENTICATION_REQUIRED: 511\r\n} as const;\r\n\r\nexport {\r\n Status\r\n};"],"mappings":"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","names":["Array"]}
@@ -1,3 +1,59 @@
1
+ declare class ValidationException extends Error {
2
+ constructor(message: string);
3
+ }
4
+
5
+ declare class ArrayType {
6
+ type: PrimitiveType[];
7
+ description: string;
8
+ empty: boolean;
9
+ constructor(...type: PrimitiveType[]);
10
+ canBeEmpty(): this;
11
+ }
12
+ type FieldDefinition$1 = {
13
+ type: ValidatorType;
14
+ required?: boolean;
15
+ validator?: (value: unknown) => unknown | ValidationException;
16
+ };
17
+ type ObjectFields = {
18
+ [name: string]: FieldDefinition$1;
19
+ };
20
+ declare class ObjectType {
21
+ fields: ObjectFields;
22
+ description: string;
23
+ constructor(fields: ObjectFields);
24
+ }
25
+ declare function Array(...type: PrimitiveType[]): ArrayType;
26
+ declare function Struct(fields: ObjectFields): ObjectType;
27
+ declare const Types: {
28
+ String: symbol;
29
+ Number: symbol;
30
+ Int: symbol;
31
+ Float: symbol;
32
+ Boolean: symbol;
33
+ Object: symbol;
34
+ Null: symbol;
35
+ Array: typeof Array;
36
+ Struct: typeof Struct;
37
+ };
38
+ type PrimitiveType = typeof Types.String | typeof Types.Number | typeof Types.Int | typeof Types.Float | typeof Types.Boolean | typeof Types.Object | typeof Types.Null;
39
+ type MultiType = PrimitiveType[];
40
+ type ValidatorType = PrimitiveType | MultiType | ArrayType | ObjectType;
41
+
42
+ type FieldDefinition = {
43
+ type: ValidatorType;
44
+ required?: boolean;
45
+ validator?: (value: unknown) => unknown | ValidationException;
46
+ };
47
+ interface BodyFields {
48
+ [name: string]: FieldDefinition;
49
+ }
50
+ interface Body {
51
+ [name: string]: unknown;
52
+ }
53
+ declare const Validator: {
54
+ body(body: Body, fields: BodyFields): Record<string, unknown>;
55
+ };
56
+
1
57
  declare const Status: {
2
58
  readonly CONTINUE: 100;
3
59
  readonly SWITCHING_PROTOCOLS: 101;
@@ -61,4 +117,4 @@ declare const Status: {
61
117
  readonly NETWORK_AUTHENTICATION_REQUIRED: 511;
62
118
  };
63
119
 
64
- export { Status };
120
+ export { Status, Types, ValidationException, Validator };
@@ -1,3 +1,59 @@
1
+ declare class ValidationException extends Error {
2
+ constructor(message: string);
3
+ }
4
+
5
+ declare class ArrayType {
6
+ type: PrimitiveType[];
7
+ description: string;
8
+ empty: boolean;
9
+ constructor(...type: PrimitiveType[]);
10
+ canBeEmpty(): this;
11
+ }
12
+ type FieldDefinition$1 = {
13
+ type: ValidatorType;
14
+ required?: boolean;
15
+ validator?: (value: unknown) => unknown | ValidationException;
16
+ };
17
+ type ObjectFields = {
18
+ [name: string]: FieldDefinition$1;
19
+ };
20
+ declare class ObjectType {
21
+ fields: ObjectFields;
22
+ description: string;
23
+ constructor(fields: ObjectFields);
24
+ }
25
+ declare function Array(...type: PrimitiveType[]): ArrayType;
26
+ declare function Struct(fields: ObjectFields): ObjectType;
27
+ declare const Types: {
28
+ String: symbol;
29
+ Number: symbol;
30
+ Int: symbol;
31
+ Float: symbol;
32
+ Boolean: symbol;
33
+ Object: symbol;
34
+ Null: symbol;
35
+ Array: typeof Array;
36
+ Struct: typeof Struct;
37
+ };
38
+ type PrimitiveType = typeof Types.String | typeof Types.Number | typeof Types.Int | typeof Types.Float | typeof Types.Boolean | typeof Types.Object | typeof Types.Null;
39
+ type MultiType = PrimitiveType[];
40
+ type ValidatorType = PrimitiveType | MultiType | ArrayType | ObjectType;
41
+
42
+ type FieldDefinition = {
43
+ type: ValidatorType;
44
+ required?: boolean;
45
+ validator?: (value: unknown) => unknown | ValidationException;
46
+ };
47
+ interface BodyFields {
48
+ [name: string]: FieldDefinition;
49
+ }
50
+ interface Body {
51
+ [name: string]: unknown;
52
+ }
53
+ declare const Validator: {
54
+ body(body: Body, fields: BodyFields): Record<string, unknown>;
55
+ };
56
+
1
57
  declare const Status: {
2
58
  readonly CONTINUE: 100;
3
59
  readonly SWITCHING_PROTOCOLS: 101;
@@ -61,4 +117,4 @@ declare const Status: {
61
117
  readonly NETWORK_AUTHENTICATION_REQUIRED: 511;
62
118
  };
63
119
 
64
- export { Status };
120
+ export { Status, Types, ValidationException, Validator };