@zerotal/core 1.8.1 → 1.10.0

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/api-surface.md +192 -424
  3. package/package.json +3 -1
  4. package/src/application/Application.ts +10 -4
  5. package/src/application/currentApp.ts +7 -1
  6. package/src/build/codemod.ts +1 -1
  7. package/src/command/CommandRunner.ts +2 -0
  8. package/src/command/OutputWriter.ts +5 -1
  9. package/src/command/builtin/AssetsPruneCommand.ts +138 -0
  10. package/src/command/builtin/DeployCommand.ts +91 -1
  11. package/src/command/builtin/TestCommand.ts +9 -2
  12. package/src/command/builtin/index.ts +1 -0
  13. package/src/command/startZerotal.ts +62 -1
  14. package/src/config/AppConfig.ts +10 -10
  15. package/src/config/ConfigLoader.ts +5 -1
  16. package/src/config/DeployConfig.ts +33 -0
  17. package/src/config/index.ts +6 -1
  18. package/src/config/registry.ts +5 -1
  19. package/src/config/validation.ts +10 -2
  20. package/src/conventions/ConventionLoader.ts +44 -3
  21. package/src/dev/BuildOutput.ts +58 -6
  22. package/src/dev/CssPlugins.ts +13 -3
  23. package/src/dev/DevBuildHook.ts +10 -2
  24. package/src/dev/DevDeck.ts +9 -3
  25. package/src/dev/DevOrchestrator.ts +2 -0
  26. package/src/dev/DevProcess.ts +19 -5
  27. package/src/dev/DevReloadMiddleware.ts +7 -1
  28. package/src/dev/DevSupervisor.ts +27 -9
  29. package/src/dev/bootBuild.ts +9 -1
  30. package/src/dev/index.ts +6 -1
  31. package/src/dev/reloadClient.ts +2 -0
  32. package/src/dev/startDevMode.ts +8 -2
  33. package/src/doctor/AppDoctor.ts +43 -1
  34. package/src/doctor/throttleIdentity.ts +118 -0
  35. package/src/errors/RuntimeMismatchError.ts +21 -0
  36. package/src/errors/index.ts +1 -0
  37. package/src/events/Emitter.ts +5 -1
  38. package/src/health/Health.ts +5 -5
  39. package/src/helpers/html.ts +2 -0
  40. package/src/helpers/index.ts +2 -1
  41. package/src/helpers/markdown.ts +14 -1
  42. package/src/helpers/pageElements.ts +2 -0
  43. package/src/http/HttpClient.ts +5 -1
  44. package/src/http/UploadedFile.ts +2 -2
  45. package/src/http/Uri.ts +5 -1
  46. package/src/http/negotiate.ts +5 -1
  47. package/src/http/originGuard.ts +2 -0
  48. package/src/http/sniffContentType.ts +7 -1
  49. package/src/index.ts +2 -1
  50. package/src/lock/LockManager.ts +4 -4
  51. package/src/logger/LoggerMiddleware.ts +1 -1
  52. package/src/logger/types.ts +4 -4
  53. package/src/macros/config.macro.ts +2 -0
  54. package/src/metrics/HttpMetrics.ts +10 -2
  55. package/src/middleware/BaseMiddleware.ts +20 -0
  56. package/src/middleware/CorsMiddleware.ts +6 -6
  57. package/src/middleware/RateLimiter.ts +105 -22
  58. package/src/middleware/SecureHeadersMiddleware.ts +8 -8
  59. package/src/middleware/ThrottleMiddleware.ts +57 -4
  60. package/src/middleware/WebhookMiddleware.ts +7 -7
  61. package/src/pipeline/ContextRegistry.ts +12 -2
  62. package/src/pipeline/HttpContext.ts +4 -0
  63. package/src/pipeline/currentPage.ts +4 -0
  64. package/src/pipeline/types.ts +2 -0
  65. package/src/router/FileRouter.ts +20 -2
  66. package/src/router/Route.ts +3 -0
  67. package/src/router/RouteHandler.ts +2 -2
  68. package/src/router/Router.ts +7 -5
  69. package/src/router/domain.ts +1 -0
  70. package/src/router/registry.ts +12 -2
  71. package/src/security/redactGraph.ts +1 -1
  72. package/src/shared/format.ts +135 -0
  73. package/src/shared/index.ts +34 -0
  74. package/src/storage/StorageFilesMiddleware.ts +4 -2
  75. package/src/storage/types.ts +10 -10
  76. package/src/support/cookie.ts +13 -7
  77. package/src/support/deepMerge.ts +49 -0
  78. package/src/support/runtime.ts +226 -0
  79. package/src/view/FileRouteResolver.ts +2 -0
  80. package/src/view/jsx-runtime.ts +4 -0
package/api-surface.md CHANGED
@@ -394,6 +394,7 @@ class LimiterDefinition = {
394
394
  register: () => LimiterDefinition
395
395
  toMiddleware: () => ThrottleMiddleware
396
396
  toMiddlewareClass: () => new () => ThrottleMiddleware
397
+ trustedProxies: (count: number) => LimiterDefinition
397
398
  }
398
399
 
399
400
  class MarkdownBuilder = {
@@ -512,20 +513,6 @@ class ResponseBuilder = {
512
513
  withWarning: (message: string) => ResponseBuilder
513
514
  }
514
515
 
515
- class RouterState = {
516
- new (): RouterState
517
- domain: string | undefined
518
- groupMiddleware: MiddlewareClass[]
519
- implicitModelResolver: ((paramName: string) => ModelBindingResolver | undefined) | null
520
- markdownDirs: MarkdownDir[]
521
- middlewareGroups: Map<string, MiddlewareClass[]>
522
- namedRoutes: Map<string, string>
523
- prefix: string
524
- rawRoutes: Map<string, (req: Request) => Response | Promise<Response>>
525
- routes: Map<string, RouteDefinition>
526
- staticDirs: StaticDir[]
527
- }
528
-
529
516
  class ScopedResolver = {
530
517
  new (_container?: Container | undefined): ScopedResolver
531
518
  acquire: () => void
@@ -576,13 +563,6 @@ class ServiceUnavailableError = {
576
563
  readonly status: number
577
564
  }
578
565
 
579
- class TerminalWriter = {
580
- new (): TerminalWriter
581
- write: (message: string) => void
582
- writeError: (message: string) => void
583
- writeLine: (message: string) => void
584
- }
585
-
586
566
  class ThrottleMiddleware = {
587
567
  new (options?: Partial<ThrottleOptions>): ThrottleMiddleware
588
568
  static with: <T extends new (...args: any[]) => BaseMiddleware<any>, Opts = T extends new (...args: any[]) => BaseMiddleware<infer U> ? U : object>(this: T, options: DeepPartial<NoInfer<Opts>>) => new () => InstanceType<T>
@@ -648,8 +628,6 @@ const App = { readonly container: Container; readonly instance: () => Appl
648
628
 
649
629
  const Artisan = { call(commandName: string, parameters?: Record<string, string | boolean | number>): Promise<ArtisanResult>;}
650
630
 
651
- const builtinDoctorChecks = DoctorCheck[]
652
-
653
631
  const Config = ConfigManager
654
632
 
655
633
  const Events = Emitter
@@ -668,8 +646,6 @@ function app = { (): Application; <T>(token: BindingToken<T>): Promise<T>;
668
646
 
669
647
  function basePath = (...segments: string[]) => string
670
648
 
671
- function buildCookie = (options: CookieOptions) => string
672
-
673
649
  function camelCase = (value: string) => string
674
650
 
675
651
  function collect = <T>(items: T[]) => Collection<T>
@@ -708,10 +684,6 @@ function make = <T>(token: BindingToken<T>) => Promise<T>
708
684
 
709
685
  function markdown = (content: string, options?: BunMarkdownOptions & { title?: string;}, status?: number) => MarkdownBuilder
710
686
 
711
- function pageElements = (current: number, last: number, each?: number) => (number | '...')[]
712
-
713
- function parseCookieHeader = (header: string, name: string) => string | undefined
714
-
715
687
  function pipe = <T, R>(value: T, fn: (val: T) => R) => R
716
688
 
717
689
  function pipeAsync = <T, R>(value: T, fn: (val: T) => Promise<R>) => Promise<R>
@@ -726,8 +698,6 @@ function redirectTo = <N extends RouteTarget>(name: N, params?: RouteParamsArg<N
726
698
 
727
699
  function registerErrorDiagnoser = (diagnoser: ErrorDiagnoser) => void
728
700
 
729
- function registerFileRouteResolver = (resolver: FileRouteResolver) => void
730
-
731
701
  function request = { (): HttpContext; <T = string>(key: string, fallback?: T): T | undefined;}
732
702
 
733
703
  function requireEnv = (key: string) => string
@@ -740,14 +710,8 @@ function runDoctor = (app: Application, extraChecks?: DoctorCheck[]) => Promise<
740
710
 
741
711
  function safeEqual = (a: string, b: string) => boolean
742
712
 
743
- function safeRedirectPath = (url: string | null | undefined, origin: string) => string | undefined
744
-
745
- function scanFileRoutes = (baseDir: string, reloadId?: string) => Promise<number>
746
-
747
713
  function setAppEnv = (command?: string) => void
748
714
 
749
- function setCurrentPageResolver = (resolver: CurrentPageResolver) => void
750
-
751
715
  function sha256Hex = (input: string | Uint8Array) => string
752
716
 
753
717
  function singularize = (value: string) => string
@@ -762,12 +726,8 @@ function tap = <T>(value: T, callback: (val: T) => void) => T
762
726
 
763
727
  function tapAsync = <T>(value: T, callback: (val: T) => Promise<void>) => Promise<T>
764
728
 
765
- function tryCurrentApp = () => Application | undefined
766
-
767
729
  function view = { (markup: string | { toString(): string; }, status?: number): void; <P extends Record<string, unknown> = Record<string, never>>(component: (ctx: HttpContext, props: P) => ViewMarkup | Promise<ViewMarkup>, props?: P, status?: number): void | Promise<void>;}
768
730
 
769
- function withApp = <T>(app: Application, fn: () => T) => T
770
-
771
731
  function withHeaders = (res: Response, headers: Record<string, string>) => Response
772
732
 
773
733
  interface ArtisanResult = {
@@ -777,18 +737,6 @@ interface ArtisanResult = {
777
737
 
778
738
  interface AuthenticatedUser = {}
779
739
 
780
- interface CompiledDomain = {
781
- params: string[]
782
- regex: RegExp
783
- source: string
784
- }
785
-
786
- interface ConcernContext = {
787
- app: Application
788
- env: AppEnvironment
789
- resolve: <T = unknown>(token: string) => T | undefined
790
- }
791
-
792
740
  interface ConcernDescriptor = {
793
741
  dir?: string
794
742
  envs?: AppEnvironment[]
@@ -860,31 +808,24 @@ interface ContainerBindings = {
860
808
  two_factor: TwoFactorService
861
809
  }
862
810
 
863
- interface ContextRegistry = {}
864
-
865
811
  interface CookieOptions = {
866
- domain?: string
867
- httpOnly?: boolean
868
- maxAge?: number
812
+ domain?: string | undefined
813
+ httpOnly?: boolean | undefined
814
+ maxAge?: number | undefined
869
815
  name: string
870
- path?: string
871
- sameSite?: SameSite
872
- secure?: boolean
816
+ path?: string | undefined
817
+ sameSite?: SameSite | undefined
818
+ secure?: boolean | undefined
873
819
  value: string
874
820
  }
875
821
 
876
822
  interface CorsOptions = {
877
- allowedHeaders?: string[]
878
- credentials?: boolean
879
- exposedHeaders?: string[]
880
- maxAge?: number
881
- methods?: string[]
882
- origin?: string | string[] | ((origin: string) => boolean)
883
- }
884
-
885
- interface DevConfigShape = {
886
- disable?: string[]
887
- processes?: DevProcessDefinition[]
823
+ allowedHeaders?: string[] | undefined
824
+ credentials?: boolean | undefined
825
+ exposedHeaders?: string[] | undefined
826
+ maxAge?: number | undefined
827
+ methods?: string[] | undefined
828
+ origin?: string | string[] | ((origin: string) => boolean) | undefined
888
829
  }
889
830
 
890
831
  interface DevProcessDefinition = {
@@ -929,28 +870,10 @@ interface ErrorDiagnosis = {
929
870
  title: string
930
871
  }
931
872
 
932
- interface FileRouteContext = {
933
- filePath: string
934
- isIndex: boolean
935
- layout?: ViewComponent | undefined
936
- middleware: MiddlewareClass[]
937
- module: Record<string, unknown>
938
- name: string
939
- urlPath: string
940
- }
941
-
942
873
  interface GroupOptions = {
943
- domain?: string
944
- middleware?: string | string[] | MiddlewareClass | MiddlewareClass[]
945
- prefix?: string
946
- }
947
-
948
- interface HasResponse = {
949
- response: Response | undefined
950
- }
951
-
952
- interface MiddlewareModule = {
953
- middleware: MiddlewareClass[]
874
+ domain?: string | undefined
875
+ middleware?: string | string[] | MiddlewareClass | MiddlewareClass[] | undefined
876
+ prefix?: string | undefined
954
877
  }
955
878
 
956
879
  interface ModelClass = {
@@ -973,28 +896,6 @@ interface ProviderReport = {
973
896
  name: string
974
897
  }
975
898
 
976
- interface QueuedListener = {
977
- handle: (event: T) => Promise<void> | void
978
- maxAttempts?: number
979
- queue: string | boolean
980
- retryDelay?: number
981
- }
982
-
983
- interface RequestIPProvider = {
984
- requestIP: (req: Request) => { address: string; family: string; port: number;} | null
985
- }
986
-
987
- interface ResolvedDevProcess = {
988
- after: 'server' | 'none'
989
- argv?: string[]
990
- color: DevProcessColor
991
- label: string
992
- name: string
993
- registrant: string
994
- restart: 'always' | 'on-failure' | 'never'
995
- run?: (signal: AbortSignal) => Promise<void>
996
- }
997
-
998
899
  interface RouteBuilder = {
999
900
  <N extends RouteTarget>(name: N, params?: RouteParamValues | undefined, query?: RouteQuery | undefined): string
1000
901
  dynamic: (name: string, params?: RouteParamValues, query?: RouteQuery) => string
@@ -1011,34 +912,6 @@ interface RouteDefinition = {
1011
912
  path: string
1012
913
  }
1013
914
 
1014
- interface RouteFileMeta = {
1015
- DELETE?: { name?: string;}
1016
- GET?: { name?: string;}
1017
- PATCH?: { name?: string;}
1018
- POST?: { name?: string;}
1019
- PUT?: { name?: string;}
1020
- }
1021
-
1022
- interface RouteMethodMiddleware = {
1023
- ALL?: MiddlewareClass[]
1024
- DELETE?: MiddlewareClass[]
1025
- GET?: MiddlewareClass[]
1026
- PATCH?: MiddlewareClass[]
1027
- POST?: MiddlewareClass[]
1028
- PUT?: MiddlewareClass[]
1029
- }
1030
-
1031
- interface RouteModule = {
1032
- DELETE?: FileHandler
1033
- GET?: FileHandler
1034
- PATCH?: FileHandler
1035
- POST?: FileHandler
1036
- PUT?: FileHandler
1037
- default?: ViewComponent | FileHandler
1038
- layout?: ViewComponent | null
1039
- middleware?: RouteMiddleware
1040
- }
1041
-
1042
915
  interface RouteRegistration = {
1043
916
  bind: (paramName: string, model: ModelClass | ModelBindingResolver) => RouteRegistration
1044
917
  name: (routeName: string) => RouteRegistration
@@ -1053,25 +926,25 @@ interface RouterMacros = {
1053
926
  }
1054
927
 
1055
928
  interface SecureHeadersOptions = {
1056
- contentSecurityPolicy?: string
1057
- frameOptions?: false | 'DENY' | 'SAMEORIGIN'
1058
- hstsIncludeSubDomains?: boolean
1059
- hstsMaxAge?: number
1060
- hstsPreload?: boolean
1061
- permissionsPolicy?: string | false
1062
- referrerPolicy?: string
1063
- secure?: boolean
929
+ contentSecurityPolicy?: string | undefined
930
+ frameOptions?: false | 'DENY' | 'SAMEORIGIN' | undefined
931
+ hstsIncludeSubDomains?: boolean | undefined
932
+ hstsMaxAge?: number | undefined
933
+ hstsPreload?: boolean | undefined
934
+ permissionsPolicy?: string | false | undefined
935
+ referrerPolicy?: string | undefined
936
+ secure?: boolean | undefined
1064
937
  }
1065
938
 
1066
939
  interface StartZerotalOptions = {
1067
- configDir?: string
940
+ configDir?: string | undefined
1068
941
  }
1069
942
 
1070
943
  interface ThrottleOptions = {
1071
- keyResolver?: (ctx: HttpContext) => string
944
+ keyResolver?: ((ctx: HttpContext) => string) | undefined
1072
945
  maxAttempts: number
1073
- trustedProxies?: number
1074
- windowSeconds?: number
946
+ trustedProxies?: number | undefined
947
+ windowSeconds?: number | undefined
1075
948
  }
1076
949
 
1077
950
  interface ViewRegistration = {
@@ -1080,14 +953,14 @@ interface ViewRegistration = {
1080
953
  }
1081
954
 
1082
955
  interface WebhookOptions = {
1083
- algorithm?: 'sha256' | 'sha1' | 'sha512'
1084
- format?: 'raw' | 'stripe'
1085
- header?: string
1086
- prefix?: string
956
+ algorithm?: 'sha256' | 'sha1' | 'sha512' | undefined
957
+ format?: 'raw' | 'stripe' | undefined
958
+ header?: string | undefined
959
+ prefix?: string | undefined
1087
960
  secret: string
1088
- timestampHeader?: string
1089
- timestampSeparator?: string
1090
- tolerance?: number
961
+ timestampHeader?: string | undefined
962
+ timestampSeparator?: string | undefined
963
+ tolerance?: number | undefined
1091
964
  }
1092
965
 
1093
966
  interface WebSocketHandlers = {
@@ -1100,38 +973,20 @@ interface WebSocketHandlers = {
1100
973
 
1101
974
  type AppEnvironment = 'web' | 'console' | 'worker' | 'test' | 'repl'
1102
975
 
1103
- type AppScopeInstaller = () => () => void
1104
-
1105
976
  type ArgDef = { name: string; required?: boolean; default?: string;}
1106
977
 
1107
978
  type BindingToken = ClassToken<T> | AbstractToken<T> | keyof ContainerBindings
1108
979
 
1109
- type ContextKey = never
1110
-
1111
- type ContextValue = ContextRegistry[K]
1112
-
1113
980
  type ControllerResponse = void | ResponseBuilder | MarkdownBuilder
1114
981
 
1115
- type CurrentPageResolver = (pageName: string) => number | undefined
1116
-
1117
982
  type DeepPartial = { [K in keyof T]?: (NonNullable<T[K]> extends _Atomic ? T[K] : NonNullable<T[K]> extends object ? DeepPartial<NonNullable<T[K]>> : T[K]) | undefined; }
1118
983
 
1119
- type DevProcessColor = 'cyan' | 'magenta' | 'yellow' | 'green' | 'blue' | 'red'
1120
-
1121
984
  type ErrorDiagnoser = (error: Error, ctx?: HttpContext) => ErrorDiagnosis | null | Promise<ErrorDiagnosis | null>
1122
985
 
1123
986
  type Factory = (container: Container) => T | Promise<T>
1124
987
 
1125
- type FileHandler = (ctx: HttpContext) => void | Response | Promise<void | Response>
1126
-
1127
- type FileRouteHandler = (ctx: HttpContext) => void | Response | Promise<void | Response>
1128
-
1129
- type FileRouteResolver = (ctx: FileRouteContext) => boolean
1130
-
1131
988
  type FileRoutingConfig = { [x: string]: FileRoutingEntry;}
1132
989
 
1133
- type FileRoutingEntry = string | { dir: string; prefix?: string; middleware?: MiddlewareInput }
1134
-
1135
990
  type FlagDef = { name: string; short?: string; type: 'string' | 'boolean' | 'number'; description?: string; default?: unknown;}
1136
991
 
1137
992
  type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
@@ -1140,12 +995,12 @@ type HttpResponse = Promise<void>
1140
995
 
1141
996
  type MiddlewareClass = new (...args: any[]) => Pipe<HttpContext>
1142
997
 
1143
- type ModelBindingResolver = (value: string, ctx: HttpContext) => Promise<unknown>
1144
-
1145
998
  type NextFn = () => Promise<Response | void>
1146
999
 
1147
1000
  type ParamsOf = P extends `${string}:${infer Name}/${infer Rest}` ? { [K in Name]: RouteParamValue; } & ParamsOf<`/${Rest}`> : P extends `${string}:${infer Name}` ? { [K in Name]: RouteParamValue; } : P extends `${string}*${string}` ? { "*": RouteParamValue | readonly RouteParamValue[];} : Record<never, never>
1148
1001
 
1002
+ type Resolved = { [K in keyof T]-?: Exclude<T[K], undefined>; }
1003
+
1149
1004
  type RouteArgs = [params?: RouteParamValues, query?: RouteQuery]
1150
1005
 
1151
1006
  type RouteMiddleware = MiddlewareClass[] | RouteMethodMiddleware
@@ -1154,22 +1009,14 @@ type RouteName = never
1154
1009
 
1155
1010
  type RouteParams = { [K in keyof ParamsOf<RoutePattern<N>>]: ParamsOf<RoutePattern<N>>[K]; }
1156
1011
 
1157
- type RouteParamsArg = { [x: string]: RouteParamValue | readonly RouteParamValue[];}
1158
-
1159
- type RouteParamValue = string | number
1160
-
1161
1012
  type RouteParamValues = { [x: string]: RouteParamValue | readonly RouteParamValue[];}
1162
1013
 
1163
- type RoutePattern = N extends never ? RouteRegistry[N] extends string ? RouteRegistry[N] : string : string
1164
-
1165
1014
  type RouteQuery = { [x: string]: string | number | boolean | readonly (string | number | boolean)[] | null | undefined;}
1166
1015
 
1167
1016
  type RouteTarget = string
1168
1017
 
1169
1018
  type RoutingConfig = { [x: string]: RoutingEntry;}
1170
1019
 
1171
- type RoutingEntry = string | { file: string; prefix?: string; middleware?: MiddlewareInput }
1172
-
1173
1020
  type SameSite = 'Strict' | 'Lax' | 'None'
1174
1021
 
1175
1022
  type ViewComponent = (ctx: HttpContext, props: P) => unknown
@@ -1193,7 +1040,7 @@ function addToDefaultArrayExport = (source: string, identifier: string) => strin
1193
1040
  function registerProvider = (options: RegisterProviderOptions) => Promise<RegisterResult>
1194
1041
 
1195
1042
  interface RegisterProviderOptions = {
1196
- bootstrapPath?: string
1043
+ bootstrapPath?: string | undefined
1197
1044
  className: string
1198
1045
  importPath: string
1199
1046
  }
@@ -1460,6 +1307,34 @@ class AssetsBuildCommand = {
1460
1307
  write: (msg: string) => void
1461
1308
  }
1462
1309
 
1310
+ class AssetsPruneCommand = {
1311
+ new (): AssetsPruneCommand
1312
+ static args: ArgDef[]
1313
+ static commandName: string
1314
+ static description: string
1315
+ static flags: ({ name: string; type: 'string'; description: string; default?: never;} | { name: string; type: 'boolean'; description: string; default: boolean;})[]
1316
+ static needsApp: boolean
1317
+ _readLine: () => Promise<string>
1318
+ _writer: OutputWriter
1319
+ app: unknown
1320
+ args: Record<string, string>
1321
+ ask: (question: string, defaultValue?: string) => Promise<string>
1322
+ choice: (question: string, options: string[]) => Promise<string>
1323
+ confirm: (question: string, defaultValue?: boolean) => Promise<boolean>
1324
+ dim: (msg: string) => void
1325
+ error: (msg: string) => void
1326
+ flags: Record<string, string | number | boolean>
1327
+ info: (msg: string) => void
1328
+ line: (msg: string) => void
1329
+ newLine: () => void
1330
+ run: () => Promise<void>
1331
+ secret: (question: string) => Promise<string>
1332
+ section: (title: string) => void
1333
+ table: (rows: [string, string][], indent?: number) => void
1334
+ warn: (msg: string) => void
1335
+ write: (msg: string) => void
1336
+ }
1337
+
1463
1338
  class CompileCommand = {
1464
1339
  new (): CompileCommand
1465
1340
  static args: ArgDef[]
@@ -2333,6 +2208,8 @@ class ConfigValidationError = {
2333
2208
  readonly status: number
2334
2209
  }
2335
2210
 
2211
+ const CONVENTIONAL_PREFLIGHT_COMMAND = 'release:check'
2212
+
2336
2213
  const DEFAULT_DEPLOY_STEPS = readonly string[]
2337
2214
 
2338
2215
  const DEFAULT_DEPLOY_TARGETS = Record<string, DeployTarget>
@@ -2345,7 +2222,7 @@ function DeployConfig = (options?: Partial<DeployConfigShape>) => DeployConfigSh
2345
2222
 
2346
2223
  interface AppAssetsConfig = {
2347
2224
  entrypoint: string | string[]
2348
- loader?: Record<string, AssetLoaderKind>
2225
+ loader?: Record<string, AssetLoaderKind> | undefined
2349
2226
  minify: boolean
2350
2227
  outDir: string
2351
2228
  prefix: string
@@ -2353,11 +2230,11 @@ interface AppAssetsConfig = {
2353
2230
 
2354
2231
  interface AppConfigShape = {
2355
2232
  allowedOrigins: string[]
2356
- assets?: AppAssetsConfig
2233
+ assets?: AppAssetsConfig | undefined
2357
2234
  conventions: ConventionsConfig
2358
2235
  cors: AppCorsConfig
2359
2236
  debug: boolean
2360
- dev?: DevConfigShape
2237
+ dev?: DevConfigShape | undefined
2361
2238
  env: string
2362
2239
  health: boolean | HealthConfigShape
2363
2240
  http3: boolean
@@ -2369,7 +2246,7 @@ interface AppConfigShape = {
2369
2246
  secureHeaders: AppSecureHeadersConfig
2370
2247
  throttle: AppThrottleConfig
2371
2248
  timezone: string
2372
- tls?: AppTlsConfig
2249
+ tls?: AppTlsConfig | undefined
2373
2250
  url: string
2374
2251
  }
2375
2252
 
@@ -2391,12 +2268,6 @@ interface ConfigRegistry = {
2391
2268
  logging: LoggingConfigShape
2392
2269
  }
2393
2270
 
2394
- interface ConfigValidationContext = {
2395
- config: ConfigManager
2396
- isProduction: boolean
2397
- namespace: string
2398
- }
2399
-
2400
2271
  interface ConventionsConfig = {
2401
2272
  enabled: boolean
2402
2273
  paths: { providers: string; middleware: string; models: string; observers: string; policies: string; listeners: string; events: string; jobs: string; schedules: string; validators: string; commands: string;}
@@ -2407,23 +2278,15 @@ interface DeployConfigShape = {
2407
2278
  }
2408
2279
 
2409
2280
  interface DeployTarget = {
2281
+ preflight?: readonly string[]
2410
2282
  steps?: readonly string[]
2411
2283
  url?: string
2412
2284
  }
2413
2285
 
2414
- interface RegisteredConfigValidator = {
2415
- namespace: string
2416
- validate: ConfigValidator
2417
- }
2418
-
2419
2286
  type AssetLoaderKind = 'file' | 'dataurl' | 'base64' | 'text' | 'json' | 'toml'
2420
2287
 
2421
2288
  type ConfigIssueLevel = 'error' | 'warning'
2422
2289
 
2423
- type ConfigMap = { [x: string]: Record<string, unknown>;}
2424
-
2425
- type ConfigPath = 'lock' | 'app' | 'deploy' | 'health' | 'logging' | 'lock.driver' | 'lock.sqlite' | 'lock.prefix' | 'lock.sqlite.path' | 'app.url' | 'app.name' | 'app.dev' | 'app.port' | 'app.health' | 'app.env' | 'app.key' | 'app.debug' | 'app.locale' | 'app.timezone' | 'app.http3' | 'app.tls' | 'app.maxRequestBodySize' | 'app.allowedOrigins' | 'app.cors' | 'app.throttle' | 'app.secureHeaders' | 'app.assets' | 'app.conventions' | 'app.cors.credentials' | 'app.cors.origin' | 'app.throttle.maxAttempts' | 'app.throttle.windowSeconds' | 'app.secureHeaders.referrerPolicy' | 'app.secureHeaders.frameOptions' | 'app.secureHeaders.secure' | 'app.secureHeaders.hstsMaxAge' | 'app.secureHeaders.hstsIncludeSubDomains' | 'app.secureHeaders.hstsPreload' | 'app.secureHeaders.contentSecurityPolicy' | 'app.conventions.paths' | 'app.conventions.enabled' | 'app.conventions.paths.events' | 'app.conventions.paths.commands' | 'app.conventions.paths.providers' | 'app.conventions.paths.middleware' | 'app.conventions.paths.models' | 'app.conventions.paths.observers' | 'app.conventions.paths.policies' | 'app.conventions.paths.listeners' | 'app.conventions.paths.jobs' | 'app.conventions.paths.schedules' | 'app.conventions.paths.validators' | 'deploy.targets' | `deploy.targets.${string}` | 'health.path' | 'health.enabled' | 'health.secret' | 'health.showDetails' | 'logging.default' | 'logging.file' | 'logging.console' | 'logging.channels' | 'logging.slowQueryMs' | 'logging.requests' | `logging.channels.${string}`
2426
-
2427
2290
  type ConfigValidator = (value: unknown, ctx: ConfigValidationContext) => ConfigIssue[] | void
2428
2291
 
2429
2292
  type ConfigValue = P extends `${infer Head}.${infer Rest}` ? Head extends keyof ConfigRegistry ? ValueAt<ConfigRegistry[Head], Rest> : unknown : P extends keyof ConfigRegistry ? ConfigRegistry[P] : unknown
@@ -2465,75 +2328,6 @@ class DevReloadMiddleware = {
2465
2328
  onError?: (ctx: HttpContext, error: Error) => Promise<void>
2466
2329
  }
2467
2330
 
2468
- class DevSupervisor = {
2469
- new (options: DevSupervisorOptions): DevSupervisor
2470
- definitions: () => ResolvedDevProcess[]
2471
- restart: (name: string) => Promise<void>
2472
- start: (definitions: ResolvedDevProcess[]) => void
2473
- statuses: () => DevProcessStatus[]
2474
- stopAll: () => Promise<void>
2475
- }
2476
-
2477
- class StreamDeck = {
2478
- new (_writer: OutputWriter, _color: boolean): StreamDeck
2479
- line: (name: string, text: string, stream: 'stdout' | 'stderr') => void
2480
- notice: (text: string) => void
2481
- start: (statuses: DevProcessStatus[]) => void
2482
- state: (status: DevProcessStatus) => void
2483
- stop: () => void
2484
- }
2485
-
2486
- class TabsDeck = {
2487
- new (_options: DeckOptions, _stdout: DeckStdout, _stdin: DeckStdin): TabsDeck
2488
- line: (name: string, text: string, stream: 'stdout' | 'stderr') => void
2489
- notice: (text: string) => void
2490
- start: (statuses: DevProcessStatus[]) => void
2491
- state: (status: DevProcessStatus) => void
2492
- stop: () => void
2493
- }
2494
-
2495
- const DEV_RELOAD_CLIENT = string
2496
-
2497
- const SERVER_PROCESS_NAME = 'server'
2498
-
2499
- function bootBuildDecision = (outDirs: string[], env: string | undefined) => Promise<BootBuildDecision>
2500
-
2501
- function buildCssBundle = (input: string, outdir: string, minify?: boolean, loader?: Record<string, string>) => Promise<BundleResult>
2502
-
2503
- function buildJsBundle = (input: string, outdir: string, minify?: boolean) => Promise<BundleResult>
2504
-
2505
- function collectDevProcesses = (app: ProviderHost, config?: ConfigReader) => Promise<ResolvedDevProcess[]>
2506
-
2507
- function createDeck = (options: DeckOptions) => Deck
2508
-
2509
- function detectCssPlugins = (cwd: string) => Promise<BunPlugin[]>
2510
-
2511
- function isWritableDir = (dir: string) => Promise<boolean>
2512
-
2513
- function registerDevHtmlSnippet = (name: string, fn: DevHtmlSnippet) => void
2514
-
2515
- function startDevMode = (options: StartDevModeOptions) => Promise<void>
2516
-
2517
- interface AssetBuildConfig = {
2518
- clean?: boolean
2519
- entrypoint: string | string[]
2520
- loader?: Record<string, string>
2521
- minify: boolean
2522
- outDir: string
2523
- prefix: string
2524
- }
2525
-
2526
- interface BootBuildDecision = {
2527
- build: boolean
2528
- reason?: string
2529
- }
2530
-
2531
- interface BuildResult = {
2532
- logs?: unknown[]
2533
- skipped?: boolean
2534
- success: boolean
2535
- }
2536
-
2537
2331
  interface Deck = {
2538
2332
  line: (name: string, text: string, stream: 'stdout' | 'stderr') => void
2539
2333
  notice: (text: string) => void
@@ -2542,57 +2336,6 @@ interface Deck = {
2542
2336
  stop: () => void
2543
2337
  }
2544
2338
 
2545
- interface DeckOptions = {
2546
- mode?: 'tabs' | 'stream'
2547
- onQuit: () => void
2548
- onRestart: (name: string) => void
2549
- stdin?: DeckStdin
2550
- stdout?: DeckStdout
2551
- writer: OutputWriter
2552
- }
2553
-
2554
- interface DevChild = {
2555
- kill: (signal?: number | NodeJS.Signals) => void
2556
- readonly exited: Promise<number>
2557
- readonly stderr: ReadableStream<Uint8Array<ArrayBufferLike>> | null
2558
- readonly stdout: ReadableStream<Uint8Array<ArrayBufferLike>> | null
2559
- }
2560
-
2561
- interface DevOrchestratorHooks = {
2562
- onCleanup?: () => void | Promise<void>
2563
- onNotice?: (text: string, level: 'info' | 'warn' | 'error') => void
2564
- onServerLine?: (line: string, stream: 'stdout' | 'stderr') => void
2565
- onServerReady?: () => void | Promise<void>
2566
- onServerState?: (state: 'starting' | 'running' | 'restarting' | 'parked') => void
2567
- }
2568
-
2569
- interface DevProcessStatus = {
2570
- attempts: number
2571
- color: DevProcessColor
2572
- exitCode?: number
2573
- label: string
2574
- name: string
2575
- state: DevProcessState
2576
- }
2577
-
2578
- interface DevSupervisorOptions = {
2579
- backoffMs?: number[]
2580
- cwd: string
2581
- env?: Record<string, string | undefined>
2582
- healthyAfterMs?: number
2583
- onLine?: (name: string, line: string, stream: 'stdout' | 'stderr') => void
2584
- onState?: (status: DevProcessStatus) => void
2585
- spawn?: DevSpawnFn
2586
- }
2587
-
2588
- type BuildHookFn = () => Promise<BuildResult>
2589
-
2590
- type DevHtmlSnippet = (ctx: HttpContext) => string
2591
-
2592
- type DevProcessState = 'starting' | 'running' | 'restarting' | 'exited' | 'parked'
2593
-
2594
- type DevSpawnFn = (argv: string[], options: { cwd: string; env: Record<string, string | undefined>;}) => DevChild
2595
-
2596
2339
  ## ./env `(./src/env/index.ts)`
2597
2340
 
2598
2341
  class Def = {
@@ -2754,6 +2497,14 @@ class NotFoundError = {
2754
2497
  readonly status: number
2755
2498
  }
2756
2499
 
2500
+ class RuntimeMismatchError = {
2501
+ new (message: string, mismatch: RuntimeMismatch): RuntimeMismatchError
2502
+ readonly code: string
2503
+ readonly context?: Record<string, unknown> | undefined
2504
+ readonly mismatch: RuntimeMismatch
2505
+ readonly status: number
2506
+ }
2507
+
2757
2508
  class ScopedAfterFlushError = {
2758
2509
  new (message: string): ScopedAfterFlushError
2759
2510
  readonly code: string
@@ -2859,10 +2610,10 @@ interface HealthCheckReport = {
2859
2610
  }
2860
2611
 
2861
2612
  interface HealthConfigShape = {
2862
- enabled?: boolean
2863
- path?: string
2864
- secret?: string
2865
- showDetails?: boolean
2613
+ enabled?: boolean | undefined
2614
+ path?: string | undefined
2615
+ secret?: string | undefined
2616
+ showDetails?: boolean | undefined
2866
2617
  }
2867
2618
 
2868
2619
  interface HealthReport = {
@@ -2882,7 +2633,7 @@ interface HealthResult = {
2882
2633
  interface ResolvedHealthConfig = {
2883
2634
  enabled: boolean
2884
2635
  path: string
2885
- secret?: string
2636
+ secret?: string | undefined
2886
2637
  showDetails: boolean
2887
2638
  }
2888
2639
 
@@ -2900,13 +2651,9 @@ function data_get = (target: unknown, key: string, defaultValue?: unknown) => un
2900
2651
 
2901
2652
  function deepMerge = <T extends object>(base: T, override: DeepPartial<T>) => T
2902
2653
 
2903
- function env = { (key: string): string | undefined; (key: string, fallback: string): string; (key: string, fallback: boolean): boolean; (key: string, fallback: number): number;}
2904
-
2905
- function escapeHtml = (value: string) => string
2906
-
2907
- function markdownPage = (title: string, body: string) => string
2654
+ function definedOnly = <T extends object>(value: T) => { [K in keyof T]?: Exclude<T[K], undefined>; }
2908
2655
 
2909
- function parseCookieHeader = (header: string, name: string) => string | undefined
2656
+ function env = { (key: string): string | undefined; (key: string, fallback: string): string; (key: string, fallback: boolean): boolean; (key: string, fallback: number): number;}
2910
2657
 
2911
2658
  function pipe = <T, R>(value: T, fn: (val: T) => R) => R
2912
2659
 
@@ -2930,23 +2677,7 @@ function tap = <T>(value: T, callback: (val: T) => void) => T
2930
2677
 
2931
2678
  function tapAsync = <T>(value: T, callback: (val: T) => Promise<void>) => Promise<T>
2932
2679
 
2933
- interface BunMarkdownOptions = {
2934
- autolinks?: boolean | { url?: boolean; www?: boolean; email?: boolean;}
2935
- collapseWhitespace?: boolean
2936
- hardSoftBreaks?: boolean
2937
- headings?: boolean | { ids?: boolean;}
2938
- latexMath?: boolean
2939
- noHtmlBlocks?: boolean
2940
- noHtmlSpans?: boolean
2941
- noIndentedCodeBlocks?: boolean
2942
- permissiveAtxHeaders?: boolean
2943
- strikethrough?: boolean
2944
- tables?: boolean
2945
- tagFilter?: boolean
2946
- tasklists?: boolean
2947
- underline?: boolean
2948
- wikiLinks?: boolean
2949
- }
2680
+ type Resolved = { [K in keyof T]-?: Exclude<T[K], undefined>; }
2950
2681
 
2951
2682
  ## ./http `(./src/http/index.ts)`
2952
2683
 
@@ -3081,12 +2812,8 @@ class UrlKeyMissingError = {
3081
2812
 
3082
2813
  const Url = UrlGenerator
3083
2814
 
3084
- function isAllowedOrigin = (request: Request, allowedOrigins?: string[]) => boolean
3085
-
3086
2815
  function negotiate = (ctx: HttpContext) => <TWeb = void, TJson = void, TCli = void>(map: NegotiateMap<TWeb, TJson, TCli>) => Promise<TWeb | TJson | TCli | void>
3087
2816
 
3088
- function sniffContentType = (bytes: Uint8Array) => SniffedType
3089
-
3090
2817
  function uri = (value?: string | Uri) => Uri
3091
2818
 
3092
2819
  function url = { (): UrlGenerator; (path: string, extra?: (string | number)[], secure?: boolean): string;}
@@ -3109,16 +2836,9 @@ interface CliContext = {
3109
2836
  writeln: (content: string) => void
3110
2837
  }
3111
2838
 
3112
- interface FakeStub = {
3113
- body?: unknown
3114
- headers?: Record<string, string>
3115
- status?: number
3116
- url: string
3117
- }
3118
-
3119
2839
  interface FileValidationOptions = {
3120
- maxSize?: number
3121
- mimes?: string[]
2840
+ maxSize?: number | undefined
2841
+ mimes?: string[] | undefined
3122
2842
  }
3123
2843
 
3124
2844
  interface NegotiateMap = {
@@ -3137,20 +2857,6 @@ interface PaginatedData = {
3137
2857
  total: number
3138
2858
  }
3139
2859
 
3140
- interface SniffedType = {
3141
- contentType: string
3142
- extension: string
3143
- recognised: boolean
3144
- }
3145
-
3146
- interface UriQueryString = {
3147
- all: () => Record<string, QueryValue>
3148
- get: (key: string) => string | undefined
3149
- getAll: (key: string) => string[]
3150
- has: (key: string) => boolean
3151
- toString: () => string
3152
- }
3153
-
3154
2860
  interface UrlGenerator = {
3155
2861
  current: () => string
3156
2862
  full: () => string
@@ -3177,8 +2883,6 @@ interface WebContext = {
3177
2883
  view: (markup: string | { toString(): string;}, status?: number) => void
3178
2884
  }
3179
2885
 
3180
- type AnsiColor = 'red' | 'green' | 'yellow' | 'blue' | 'cyan' | 'dim'
3181
-
3182
2886
  type Channel = 'web' | 'json' | 'cli'
3183
2887
 
3184
2888
  type QueryInput = { [x: string]: string | number | boolean | string[];}
@@ -3286,10 +2990,10 @@ class SqliteLockDriver = {
3286
2990
  function LockConfig = (options?: Partial<LockConfigShape>) => LockConfigShape
3287
2991
 
3288
2992
  interface BlockOptions = {
3289
- refresh?: boolean
3290
- refreshEvery?: number
3291
- retryDelay?: number
3292
- timeout?: number
2993
+ refresh?: boolean | undefined
2994
+ refreshEvery?: number | undefined
2995
+ retryDelay?: number | undefined
2996
+ timeout?: number | undefined
3293
2997
  }
3294
2998
 
3295
2999
  interface LockConfigShape = {
@@ -3308,8 +3012,8 @@ interface LockDriver = {
3308
3012
  }
3309
3013
 
3310
3014
  interface RefreshOptions = {
3311
- refresh?: boolean
3312
- refreshEvery?: number
3015
+ refresh?: boolean | undefined
3016
+ refreshEvery?: number | undefined
3313
3017
  }
3314
3018
 
3315
3019
  type LockedCallback = (lock: ManagedLock, signal: AbortSignal) => Promise<T> | T
@@ -3424,16 +3128,16 @@ interface LogEntry = {
3424
3128
  }
3425
3129
 
3426
3130
  interface LoggerOptions = {
3427
- format?: 'text' | 'json'
3131
+ format?: 'text' | 'json' | undefined
3428
3132
  }
3429
3133
 
3430
3134
  interface LoggingConfigShape = {
3431
3135
  channels: Record<string, ChannelConfig>
3432
- console?: ConsoleSinkConfig
3136
+ console?: ConsoleSinkConfig | undefined
3433
3137
  default: string
3434
- file?: FileSinkConfig
3435
- requests?: boolean
3436
- slowQueryMs?: number
3138
+ file?: FileSinkConfig | undefined
3139
+ requests?: boolean | undefined
3140
+ slowQueryMs?: number | undefined
3437
3141
  }
3438
3142
 
3439
3143
  type ChannelConfig = { driver: 'console'; level?: LogLevel; format?: 'json' | 'pretty' } | { driver: 'single'; level?: LogLevel; path: string } | { driver: 'daily'; level?: LogLevel; path: string; days?: number } | { driver: 'stack'; level?: LogLevel; channels: string[] } | { driver: 'null' }
@@ -3444,14 +3148,10 @@ type TableData = Record<string, unknown> | ReadonlyArray<Record<string, unknown>
3444
3148
 
3445
3149
  ## ./macros/config `(./src/macros/config.macro.ts)`
3446
3150
 
3447
- function loadConfigsSync = (configDir: string) => Record<string, Record<string, unknown>>
3151
+ _(no exports)_
3448
3152
 
3449
3153
  ## ./metrics `(./src/metrics/index.ts)`
3450
3154
 
3451
- function beginHttp = () => void
3452
-
3453
- function endHttp = () => void
3454
-
3455
3155
  function httpMetrics = () => HttpMetricsSnapshot
3456
3156
 
3457
3157
  function recordHttp = (status: number, ms: number) => void
@@ -3499,6 +3199,38 @@ type RouteTable = Readonly<Record<string, string>> | ReadonlyMap<string, string>
3499
3199
 
3500
3200
  type RouteTarget = string
3501
3201
 
3202
+ ## ./runtime `(./src/support/runtime.ts)`
3203
+
3204
+ const RUNTIME_MISMATCH_ESCAPE = 'ZT_ALLOW_RUNTIME_MISMATCH'
3205
+
3206
+ function bunBinary = () => string
3207
+
3208
+ function declaredBunFloor = (cwd: string) => { range: string; manifest: string;} | null
3209
+
3210
+ function installedBunVersion = (cwd: string) => { version: string; manifest: string;} | null
3211
+
3212
+ function runtimeBelowFloor = (cwd?: string) => RuntimeFloor | null
3213
+
3214
+ function runtimeBelowFloorMessage = (floor: RuntimeFloor) => string
3215
+
3216
+ function runtimeMismatch = (cwd?: string) => RuntimeMismatch | null
3217
+
3218
+ function runtimeMismatchAllowed = () => boolean
3219
+
3220
+ function runtimeMismatchMessage = (mismatch: RuntimeMismatch) => string
3221
+
3222
+ interface RuntimeFloor = {
3223
+ manifest: string
3224
+ required: string
3225
+ running: string
3226
+ }
3227
+
3228
+ interface RuntimeMismatch = {
3229
+ installed: string
3230
+ manifest: string
3231
+ running: string
3232
+ }
3233
+
3502
3234
  ## ./security `(./src/security/index.ts)`
3503
3235
 
3504
3236
  class CryptKeyMissingError = {
@@ -3529,7 +3261,7 @@ function redactGraph = (value: unknown, options: RedactGraphOptions) => unknown
3529
3261
 
3530
3262
  interface RedactGraphOptions = {
3531
3263
  circular: string
3532
- flatten?: (value: unknown) => string | undefined
3264
+ flatten?: ((value: unknown) => string | undefined) | undefined
3533
3265
  mask: string
3534
3266
  maxDepth: number
3535
3267
  sensitive: (key: string) => boolean
@@ -3538,6 +3270,50 @@ interface RedactGraphOptions = {
3538
3270
 
3539
3271
  type HashAlgorithm = 'argon2id' | 'argon2i' | 'argon2d' | 'bcrypt'
3540
3272
 
3273
+ ## ./shared `(./src/shared/index.ts)`
3274
+
3275
+ const Str = { camelCase(value: string): string; snakeCase(value: string): string; slugify(value: string): string; titleCase(value: string): string; pascalCase(value: string): string; capitalize(value: string): string; lcfirst(value: string): string; truncate(value: string, maxLength: number, suffix?: string): string; isAlphanumeric(value: string): boolean; padLeft(value: string, length: number, char?: string): string; kebab(value: string): string; squish(value: string): string; finish(value: string, cap: string): string; start(value: string, prefix: string): string; after(value: string, needle: string): string; before(value: string, needle: string): string; afterLast(value: string, needle: string): string; beforeLast(value: string, needle: string): string; contains(value: string, substring: string): boolean; random(length?: number): string; replaceFirst(value: string, search: string, replace: string): string; replaceLast(value: string, search: string, replace: string): string; reverse(value: string): string; words(value: string, maxWords: number, suffix?: string): string; macro(name: string, fn: (...args: unknown[]) => unknown): void;}
3276
+
3277
+ function camelCase = (value: string) => string
3278
+
3279
+ function formatDate = (value: Date | number | string, options?: DateOptions) => string
3280
+
3281
+ function formatMoney = (amount: number, options: MoneyOptions) => string
3282
+
3283
+ function formatNumber = (value: number, options?: NumberOptions) => string
3284
+
3285
+ function pluralize = (value: string) => string
3286
+
3287
+ function singularize = (value: string) => string
3288
+
3289
+ function snakeCase = (value: string) => string
3290
+
3291
+ function tableNameFor = (className: string) => string
3292
+
3293
+ interface DateOptions = {
3294
+ dateStyle?: 'medium' | 'short' | 'full' | 'long' | undefined
3295
+ locale?: string | undefined
3296
+ timeStyle?: 'medium' | 'short' | 'full' | 'long' | undefined
3297
+ timeZone?: string | undefined
3298
+ }
3299
+
3300
+ interface FormatOptions = {
3301
+ locale?: string | undefined
3302
+ }
3303
+
3304
+ interface MoneyOptions = {
3305
+ currency: string
3306
+ fractionDigits?: number | undefined
3307
+ locale?: string | undefined
3308
+ minorUnits?: boolean | undefined
3309
+ }
3310
+
3311
+ interface NumberOptions = {
3312
+ locale?: string | undefined
3313
+ maximumFractionDigits?: number | undefined
3314
+ minimumFractionDigits?: number | undefined
3315
+ }
3316
+
3541
3317
  ## ./storage `(./src/storage/index.ts)`
3542
3318
 
3543
3319
  class DiskNotConfiguredError = {
@@ -3699,15 +3475,13 @@ class UnsupportedOperationError = {
3699
3475
 
3700
3476
  const Storage = StorageManager
3701
3477
 
3702
- function mountsFrom = (config: StorageConfigShape) => Mount[]
3703
-
3704
3478
  function StorageConfig = (options?: Partial<StorageConfigShape>) => StorageConfigShape
3705
3479
 
3706
3480
  interface DiskServeConfig = {
3707
- expiresIn?: number
3708
- headers?: Record<string, string>
3481
+ expiresIn?: number | undefined
3482
+ headers?: Record<string, string> | undefined
3709
3483
  path: string
3710
- signed?: boolean
3484
+ signed?: boolean | undefined
3711
3485
  }
3712
3486
 
3713
3487
  interface FakeStoredFile = {
@@ -3721,24 +3495,24 @@ interface FakeStoredFile = {
3721
3495
  interface LocalDiskConfig = {
3722
3496
  driver: 'local'
3723
3497
  root: string
3724
- serve?: DiskServeConfig
3725
- url?: string
3498
+ serve?: DiskServeConfig | undefined
3499
+ url?: string | undefined
3726
3500
  }
3727
3501
 
3728
3502
  interface PutOptions = {
3729
- contentType?: string
3730
- visibility?: 'public' | 'private'
3503
+ contentType?: string | undefined
3504
+ visibility?: 'public' | 'private' | undefined
3731
3505
  }
3732
3506
 
3733
3507
  interface S3DiskConfig = {
3734
3508
  bucket: string
3735
3509
  driver: 's3'
3736
- endpoint?: string
3510
+ endpoint?: string | undefined
3737
3511
  key: string
3738
3512
  region: string
3739
3513
  secret: string
3740
- serve?: DiskServeConfig
3741
- url?: string
3514
+ serve?: DiskServeConfig | undefined
3515
+ url?: string | undefined
3742
3516
  }
3743
3517
 
3744
3518
  interface StorageConfigShape = {
@@ -3763,8 +3537,8 @@ interface StorageDriver = {
3763
3537
  }
3764
3538
 
3765
3539
  interface StorageFilesOptions = {
3766
- mounts?: Mount[]
3767
- storage?: StorageManager
3540
+ mounts?: Mount[] | undefined
3541
+ storage?: StorageManager | undefined
3768
3542
  }
3769
3543
 
3770
3544
  type DiskConfig = LocalDiskConfig | S3DiskConfig
@@ -3783,10 +3557,6 @@ class SafeHtml = {
3783
3557
  toString: () => string
3784
3558
  }
3785
3559
 
3786
- const VIEW_COMPONENT_PROP = '__zerotalViewComponent'
3787
-
3788
- const VIEW_COMPONENT_SYMBOL = typeof VIEW_COMPONENT_SYMBOL
3789
-
3790
3560
  function defineLayout = <LP extends Record<string, unknown>>(Layout: (props: LP & { children?: unknown;}) => SafeHtml) => <PP extends Record<string, unknown> = Record<string, never>>(Page: (props: PP & { children?: unknown;}) => SafeHtml) => (props: LP & PP) => SafeHtml
3791
3561
 
3792
3562
  function definePage = <P extends Record<string, unknown> = Record<string, unknown>>(component: (ctx: HttpContext, params: P) => SafeHtml | string | Promise<SafeHtml | string>) => typeof component
@@ -3797,8 +3567,6 @@ function Fragment = ({ children }: { children?: unknown;}) => SafeHtml
3797
3567
 
3798
3568
  function Raw = ({ html }: { html: string;}) => SafeHtml
3799
3569
 
3800
- function registerViewFileRouteResolver = () => void
3801
-
3802
3570
  function safe = (html: string) => SafeHtml
3803
3571
 
3804
3572
  type Children = unknown