@storm-stack/cli
Advanced tools
Comparing version 1.17.2 to 1.18.0
1799
dist/index.d.ts
@@ -1,1798 +0,11 @@ | ||
/// <reference types="node" /> | ||
import { Command } from 'commander'; | ||
import { ExecOptions } from 'child_process'; | ||
import { Fonts } from 'figlet'; | ||
import type { Logger } from 'pino'; | ||
import type { LoggerOptions } from 'pino'; | ||
import { Options } from 'figlet'; | ||
import pino from 'pino'; | ||
import { Readable } from 'node:stream'; | ||
import { StdioOptions } from 'child_process'; | ||
import type { StormConfig } from '@storm-software/config'; | ||
import { Temporal } from '@js-temporal/polyfill'; | ||
declare interface CLIArgument { | ||
flags: string; | ||
description?: string; | ||
default?: unknown | undefined; | ||
} | ||
export { CLIArgument } | ||
export { CLIArgument as CLIArgument_alias_1 } | ||
declare interface CLICommand { | ||
name: string; | ||
description: string; | ||
commands?: CLICommand[]; | ||
options?: CLIOption[]; | ||
argument?: CLIArgument[]; | ||
action: (...args: any[]) => MaybePromise<void>; | ||
} | ||
export { CLICommand } | ||
export { CLICommand as CLICommand_alias_1 } | ||
declare interface CLIConfig { | ||
name: string; | ||
banner?: CLITitle; | ||
by?: CLITitle; | ||
description: string; | ||
homepageUrl?: string; | ||
documentationUrl?: string; | ||
repositoryUrl?: string; | ||
license?: string; | ||
licenseUrl?: string; | ||
commands: CLICommand[]; | ||
preAction: (command: Command) => MaybePromise<void>; | ||
postAction: (command: Command) => MaybePromise<void>; | ||
} | ||
export { CLIConfig } | ||
export { CLIConfig as CLIConfig_alias_1 } | ||
declare interface CLIOption { | ||
flags: string; | ||
description: string | undefined; | ||
choices?: string[]; | ||
default?: CLIOptionDefault; | ||
} | ||
export { CLIOption } | ||
export { CLIOption as CLIOption_alias_1 } | ||
declare interface CLIOptionDefault { | ||
value: unknown; | ||
description?: string | undefined; | ||
} | ||
export { CLIOptionDefault } | ||
export { CLIOptionDefault as CLIOptionDefault_alias_1 } | ||
declare interface CLITitle { | ||
name?: string; | ||
font?: Fonts; | ||
options?: Options; | ||
hide?: boolean; | ||
} | ||
export { CLITitle } | ||
export { CLITitle as CLITitle_alias_1 } | ||
/** | ||
* Create CLI options from an object. | ||
* The cli library used by Storm Software for building TypeScript applications. | ||
* | ||
* @param obj - The object to create CLI options from | ||
* @returns The CLI options | ||
*/ | ||
declare function createCliOptions(obj: Record<string, string | number | boolean>): string[]; | ||
export { createCliOptions } | ||
export { createCliOptions as createCliOptions_alias_1 } | ||
export { createCliOptions as createCliOptions_alias_2 } | ||
/** | ||
* Create CLI options from an object and join them into a string. | ||
* | ||
* @param obj - The object to create CLI options from | ||
* @returns The CLI options as a string | ||
*/ | ||
declare function createCliOptionsString(obj: Record<string, string | number | boolean>): string; | ||
export { createCliOptionsString } | ||
export { createCliOptionsString as createCliOptionsString_alias_1 } | ||
export { createCliOptionsString as createCliOptionsString_alias_2 } | ||
declare function createCLIProgram(cliConfig: CLIConfig): Promise<void>; | ||
export { createCLIProgram } | ||
export { createCLIProgram as createCLIProgram_alias_1 } | ||
/** | ||
* The input types that can be used to create a DateTime object | ||
*/ | ||
declare type DateTimeInput = | ||
| StormDateTime | ||
| Temporal.Instant | ||
| Date | ||
| string | ||
| number | ||
| bigint | ||
| null | ||
| undefined; | ||
/** | ||
* The options to use when creating a new DateTime object | ||
*/ | ||
declare interface DateTimeOptions { | ||
/** | ||
* The time zone to use. If not specified, the default time zone for the runtime is used. | ||
*/ | ||
timeZone?: Temporal.TimeZoneLike; | ||
/** | ||
* The calendar to use. If not specified, the default calendar for the runtime is used. | ||
*/ | ||
calendar?: Temporal.CalendarLike; | ||
/** | ||
* If false, the current date and time is defaulted when undefined or null is passed. If true, the current date and time is not defaulted. | ||
* | ||
* @default false | ||
*/ | ||
skipDefaulting?: boolean; | ||
} | ||
/** | ||
* Execute a command. | ||
* | ||
* @param command - The command to execute | ||
* @param options - The options to use when executing the command | ||
* @param env - The environment variables to use when executing the command | ||
* @param stdio - The stdio options to use when executing the command | ||
* @returns The result of the command | ||
*/ | ||
declare const execute: (command: string, options?: ExecOptions, env?: Record<string, string>, stdio?: StdioOptions) => string | Buffer | Readable | undefined; | ||
export { execute } | ||
export { execute as execute_alias_1 } | ||
export { execute as execute_alias_2 } | ||
/** | ||
* Execute a command asynchronously. | ||
* | ||
* @param command - The command to execute | ||
* @param options - The options to use when executing the command | ||
* @param env - The environment variables to use when executing the command | ||
* @param stdio - The stdio options to use when executing the command | ||
* @returns The result of the command | ||
*/ | ||
declare const executeAsync: (command: string, options?: ExecOptions, env?: Record<string, string>, stdio?: StdioOptions) => Promise<string | Buffer | undefined>; | ||
export { executeAsync } | ||
export { executeAsync as executeAsync_alias_1 } | ||
export { executeAsync as executeAsync_alias_2 } | ||
declare type GetLoggersResult = pino.BaseLogger & { | ||
logLevel: LogLevel; | ||
logLevelLabel: LogLevelLabel; | ||
}; | ||
declare interface ILogger { | ||
/** | ||
* Write a success message to the logs. | ||
* | ||
* @param message - The message to print. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
success?: (message: string) => MaybePromise<void>; | ||
/** | ||
* Write a fatal message to the logs. | ||
* | ||
* @param message - The fatal message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
fatal?: (message: string) => MaybePromise<void>; | ||
/** | ||
* Write an error message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
error: (message: string) => MaybePromise<void>; | ||
/** | ||
* Write an exception message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
exception?: (message: string) => MaybePromise<void>; | ||
/** | ||
* Write a warning message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
warn: (message: string) => MaybePromise<void>; | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
info: (message: string) => MaybePromise<void>; | ||
/** | ||
* Write a debug message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
debug?: (message: string) => MaybePromise<void>; | ||
/** | ||
* Write a trace message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
trace?: (message: string) => MaybePromise<void>; | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
log?: (message: string) => MaybePromise<void>; | ||
} | ||
declare interface ILoggerWrapper { | ||
/** | ||
* Write a success message to the logs. | ||
* | ||
* @param message - The message to print. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
success: (message: any) => MaybePromise<void>; | ||
/** | ||
* Write a fatal message to the logs. | ||
* | ||
* @param message - The fatal message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
fatal: (error: string | Error) => MaybePromise<void>; | ||
/** | ||
* Write an error message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
error: (error: string | Error) => MaybePromise<void>; | ||
/** | ||
* Write an exception message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
exception: (error: string | Error) => MaybePromise<void>; | ||
/** | ||
* Write a warning message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
warn: (message: any) => MaybePromise<void>; | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
info: (message: any) => MaybePromise<void>; | ||
/** | ||
* Write a debug message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
debug: (message: any) => MaybePromise<void>; | ||
/** | ||
* Write a trace message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
trace: (message: any) => MaybePromise<void>; | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
log: (message: any) => MaybePromise<void>; | ||
} | ||
/** | ||
* Returns true if the current environment is a CI environment. | ||
* | ||
* @returns True if the current environment is a CI environment. | ||
*/ | ||
declare const isCI: () => boolean; | ||
export { isCI } | ||
export { isCI as isCI_alias_1 } | ||
export { isCI as isCI_alias_2 } | ||
/** | ||
* Check if the current process is interactive | ||
* | ||
* @param stream - The stream to check | ||
* @returns True if the current process is interactive | ||
*/ | ||
declare const isInteractive: (stream?: NodeJS.ReadStream & { | ||
fd: 0; | ||
}) => boolean; | ||
export { isInteractive } | ||
export { isInteractive as isInteractive_alias_1 } | ||
export { isInteractive as isInteractive_alias_2 } | ||
declare interface IStormLog { | ||
/** | ||
* Write a success message to the logs. | ||
* | ||
* @param message - The message to print. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
success: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Write a fatal message to the logs. | ||
* | ||
* @param message - The fatal message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
fatal: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Write an error message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
error: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Write an exception message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
exception: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Write a warning message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
warn: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
info: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Write a debug message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
debug: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Write a trace message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
trace: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
log: (...message: any[]) => MaybePromise<void>; | ||
/** | ||
* Start a process | ||
* | ||
* @param name - The name of the process | ||
*/ | ||
start: (name: string) => MaybePromise<void>; | ||
/** | ||
* Write an message to the logs specifying how long it took to complete a process | ||
* | ||
* @param name - The name of the process | ||
* @param startTime - The start time of the process | ||
*/ | ||
stopwatch: (name?: string, startTime?: StormTime) => MaybePromise<void>; | ||
/** | ||
* Create a child logger | ||
* | ||
* @param name - The name of the child logger | ||
* @returns The child logger | ||
*/ | ||
child: (options: { name: string } & Record<string, any>) => IStormLog; | ||
} | ||
/** | ||
* Create a link to a URL in the terminal. | ||
* | ||
* @param url - The URL to link to. | ||
* @returns A terminal link | ||
*/ | ||
declare function link(url: string): string; | ||
export { link } | ||
export { link as link_alias_1 } | ||
export { link as link_alias_2 } | ||
declare type LogLevel = 0 | 10 | 20 | 30 | 40 | 60 | 70; | ||
declare const LogLevel = { | ||
SILENT: 0 as LogLevel, | ||
FATAL: 10 as LogLevel, | ||
ERROR: 20 as LogLevel, | ||
WARN: 30 as LogLevel, | ||
INFO: 40 as LogLevel, | ||
DEBUG: 60 as LogLevel, | ||
TRACE: 70 as LogLevel | ||
}; | ||
declare type LogLevelLabel = "silent" | "fatal" | "error" | "warn" | "info" | "debug" | "trace"; | ||
declare const LogLevelLabel = { | ||
SILENT: "silent" as LogLevelLabel, | ||
FATAL: "fatal" as LogLevelLabel, | ||
ERROR: "error" as LogLevelLabel, | ||
WARN: "warn" as LogLevelLabel, | ||
INFO: "info" as LogLevelLabel, | ||
DEBUG: "debug" as LogLevelLabel, | ||
TRACE: "trace" as LogLevelLabel | ||
}; | ||
declare type MaybePromise<T> = T | Promise<T>; | ||
export declare function registerShutdown(config: { | ||
logger: StormLog; | ||
onShutdown(): void | MaybePromise<void>; | ||
}): (reason?: string) => Promise<void>; | ||
/** | ||
* A wrapper of the and Date class used by Storm Software to provide Date-Time values | ||
* | ||
* @decorator `@Serializable()` | ||
*/ | ||
declare @Serializable() | ||
class StormDateTime extends Date { | ||
/** | ||
* Type-check to determine if `obj` is a `DateTime` object | ||
* | ||
* `isDateTime` returns true if the object passed to it has a `_symbol` property that is equal to | ||
* `DATE_TIME_SYMBOL` | ||
* | ||
* @param obj - the object to check | ||
* @returns The function isDateTime is returning a boolean value. | ||
*/ | ||
public static isDateTime(obj: unknown): obj is StormDateTime { | ||
return ( | ||
isDate(obj) && | ||
isSet((obj as unknown as StormDateTime)?.instant) && | ||
isSet((obj as unknown as StormDateTime)?.zonedDateTime) && | ||
isSetString((obj as unknown as StormDateTime)?.timeZoneId) | ||
); | ||
} | ||
/** | ||
* The current function returns a new StormDateTime object with the current date and time | ||
* | ||
* @returns A new instance of StormDateTime with the current date and time. | ||
*/ | ||
public static override now(): number { | ||
return StormDateTime.current().epochMilliseconds; | ||
} | ||
/** | ||
* The current function returns a new StormDateTime object with the current date and time | ||
* | ||
* @returns A new instance of StormDateTime with the current date and time. | ||
*/ | ||
public static current(): StormDateTime { | ||
return StormDateTime.create(Temporal.Now.instant()); | ||
} | ||
/** | ||
* The maximum function returns a new StormDateTime object with the maximum date and time | ||
* | ||
* @returns A new instance of StormDateTime with the maximum date and time. | ||
*/ | ||
public static minimum(): StormDateTime { | ||
return StormDateTime.create(new Date(-8640000000000000)); | ||
} | ||
/** | ||
* The maximum function returns a new StormDateTime object with the maximum date and time | ||
* | ||
* @returns A new instance of StormDateTime with the maximum date and time. | ||
*/ | ||
public static maximum(): StormDateTime { | ||
return StormDateTime.create(new Date(8640000000000000)); | ||
} | ||
/** | ||
* Creates a new instance of StormDateTime from a string with a specified format. | ||
* | ||
* @param dateTime - The input value used to determine the current date and time | ||
* @param options - The options to use when creating the StormDateTime object | ||
* @returns A new instance of StormDateTime with the current date and time. | ||
*/ | ||
public static create = (dateTime?: DateTimeInput, options?: DateTimeOptions) => | ||
new StormDateTime(dateTime, { | ||
timeZone: | ||
(StormDateTime.isDateTime(dateTime) ? dateTime.timeZoneId : options?.timeZone) ?? | ||
process.env.STORM_TIMEZONE ?? | ||
Temporal.Now.timeZoneId(), | ||
calendar: StormDateTime.isDateTime(dateTime) | ||
? dateTime.calendarId | ||
: options?.calendar ?? new Intl.DateTimeFormat().resolvedOptions().calendar | ||
}); | ||
/** | ||
* A private accessor that stores the `Temporal.Instant` object of the DateTime object | ||
*/ | ||
#instant: Temporal.Instant = Temporal.Now.instant(); | ||
/** | ||
* A private accessor that stores the `Temporal.ZonedDateTime` object of the DateTime object | ||
*/ | ||
#zonedDateTime: Temporal.ZonedDateTime = Temporal.Now.zonedDateTime( | ||
new Intl.DateTimeFormat().resolvedOptions().calendar, | ||
process.env.STORM_TIMEZONE ?? Temporal.Now.timeZoneId() | ||
); | ||
/** | ||
* A private accessor that stores the input value used to create the DateTime object | ||
*/ | ||
#input: DateTimeInput; | ||
/** | ||
* A private accessor that stores the options used to create the DateTime object | ||
*/ | ||
#options: DateTimeOptions; | ||
public constructor(dateTime?: DateTimeInput, options?: DateTimeOptions) { | ||
let _dateTime = dateTime; | ||
const input = dateTime; | ||
if (!_dateTime && !options?.skipDefaulting) { | ||
_dateTime = Temporal.Now.instant(); | ||
} | ||
const instant = !_dateTime | ||
? undefined | ||
: StormDateTime.isDateTime(_dateTime) | ||
? _dateTime.instant | ||
: Temporal.Instant.from( | ||
isDate(_dateTime) | ||
? _dateTime.toJSON() | ||
: isObject(_dateTime) && "epochMilliseconds" in _dateTime | ||
? new Date(Number(_dateTime.epochMilliseconds)).toISOString() | ||
: isNumber(_dateTime) || isBigInt(_dateTime) | ||
? new Date(Number(_dateTime)).toISOString() | ||
: _dateTime | ||
); | ||
super(instant ? Number(instant.epochMilliseconds) : "MISSING_DATE"); | ||
if (instant && this.validate(_dateTime, options)) { | ||
this.#instant = instant; | ||
const timeZone = options?.timeZone | ||
? options?.timeZone | ||
: process.env.TZ | ||
? process.env.TZ | ||
: Temporal.Now.timeZoneId(); | ||
this.#zonedDateTime = options?.calendar | ||
? this.#instant.toZonedDateTime({ | ||
timeZone, | ||
calendar: options.calendar | ||
}) | ||
: this.#instant.toZonedDateTimeISO(timeZone); | ||
} | ||
this.#input = input; | ||
this.#options = options ?? {}; | ||
} | ||
/** | ||
* An accessor that returns the epoch milliseconds of the DateTime object | ||
*/ | ||
public get epochMilliseconds(): number { | ||
return this.instant.epochMilliseconds; | ||
} | ||
/** | ||
* An accessor that returns the `Temporal.Instant` object of the DateTime object | ||
*/ | ||
public get instant(): Temporal.Instant { | ||
return this.#instant; | ||
} | ||
/** | ||
* An accessor that sets the `Temporal.Instant` object of the DateTime object | ||
*/ | ||
protected set instant(instant: Temporal.Instant) { | ||
this.#instant = instant; | ||
} | ||
/** | ||
* An accessor that returns the `Temporal.ZonedDateTime` object of the DateTime object | ||
*/ | ||
public get zonedDateTime(): Temporal.ZonedDateTime { | ||
return this.#zonedDateTime; | ||
} | ||
/** | ||
* An accessor that sets the `Temporal.ZonedDateTime` object of the DateTime object | ||
*/ | ||
protected set zonedDateTime(zonedDateTime: Temporal.ZonedDateTime) { | ||
this.#zonedDateTime = zonedDateTime; | ||
} | ||
/** | ||
* An accessor that returns the `calendarId` string of the DateTime object | ||
*/ | ||
public get calendarId(): string { | ||
return this.#zonedDateTime.calendarId; | ||
} | ||
/** | ||
* An accessor that returns the `timeZoneId` string of the DateTime object | ||
*/ | ||
public get timeZoneId(): string { | ||
return this.#zonedDateTime.timeZoneId; | ||
} | ||
/** | ||
* An accessor that returns the `isValid` boolean of the DateTime object | ||
*/ | ||
public get isValid(): boolean { | ||
return this.validate(this.#zonedDateTime.epochMilliseconds, this.#options); | ||
} | ||
/** | ||
* Returns the input value used to create the DateTime object | ||
*/ | ||
public get input(): DateTimeInput { | ||
return this.#input; | ||
} | ||
/** | ||
* Returns the options used to create the DateTime object | ||
*/ | ||
public get options(): DateTimeOptions { | ||
return this.#options; | ||
} | ||
/** | ||
* Validate the input date value | ||
* | ||
* @param dateTime - The date value to validate | ||
* @param _options - The options to use | ||
* @returns A boolean representing whether the value is a valid *date-time* | ||
*/ | ||
protected validate(value?: DateTimeInput, _options?: DateTimeOptions): boolean { | ||
if (StormDateTime.isDateTime(value)) { | ||
return value.isValid; | ||
} | ||
if (isInstant(value)) { | ||
return !!value.epochMilliseconds; | ||
} | ||
let datetime: string | undefined; | ||
if (isDate(value) || isNumber(value) || isBigInt(value)) { | ||
let date!: Date; | ||
if (isNumber(value) || isBigInt(value)) { | ||
date = new Date(Number(value)); | ||
} else { | ||
date = value; | ||
} | ||
if (Number.isNaN(date.getTime())) { | ||
return false; | ||
} | ||
datetime = date.toUTCString(); | ||
} else { | ||
datetime = value === null || value === void 0 ? void 0 : value.toUpperCase(); | ||
} | ||
if (!datetime) { | ||
return false; | ||
} | ||
// Validate the structure of the date-string | ||
if (!RFC_3339_DATETIME_REGEX.test(datetime)) { | ||
return false; | ||
} | ||
// Check if it is a correct date using the javascript Date parse() method. | ||
if (!Date.parse(datetime)) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
/** | ||
* Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC. | ||
*/ | ||
public override getTime(): number { | ||
return this.epochMilliseconds; | ||
} | ||
/** | ||
* Gets the year, using local time. | ||
*/ | ||
public override getFullYear(): number { | ||
return this.#zonedDateTime.year; | ||
} | ||
/** | ||
* Gets the year using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCFullYear(): number { | ||
return this.#instant.toZonedDateTimeISO("UTC").year; | ||
} | ||
/** | ||
* Gets the month, using local time. | ||
*/ | ||
public override getMonth(): number { | ||
return this.#zonedDateTime.month; | ||
} | ||
/** | ||
* Gets the month of a Date object using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCMonth(): number { | ||
return this.#instant.toZonedDateTimeISO("UTC").month; | ||
} | ||
/** | ||
* Gets the day-of-the-month, using local time. | ||
*/ | ||
public override getDate(): number { | ||
return this.#zonedDateTime.day; | ||
} | ||
/** | ||
* Gets the day-of-the-month, using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCDate(): number { | ||
return this.#instant.toZonedDateTimeISO("UTC").day; | ||
} | ||
/** | ||
* Gets the day of the week, using local time. | ||
*/ | ||
public override getDay(): number { | ||
return this.#zonedDateTime.dayOfWeek; | ||
} | ||
/** | ||
* Gets the day of the week using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCDay(): number { | ||
return this.#instant.toZonedDateTimeISO("UTC").dayOfWeek; | ||
} | ||
/** | ||
* Gets the hours in a date, using local time. | ||
*/ | ||
public override getHours(): number { | ||
return this.#zonedDateTime.hour; | ||
} | ||
/** | ||
* Gets the hours value in a Date object using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCHours(): number { | ||
return this.#instant.toZonedDateTimeISO("UTC").hour; | ||
} | ||
/** | ||
* Gets the minutes of a Date object, using local time. | ||
*/ | ||
public override getMinutes(): number { | ||
return this.#zonedDateTime.minute; | ||
} | ||
/** | ||
* Gets the minutes of a Date object using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCMinutes(): number { | ||
return this.#instant.toZonedDateTimeISO("UTC").minute; | ||
} | ||
/** | ||
* Gets the seconds of a Date object, using local time. | ||
*/ | ||
public override getSeconds(): number { | ||
return this.#zonedDateTime.second; | ||
} | ||
/** | ||
* Gets the seconds of a Date object using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCSeconds(): number { | ||
return this.#instant.toZonedDateTimeISO("UTC").second; | ||
} | ||
/** | ||
* Gets the milliseconds of a Date, using local time. | ||
*/ | ||
public override getMilliseconds(): number { | ||
return this.#zonedDateTime.millisecond; | ||
} | ||
/** | ||
* Gets the milliseconds of a Date object using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCMilliseconds(): number { | ||
return this.#instant.toZonedDateTimeISO("UTC").millisecond; | ||
} | ||
/** | ||
* Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC). | ||
*/ | ||
public override getTimezoneOffset(): number { | ||
return this.#zonedDateTime.offsetNanoseconds / 1000000; | ||
} | ||
/** | ||
* Sets the date and time value in the Date object. | ||
* @param time - A numeric value representing the number of elapsed milliseconds since midnight, January 1, 1970 GMT. | ||
*/ | ||
public override setTime(time: number): number { | ||
this.#zonedDateTime = this.#zonedDateTime.add({ | ||
milliseconds: time - this.epochMilliseconds | ||
}); | ||
this.#instant = this.#zonedDateTime.toInstant(); | ||
return super.setTime(this.#instant.epochMilliseconds); | ||
} | ||
/** | ||
* Sets the milliseconds value in the Date object using local time. | ||
* @param millisecond - A numeric value equal to the millisecond value. | ||
*/ | ||
public override setMilliseconds(millisecond: number): number { | ||
this.#zonedDateTime = this.#zonedDateTime.with({ millisecond }); | ||
this.#instant = this.#zonedDateTime.toInstant(); | ||
return super.setMilliseconds(this.#instant.toZonedDateTimeISO("UTC").millisecond); | ||
} | ||
/** | ||
* Sets the milliseconds value in the Date object using Universal Coordinated Time (UTC). | ||
* @param millisecond - A numeric value equal to the millisecond value. | ||
*/ | ||
public override setUTCMilliseconds(millisecond: number): number { | ||
this.#instant = this.#instant.toZonedDateTimeISO("UTC").with({ millisecond }).toInstant(); | ||
this.#zonedDateTime = this.#instant.toZonedDateTime({ | ||
timeZone: this.timeZoneId, | ||
calendar: this.calendarId | ||
}); | ||
return super.setUTCMilliseconds(this.#instant.toZonedDateTimeISO("UTC").millisecond); | ||
} | ||
/** | ||
* Sets the seconds value in the Date object using local time. | ||
* @param second - A numeric value equal to the seconds value. | ||
* @param millisecond - A numeric value equal to the milliseconds value. | ||
*/ | ||
public override setSeconds(second: number, millisecond?: number): number { | ||
this.#zonedDateTime = this.#zonedDateTime.with({ second, millisecond }); | ||
this.#instant = this.#zonedDateTime.toInstant(); | ||
return super.setSeconds(this.#zonedDateTime.second, this.#zonedDateTime.millisecond); | ||
} | ||
/** | ||
* Sets the seconds value in the Date object using Universal Coordinated Time (UTC). | ||
* @param second - A numeric value equal to the seconds value. | ||
* @param millisecond - A numeric value equal to the milliseconds value. | ||
*/ | ||
public override setUTCSeconds(second: number, millisecond?: number): number { | ||
this.#instant = this.#instant | ||
.toZonedDateTimeISO("UTC") | ||
.with({ second, millisecond }) | ||
.toInstant(); | ||
this.#zonedDateTime = this.#instant.toZonedDateTime({ | ||
timeZone: this.timeZoneId, | ||
calendar: this.calendarId | ||
}); | ||
const utcDateTime = this.#instant.toZonedDateTimeISO("UTC"); | ||
return super.setUTCSeconds(utcDateTime.second, utcDateTime.millisecond); | ||
} | ||
/** | ||
* Sets the minutes value in the Date object using local time. | ||
* @param minute - A numeric value equal to the minutes value. | ||
* @param second - A numeric value equal to the seconds value. | ||
* @param millisecond - A numeric value equal to the milliseconds value. | ||
*/ | ||
public override setMinutes(minute: number, second?: number, millisecond?: number): number { | ||
this.#zonedDateTime = this.#zonedDateTime.with({ | ||
minute, | ||
second, | ||
millisecond | ||
}); | ||
this.#instant = this.#zonedDateTime.toInstant(); | ||
return super.setMinutes( | ||
this.#zonedDateTime.minute, | ||
this.#zonedDateTime.second, | ||
this.#zonedDateTime.millisecond | ||
); | ||
} | ||
/** | ||
* Sets the minutes value in the Date object using Universal Coordinated Time (UTC). | ||
* @param minute - A numeric value equal to the minutes value. | ||
* @param second - A numeric value equal to the seconds value. | ||
* @param millisecond - A numeric value equal to the milliseconds value. | ||
*/ | ||
public override setUTCMinutes(minute: number, second?: number, millisecond?: number): number { | ||
this.#instant = this.#instant | ||
.toZonedDateTimeISO("UTC") | ||
.with({ minute, second, millisecond }) | ||
.toInstant(); | ||
this.#zonedDateTime = this.#instant.toZonedDateTime({ | ||
timeZone: this.timeZoneId, | ||
calendar: this.calendarId | ||
}); | ||
const utcDateTime = this.#instant.toZonedDateTimeISO("UTC"); | ||
return super.setUTCMinutes(utcDateTime.minute, utcDateTime.second, utcDateTime.millisecond); | ||
} | ||
/** | ||
* Sets the hour value in the Date object using local time. | ||
* | ||
* @param hour - A numeric value equal to the hours value. | ||
* @param minute - A numeric value equal to the minutes value. | ||
* @param second - A numeric value equal to the seconds value. | ||
* @param millisecond - A numeric value equal to the milliseconds value. | ||
*/ | ||
public override setHours( | ||
hour: number, | ||
minute: number, | ||
second?: number, | ||
millisecond?: number | ||
): number { | ||
this.#zonedDateTime = this.#zonedDateTime.with({ | ||
hour, | ||
minute, | ||
second, | ||
millisecond | ||
}); | ||
this.#instant = this.#zonedDateTime.toInstant(); | ||
return super.setHours( | ||
this.#zonedDateTime.hour, | ||
this.#zonedDateTime.minute, | ||
this.#zonedDateTime.second, | ||
this.#zonedDateTime.millisecond | ||
); | ||
} | ||
/** | ||
* Sets the hours value in the Date object using Universal Coordinated Time (UTC). | ||
* | ||
* @param hour - A numeric value equal to the hours value. | ||
* @param minute - A numeric value equal to the minutes value. | ||
* @param second - A numeric value equal to the seconds value. | ||
* @param millisecond - A numeric value equal to the milliseconds value. | ||
*/ | ||
public override setUTCHours( | ||
hour: number, | ||
minute: number, | ||
second?: number, | ||
millisecond?: number | ||
): number { | ||
this.#instant = this.#instant | ||
.toZonedDateTimeISO("UTC") | ||
.with({ hour, minute, second, millisecond }) | ||
.toInstant(); | ||
this.#zonedDateTime = this.#instant.toZonedDateTime({ | ||
timeZone: this.timeZoneId, | ||
calendar: this.calendarId | ||
}); | ||
const utcDateTime = this.#instant.toZonedDateTimeISO("UTC"); | ||
return super.setUTCHours( | ||
utcDateTime.hour, | ||
utcDateTime.minute, | ||
utcDateTime.second, | ||
utcDateTime.millisecond | ||
); | ||
} | ||
/** | ||
* Sets the numeric day-of-the-month value of the Date object using local time. | ||
* | ||
* @param day - A numeric value equal to the day of the month. | ||
*/ | ||
public override setDate(day: number): number { | ||
this.#zonedDateTime = this.#zonedDateTime.with({ | ||
day | ||
}); | ||
this.#instant = this.#zonedDateTime.toInstant(); | ||
return super.setDate(this.#zonedDateTime.day); | ||
} | ||
/** | ||
* Sets the numeric day of the month in the Date object using Universal Coordinated Time (UTC). | ||
* | ||
* @param day - A numeric value equal to the day of the month. | ||
*/ | ||
public override setUTCDate(day: number): number { | ||
this.#instant = this.#instant.toZonedDateTimeISO("UTC").with({ day }).toInstant(); | ||
this.#zonedDateTime = this.#instant.toZonedDateTime({ | ||
timeZone: this.timeZoneId, | ||
calendar: this.calendarId | ||
}); | ||
return super.setUTCDate(this.#instant.toZonedDateTimeISO("UTC").day); | ||
} | ||
/** | ||
* Sets the month value in the Date object using local time. | ||
* | ||
* @param month - A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. | ||
* @param day - A numeric value representing the day of the month. If this value is not supplied, the value from a call to the getDate method is used. | ||
*/ | ||
public override setMonth(month: number, day?: number): number { | ||
this.#zonedDateTime = this.#zonedDateTime.with({ month, day }); | ||
this.#instant = this.#zonedDateTime.toInstant(); | ||
return super.setMonth(this.#zonedDateTime.month, this.#zonedDateTime.day); | ||
} | ||
/** | ||
* Sets the month value in the Date object using Universal Coordinated Time (UTC). | ||
* | ||
* @param month - A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. | ||
* @param day - A numeric value representing the day of the month. If it is not supplied, the value from a call to the getUTCDate method is used. | ||
*/ | ||
public override setUTCMonth(month: number, day?: number): number { | ||
this.#instant = this.#instant.toZonedDateTimeISO("UTC").with({ month, day }).toInstant(); | ||
this.#zonedDateTime = this.#instant.toZonedDateTime({ | ||
timeZone: this.timeZoneId, | ||
calendar: this.calendarId | ||
}); | ||
const utcDateTime = this.#instant.toZonedDateTimeISO("UTC"); | ||
return super.setUTCMonth(utcDateTime.month, utcDateTime.day); | ||
} | ||
/** | ||
* Sets the year of the Date object using local time. | ||
* @param year - A numeric value for the year. | ||
* @param month - A zero-based numeric value for the month (0 for January, 11 for December). Must be specified if numDate is specified. | ||
* @param day - A numeric value equal for the day of the month. | ||
*/ | ||
public override setFullYear(year: number, month?: number, day?: number): number { | ||
this.#zonedDateTime = this.#zonedDateTime.with({ year, month, day }); | ||
this.#instant = this.#zonedDateTime.toInstant(); | ||
return super.setFullYear( | ||
this.#zonedDateTime.year, | ||
this.#zonedDateTime.month, | ||
this.#zonedDateTime.day | ||
); | ||
} | ||
/** | ||
* Sets the year value in the Date object using Universal Coordinated Time (UTC). | ||
* | ||
* @param year - A numeric value equal to the year. | ||
* @param month - A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. Must be supplied if numDate is supplied. | ||
* @param day - A numeric value equal to the day of the month. | ||
*/ | ||
public override setUTCFullYear(year: number, month?: number, day?: number): number { | ||
this.#instant = this.#instant.toZonedDateTimeISO("UTC").with({ year, month, day }).toInstant(); | ||
this.#zonedDateTime = this.#instant.toZonedDateTime({ | ||
timeZone: this.timeZoneId, | ||
calendar: this.calendarId | ||
}); | ||
const utcDateTime = this.#instant.toZonedDateTimeISO("UTC"); | ||
return super.setUTCFullYear(utcDateTime.year, utcDateTime.month, utcDateTime.day); | ||
} | ||
/** | ||
* It returns a plain date object from a DateTime object | ||
* | ||
* @returns A PlainDate object. | ||
*/ | ||
public getPlainDate(): StormDateTime { | ||
return StormDateTime.create( | ||
this.#zonedDateTime.toPlainDate().toZonedDateTime({ | ||
timeZone: Temporal.Now.timeZoneId(), | ||
plainTime: undefined | ||
}).epochMilliseconds, | ||
{ | ||
timeZone: this.#zonedDateTime.timeZoneId, | ||
calendar: this.#zonedDateTime.calendarId | ||
} | ||
); | ||
} | ||
/** | ||
* `getPlainTime` returns a `PlainTime` object from a `DateTime` object | ||
* | ||
* @returns A PlainTime object. | ||
*/ | ||
public getPlainTime(): StormDateTime { | ||
return StormDateTime.create( | ||
this.#zonedDateTime.toPlainTime().toZonedDateTime({ | ||
timeZone: Temporal.Now.timeZoneId(), | ||
plainDate: Temporal.PlainDate.from({ | ||
year: 1970, | ||
month: 0, | ||
day: 1 | ||
}) | ||
}).epochMilliseconds, | ||
{ | ||
timeZone: this.#zonedDateTime.timeZoneId, | ||
calendar: this.#zonedDateTime.calendarId | ||
} | ||
); | ||
} | ||
/** | ||
* It returns the duration between two dates. | ||
* | ||
* @param dateTimeTo - DateTime = DateTime.current | ||
* @returns A duration object. | ||
*/ | ||
public since(dateTimeTo: StormDateTime = StormDateTime.current()): Temporal.Duration { | ||
return this.#instant.since(dateTimeTo.instant); | ||
} | ||
/** | ||
* It returns the duration between two date times. | ||
* | ||
* @param dateTimeTo - DateTime = DateTime.current | ||
* @returns A duration object. | ||
*/ | ||
public getDuration(dateTimeTo: StormDateTime = StormDateTime.current()): Temporal.Duration { | ||
return this.instant.since(dateTimeTo.instant); | ||
} | ||
} | ||
/** | ||
* The default logger class. | ||
* | ||
* @remarks | ||
* This logger writes to the console. | ||
*/ | ||
declare class StormLog implements IStormLog { | ||
protected static logger: Logger<LoggerOptions>; | ||
protected static logLevel: LogLevel; | ||
protected static logLevelLabel: LogLevelLabel; | ||
protected static getLoggers = (): Promise<GetLoggersResult> => { | ||
if (!StormLog.logger) { | ||
throw new StormError(LoggingErrorCode.logs_uninitialized, { | ||
message: | ||
"The Storm Log has not been initialized. Please initialize the logs by invoking `StormLog.initialize` before using them" | ||
}); | ||
} | ||
return Promise.resolve({ | ||
...StormLog.logger, | ||
logLevel: StormLog.logLevel, | ||
logLevelLabel: StormLog.logLevelLabel | ||
}); | ||
}; | ||
/** | ||
* Initialize the logs. | ||
* | ||
* @param config - The Storm config | ||
* @param name - The name of the project to initialized the loggers for | ||
* @returns The initialized loggers | ||
*/ | ||
protected static initialize = ( | ||
config: StormConfig, | ||
name?: string, | ||
streams: (pino.DestinationStream | pino.StreamEntry<pino.Level>)[] = [] | ||
): Logger<LoggerOptions> => { | ||
const pinoLogger: Logger<LoggerOptions> = | ||
streams.length > 0 | ||
? pino(getPinoOptions(config, name), pino.multistream(streams, { dedupe: false })) | ||
: pino(getPinoOptions(config, name)); | ||
pinoLogger.debug("The Storm log has ben initialized"); | ||
return pinoLogger; | ||
}; | ||
#logger: Logger<LoggerOptions>; | ||
#logLevel: LogLevel; | ||
#processes: Array<{ name: string; startedAt: StormTime }> = []; | ||
/** | ||
* The Singleton's constructor should always be private to prevent direct | ||
* construction calls with the `new` operator. | ||
*/ | ||
protected constructor( | ||
protected config: StormConfig, | ||
protected name?: string, | ||
protected additionalLoggers: ILoggerWrapper[] = [] | ||
) { | ||
this.name = name ? name : config.name; | ||
this.#logger = StormLog.initialize(this.config, this.name, this.getStreams()); | ||
this.#logLevel = getLogLevel(config.logLevel); | ||
} | ||
/** | ||
* Create a new instance of the logger | ||
* | ||
* @param config - The Storm config | ||
* @param name - The name of the project to initialized the loggers for | ||
* @param additionalLoggers - Additional loggers to use | ||
* @returns The initialized logger | ||
*/ | ||
public static create( | ||
config: StormConfig, | ||
name?: string, | ||
additionalLoggers: ILoggerWrapper[] = [] | ||
) { | ||
return new StormLog(config, name, additionalLoggers); | ||
} | ||
/** | ||
* Write a success message to the logs. | ||
* | ||
* @param message - The message to print. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static success(message: any) { | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.INFO && logger.info({ msg: message, level: "success" }); | ||
}); | ||
} | ||
/** | ||
* Write a fatal message to the logs. | ||
* | ||
* @param message - The fatal message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static fatal(message: any) { | ||
const error = getCauseFromUnknown(message); | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.FATAL && logger.fatal({ error, level: "fatal" }); | ||
}); | ||
} | ||
/** | ||
* Write an error message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static error(message: any) { | ||
const error = getCauseFromUnknown(message); | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.ERROR && logger.error({ error, level: "error" }); | ||
}); | ||
} | ||
/** | ||
* Write an exception message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static exception(message: any) { | ||
const error = getCauseFromUnknown(message); | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.ERROR && logger.error({ error, level: "exception" }); | ||
}); | ||
} | ||
/** | ||
* Write a warning message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static warn(message: any) { | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.WARN && logger.warn(message); | ||
}); | ||
} | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static info(message: any) { | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.INFO && logger.info(message); | ||
}); | ||
} | ||
/** | ||
* Write a debug message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static debug(message: any) { | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.DEBUG && logger.debug(message); | ||
}); | ||
} | ||
/** | ||
* Write a trace message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static trace(message: any) { | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.TRACE && logger.trace(message); | ||
}); | ||
} | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public static log(message: any) { | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.INFO && logger.info(message); | ||
}); | ||
} | ||
/** | ||
* Write an message to the logs specifying how long it took to complete a process | ||
* @param startTime - The start time of the process | ||
* @param name - The name of the process | ||
*/ | ||
public static stopwatch(startTime: StormTime, name?: string) { | ||
StormLog.getLoggers().then((logger) => { | ||
StormLog.logLevel >= LogLevel.INFO && | ||
logger.info( | ||
`\n⏱️ Completed ${name ? ` ${name}` : ""} process in ${formatSince(startTime.since())}\n` | ||
); | ||
}); | ||
} | ||
/** | ||
* Write a success message to the logs. | ||
* | ||
* @param message - The message to print. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public success(message: any) { | ||
if (this.#logLevel >= LogLevel.INFO) { | ||
this.#logger.info({ msg: message, level: "success" }); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.success(message))); | ||
} | ||
} | ||
/** | ||
* Write a fatal message to the logs. | ||
* | ||
* @param message - The fatal message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public fatal(message: any) { | ||
if (this.#logLevel >= LogLevel.FATAL) { | ||
const error = getCauseFromUnknown(message); | ||
this.#logger.fatal({ error, level: "fatal" }); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.fatal(error))); | ||
} | ||
} | ||
/** | ||
* Write an error message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public error(message: any) { | ||
if (this.#logLevel >= LogLevel.ERROR) { | ||
const error = getCauseFromUnknown(message); | ||
this.#logger.error({ error, level: "error" }); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.error(error))); | ||
} | ||
} | ||
/** | ||
* Write an exception message to the logs. | ||
* | ||
* @param message - The message to be displayed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public exception(message: any) { | ||
if (this.#logLevel >= LogLevel.ERROR) { | ||
const error = getCauseFromUnknown(message); | ||
this.#logger.error({ error, level: "exception" }); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.exception(error))); | ||
} | ||
} | ||
/** | ||
* Write a warning message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public warn(message: any) { | ||
if (this.#logLevel >= LogLevel.WARN) { | ||
this.#logger.warn(message); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.warn(message))); | ||
} | ||
} | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public info(message: any) { | ||
if (this.#logLevel >= LogLevel.INFO) { | ||
this.#logger.info(message); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.info(message))); | ||
} | ||
} | ||
/** | ||
* Write a debug message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public debug(message: any) { | ||
if (this.#logLevel >= LogLevel.DEBUG) { | ||
this.#logger.debug(message); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.debug(message))); | ||
} | ||
} | ||
/** | ||
* Write a trace message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public trace(message: any) { | ||
if (this.#logLevel >= LogLevel.TRACE) { | ||
this.#logger.trace(message); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.trace(message))); | ||
} | ||
} | ||
/** | ||
* Write an informational message to the logs. | ||
* | ||
* @param message - The message to be printed. | ||
* @returns Either a promise that resolves to void or void. | ||
*/ | ||
public log(message: any) { | ||
if (this.#logLevel >= LogLevel.INFO) { | ||
this.#logger.info(message); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.log(message))); | ||
} | ||
} | ||
/** | ||
* Start a logging process to track | ||
* | ||
* @param name - The name of the process | ||
*/ | ||
public start(name: string) { | ||
if (this.#logLevel >= LogLevel.INFO && !this.#processes.some((item) => item.name === name)) { | ||
this.#processes.push({ name, startedAt: StormTime.current() }); | ||
this.#logger.info( | ||
`▶️ Starting process ${this.#processes.map((item) => item.name).join(" ❯ ")}` | ||
); | ||
} | ||
} | ||
/** | ||
* Write an message to the logs specifying how long it took to complete a process | ||
* | ||
* @param name - The name of the process | ||
* @param startTime - The start time of the process | ||
*/ | ||
public stopwatch(name?: string, startTime?: StormTime) { | ||
let _startTime = startTime; | ||
if (this.#logLevel < LogLevel.INFO) { | ||
return; | ||
} | ||
if (!name && !_startTime) { | ||
this.warn("No name or start time was provided to the stopwatch method"); | ||
return; | ||
} | ||
if (!_startTime && !this.#processes.some((item) => item.name === name)) { | ||
this.warn(`No start time was provided and the ${name} process was never started`); | ||
return; | ||
} | ||
if (name && this.#processes.some((item) => item.name === name)) { | ||
_startTime = this.#processes.find((item) => item.name === name)?.startedAt; | ||
} | ||
let proc = name; | ||
if (this.#processes.length > 0 && proc && this.#processes.some((item) => item.name === proc)) { | ||
proc = this.#processes | ||
.map((item) => item.name) | ||
.slice( | ||
0, | ||
this.#processes.findIndex((item) => item.name === proc) | ||
) | ||
.join(" ❯ "); | ||
} | ||
const message = `\n${proc ? `⏱️ Completed ${proc}` : "The process has completed"} in ${ | ||
_startTime ? formatSince(_startTime.since()) : "0ms" | ||
}\n`; | ||
this.#logger.info(message); | ||
Promise.all(this.additionalLoggers.map((logger) => logger.info(message))); | ||
if (name && this.#processes.some((item) => item.name === name)) { | ||
const index = this.#processes.findLastIndex((item) => item.name === name); | ||
if (index) { | ||
this.#processes.splice(index, 1); | ||
} | ||
} | ||
} | ||
/** | ||
* Start a process | ||
* | ||
* @param options - The options of the child process | ||
*/ | ||
public child(options: { name: string } & Record<string, any>): IStormLog { | ||
return new StormLog(this.config, `${this.name} ❯ ${options?.name}`, this.additionalLoggers); | ||
} | ||
/** | ||
* Add a logger wrapper to the internal loggers list | ||
* | ||
* @param wrapper - The logger wrapper to use | ||
*/ | ||
public addWrappedLogger(wrapper: ILoggerWrapper) { | ||
if (wrapper) { | ||
this.additionalLoggers.push(wrapper); | ||
} | ||
} | ||
/** | ||
* Add a logger to the internal loggers list | ||
* | ||
* @param logger - The logger to add | ||
*/ | ||
public addLogger(logger: ILogger) { | ||
if (logger) { | ||
this.addWrappedLogger(LoggerWrapper.wrap(logger, this.config.modules?.logging)); | ||
} | ||
} | ||
/** | ||
* Allow child classes to specify additional pino log streams | ||
* | ||
* @returns Additional log streams to use during initialization | ||
*/ | ||
protected getStreams = (): Array<pino.DestinationStream | pino.StreamEntry<pino.Level>> => []; | ||
} | ||
/** | ||
* A wrapper of the and Date class used by Storm Software to provide Date-Time values | ||
* A collection of CLI utilities to assist in creating command line applications | ||
* | ||
* @decorator `@Serializable()` | ||
* @packageDocumentation | ||
*/ | ||
declare @Serializable() | ||
class StormTime extends StormDateTime { | ||
/** | ||
* The current function returns a new DateTime object with the current date and time | ||
* @returns A new instance of DateTime with the current date and time. | ||
*/ | ||
public static override now(): number { | ||
return StormTime.current().epochMilliseconds; | ||
} | ||
/** | ||
* The current function returns a new DateTime object with the current date and time | ||
* @returns A new instance of DateTime with the current date and time. | ||
*/ | ||
public static override current(): StormTime { | ||
return StormTime.create(Temporal.Now.instant()); | ||
} | ||
/** | ||
* Creates a new instance of DateTime from a string with a specified format. | ||
* | ||
* @param time - The input value used to determine the current time | ||
* @param options - The options to use | ||
* @returns A new instance of StormTime with the time provided in the time parameter. | ||
*/ | ||
public static override create = (time?: DateTimeInput, options?: DateTimeOptions) => | ||
new StormTime(time, { | ||
timeZone: | ||
(StormDateTime.isDateTime(time) ? time.timeZoneId : options?.timeZone) ?? | ||
Temporal.Now.timeZoneId(), | ||
calendar: StormDateTime.isDateTime(time) ? time.calendarId : options?.calendar | ||
}); | ||
public constructor(dateTime?: DateTimeInput, options?: DateTimeOptions) { | ||
super(dateTime, options); | ||
const stormDateTime = StormDateTime.create(dateTime, options); | ||
this.instant = stormDateTime.instant | ||
.toZonedDateTimeISO("UTC") | ||
.with({ | ||
year: 1970, | ||
month: 1, | ||
day: 1 | ||
}) | ||
.toInstant(); | ||
this.zonedDateTime = stormDateTime.zonedDateTime.with({ | ||
year: 1970, | ||
month: 1, | ||
day: 1 | ||
}); | ||
} | ||
/** | ||
* Validate the input time value | ||
* | ||
* @param dateTime - The date value to validate | ||
* @param _options - The options to use | ||
* @returns A boolean representing whether the value is a valid *date-time* | ||
*/ | ||
protected override validate(value?: DateTimeInput, _options?: DateTimeOptions): boolean { | ||
if (StormDateTime.isDateTime(value)) { | ||
return value.isValid; | ||
} | ||
if (isInstant(value)) { | ||
return !!value.epochMilliseconds; | ||
} | ||
let datetime: string | undefined; | ||
if (isDate(value) || isNumber(value) || isBigInt(value)) { | ||
let date!: Date; | ||
if (isNumber(value) || isBigInt(value)) { | ||
date = new Date(Number(value)); | ||
} else { | ||
date = value; | ||
} | ||
if (Number.isNaN(date.getTime())) { | ||
return false; | ||
} | ||
datetime = date.toUTCString(); | ||
} else { | ||
datetime = value === null || value === void 0 ? void 0 : value.toUpperCase(); | ||
} | ||
if (!datetime) { | ||
return false; | ||
} | ||
return RFC_3339_TIME_REGEX.test(datetime); | ||
} | ||
/** | ||
* Gets the year, using local time. | ||
*/ | ||
public override getFullYear(): number { | ||
return 1970; | ||
} | ||
/** | ||
* Gets the year using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCFullYear(): number { | ||
return 1970; | ||
} | ||
/** | ||
* Gets the month, using local time. | ||
*/ | ||
public override getMonth(): number { | ||
return 1; | ||
} | ||
/** | ||
* Gets the month of a Date object using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCMonth(): number { | ||
return 1; | ||
} | ||
/** | ||
* Gets the day-of-the-month, using local time. | ||
*/ | ||
public override getDate(): number { | ||
return 1; | ||
} | ||
/** | ||
* Gets the day-of-the-month, using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCDate(): number { | ||
return 1; | ||
} | ||
/** | ||
* Gets the day of the week, using local time. | ||
*/ | ||
public override getDay(): number { | ||
return 1; | ||
} | ||
/** | ||
* Gets the day of the week using Universal Coordinated Time (UTC). | ||
*/ | ||
public override getUTCDay(): number { | ||
return 1; | ||
} | ||
/** | ||
* It returns the duration between two dates. | ||
* | ||
* @param dateTimeTo - DateTime = DateTime.current | ||
* @returns A duration object. | ||
*/ | ||
public override getDuration(dateTimeTo: StormTime = StormTime.current()): Temporal.Duration { | ||
return this.instant.since(dateTimeTo.instant); | ||
} | ||
} | ||
export { } | ||
export * from "./program"; | ||
export * from "./types"; | ||
export * from "./utilities"; |
134
package.json
{ | ||
"name": "@storm-stack/cli", | ||
"version": "1.17.2", | ||
"private": false, | ||
"version": "1.18.0", | ||
"type": "module", | ||
"description": "A collection of CLI utilities to assist in creating command line applications.", | ||
@@ -11,3 +11,3 @@ "repository": { | ||
}, | ||
"type": "module", | ||
"private": false, | ||
"dependencies": { | ||
@@ -18,3 +18,3 @@ "@storm-software/config": "latest", | ||
"commander": "11.1.0", | ||
"console-table-printer": "2.11.2", | ||
"console-table-printer": "2.12.1", | ||
"figlet": "^1.7.0", | ||
@@ -24,23 +24,9 @@ "prompts": "^2.4.2", | ||
}, | ||
"devDependencies": { "@types/figlet": "^1.5.8", "@types/node": "^20.10.5" }, | ||
"publishConfig": { "access": "public" }, | ||
"exports": { | ||
".": { | ||
"import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, | ||
"require": { | ||
"types": "./dist/index.d.cts", | ||
"default": "./dist/index.cjs" | ||
}, | ||
"default": { "types": "./dist/index.d.ts", "default": "./dist/index.js" } | ||
}, | ||
"./package.json": "./package.json", | ||
"./index": { | ||
"import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, | ||
"require": { | ||
"types": "./dist/index.d.cts", | ||
"default": "./dist/index.cjs" | ||
}, | ||
"default": { "types": "./dist/index.d.ts", "default": "./dist/index.js" } | ||
} | ||
"devDependencies": { | ||
"@types/figlet": "^1.5.8", | ||
"@types/node": "^22.5.5" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"sideEffects": false, | ||
@@ -51,19 +37,11 @@ "funding": { | ||
}, | ||
"types": "dist/index.d.ts", | ||
"typings": "dist/index.d.ts", | ||
"typescript": { "definition": "dist/index.d.ts" }, | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.js", | ||
"files": ["dist/**/*"], | ||
"homepage": "https://stormsoftware.org", | ||
"files": [ | ||
"dist/**/*" | ||
], | ||
"homepage": "https://stormsoftware.com", | ||
"bugs": { | ||
"url": "https://stormsoftware.org/support", | ||
"email": "support@stormsoftware.org" | ||
"url": "https://stormsoftware.com/support", | ||
"email": "support@stormsoftware.com" | ||
}, | ||
"author": { | ||
"name": "Storm Software", | ||
"email": "contact@stormsoftware.org", | ||
"url": "https://stormsoftware.org" | ||
}, | ||
"license": "Apache License 2.0", | ||
"license": "Apache-2.0", | ||
"keywords": [ | ||
@@ -78,12 +56,78 @@ "storm-stack", | ||
"acidic-model", | ||
"impact", | ||
"cyclone-ui", | ||
"nextjs", | ||
"prisma", | ||
"zenstack", | ||
"hasura", | ||
"strapi", | ||
"graphql", | ||
"sullivanpj", | ||
"monorepo" | ||
] | ||
} | ||
], | ||
"author": { | ||
"name": "Storm Software", | ||
"email": "contact@stormsoftware.com", | ||
"url": "https://stormsoftware.com" | ||
}, | ||
"contributors": [ | ||
{ | ||
"name": "Storm Software", | ||
"email": "contact@stormsoftware.com", | ||
"url": "https://stormsoftware.com" | ||
} | ||
], | ||
"exports": { | ||
"./types": { | ||
"import": "./dist/types.mjs", | ||
"require": "./dist/types.cjs", | ||
"types": "./dist/types.d.ts" | ||
}, | ||
"./index": { | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/index.cjs", | ||
"types": "./dist/index.d.ts" | ||
}, | ||
"./utilities/is-interactive": { | ||
"import": "./dist/utilities/is-interactive.mjs", | ||
"require": "./dist/utilities/is-interactive.cjs", | ||
"types": "./dist/utilities/is-interactive.d.ts" | ||
}, | ||
"./utilities/is-ci": { | ||
"import": "./dist/utilities/is-ci.mjs", | ||
"require": "./dist/utilities/is-ci.cjs", | ||
"types": "./dist/utilities/is-ci.d.ts" | ||
}, | ||
"./utilities/index": { | ||
"import": "./dist/utilities/index.mjs", | ||
"require": "./dist/utilities/index.cjs", | ||
"types": "./dist/utilities/index.d.ts" | ||
}, | ||
"./utilities/execute": { | ||
"import": "./dist/utilities/execute.mjs", | ||
"require": "./dist/utilities/execute.cjs", | ||
"types": "./dist/utilities/execute.d.ts" | ||
}, | ||
"./utilities/create-cli-options": { | ||
"import": "./dist/utilities/create-cli-options.mjs", | ||
"require": "./dist/utilities/create-cli-options.cjs", | ||
"types": "./dist/utilities/create-cli-options.d.ts" | ||
}, | ||
"./utilities/cli-link": { | ||
"import": "./dist/utilities/cli-link.mjs", | ||
"require": "./dist/utilities/cli-link.cjs", | ||
"types": "./dist/utilities/cli-link.d.ts" | ||
}, | ||
"./program/shutdown": { | ||
"import": "./dist/program/shutdown.mjs", | ||
"require": "./dist/program/shutdown.cjs", | ||
"types": "./dist/program/shutdown.d.ts" | ||
}, | ||
"./program/index": { | ||
"import": "./dist/program/index.mjs", | ||
"require": "./dist/program/index.cjs", | ||
"types": "./dist/program/index.d.ts" | ||
}, | ||
"./program/error-report": { | ||
"import": "./dist/program/error-report.mjs", | ||
"require": "./dist/program/error-report.cjs", | ||
"types": "./dist/program/error-report.d.ts" | ||
} | ||
} | ||
} |
192
README.md
@@ -6,24 +6,61 @@ <!-- START header --> | ||
<div align="center"><img src="https://pub-761b436209f44a4d886487c917806c08.r2.dev/storm-banner.gif" width="100%" altText="Storm Software" /></div> | ||
<div align="center"><img src="https://pub-761b436209f44a4d886487c917806c08.r2.dev/storm-banner.gif" width="100%" alt="Storm Software" /></div> | ||
<br /> | ||
<br /> | ||
<div align="center"> | ||
<a href="https://stormsoftware.org" target="_blank">Website</a> | <a href="https://stormsoftware.org/contact" target="_blank">Contact</a> | <a href="https://github.com/storm-software/storm-stack" target="_blank">Repository</a> | <a href="https://storm-software.github.io/storm-stack/" target="_blank">Documentation</a> | <a href="https://github.com/storm-software/storm-stack/issues/new?assignees=&labels=bug&template=bug-report.yml&title=Bug Report%3A+">Report a Bug</a> | <a href="https://github.com/storm-software/storm-stack/issues/new?assignees=&labels=enhancement&template=feature-request.yml&title=Feature Request%3A+">Request a Feature</a> | <a href="https://github.com/storm-software/storm-stack/discussions">Ask a Question</a> | ||
<b> | ||
<a href="https://stormsoftware.com" target="_blank">Website</a> • | ||
<a href="https://github.com/storm-software/storm-stack" target="_blank">GitHub</a> • | ||
<a href="https://discord.gg/MQ6YVzakM5">Discord</a> • <a href="https://stormstack.github.io/stormstack/" target="_blank">Docs</a> • <a href="https://stormsoftware.com/contact" target="_blank">Contact</a> • | ||
<a href="https://github.com/storm-software/storm-stack/issues/new?assignees=&labels=bug&template=bug-report.yml&title=Bug Report%3A+">Report a Bug</a> | ||
</b> | ||
</div> | ||
<br /> | ||
This package is part of the <b>⚡storm-stack</b> monorepo. The storm-stack packages include CLI utility applications, tools, and various libraries used to create modern, scalable web applications. | ||
This package is part of the ⚡<b>Storm Stack</b> monorepo. Storm Stack packages include CLI utility applications, tools, and various libraries used to create modern, scalable web applications. | ||
<br /> | ||
<h3 align="center">💻 Visit <a href="https://stormsoftware.org" target="_blank">stormsoftware.org</a> to stay up to date with this developer</h3><br /> | ||
<h3 align="center">💻 Visit <a href="https://stormsoftware.com" target="_blank">stormsoftware.com</a> to stay up to date with this developer</h3><br /> | ||
[![Version](https://img.shields.io/badge/version-1.16.2-1fb2a6.svg?style=for-the-badge&color=1fb2a6)](https://prettier.io/) | ||
[![Nx](https://img.shields.io/badge/Nx-17.0.2-lightgrey?style=for-the-badge&logo=nx&logoWidth=20&&color=1fb2a6)](http://nx.dev/) [![NextJs](https://img.shields.io/badge/Next.js-14.0.2-lightgrey?style=for-the-badge&logo=nextdotjs&logoWidth=20&color=1fb2a6)](https://nextjs.org/) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge&logo=commitlint&color=1fb2a6)](http://commitizen.github.io/cz-cli/) ![Semantic-Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=for-the-badge&color=1fb2a6) [![documented with docusaurus](https://img.shields.io/badge/documented_with-docusaurus-success.svg?style=for-the-badge&logo=readthedocs&color=1fb2a6)](https://docusaurus.io/) ![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/storm-software/storm-ops/cr.yml?style=for-the-badge&logo=github-actions&color=1fb2a6) | ||
[![Version](https://img.shields.io/badge/version-1.18.0-1fb2a6.svg?style=for-the-badge&color=1fb2a6)](https://prettier.io/) [![Nx](https://img.shields.io/badge/Nx-17.0.2-lightgrey?style=for-the-badge&logo=nx&logoWidth=20&&color=1fb2a6)](http://nx.dev/) [![NextJs](https://img.shields.io/badge/Next.js-14.0.2-lightgrey?style=for-the-badge&logo=nextdotjs&logoWidth=20&color=1fb2a6)](https://nextjs.org/) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge&logo=commitlint&color=1fb2a6)](http://commitizen.github.io/cz-cli/) ![Semantic-Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=for-the-badge&color=1fb2a6) [![documented with Fumadocs](https://img.shields.io/badge/documented_with-fumadocs-success.svg?style=for-the-badge&logo=readthedocs&color=1fb2a6)](https://fumadocs.vercel.app/) ![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/storm-software/storm-stack/cr.yml?style=for-the-badge&logo=github-actions&color=1fb2a6) | ||
> [!IMPORTANT] | ||
<!-- prettier-ignore-start --> | ||
<!-- markdownlint-disable --> | ||
> [!IMPORTANT] | ||
> This repository, and the apps, libraries, and tools contained within, is still in it's initial development phase. As a result, bugs and issues are expected with it's usage. When the main development phase completes, a proper release will be performed, the packages will be availible through NPM (and other distributions), and this message will be removed. However, in the meantime, please feel free to report any issues you may come across. | ||
<!-- markdownlint-restore --> | ||
<!-- prettier-ignore-end --> | ||
<div align="center"> | ||
<b>Be sure to ⭐ this repository on <a href="https://github.com/storm-software/storm-stack" target="_blank">GitHub</a> so you can keep up to date on any daily progress!</b> | ||
</div> | ||
<br /> | ||
<!-- START doctoc --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
## Table of Contents | ||
- [Command Line Utility Library](#command-line-utility-library) | ||
- [Table of Contents](#table-of-contents) | ||
- [Installing](#installing) | ||
- [Reduced Package Size](#reduced-package-size) | ||
- [Development](#development) | ||
- [Building](#building) | ||
- [Running unit tests](#running-unit-tests) | ||
- [Linting](#linting) | ||
- [Storm Workspaces](#storm-workspaces) | ||
- [Roadmap](#roadmap) | ||
- [Support](#support) | ||
- [License](#license) | ||
- [Changelog](#changelog) | ||
- [Contributing](#contributing) | ||
- [Contributors](#contributors) | ||
<!-- END doctoc --> | ||
<br /> | ||
<!-- markdownlint-restore --> | ||
@@ -39,2 +76,21 @@ <!-- prettier-ignore-end --> | ||
<!-- START doctoc --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
## Table of Contents | ||
- [Installing](#installing) | ||
- [Reduced Package Size](#reduced-package-size) | ||
- [Development](#development) | ||
- [Building](#building) | ||
- [Running unit tests](#running-unit-tests) | ||
- [Linting](#linting) | ||
- [Storm Workspaces](#storm-workspaces) | ||
- [Roadmap](#roadmap) | ||
- [Support](#support) | ||
- [License](#license) | ||
- [Changelog](#changelog) | ||
- [Contributing](#contributing) | ||
- [Contributors](#contributors) | ||
- [💻 Visit stormsoftware.org to stay up to date with this developer](#-visit-stormsoftwareorg-to-stay-up-to-date-with-this-developer) | ||
<!-- END doctoc --> | ||
@@ -70,7 +126,11 @@ | ||
This project uses [tsup](https://tsup.egoist.dev/) to package the source code due to its ability to remove unused code and ship smaller javascript files thanks to code splitting. This helps to greatly reduce the size of the package and to make it easier to use in other projects. | ||
This project uses [tsup](https://tsup.egoist.dev/) to package the source code | ||
due to its ability to remove unused code and ship smaller javascript files | ||
thanks to code splitting. This helps to greatly reduce the size of the package | ||
and to make it easier to use in other projects. | ||
## Development | ||
This project is built using [Nx](https://nx.dev). As a result, many of the usual commands are available to assist in development. | ||
This project is built using [Nx](https://nx.dev). As a result, many of the usual | ||
commands are available to assist in development. | ||
@@ -96,12 +156,26 @@ ### Building | ||
Storm workspaces are built using <a href="https://nx.dev/" target="_blank">Nx</a>, a set of extensible dev tools for monorepos, which helps you develop like Google, Facebook, and Microsoft. Building on top of Nx, the Open System provides a set of tools and patterns that help you scale your monorepo to many teams while keeping the codebase maintainable. | ||
Storm workspaces are built using | ||
<a href="https://nx.dev/" target="_blank">Nx</a>, a set of extensible dev tools | ||
for monorepos, which helps you develop like Google, Facebook, and Microsoft. | ||
Building on top of Nx, the Open System provides a set of tools and patterns that | ||
help you scale your monorepo to many teams while keeping the codebase | ||
maintainable. | ||
<div align="right">[ <a href="#table-of-contents">Back to top ▲</a> ]</div> | ||
<br /> | ||
## Roadmap | ||
See the [open issues](https://github.com/storm-software/storm-stack/issues) for a list of proposed features (and known issues). | ||
See the [open issues](https://github.com/storm-software/storm-stack/issues) for a | ||
list of proposed features (and known issues). | ||
- [Top Feature Requests](https://github.com/storm-software/storm-stack/issues?q=label%3Aenhancement+is%3Aopen+sort%3Areactions-%2B1-desc) (Add your votes using the 👍 reaction) | ||
- [Top Bugs](https://github.com/storm-software/storm-stack/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Areactions-%2B1-desc) (Add your votes using the 👍 reaction) | ||
- [Top Feature Requests](https://github.com/storm-software/storm-stack/issues?q=label%3Aenhancement+is%3Aopen+sort%3Areactions-%2B1-desc) | ||
(Add your votes using the 👍 reaction) | ||
- [Top Bugs](https://github.com/storm-software/storm-stack/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Areactions-%2B1-desc) | ||
(Add your votes using the 👍 reaction) | ||
- [Newest Bugs](https://github.com/storm-software/storm-stack/issues?q=is%3Aopen+is%3Aissue+label%3Abug) | ||
<div align="right">[ <a href="#table-of-contents">Back to top ▲</a> ]</div> | ||
<br /> | ||
## Support | ||
@@ -111,19 +185,35 @@ | ||
- [Contact](https://stormsoftware.org/contact) | ||
- [Contact](https://stormsoftware.com/contact) | ||
- [GitHub discussions](https://github.com/storm-software/storm-stack/discussions) | ||
- <support@stormsoftware.org> | ||
- <support@stormsoftware.com> | ||
<div align="right">[ <a href="#table-of-contents">Back to top ▲</a> ]</div> | ||
<br /> | ||
## License | ||
This project is licensed under the **Apache License 2.0**. Feel free to edit and distribute this template as you like. | ||
This project is licensed under the **Apache License 2.0**. Feel free to edit and | ||
distribute this template as you like. | ||
See [LICENSE](LICENSE) for more information. | ||
<div align="right">[ <a href="#table-of-contents">Back to top ▲</a> ]</div> | ||
<br /> | ||
## Changelog | ||
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Every release, along with the migration instructions, is documented in the [CHANGELOG](CHANGELOG.md) file | ||
This project adheres to | ||
[Semantic Versioning](https://semver.org/spec/v2.0.0.html). Every release, along | ||
with the migration instructions, is documented in the [CHANGELOG](CHANGELOG.md) | ||
file | ||
<div align="right">[ <a href="#table-of-contents">Back to top ▲</a> ]</div> | ||
<br /> | ||
## Contributing | ||
First off, thanks for taking the time to contribute! Contributions are what makes the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are **greatly appreciated**. | ||
First off, thanks for taking the time to contribute! Contributions are what | ||
makes the open-source community such an amazing place to learn, inspire, and | ||
create. Any contributions you make will benefit everybody else and are **greatly | ||
appreciated**. | ||
@@ -133,3 +223,4 @@ Please try to create bug reports that are: | ||
- _Reproducible._ Include steps to reproduce the problem. | ||
- _Specific._ Include as much detail as possible: which version, what environment, etc. | ||
- _Specific._ Include as much detail as possible: which version, what | ||
environment, etc. | ||
- _Unique._ Do not duplicate existing opened issues. | ||
@@ -140,7 +231,13 @@ - _Scoped to a Single Bug._ One bug per report. | ||
You can use [markdownlint-cli](https://github.com/storm-software/storm-stack/markdownlint-cli) to check for common markdown style inconsistency. | ||
You can use | ||
[markdownlint-cli](https://github.com/storm-software/storm-stack/markdownlint-cli) | ||
to check for common markdown style inconsistency. | ||
<div align="right">[ <a href="#table-of-contents">Back to top ▲</a> ]</div> | ||
<br /> | ||
## Contributors | ||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): | ||
Thanks goes to these wonderful people | ||
([emoji key](https://allcontributors.org/docs/en/emoji-key)): | ||
@@ -152,5 +249,5 @@ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||
<tr> | ||
<td align="center" valign="top" width="14.28%"><a href="http://www.sullypat.com/"><img src="https://avatars.githubusercontent.com/u/99053093?v=4?s=100" width="100px;" alt="Patrick Sullivan"/><br /><sub><b>Patrick Sullivan</b></sub></a><br /><a href="#design-sullivanpj" title="Design">🎨</a> <a href="https://github.com/storm-software/storm-ops/commits?author=sullivanpj" title="Code">💻</a> <a href="#tool-sullivanpj" title="Tools">🔧</a> <a href="https://github.com/storm-software/storm-ops/commits?author=sullivanpj" title="Documentation">📖</a> <a href="https://github.com/storm-software/storm-ops/commits?author=sullivanpj" title="Tests">⚠️</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="http://www.sullypat.com/"><img src="https://avatars.githubusercontent.com/u/99053093?v=4?s=100" width="100px;" alt="Patrick Sullivan"/><br /><sub><b>Patrick Sullivan</b></sub></a><br /><a href="#design-sullivanpj" title="Design">🎨</a> <a href="https://github.com/storm-software/storm-stack/commits?author=sullivanpj" title="Code">💻</a> <a href="#tool-sullivanpj" title="Tools">🔧</a> <a href="https://github.com/storm-software/storm-stack/commits?author=sullivanpj" title="Documentation">📖</a> <a href="https://github.com/storm-software/storm-stack/commits?author=sullivanpj" title="Tests">⚠️</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="https://tylerbenning.com/"><img src="https://avatars.githubusercontent.com/u/7265547?v=4?s=100" width="100px;" alt="Tyler Benning"/><br /><sub><b>Tyler Benning</b></sub></a><br /><a href="#design-tbenning" title="Design">🎨</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="http://stormsoftware.org"><img src="https://avatars.githubusercontent.com/u/149802440?v=4?s=100" width="100px;" alt="Stormie"/><br /><sub><b>Stormie</b></sub></a><br /><a href="#maintenance-stormie-bot" title="Maintenance">🚧</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="http://stormsoftware.com"><img src="https://avatars.githubusercontent.com/u/149802440?v=4?s=100" width="100px;" alt="Stormie"/><br /><sub><b>Stormie</b></sub></a><br /><a href="#maintenance-stormie-bot" title="Maintenance">🚧</a></td> | ||
</tr> | ||
@@ -161,3 +258,3 @@ </tbody> | ||
<td align="center" size="13px" colspan="7"> | ||
<img src="https://raw.githubusercontent.com/all-contributors/all-contributors-cli/1b8533af435da9854653492b1327a23a4dbd0a10/assets/logo-small.svg"> | ||
<img src="https://raw.githubusercontent.com/all-contributors/all-contributors-cli/1b8533af435da9854653492b1327a23a4dbd0a10/assets/logo-small.svg" alt="All Contributors"> | ||
<a href="https://all-contributors.js.org/docs/en/bot/usage">Add your contributions</a> | ||
@@ -172,24 +269,55 @@ </img> | ||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! | ||
This project follows the | ||
[all-contributors](https://github.com/all-contributors/all-contributors) | ||
specification. Contributions of any kind welcome! | ||
<div align="right">[ <a href="#table-of-contents">Back to top ▲</a> ]</div> | ||
<br /> | ||
<hr /> | ||
<br /> | ||
<div align="center"> | ||
<img src="https://pub-761b436209f44a4d886487c917806c08.r2.dev/logo-banner.png" width="100%" altText="Storm Software" /> | ||
<img src="https://pub-761b436209f44a4d886487c917806c08.r2.dev/logo-banner.png" width="100%" alt="Storm Software" /> | ||
</div> | ||
<br /> | ||
<div align="center"> | ||
<a href="https://stormsoftware.org" target="_blank">Website</a> | <a href="https://stormsoftware.org/contact" target="_blank">Contact</a> | <a href="https://linkedin.com/in/patrick-sullivan-865526b0" target="_blank">LinkedIn</a> | <a href="https://medium.com/@pat.joseph.sullivan" target="_blank">Medium</a> | <a href="https://github.com/storm-software" target="_blank">GitHub</a> | <a href="https://keybase.io/sullivanp" target="_blank">OpenPGP Key</a> | ||
<a href="https://stormsoftware.com" target="_blank">Website</a> • <a href="https://stormsoftware.com/contact" target="_blank">Contact</a> • <a href="https://linkedin.com/in/patrick-sullivan-865526b0" target="_blank">LinkedIn</a> • <a href="https://medium.com/@pat.joseph.sullivan" target="_blank">Medium</a> • <a href="https://github.com/storm-software" target="_blank">GitHub</a> • <a href="https://keybase.io/sullivanp" target="_blank">OpenPGP Key</a> | ||
</div> | ||
<div align="center"> | ||
<p><b>Fingerprint:</b> 1BD2 7192 7770 2549 F4C9 F238 E6AD C420 DA5C 4C2D</p> | ||
<b>Fingerprint:</b> 1BD2 7192 7770 2549 F4C9 F238 E6AD C420 DA5C 4C2D | ||
</div> | ||
<br /> | ||
Storm Software is an open source software development organization and creator of Acidic, StormStack and StormCloud. Our mission is to make software development more accessible. Our ideal future is one where anyone can create software without years of prior development experience serving as a barrier to entry. We hope to achieve this via LLMs, Generative AI, and intuitive, high-level data modeling/programming languagues. | ||
Storm Software is an open source software development organization and creator | ||
of Acidic, StormStack and StormCloud. | ||
If this sounds interesting, and you would like to help us in creating the next generation of development tools, please reach out on our website! | ||
Our mission is to make software development more accessible. Our ideal future is | ||
one where anyone can create software without years of prior development | ||
experience serving as a barrier to entry. We hope to achieve this via LLMs, | ||
Generative AI, and intuitive, high-level data modeling/programming languages. | ||
<h3 align="center">💻 Visit <a href="https://stormsoftware.org" target="_blank">stormsoftware.org</a> to stay up to date with this developer</h3><br /><br /> | ||
Join us on [Discord](https://discord.gg/MQ6YVzakM5) to chat with the team, | ||
receive release notifications, ask questions, and get involved. | ||
If this sounds interesting, and you would like to help us in creating the next | ||
generation of development tools, please reach out on our | ||
[website](https://stormsoftware.com/contact) or join our | ||
[Slack channel](https://join.slack.com/t/storm-software/shared_invite/zt-2gsmk04hs-i6yhK_r6urq0dkZYAwq2pA)! | ||
<br /> | ||
<div align="center"><a href="https://stormsoftware.com" target="_blank"><img src="https://pub-761b436209f44a4d886487c917806c08.r2.dev/icon-fill.png" alt="Storm Software" width="200px"/></a></div> | ||
<br /> | ||
<div align="center"><a href="https://stormsoftware.com" target="_blank"><img src="https://pub-761b436209f44a4d886487c917806c08.r2.dev/visit-us-text.svg" alt="Visit us at stormsoftware.com" height="90px"/></a></div> | ||
<br /> | ||
<div align="right">[ <a href="#table-of-contents">Back to top ▲</a> ]</div> | ||
<br /> | ||
<br /> | ||
<!-- markdownlint-restore --> | ||
@@ -196,0 +324,0 @@ <!-- prettier-ignore-end --> |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
36
0
0
317
2
1
60653
879
+ Addedconsole-table-printer@2.12.1(transitive)
- Removedconsole-table-printer@2.11.2(transitive)
Updatedconsole-table-printer@2.12.1