@gesslar/bedoc 1.11.0 → 2.0.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 (88) hide show
  1. package/LICENSE.txt +12 -0
  2. package/README.md +15 -3
  3. package/dist/schema/bedoc.action.json +42 -0
  4. package/dist/types/Action.d.ts +3 -0
  5. package/dist/types/Action.d.ts.map +1 -0
  6. package/dist/types/BeDoc.d.ts +208 -0
  7. package/dist/types/BeDoc.d.ts.map +1 -0
  8. package/dist/types/Configuration.d.ts +11 -0
  9. package/dist/types/Configuration.d.ts.map +1 -0
  10. package/dist/types/ConfigurationParameters.d.ts +3 -0
  11. package/dist/types/ConfigurationParameters.d.ts.map +1 -0
  12. package/dist/types/Conveyor.d.ts +27 -0
  13. package/dist/types/Conveyor.d.ts.map +1 -0
  14. package/dist/types/Discovery.d.ts +215 -0
  15. package/dist/types/Discovery.d.ts.map +1 -0
  16. package/dist/types/Environment.d.ts +3 -0
  17. package/dist/types/Environment.d.ts.map +1 -0
  18. package/dist/types/Logger.d.ts +47 -0
  19. package/dist/types/Logger.d.ts.map +1 -0
  20. package/dist/types/Schema.d.ts +3 -0
  21. package/dist/types/Schema.d.ts.map +1 -0
  22. package/dist/types/cli.d.ts +2 -2
  23. package/dist/types/cli.d.ts.map +1 -10
  24. package/package.json +24 -23
  25. package/src/Action.js +9 -0
  26. package/src/BeDoc.js +276 -0
  27. package/src/CLIOutput.js +198 -0
  28. package/src/{core/Configuration.js → Configuration.js} +72 -58
  29. package/src/{core/ConfigurationParameters.js → ConfigurationParameters.js} +35 -27
  30. package/src/Conveyor.js +256 -0
  31. package/src/Discovery.js +442 -0
  32. package/src/Environment.js +8 -0
  33. package/src/{core/Logger.js → Logger.js} +30 -18
  34. package/src/Schema.js +6 -0
  35. package/src/cli.js +77 -34
  36. package/tsconfig.types.json +42 -0
  37. package/LICENSE +0 -24
  38. package/dist/types/core/ActionManager.d.ts +0 -58
  39. package/dist/types/core/ActionManager.d.ts.map +0 -10
  40. package/dist/types/core/Configuration.d.ts +0 -27
  41. package/dist/types/core/Configuration.d.ts.map +0 -10
  42. package/dist/types/core/ConfigurationParameters.d.ts +0 -38
  43. package/dist/types/core/ConfigurationParameters.d.ts.map +0 -10
  44. package/dist/types/core/Conveyor.d.ts +0 -49
  45. package/dist/types/core/Conveyor.d.ts.map +0 -10
  46. package/dist/types/core/Core.d.ts +0 -48
  47. package/dist/types/core/Core.d.ts.map +0 -10
  48. package/dist/types/core/Discovery.d.ts +0 -73
  49. package/dist/types/core/Discovery.d.ts.map +0 -10
  50. package/dist/types/core/HookManager.d.ts +0 -60
  51. package/dist/types/core/HookManager.d.ts.map +0 -10
  52. package/dist/types/core/Logger.d.ts +0 -63
  53. package/dist/types/core/Logger.d.ts.map +0 -10
  54. package/dist/types/core/action/ParseManager.d.ts +0 -8
  55. package/dist/types/core/action/ParseManager.d.ts.map +0 -10
  56. package/dist/types/core/action/PrintManager.d.ts +0 -8
  57. package/dist/types/core/action/PrintManager.d.ts.map +0 -10
  58. package/dist/types/core/util/ActionUtil.d.ts +0 -35
  59. package/dist/types/core/util/ActionUtil.d.ts.map +0 -10
  60. package/dist/types/core/util/DataUtil.d.ts +0 -52
  61. package/dist/types/core/util/DataUtil.d.ts.map +0 -10
  62. package/dist/types/core/util/FDUtil.d.ts +0 -171
  63. package/dist/types/core/util/FDUtil.d.ts.map +0 -10
  64. package/dist/types/core/util/ModuleUtil.d.ts +0 -27
  65. package/dist/types/core/util/ModuleUtil.d.ts.map +0 -10
  66. package/dist/types/core/util/StringUtil.d.ts +0 -5
  67. package/dist/types/core/util/StringUtil.d.ts.map +0 -10
  68. package/dist/types/core/util/TypeSpec.d.ts +0 -42
  69. package/dist/types/core/util/TypeSpec.d.ts.map +0 -10
  70. package/dist/types/core/util/ValidUtil.d.ts +0 -29
  71. package/dist/types/core/util/ValidUtil.d.ts.map +0 -10
  72. package/src/core/ActionManager.js +0 -147
  73. package/src/core/ContractManager.js +0 -112
  74. package/src/core/Conveyor.js +0 -185
  75. package/src/core/Core.js +0 -166
  76. package/src/core/Discovery.js +0 -403
  77. package/src/core/HookManager.js +0 -143
  78. package/src/core/action/ParseManager.js +0 -7
  79. package/src/core/action/PrintManager.js +0 -7
  80. package/src/core/contract/ParseContract.js +0 -7
  81. package/src/core/contract/PrintContract.js +0 -7
  82. package/src/core/util/ActionUtil.js +0 -62
  83. package/src/core/util/ContractUtil.js +0 -63
  84. package/src/core/util/DataUtil.js +0 -540
  85. package/src/core/util/FDUtil.js +0 -388
  86. package/src/core/util/StringUtil.js +0 -11
  87. package/src/core/util/TypeSpec.js +0 -114
  88. package/src/core/util/ValidUtil.js +0 -50
@@ -0,0 +1,442 @@
1
+ import {Terms} from "@gesslar/negotiator"
2
+ import {Collection, Data, DirectoryObject, FileObject, Promised, Sass} from "@gesslar/toolkit"
3
+ import {execSync} from "child_process"
4
+
5
+ import Action from "./Action.js"
6
+ import {Schemer} from "@gesslar/negotiator/browser"
7
+
8
+ /**
9
+ * @import {Glog} from "@gesslar/toolkit"
10
+ */
11
+
12
+ export default class Discovery {
13
+ /** @type {Glog} */
14
+ #glog
15
+
16
+ #options
17
+
18
+ /**
19
+ * Constructor for Discovery.
20
+ *
21
+ * @param {object} arg - Constructor argument
22
+ * @param {object} arg.options - BeDoc options
23
+ * @param {Glog} arg.glog - Glog instance
24
+ */
25
+ constructor({options = {}, glog}) {
26
+ this.#options = options
27
+ this.#glog = glog
28
+ }
29
+
30
+ /**
31
+ * Discover actions from local or global node_modules
32
+ *
33
+ * @param {object} [specific] Configuration options for action discovery
34
+ * @param {FileObject} [specific.formatter] Print-related configuration options
35
+ * @param {FileObject} [specific.parser] Parse-related configuration options
36
+ * @param {Function} validateBeDocSchema - The validator function for BeDoc's action schema
37
+ * @returns {Promise<object>} A map of discovered modules
38
+ */
39
+ async discoverActions(specific = {}, validateBeDocSchema) {
40
+ const glog = this.#glog
41
+
42
+ glog.debug("Discovering actions", 2)
43
+
44
+ glog.debug("Specific modules provided: %o", 2, Object.values(specific).filter(Boolean).length)
45
+ glog.debug("Specific modules provided: %j", 4, specific)
46
+
47
+ const files = []
48
+ const options = this.#options
49
+ const mock = options?.mock
50
+ ? Data.isType(options.mock, "DirectoryObject")
51
+ ? options.mock
52
+ : new DirectoryObject(options.mock)
53
+ : null
54
+
55
+ if(mock) {
56
+ glog.debug("Discovering mock actions in %o", 2, mock.path)
57
+
58
+ const {files: formatters} = await mock.glob("bedoc-*-formatter.js")
59
+ const {files: parsers} = await mock.glob("bedoc-*-parser.js")
60
+
61
+ files.push(...formatters, ...parsers)
62
+ } else {
63
+ glog.debug("Mock path not set, discovering actions in node_modules", 2)
64
+
65
+ glog.debug("Looking for actions in project's package.json", 2)
66
+ if(options.project) {
67
+ const exported = (options.project.actions || [])
68
+ .map(m => new FileObject(m, options.basePath))
69
+ .flat()
70
+
71
+ glog.debug("Found %o modules in project's package.json", 2, exported.length)
72
+ glog.debug("Found modules in project's package.json: %o", 2, exported)
73
+
74
+ files.push(...exported)
75
+ } else {
76
+ glog.debug("No modules found in project's package.json", 2)
77
+ }
78
+
79
+ glog.debug("Looking for modules in node_modules (global and locally installed)", 2)
80
+
81
+ // `npm root -g` in particular is unreliable in Docker/CI/nvm/volta
82
+ // environments without a configured global prefix. Fall back to skipping
83
+ // any root that can't be resolved rather than aborting the whole run.
84
+ const npmRoot = cmd => {
85
+ try {
86
+ return execSync(cmd).toString().trim()
87
+ } catch {
88
+ glog.debug("`%o` failed; skipping", 2, cmd)
89
+
90
+ return ""
91
+ }
92
+ }
93
+
94
+ const directories = [
95
+ npmRoot("npm root"),
96
+ npmRoot("npm root -g"),
97
+ ]
98
+ .filter(Boolean)
99
+ .map(d => new DirectoryObject(d))
100
+
101
+ const nodeModulesDirs = await Data.asyncFilter(directories, d => d.exists)
102
+
103
+ glog.debug("Found %o directories to search for actions", 2, directories.length)
104
+
105
+ glog.debug("Directories to search for actions: %o", 4, directories)
106
+
107
+ for(const nodeModulesDir of nodeModulesDirs) {
108
+ const dirsToSearch = []
109
+ const {directories: moduleDirs} = await nodeModulesDir.read()
110
+
111
+ glog.debug("Found %o directories in %o", 2, moduleDirs.length, nodeModulesDir.path)
112
+
113
+ // Handle scoped packages (e.g., @bedoc/something)
114
+ const scopedDirs = moduleDirs.filter(d => d.name.startsWith("@"))
115
+
116
+ dirsToSearch.push(...moduleDirs)
117
+
118
+ // If we find a scope (e.g., "@bedoc"), look inside it for bedoc modules
119
+ for(const scopedDir of scopedDirs) {
120
+ const {directories: scopedPackages} = await scopedDir.read()
121
+
122
+ glog.debug("Found %o directories under scoped package %o", 2, directories.length, scopedDir.name)
123
+ glog.debug("Found directories under scoped package %o\n%o", 2, scopedDir.path, scopedPackages.map(d => d.path))
124
+
125
+ dirsToSearch.push(...scopedPackages)
126
+ }
127
+
128
+ glog.debug("Found %o directories to search for actions", 2, dirsToSearch.length)
129
+ glog.debug("Found directories to search for actions: %o", 4, dirsToSearch)
130
+
131
+ const visibleDirs = dirsToSearch.filter(d => !d.name.startsWith("."))
132
+
133
+ for(const dir of visibleDirs) {
134
+ const packageJsonFile = new FileObject("package.json", dir)
135
+
136
+ if(!await packageJsonFile.exists)
137
+ continue
138
+
139
+ const packageJson = await packageJsonFile.loadData()
140
+
141
+ if(!packageJson.bedoc)
142
+ continue
143
+
144
+ const {actions} = packageJson.bedoc ?? null
145
+
146
+ if(!actions || !Array.isArray(actions))
147
+ continue
148
+
149
+ const moduleFileObjects = actions.map(f => new FileObject(f, dir))
150
+ const actionObjects = await Data.asyncFilter(
151
+ moduleFileObjects, f => f.exists)
152
+
153
+ glog.debug("Discovered %o modules from package.json file: %o", 2,
154
+ actions.length,
155
+ packageJsonFile.path
156
+ )
157
+
158
+ glog.debug("Discovered from package.json files: %o", 3, actions)
159
+
160
+ files.push(...actionObjects)
161
+ }
162
+ }
163
+ }
164
+
165
+ glog.debug("Discovered %o modules", 2, files.length)
166
+ glog.debug("Discovered modules", 2, files.map(f => f.path))
167
+ glog.debug("Discovered modules %o", 3, files)
168
+
169
+ const loaded = await this.#loadActionsAndContracts(files, specific)
170
+
171
+ for(const [kind, actions] of Object.entries(loaded)) {
172
+ glog.debug("%o %o", 4, kind, actions)
173
+
174
+ for(const {file, terms} of actions) {
175
+
176
+ try {
177
+ const isValid = validateBeDocSchema(terms)
178
+ if(!isValid) {
179
+ const {errors} = validateBeDocSchema
180
+ const report = Schemer.reportValidationErrors(errors)
181
+
182
+ throw Sass.new(report)
183
+ }
184
+
185
+ } catch(error) {
186
+ glog.error(error)
187
+
188
+ throw Sass.new(`Validating schema for ${file.path}`, error)
189
+ }
190
+ }
191
+ }
192
+
193
+ return loaded
194
+ }
195
+
196
+ /**
197
+ * Process the discovered file objects and return the action and their
198
+ * respective contracts.
199
+ *
200
+ * @param {Array<FileObject>} moduleFiles - The module file objects to process
201
+ * @param {{parser: FileObject, formatter: FileObject}} specificModules - The specific modules to load
202
+ * @returns {Promise<object>} The discovered actions
203
+ */
204
+ async #loadActionsAndContracts(moduleFiles, specificModules) {
205
+ const glog = this.#glog
206
+
207
+ glog.debug("Loading actions and contracts", 2)
208
+ glog.debug("Loading %o module files", 2, moduleFiles.length)
209
+ glog.debug("Specific modules to load: %o", 4, specificModules)
210
+
211
+ const resultActions = await Collection.allocateObject(
212
+ Action.actionTypes,
213
+ Action.actionTypes.map(() => new Array())
214
+ )
215
+
216
+ // Tag the specific actions to load, so we can filter them later
217
+ for(const [type, file] of Object.entries(specificModules)) {
218
+ if(file) {
219
+ glog.debug("Tagging specific module `%o` as `%o`", 3, file.path, type)
220
+ file.specificType = file.specificType || []
221
+ file.specificType.push(type)
222
+ }
223
+ }
224
+
225
+ const toLoad = [
226
+ ...moduleFiles,
227
+ ...Object.values(specificModules).filter(Boolean),
228
+ ]
229
+
230
+ glog.debug("Loading %o discovered modules", 2, toLoad.length)
231
+ glog.debug("Modules to load: %o", 4, toLoad)
232
+
233
+ // Load the BeDoc action schema once for validating all contract terms
234
+ // const schemaValidator = await this.#loadSchemaValidator()
235
+
236
+ const settledLoading = await Promised.settle(
237
+ toLoad.map(async file => {
238
+ const action = await file.import()
239
+
240
+ if(!action.default?.meta)
241
+ return null
242
+
243
+ const {terms: actionTerms} = action.default.meta
244
+
245
+ const terms = await Terms.parse(actionTerms, file.parent)
246
+
247
+ return {file, action, terms}
248
+ })
249
+ )
250
+
251
+ if(Promised.hasRejected(settledLoading))
252
+ Promised.throw("Loading actions and contracts", settledLoading)
253
+
254
+ const loadedActions = Promised.values(settledLoading).filter(Boolean)
255
+
256
+ glog.debug("Loaded %o actions", 2, loadedActions.length)
257
+ glog.debug("Loaded actions", 4, loadedActions)
258
+
259
+ const filteredActions = []
260
+
261
+ for(const actionType of Action.actionTypes) {
262
+ const moduleFile = specificModules[actionType]
263
+ const matchingActions = []
264
+
265
+ if(moduleFile) {
266
+ glog.debug("Filtering actions for specific: %o", 2, actionType)
267
+ const found = loadedActions.find(
268
+ e => e.file.specificType?.includes(actionType) &&
269
+ e.action.default.meta.kind === actionType
270
+ )
271
+
272
+ if(!found)
273
+ throw Sass.new(`Could not find specific action: ${moduleFile.path}`)
274
+
275
+ matchingActions.push(found)
276
+ } else {
277
+ glog.debug("No specific action required for %o", 2, actionType)
278
+
279
+ const found = loadedActions.filter(
280
+ e => e.action.default.meta.kind === actionType
281
+ )
282
+
283
+ matchingActions.push(...found)
284
+ }
285
+
286
+ glog.debug("Filtered %o actions for %o", 2,
287
+ matchingActions.length, actionType
288
+ )
289
+
290
+ filteredActions.push(...matchingActions)
291
+ }
292
+
293
+ glog.debug("Filtered %o actions", 2, filteredActions.length)
294
+ glog.debug("Filtered actions %o", 4, filteredActions)
295
+
296
+ // Now check the metas for validity
297
+ for(const filtered of filteredActions) {
298
+ const {action, terms, file: moduleFile} = filtered
299
+ const {meta} = action.default
300
+ const {kind} = meta
301
+
302
+ glog.debug("Checking %o action", 2, kind)
303
+
304
+ const isValid = this.#validMeta(kind, {action, terms})
305
+
306
+ glog.debug("Meta in action %o in %o is %o", 3,
307
+ kind, moduleFile.module, isValid ? "valid" : "invalid"
308
+ )
309
+
310
+ if(isValid) {
311
+ glog.debug("Action is a valid %o action", 3, kind)
312
+
313
+ resultActions[kind].push({
314
+ file: moduleFile,
315
+ action,
316
+ terms,
317
+ })
318
+ } else {
319
+ glog.debug("Action is not a valid %o action", 3, kind)
320
+ }
321
+
322
+ glog.debug("Processed %o action", 2, kind)
323
+ }
324
+
325
+ for(const actionType of Action.actionTypes) {
326
+ const total = resultActions[actionType].length
327
+
328
+ glog.debug("Found %o %o actions", 2, total, actionType)
329
+ }
330
+
331
+ const total = Object.keys(resultActions).reduce((acc, curr) => {
332
+ return acc + resultActions[curr].length
333
+ }, 0)
334
+
335
+ glog.debug("Loaded %o action definitions from %o modules", 2,
336
+ total, moduleFiles.length
337
+ )
338
+
339
+ return resultActions
340
+ }
341
+
342
+ satisfyCriteria(actions, validatedConfig) {
343
+ const glog = this.#glog
344
+
345
+ glog.debug("Available actions to check %o", 4, actions)
346
+
347
+ const satisfied = {parser: [], formatter: []}
348
+ const toMatch = {
349
+ // TODO: investigate
350
+ parser: {metaKey: "input", configKey: "language", config: "parser"},
351
+ formatter: {metaKey: "format", configKey: "format", config: "formatter"},
352
+ }
353
+
354
+ glog.debug("Satisfying criteria for actions", 2)
355
+ for(const [actionType, search] of Object.entries(toMatch)) {
356
+ glog.debug("Satisfying criteria for %o actions", 2, actionType)
357
+
358
+ const {metaKey, configKey, config} = search
359
+
360
+ glog.debug("Meta key: %o, Config key: %o", 3, metaKey, configKey)
361
+
362
+ // First let's check if we wanted something specific
363
+ if(validatedConfig[config]) {
364
+ glog.debug("Checking for specific %o action", 3, actionType)
365
+ const found = actions[actionType].find(
366
+ a => a.file.specificType?.includes(actionType)
367
+ )
368
+
369
+ if(found) {
370
+ glog.debug("Found specific %o action", 3, actionType)
371
+ satisfied[actionType].push(found)
372
+ continue
373
+ }
374
+
375
+ glog.debug("No specific %o action found", 3, actionType)
376
+ }
377
+
378
+ // Hmm! We didn't find anything specific. Let's check the criterion
379
+ glog.debug("Checking for %o actions with meta key %o", 3, actionType, metaKey)
380
+ glog.debug("Validated config to check against: %O", 3, validatedConfig)
381
+
382
+ const found = actions[actionType].filter(a => {
383
+ glog.debug("Meta criterion value: %o", 4, a.action.default.meta[metaKey])
384
+ glog.debug("Config criterion value: %o", 4, validatedConfig[configKey])
385
+
386
+ return a.action.default.meta[metaKey] === validatedConfig[configKey]
387
+ })
388
+ glog.debug("Found %o %o actions with criterion %o", 3, found.length, actionType, metaKey)
389
+
390
+ // Shove them into the result!
391
+ satisfied[actionType].push(...found)
392
+
393
+ // That should about cover it!
394
+ }
395
+
396
+ return satisfied
397
+ }
398
+
399
+ /**
400
+ * Validates the meta requirements for an action
401
+ *
402
+ * @param {string} actionType The action type to validate
403
+ * @param {object} toValidate - The action object to validate
404
+ * @returns {boolean} Whether the action object meets the meta requirements
405
+ */
406
+ #validMeta(actionType, toValidate) {
407
+ const glog = this.#glog
408
+
409
+ glog.debug("Checking meta requirements for %o", 3, actionType)
410
+
411
+ const requirements = Action.actionMetaRequirements[actionType]
412
+
413
+ if(!requirements)
414
+ throw Sass.new(
415
+ `No meta requirements found for action type \`${actionType}\``,
416
+ )
417
+
418
+ for(const requirement of requirements) {
419
+ glog.debug("Checking requirement %o", 4, requirement)
420
+
421
+ if(Data.isType(requirement, "object")) {
422
+ for(const [key, value] of Object.entries(requirement)) {
423
+ glog.debug("Checking object requirement %o", 4, {key, value})
424
+
425
+ if(toValidate.action.default.meta[key] !== value)
426
+ return false
427
+
428
+ glog.debug("Requirement met: %o", 4, {key, value})
429
+ }
430
+ } else if(Data.isType(requirement, "string")) {
431
+ glog.debug("Checking string requirement: %o", 4, requirement)
432
+
433
+ if(!toValidate.action.default.meta[requirement])
434
+ return false
435
+
436
+ glog.debug("Requirement met: %o", 4, requirement)
437
+ }
438
+ }
439
+
440
+ return true
441
+ }
442
+ }
@@ -0,0 +1,8 @@
1
+ import {Data} from "@gesslar/toolkit"
2
+
3
+ export default Data.deepFreezeObject({
4
+ EXTENSION: "extension",
5
+ NPM: "npm",
6
+ ACTION: "action",
7
+ CLI: "cli",
8
+ })
@@ -23,15 +23,10 @@
23
23
 
24
24
  */
25
25
 
26
- import console from "node:console"
27
26
  import ErrorStackParser from "error-stack-parser"
28
- import {Environment} from "./Core.js"
29
-
30
- import * as FDUtil from "./util/FDUtil.js"
31
- import * as StringUtil from "./util/StringUtil.js"
32
-
33
- const {resolveFilename} = FDUtil
34
- const {capitalize} = StringUtil
27
+ import console from "node:console"
28
+ import Environment from "./Environment.js"
29
+ import {FileObject, Util} from "@gesslar/toolkit"
35
30
 
36
31
  export const loggerColours = {
37
32
  debug: [
@@ -71,15 +66,29 @@ export default class Logger {
71
66
 
72
67
  constructor(options) {
73
68
  this.#name = "BeDoc"
74
- if(options) {
69
+ if(options)
75
70
  this.setOptions(options)
76
- if(options.env === Environment.EXTENSION) {
77
- const vscode = import("vscode")
78
- this.vscodeError = vscode.window.showErrorMessage
79
- this.vscodeWarn = vscode.window.showWarningMessage
80
- this.vscodeInfo = vscode.window.showInformationMessage
81
- }
71
+ }
72
+
73
+ /**
74
+ * Create a Logger, performing any asynchronous setup (e.g. binding vscode
75
+ * notification handlers when running in an extension environment).
76
+ *
77
+ * @param {object} [options] - Logger options
78
+ * @returns {Promise<Logger>} The configured logger
79
+ */
80
+ static async create(options) {
81
+ const logger = new Logger(options)
82
+
83
+ if(options?.env === Environment.EXTENSION) {
84
+ const vscode = await import("vscode")
85
+
86
+ logger.vscodeError = vscode.window.showErrorMessage
87
+ logger.vscodeWarn = vscode.window.showWarningMessage
88
+ logger.vscodeInfo = vscode.window.showInformationMessage
82
89
  }
90
+
91
+ return logger
83
92
  }
84
93
 
85
94
  get name() {
@@ -103,7 +112,7 @@ export default class Logger {
103
112
  }
104
113
 
105
114
  #compose(level, message, debugLevel = 0) {
106
- const tag = capitalize(level)
115
+ const tag = Util.capitalize(level)
107
116
 
108
117
  if(level === "debug")
109
118
  return `[${this.#name}] ${loggerColours[level][debugLevel]}${tag}${loggerColours.reset}: ${message}`
@@ -113,6 +122,7 @@ export default class Logger {
113
122
 
114
123
  lastStackLine(error = new Error(), stepsRemoved = 3) {
115
124
  const stack = ErrorStackParser.parse(error)
125
+
116
126
  return stack[stepsRemoved]
117
127
  }
118
128
 
@@ -125,9 +135,11 @@ export default class Logger {
125
135
  columnNumber: col,
126
136
  } = frame
127
137
 
128
- const {module, absoluteUri} = resolveFilename(file)
138
+ const tempFile = new FileObject(file)
139
+ const {module, url} = tempFile
129
140
 
130
141
  let functionName = func ?? "anonymous"
142
+
131
143
  if(functionName.startsWith("#"))
132
144
  functionName = `${module}.${functionName}`
133
145
 
@@ -149,7 +161,7 @@ export default class Logger {
149
161
  result = `${result}:${line}:${col}`
150
162
 
151
163
  if(level >= 3)
152
- result = `${absoluteUri} ${result}`
164
+ result = `${url} ${result}`
153
165
 
154
166
  return result
155
167
  }
package/src/Schema.js ADDED
@@ -0,0 +1,6 @@
1
+ import {Data} from "@gesslar/toolkit"
2
+
3
+ export default Data.deepFreezeObject({
4
+ local: "dist/schema/bedoc.action.json",
5
+ url: "https://schema.gesslar.dev/bedoc/v1/bedoc-action.json",
6
+ })