@larablox/monolog 0.1.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 (70) hide show
  1. package/out/Monolog/Attribute/AsMonologProcessor.d.ts +30 -0
  2. package/out/Monolog/Attribute/AsMonologProcessor.luau +59 -0
  3. package/out/Monolog/Attribute/WithMonologChannel.d.ts +18 -0
  4. package/out/Monolog/Attribute/WithMonologChannel.luau +33 -0
  5. package/out/Monolog/Formatter/FormatterInterface.d.ts +8 -0
  6. package/out/Monolog/Formatter/FormatterInterface.luau +3 -0
  7. package/out/Monolog/Formatter/HtmlFormatter.d.ts +23 -0
  8. package/out/Monolog/Formatter/HtmlFormatter.luau +128 -0
  9. package/out/Monolog/Formatter/JsonFormatter.d.ts +34 -0
  10. package/out/Monolog/Formatter/JsonFormatter.luau +114 -0
  11. package/out/Monolog/Formatter/LineFormatter.d.ts +52 -0
  12. package/out/Monolog/Formatter/LineFormatter.luau +228 -0
  13. package/out/Monolog/Formatter/NormalizerFormatter.d.ts +87 -0
  14. package/out/Monolog/Formatter/NormalizerFormatter.luau +214 -0
  15. package/out/Monolog/Formatter/ScalarFormatter.d.ts +19 -0
  16. package/out/Monolog/Formatter/ScalarFormatter.luau +53 -0
  17. package/out/Monolog/Handler/AbstractHandler.d.ts +22 -0
  18. package/out/Monolog/Handler/AbstractHandler.luau +50 -0
  19. package/out/Monolog/Handler/AbstractProcessingHandler.d.ts +30 -0
  20. package/out/Monolog/Handler/AbstractProcessingHandler.luau +79 -0
  21. package/out/Monolog/Handler/Handler.d.ts +15 -0
  22. package/out/Monolog/Handler/Handler.luau +25 -0
  23. package/out/Monolog/Handler/HandlerInterface.d.ts +12 -0
  24. package/out/Monolog/Handler/HandlerInterface.luau +3 -0
  25. package/out/Monolog/Handler/NullHandler.d.ts +10 -0
  26. package/out/Monolog/Handler/NullHandler.luau +36 -0
  27. package/out/Monolog/Handler/RobloxConsoleHandler.d.ts +55 -0
  28. package/out/Monolog/Handler/RobloxConsoleHandler.luau +141 -0
  29. package/out/Monolog/Handler/TestHandler.d.ts +90 -0
  30. package/out/Monolog/Handler/TestHandler.luau +288 -0
  31. package/out/Monolog/Level.d.ts +38 -0
  32. package/out/Monolog/Level.luau +119 -0
  33. package/out/Monolog/LogRecord.d.ts +43 -0
  34. package/out/Monolog/LogRecord.luau +77 -0
  35. package/out/Monolog/Logger.d.ts +93 -0
  36. package/out/Monolog/Logger.luau +248 -0
  37. package/out/Monolog/LoggerInterface.d.ts +33 -0
  38. package/out/Monolog/LoggerInterface.luau +15 -0
  39. package/out/Monolog/Processor/ClosureContextProcessor.d.ts +13 -0
  40. package/out/Monolog/Processor/ClosureContextProcessor.luau +76 -0
  41. package/out/Monolog/Processor/IntrospectionProcessor.d.ts +33 -0
  42. package/out/Monolog/Processor/IntrospectionProcessor.luau +69 -0
  43. package/out/Monolog/Processor/MemoryPeakUsageProcessor.d.ts +17 -0
  44. package/out/Monolog/Processor/MemoryPeakUsageProcessor.luau +49 -0
  45. package/out/Monolog/Processor/MemoryProcessor.d.ts +20 -0
  46. package/out/Monolog/Processor/MemoryProcessor.luau +41 -0
  47. package/out/Monolog/Processor/MemoryUsageProcessor.d.ts +12 -0
  48. package/out/Monolog/Processor/MemoryUsageProcessor.luau +38 -0
  49. package/out/Monolog/Processor/ProcessIdProcessor.d.ts +13 -0
  50. package/out/Monolog/Processor/ProcessIdProcessor.luau +33 -0
  51. package/out/Monolog/Processor/ProcessorInterface.d.ts +13 -0
  52. package/out/Monolog/Processor/ProcessorInterface.luau +20 -0
  53. package/out/Monolog/Processor/PsrLogMessageProcessor.d.ts +12 -0
  54. package/out/Monolog/Processor/PsrLogMessageProcessor.luau +62 -0
  55. package/out/Monolog/Processor/TagProcessor.d.ts +12 -0
  56. package/out/Monolog/Processor/TagProcessor.luau +46 -0
  57. package/out/Monolog/Processor/UidProcessor.d.ts +18 -0
  58. package/out/Monolog/Processor/UidProcessor.luau +53 -0
  59. package/out/Monolog/Registry.d.ts +21 -0
  60. package/out/Monolog/Registry.luau +86 -0
  61. package/out/Monolog/ResettableInterface.d.ts +11 -0
  62. package/out/Monolog/ResettableInterface.luau +21 -0
  63. package/out/Monolog/Test/MonologTestCase.d.ts +26 -0
  64. package/out/Monolog/Test/MonologTestCase.luau +73 -0
  65. package/out/Monolog/Test/TestCase.d.ts +4 -0
  66. package/out/Monolog/Test/TestCase.luau +25 -0
  67. package/out/Monolog/Utils.d.ts +21 -0
  68. package/out/Monolog/Utils.luau +181 -0
  69. package/out/index.d.ts +1 -0
  70. package/package.json +51 -0
@@ -0,0 +1,228 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local NormalizerFormatter = TS.import(script, script.Parent, "NormalizerFormatter").NormalizerFormatter
4
+ --[[
5
+ *
6
+ * PHP: `Monolog\Formatter\LineFormatter`.
7
+ *
8
+ * The default format drops PHP's trailing newline -- `print` and `warn` add
9
+ * their own.
10
+ *
11
+ * `includeStacktraces`/`indentStacktraces`/`stacktracesParser` are kept for
12
+ * API-shape parity but have nothing to act on: they format PHP's
13
+ * `getTraceAsString()` output, and there is no PHP exception/stack-trace
14
+ * object on this platform for `NormalizerFormatter.normalize()` to have kept
15
+ * a trace from in the first place (see that file's class comment). Setting
16
+ * them changes bookkeeping only, never formatted output.
17
+ *
18
+ * TypeScript can't have a property and a method share a name the way PHP's
19
+ * `$ignoreEmptyContextAndExtra`/`ignoreEmptyContextAndExtra()` (and similarly
20
+ * `allowInlineLineBreaks`, `includeStacktraces`) do -- each such flag's
21
+ * backing field is suffixed (`...Flag`/`...Value`) below; the public method
22
+ * names match upstream exactly.
23
+
24
+ ]]
25
+ local copyBag
26
+ local LineFormatter
27
+ do
28
+ local super = NormalizerFormatter
29
+ LineFormatter = setmetatable({}, {
30
+ __tostring = function()
31
+ return "LineFormatter"
32
+ end,
33
+ __index = super,
34
+ })
35
+ LineFormatter.__index = LineFormatter
36
+ function LineFormatter.new(...)
37
+ local self = setmetatable({}, LineFormatter)
38
+ return self:constructor(...) or self
39
+ end
40
+ function LineFormatter:constructor(format_, dateFormat, allowInlineLineBreaks, ignoreEmptyContextAndExtra, includeStacktraces)
41
+ if format_ == nil then
42
+ format_ = LineFormatter.SIMPLE_FORMAT
43
+ end
44
+ if dateFormat == nil then
45
+ dateFormat = LineFormatter.SIMPLE_DATE
46
+ end
47
+ if allowInlineLineBreaks == nil then
48
+ allowInlineLineBreaks = false
49
+ end
50
+ if ignoreEmptyContextAndExtra == nil then
51
+ ignoreEmptyContextAndExtra = false
52
+ end
53
+ if includeStacktraces == nil then
54
+ includeStacktraces = false
55
+ end
56
+ super.constructor(self, dateFormat)
57
+ self.format_ = format_
58
+ self.includeStacktracesFlag = false
59
+ self.indentStacktracesValue = ""
60
+ self.allowInlineLineBreaksFlag = allowInlineLineBreaks
61
+ self.ignoreEmptyContextAndExtraFlag = ignoreEmptyContextAndExtra
62
+ self:includeStacktraces(includeStacktraces)
63
+ end
64
+ function LineFormatter:includeStacktraces(include, parser)
65
+ if include == nil then
66
+ include = true
67
+ end
68
+ self.includeStacktracesFlag = include
69
+ self.stacktracesParser = parser
70
+ if self.includeStacktracesFlag then
71
+ self.allowInlineLineBreaksFlag = true
72
+ end
73
+ return self
74
+ end
75
+ function LineFormatter:indentStacktraces(indent)
76
+ self.indentStacktracesValue = indent
77
+ return self
78
+ end
79
+ function LineFormatter:allowInlineLineBreaks(allow)
80
+ if allow == nil then
81
+ allow = true
82
+ end
83
+ self.allowInlineLineBreaksFlag = allow
84
+ return self
85
+ end
86
+ function LineFormatter:ignoreEmptyContextAndExtra(ignore)
87
+ if ignore == nil then
88
+ ignore = true
89
+ end
90
+ self.ignoreEmptyContextAndExtraFlag = ignore
91
+ return self
92
+ end
93
+ function LineFormatter:setMaxLevelNameLength(maxLevelNameLength)
94
+ self.maxLevelNameLength = maxLevelNameLength
95
+ return self
96
+ end
97
+ function LineFormatter:format(record)
98
+ -- Upstream calls `parent::format($record)` here for the normalized
99
+ -- array; this port's `NormalizerFormatter.format()` returns a JSON
100
+ -- *string* instead (see that file's class comment), so the protected
101
+ -- `normalizeRecord()` is called directly instead, exactly as upstream's
102
+ -- own `JsonFormatter` already does.
103
+ local vars = self:normalizeRecord(record)
104
+ if self.maxLevelNameLength ~= nil then
105
+ local _exp = (vars.level_name)
106
+ local _maxLevelNameLength = self.maxLevelNameLength
107
+ vars.level_name = string.sub(_exp, 1, _maxLevelNameLength)
108
+ end
109
+ local output = self.format_
110
+ local extra = copyBag(vars.extra)
111
+ local context = copyBag(vars.context)
112
+ for key, value in pairs(extra) do
113
+ local placeholder = `%extra.{key}%`
114
+ if (string.find(output, placeholder, 1, true)) ~= nil then
115
+ local _exp = string.split(output, placeholder)
116
+ local _arg0 = self:stringify(value)
117
+ -- ▼ ReadonlyArray.join ▼
118
+ local _arg0_1 = _arg0
119
+ if _arg0_1 == nil then
120
+ _arg0_1 = ", "
121
+ end
122
+ -- ▲ ReadonlyArray.join ▲
123
+ output = table.concat(_exp, _arg0_1)
124
+ extra[key] = nil
125
+ end
126
+ end
127
+ for key, value in pairs(context) do
128
+ local placeholder = `%context.{key}%`
129
+ if (string.find(output, placeholder, 1, true)) ~= nil then
130
+ local _exp = string.split(output, placeholder)
131
+ local _arg0 = self:stringify(value)
132
+ -- ▼ ReadonlyArray.join ▼
133
+ local _arg0_1 = _arg0
134
+ if _arg0_1 == nil then
135
+ _arg0_1 = ", "
136
+ end
137
+ -- ▲ ReadonlyArray.join ▲
138
+ output = table.concat(_exp, _arg0_1)
139
+ context[key] = nil
140
+ end
141
+ end
142
+ if self.ignoreEmptyContextAndExtraFlag then
143
+ if (next(context)) == nil then
144
+ output = table.concat(string.split(output, "%context%"), "")
145
+ end
146
+ if (next(extra)) == nil then
147
+ output = table.concat(string.split(output, "%extra%"), "")
148
+ end
149
+ end
150
+ vars.context = context
151
+ vars.extra = extra
152
+ for key, value in pairs(vars) do
153
+ local placeholder = `%{key}%`
154
+ if (string.find(output, placeholder, 1, true)) ~= nil then
155
+ local _exp = string.split(output, placeholder)
156
+ local _arg0 = self:stringify(value)
157
+ -- ▼ ReadonlyArray.join ▼
158
+ local _arg0_1 = _arg0
159
+ if _arg0_1 == nil then
160
+ _arg0_1 = ", "
161
+ end
162
+ -- ▲ ReadonlyArray.join ▲
163
+ output = table.concat(_exp, _arg0_1)
164
+ end
165
+ end
166
+ -- Leftover `%extra.xxx%`/`%context.xxx%` placeholders: upstream removes
167
+ -- them with a single PCRE alternation; Lua patterns have no `|`
168
+ -- alternation, so this is two passes instead of one.
169
+ local cleaned = string.gsub(output, "%%extra%.[^%%]-%%", "")
170
+ cleaned = string.gsub(cleaned, "%%context%.[^%%]-%%", "")
171
+ return cleaned
172
+ end
173
+ function LineFormatter:formatBatch(records)
174
+ local lines = {}
175
+ for _, record in records do
176
+ local _arg0 = self:format(record)
177
+ table.insert(lines, _arg0)
178
+ end
179
+ return table.concat(lines, "\n")
180
+ end
181
+ function LineFormatter:stringify(value)
182
+ return self:replaceNewlines(self:convertToString(value))
183
+ end
184
+ function LineFormatter:convertToString(data)
185
+ if data == nil then
186
+ return "null"
187
+ end
188
+ local _data = data
189
+ if type(_data) == "boolean" then
190
+ return if data then "true" else "false"
191
+ end
192
+ local _data_1 = data
193
+ local _condition = type(_data_1) == "string"
194
+ if not _condition then
195
+ local _data_2 = data
196
+ _condition = type(_data_2) == "number"
197
+ end
198
+ if _condition then
199
+ return tostring(data)
200
+ end
201
+ return self:toJson(data)
202
+ end
203
+ function LineFormatter:replaceNewlines(str)
204
+ if self.allowInlineLineBreaksFlag then
205
+ -- Upstream also unescapes literal `\r`/`\n` sequences inside a
206
+ -- JSON-looking string here via a PCRE; there is no PCRE on this
207
+ -- platform, so that step is dropped and the string passes through.
208
+ return str
209
+ end
210
+ local out = string.gsub(str, "\r\n", " ")
211
+ out = string.gsub(out, "\r", " ")
212
+ out = string.gsub(out, "\n", " ")
213
+ return out
214
+ end
215
+ LineFormatter.SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%"
216
+ LineFormatter.SIMPLE_DATE = "%Y-%m-%d %H:%M:%S"
217
+ end
218
+ --* Shallow-copy a `RecordBag` so `format()` can drop matched placeholder keys without mutating the normalized record.
219
+ function copyBag(bag)
220
+ local copy = {}
221
+ for key, value in pairs(bag) do
222
+ copy[key] = value
223
+ end
224
+ return copy
225
+ end
226
+ return {
227
+ LineFormatter = LineFormatter,
228
+ }
@@ -0,0 +1,87 @@
1
+ import type { FormatterInterface } from "./FormatterInterface";
2
+ import type { LogRecord, RecordBag } from "../LogRecord";
3
+ /**
4
+ * PHP: `Monolog\Formatter\NormalizerFormatter`.
5
+ *
6
+ * Normalizes a record's context/extra into plain scalars/tables so it can be
7
+ * dumped to a string. Upstream's `normalize()` recognizes PHP object kinds one
8
+ * by one (`Throwable`, `JsonSerializable`, `__PHP_Incomplete_Class`,
9
+ * `is_resource`) -- none of that exists here, so anything that is not a scalar
10
+ * or a plain data table (a Luau table with no metatable) collapses to
11
+ * `tostring()`, the same way an unrecognized PHP object type would. There is
12
+ * no established "this is how an exception looks in a record" convention
13
+ * anywhere in this codebase (checked -- nothing under `src/Monolog` treats
14
+ * `context.exception` specially), so `normalizeException()`'s field-by-field
15
+ * shape (`class`/`message`/`code`/`file`/`trace`/`previous`) is not ported:
16
+ * there is no structured exception object to pull those fields from.
17
+ *
18
+ * `format()` is narrowed to return `string` here (this port's
19
+ * `FormatterInterface`, unlike upstream's `mixed`-returning one, already
20
+ * commits to that) rather than the raw normalized record upstream returns; it
21
+ * JSON-encodes `normalizeRecord()`'s result instead. Subclasses that need the
22
+ * raw record (`LineFormatter`, `JsonFormatter`, `ScalarFormatter`) call the
23
+ * protected `normalizeRecord()` directly, exactly as upstream's `JsonFormatter`
24
+ * already does rather than going through `parent::format()`.
25
+ */
26
+ export declare class NormalizerFormatter implements FormatterInterface {
27
+ static readonly SIMPLE_DATE: string;
28
+ protected dateFormat: string;
29
+ protected maxNormalizeDepth: number;
30
+ protected maxNormalizeItemCount: number;
31
+ /** Toggled by `setJsonPrettyPrint()`; the only `jsonEncodeOptions` bit this port's encoder understands. */
32
+ private prettyPrint;
33
+ /**
34
+ * PHP: `NormalizerFormatter::$basePath`. Kept for API-shape parity: there
35
+ * is no PHP exception/stack-trace file path to shorten with it here, so
36
+ * it is stored and otherwise unused.
37
+ */
38
+ protected basePath: string;
39
+ constructor(dateFormat?: string);
40
+ /** Formats a log record. */
41
+ format(record: LogRecord): string;
42
+ /** Normalize an arbitrary value to a scalar/table/undefined. */
43
+ normalizeValue(data: unknown): unknown;
44
+ /**
45
+ * Formats a set of log records. Upstream returns an array of normalized
46
+ * records (`mixed`, per its `FormatterInterface`); this JSON-encodes that
47
+ * same array once, for the same `string`-return reason `format()` does.
48
+ */
49
+ formatBatch(records: Array<LogRecord>): string;
50
+ getDateFormat(): string;
51
+ setDateFormat(dateFormat: string): this;
52
+ /** The maximum number of normalization levels to go through. */
53
+ getMaxNormalizeDepth(): number;
54
+ setMaxNormalizeDepth(maxNormalizeDepth: number): this;
55
+ /** The maximum number of items to normalize per level. */
56
+ getMaxNormalizeItemCount(): number;
57
+ setMaxNormalizeItemCount(maxNormalizeItemCount: number): this;
58
+ /** Enables pretty-printed JSON output. */
59
+ setJsonPrettyPrint(enable: boolean): this;
60
+ /**
61
+ * Setting a base path would hide it from exception/stack-trace file names
62
+ * to shorten them upstream; there is nothing here that produces either, so
63
+ * this only stores the value.
64
+ */
65
+ setBasePath(path?: string): this;
66
+ /**
67
+ * Provided as an extension point, as upstream: `normalize()` is called
68
+ * with sub-values of context data etc., so `normalizeRecord()` can be
69
+ * overridden when data needs to be appended to the record but not to other
70
+ * normalized data (see `JsonFormatter`).
71
+ */
72
+ protected normalizeRecord(record: LogRecord): RecordBag;
73
+ protected normalize(data: unknown, depth?: number): unknown;
74
+ /** Return the JSON representation of a value. */
75
+ protected toJson(data: unknown): string;
76
+ protected formatDate(date: number): string;
77
+ /**
78
+ * PHP bitflag `json_encode` options have no equivalent when there is no
79
+ * `json_encode` to pass them to -- `toJson()` never consults this set, it
80
+ * exists only so callers ported against the upstream API have somewhere to
81
+ * put a call. Use `setJsonPrettyPrint()` for the one option this port's
82
+ * encoder actually understands.
83
+ */
84
+ private jsonEncodeOptions;
85
+ addJsonEncodeOption(option: unknown): this;
86
+ removeJsonEncodeOption(option: unknown): this;
87
+ }
@@ -0,0 +1,214 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local Utils = TS.import(script, script.Parent.Parent, "Utils").Utils
4
+ --[[
5
+ *
6
+ * PHP: `Monolog\Formatter\NormalizerFormatter`.
7
+ *
8
+ * Normalizes a record's context/extra into plain scalars/tables so it can be
9
+ * dumped to a string. Upstream's `normalize()` recognizes PHP object kinds one
10
+ * by one (`Throwable`, `JsonSerializable`, `__PHP_Incomplete_Class`,
11
+ * `is_resource`) -- none of that exists here, so anything that is not a scalar
12
+ * or a plain data table (a Luau table with no metatable) collapses to
13
+ * `tostring()`, the same way an unrecognized PHP object type would. There is
14
+ * no established "this is how an exception looks in a record" convention
15
+ * anywhere in this codebase (checked -- nothing under `src/Monolog` treats
16
+ * `context.exception` specially), so `normalizeException()`'s field-by-field
17
+ * shape (`class`/`message`/`code`/`file`/`trace`/`previous`) is not ported:
18
+ * there is no structured exception object to pull those fields from.
19
+ *
20
+ * `format()` is narrowed to return `string` here (this port's
21
+ * `FormatterInterface`, unlike upstream's `mixed`-returning one, already
22
+ * commits to that) rather than the raw normalized record upstream returns; it
23
+ * JSON-encodes `normalizeRecord()`'s result instead. Subclasses that need the
24
+ * raw record (`LineFormatter`, `JsonFormatter`, `ScalarFormatter`) call the
25
+ * protected `normalizeRecord()` directly, exactly as upstream's `JsonFormatter`
26
+ * already does rather than going through `parent::format()`.
27
+
28
+ ]]
29
+ local NormalizerFormatter
30
+ do
31
+ NormalizerFormatter = setmetatable({}, {
32
+ __tostring = function()
33
+ return "NormalizerFormatter"
34
+ end,
35
+ })
36
+ NormalizerFormatter.__index = NormalizerFormatter
37
+ function NormalizerFormatter.new(...)
38
+ local self = setmetatable({}, NormalizerFormatter)
39
+ return self:constructor(...) or self
40
+ end
41
+ function NormalizerFormatter:constructor(dateFormat)
42
+ self.maxNormalizeDepth = 9
43
+ self.maxNormalizeItemCount = 1000
44
+ self.prettyPrint = false
45
+ self.basePath = ""
46
+ self.jsonEncodeOptions = {}
47
+ local _condition = dateFormat
48
+ if _condition == nil then
49
+ _condition = NormalizerFormatter.SIMPLE_DATE
50
+ end
51
+ self.dateFormat = _condition
52
+ end
53
+ function NormalizerFormatter:format(record)
54
+ return self:toJson(self:normalizeRecord(record))
55
+ end
56
+ function NormalizerFormatter:normalizeValue(data)
57
+ return self:normalize(data)
58
+ end
59
+ function NormalizerFormatter:formatBatch(records)
60
+ local normalized = {}
61
+ for _, record in records do
62
+ local _arg0 = self:normalizeRecord(record)
63
+ table.insert(normalized, _arg0)
64
+ end
65
+ return self:toJson(normalized)
66
+ end
67
+ function NormalizerFormatter:getDateFormat()
68
+ return self.dateFormat
69
+ end
70
+ function NormalizerFormatter:setDateFormat(dateFormat)
71
+ self.dateFormat = dateFormat
72
+ return self
73
+ end
74
+ function NormalizerFormatter:getMaxNormalizeDepth()
75
+ return self.maxNormalizeDepth
76
+ end
77
+ function NormalizerFormatter:setMaxNormalizeDepth(maxNormalizeDepth)
78
+ self.maxNormalizeDepth = maxNormalizeDepth
79
+ return self
80
+ end
81
+ function NormalizerFormatter:getMaxNormalizeItemCount()
82
+ return self.maxNormalizeItemCount
83
+ end
84
+ function NormalizerFormatter:setMaxNormalizeItemCount(maxNormalizeItemCount)
85
+ self.maxNormalizeItemCount = maxNormalizeItemCount
86
+ return self
87
+ end
88
+ function NormalizerFormatter:setJsonPrettyPrint(enable)
89
+ self.prettyPrint = enable
90
+ return self
91
+ end
92
+ function NormalizerFormatter:setBasePath(path)
93
+ if path == nil then
94
+ path = ""
95
+ end
96
+ self.basePath = path
97
+ return self
98
+ end
99
+ function NormalizerFormatter:normalizeRecord(record)
100
+ local normalized = self:normalize(record:toArray())
101
+ -- `datetime` is a plain Unix timestamp, not a `DateTimeInterface`
102
+ -- upstream's `normalize()` can recognize among arbitrary values by type
103
+ -- -- there is nothing to `instanceof`-check here, so it is formatted
104
+ -- explicitly instead of relying on that recursive detection.
105
+ normalized.datetime = self:formatDate(record.datetime)
106
+ return normalized
107
+ end
108
+ function NormalizerFormatter:normalize(data, depth)
109
+ if depth == nil then
110
+ depth = 0
111
+ end
112
+ if depth > self.maxNormalizeDepth then
113
+ return `Over {self.maxNormalizeDepth} levels deep, aborting normalization`
114
+ end
115
+ if data == nil then
116
+ return nil
117
+ end
118
+ local _data = data
119
+ local _condition = type(_data) == "string"
120
+ if not _condition then
121
+ local _data_1 = data
122
+ _condition = type(_data_1) == "boolean"
123
+ end
124
+ if _condition then
125
+ return data
126
+ end
127
+ local _data_1 = data
128
+ if type(_data_1) == "number" then
129
+ if data ~= data then
130
+ return "NaN"
131
+ end
132
+ if data == math.huge then
133
+ return "INF"
134
+ end
135
+ if data == -math.huge then
136
+ return "-INF"
137
+ end
138
+ return data
139
+ end
140
+ local _data_2 = data
141
+ if type(_data_2) == "table" then
142
+ -- A table with a metatable is a class instance (a Roblox `Instance`,
143
+ -- an OOP object elsewhere in this codebase, etc.) rather than plain
144
+ -- record data -- there is no PHP object/`Throwable`/`JsonSerializable`
145
+ -- system to special-case one against, so it collapses to a string the
146
+ -- same way an unrecognized PHP object type would.
147
+ if getmetatable(data) ~= nil then
148
+ return tostring(data)
149
+ end
150
+ local list = data
151
+ if #list > 0 then
152
+ -- `Array<T>.push()` requires `T extends defined` (Luau arrays
153
+ -- cannot reliably hold a `nil` mid-list); a normalized value is
154
+ -- rarely actually `undefined`, but cast rather than narrow the
155
+ -- element type to `unknown`, which `push()` itself rejects.
156
+ local normalized = {}
157
+ local count = 0
158
+ for _, item in list do
159
+ count += 1
160
+ if count > self.maxNormalizeItemCount then
161
+ local _arg0 = `Over {self.maxNormalizeItemCount} items ({#list} total), aborting normalization`
162
+ table.insert(normalized, _arg0)
163
+ break
164
+ end
165
+ local _arg0 = self:normalize(item, depth + 1)
166
+ table.insert(normalized, _arg0)
167
+ end
168
+ return normalized
169
+ end
170
+ local bag = data
171
+ local keys = {}
172
+ for key in pairs(bag) do
173
+ local _arg0 = tostring(key)
174
+ table.insert(keys, _arg0)
175
+ end
176
+ table.sort(keys)
177
+ local normalized = {}
178
+ local count = 0
179
+ for _, key in keys do
180
+ count += 1
181
+ if count > self.maxNormalizeItemCount then
182
+ normalized["..."] = `Over {self.maxNormalizeItemCount} items ({#keys} total), aborting normalization`
183
+ break
184
+ end
185
+ normalized[key] = self:normalize(bag[key], depth + 1)
186
+ end
187
+ return normalized
188
+ end
189
+ -- Function/thread/opaque instance: nothing left to reflect on.
190
+ return tostring(data)
191
+ end
192
+ function NormalizerFormatter:toJson(data)
193
+ return Utils:jsonEncode(data, self.prettyPrint)
194
+ end
195
+ function NormalizerFormatter:formatDate(date)
196
+ return os.date(self.dateFormat, date)
197
+ end
198
+ function NormalizerFormatter:addJsonEncodeOption(option)
199
+ local _jsonEncodeOptions = self.jsonEncodeOptions
200
+ local _option = option
201
+ _jsonEncodeOptions[_option] = true
202
+ return self
203
+ end
204
+ function NormalizerFormatter:removeJsonEncodeOption(option)
205
+ local _jsonEncodeOptions = self.jsonEncodeOptions
206
+ local _option = option
207
+ _jsonEncodeOptions[_option] = nil
208
+ return self
209
+ end
210
+ NormalizerFormatter.SIMPLE_DATE = "%Y-%m-%dT%H:%M:%S%z"
211
+ end
212
+ return {
213
+ NormalizerFormatter = NormalizerFormatter,
214
+ }
@@ -0,0 +1,19 @@
1
+ import { NormalizerFormatter } from "./NormalizerFormatter";
2
+ import type { LogRecord, RecordBag } from "../LogRecord";
3
+ /**
4
+ * PHP: `Monolog\Formatter\ScalarFormatter`.
5
+ *
6
+ * Formats data into a map of scalar (or `undefined`) values; anything
7
+ * non-scalar is JSON-encoded instead. Upstream's `format()` returns that map
8
+ * directly; this port's `FormatterInterface.format()` is narrowed to `string`
9
+ * (see `NormalizerFormatter`'s class comment), so `format()` here JSON-encodes
10
+ * it, and the map itself is exposed as `toScalarRecord()` for callers that
11
+ * want the structured form.
12
+ */
13
+ export declare class ScalarFormatter extends NormalizerFormatter {
14
+ /** Formats a log record. */
15
+ format(record: LogRecord): string;
16
+ /** PHP: `ScalarFormatter::format()`'s actual return value. */
17
+ toScalarRecord(record: LogRecord): RecordBag;
18
+ protected toScalar(value: unknown): unknown;
19
+ }
@@ -0,0 +1,53 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local NormalizerFormatter = TS.import(script, script.Parent, "NormalizerFormatter").NormalizerFormatter
4
+ --[[
5
+ *
6
+ * PHP: `Monolog\Formatter\ScalarFormatter`.
7
+ *
8
+ * Formats data into a map of scalar (or `undefined`) values; anything
9
+ * non-scalar is JSON-encoded instead. Upstream's `format()` returns that map
10
+ * directly; this port's `FormatterInterface.format()` is narrowed to `string`
11
+ * (see `NormalizerFormatter`'s class comment), so `format()` here JSON-encodes
12
+ * it, and the map itself is exposed as `toScalarRecord()` for callers that
13
+ * want the structured form.
14
+
15
+ ]]
16
+ local ScalarFormatter
17
+ do
18
+ local super = NormalizerFormatter
19
+ ScalarFormatter = setmetatable({}, {
20
+ __tostring = function()
21
+ return "ScalarFormatter"
22
+ end,
23
+ __index = super,
24
+ })
25
+ ScalarFormatter.__index = ScalarFormatter
26
+ function ScalarFormatter.new(...)
27
+ local self = setmetatable({}, ScalarFormatter)
28
+ return self:constructor(...) or self
29
+ end
30
+ function ScalarFormatter:constructor(...)
31
+ super.constructor(self, ...)
32
+ end
33
+ function ScalarFormatter:format(record)
34
+ return self:toJson(self:toScalarRecord(record))
35
+ end
36
+ function ScalarFormatter:toScalarRecord(record)
37
+ local result = {}
38
+ for key, value in pairs(record:toArray()) do
39
+ result[key] = self:toScalar(value)
40
+ end
41
+ return result
42
+ end
43
+ function ScalarFormatter:toScalar(value)
44
+ local normalized = self:normalize(value)
45
+ if type(normalized) == "table" then
46
+ return self:toJson(normalized)
47
+ end
48
+ return normalized
49
+ end
50
+ end
51
+ return {
52
+ ScalarFormatter = ScalarFormatter,
53
+ }
@@ -0,0 +1,22 @@
1
+ import { Handler } from "./Handler";
2
+ import { Level } from "../Level";
3
+ import type { LogRecord } from "../LogRecord";
4
+ import type { ResettableInterface } from "../ResettableInterface";
5
+ /** PHP: `Monolog\Handler\AbstractHandler`. */
6
+ export declare abstract class AbstractHandler extends Handler implements ResettableInterface {
7
+ protected level: Level;
8
+ protected bubble: boolean;
9
+ constructor(level?: Level, bubble?: boolean);
10
+ /** Checks whether the given record will be handled by this handler. */
11
+ isHandling(record: LogRecord): boolean;
12
+ /** Sets minimum logging level at which this handler will be triggered. */
13
+ setLevel(level: Level): this;
14
+ /** Gets minimum logging level at which this handler will be triggered. */
15
+ getLevel(): Level;
16
+ /** Sets the bubbling behavior. */
17
+ setBubble(bubble: boolean): this;
18
+ /** Gets the bubbling behavior. */
19
+ getBubble(): boolean;
20
+ /** Resets the handler's state. */
21
+ reset(): void;
22
+ }
@@ -0,0 +1,50 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local Handler = TS.import(script, script.Parent, "Handler").Handler
4
+ local Level = TS.import(script, script.Parent.Parent, "Level").Level
5
+ --* PHP: `Monolog\Handler\AbstractHandler`.
6
+ local AbstractHandler
7
+ do
8
+ local super = Handler
9
+ AbstractHandler = setmetatable({}, {
10
+ __tostring = function()
11
+ return "AbstractHandler"
12
+ end,
13
+ __index = super,
14
+ })
15
+ AbstractHandler.__index = AbstractHandler
16
+ function AbstractHandler:constructor(level, bubble)
17
+ if level == nil then
18
+ level = Level.Debug
19
+ end
20
+ if bubble == nil then
21
+ bubble = true
22
+ end
23
+ super.constructor(self)
24
+ self.level = level
25
+ self.bubble = bubble
26
+ end
27
+ function AbstractHandler:isHandling(record)
28
+ return record.level >= self.level
29
+ end
30
+ function AbstractHandler:setLevel(level)
31
+ self.level = level
32
+ return self
33
+ end
34
+ function AbstractHandler:getLevel()
35
+ return self.level
36
+ end
37
+ function AbstractHandler:setBubble(bubble)
38
+ self.bubble = bubble
39
+ return self
40
+ end
41
+ function AbstractHandler:getBubble()
42
+ return self.bubble
43
+ end
44
+ function AbstractHandler:reset()
45
+ --
46
+ end
47
+ end
48
+ return {
49
+ AbstractHandler = AbstractHandler,
50
+ }