@gesslar/bedoc 1.10.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 (89) 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 -53
  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/ModuleUtil.js +0 -40
  87. package/src/core/util/StringUtil.js +0 -11
  88. package/src/core/util/TypeSpec.js +0 -114
  89. package/src/core/util/ValidUtil.js +0 -50
@@ -1,403 +0,0 @@
1
- import {execSync} from "child_process"
2
- import path from "node:path"
3
-
4
- import ContractManager from "./ContractManager.js"
5
- import * as FDUtil from "./util/FDUtil.js"
6
- import * as ActionUtil from "./util/ActionUtil.js"
7
- import * as DataUtil from "./util/DataUtil.js"
8
-
9
- const {composeDirectory,directoryExists,resolveDirectory} = FDUtil
10
- const {newContract,parse} = ContractManager
11
- const {ls,fileExists,composeFilename,getFiles} = FDUtil
12
- const {actionTypes, actionMetaRequirements, loadJson} = ActionUtil
13
- const {isType} = DataUtil
14
-
15
- export default class Discovery {
16
- #logger
17
- #debug
18
-
19
- constructor(core) {
20
- this.core = core
21
- this.#logger = core.logger
22
- this.#debug = this.#logger.newDebug()
23
- }
24
-
25
- /**
26
- * Discover actions from local or global node_modules
27
- *
28
- * @param {object} [specific] Configuration options for action discovery
29
- * @param {object} [specific.print] Print-related configuration options
30
- * @param {object} [specific.parse] Parse-related configuration options
31
- * @returns {Promise<object>} A map of discovered modules
32
- */
33
- async discoverActions(specific = {}) {
34
- const debug = this.#debug
35
-
36
- debug("Discovering actions", 2)
37
-
38
- debug("Specific modules provided: %o", 2, Object.values(specific).filter(Boolean).length)
39
- debug("Specific modules provided: %o", 3, specific)
40
-
41
- const files = []
42
- const options = this.core.options ?? {}
43
-
44
- if(options?.mockPath) {
45
- debug("Discovering mock actions in `%s`", 2, options.mockPath)
46
-
47
- files.push(
48
- ...(await getFiles([
49
- `${options.mockPath}/bedoc-*-printer.js`,
50
- `${options.mockPath}/bedoc-*-parser.js`,
51
- ])),
52
- )
53
- } else {
54
- debug("Mock path not set, discovering actions in node_modules", 2)
55
-
56
- debug("Looking for actions in project's package.json", 2)
57
- if(this.core.packageJson) {
58
- const exported = (this.core.packageJson.modules || [])
59
- .map(m => composeFilename(options.basePath, m))
60
- .flat()
61
-
62
- debug("Found %o modules in project's package.json", 2, exported.length)
63
- debug("Found modules in project's package.json: %o", 2, exported)
64
-
65
- files.push(...exported)
66
- } else {
67
- debug("No modules found in project's package.json", 2)
68
- }
69
-
70
- debug("Looking for modules in node_modules (global and locally installed)", 2)
71
- const directories = [
72
- execSync("npm root").toString().trim(),
73
- execSync("npm root -g").toString().trim(),
74
- ].filter(Boolean)
75
-
76
- const nodeModulesDirs = directories
77
- .map(composeDirectory)
78
- .filter(directoryExists)
79
-
80
- debug("Found %o directories to search for actions", 2, directories.length)
81
- debug("Directories to search for actions: %o", 3, directories)
82
-
83
- for(const nodeModulesDir of nodeModulesDirs) {
84
- const dirsToSearch = []
85
- const {directories: moduleDirs} = await ls(nodeModulesDir.absolutePath)
86
-
87
- debug("Found %o directories in %o", 2, moduleDirs.length, nodeModulesDir.absolutePath)
88
-
89
- // Handle scoped packages (e.g., @bedoc/something)
90
- const scopedDirs = moduleDirs.filter(d => d.name.startsWith("@"))
91
-
92
- dirsToSearch.push(...moduleDirs)
93
-
94
- // If we find a scope (e.g., "@bedoc"), look inside it for bedoc modules
95
- for(const scopedDir of scopedDirs) {
96
- const {directories: scopedPackages} = await ls(scopedDir.absolutePath)
97
-
98
- debug("Found %o directories under scoped package %o", 2, directories.length, scopedDir.name)
99
- debug("Found directories under scoped package %o\n%o", 2, scopedDir.absolutePath, scopedPackages.map(d => d.absolutePath))
100
-
101
- dirsToSearch.push(...scopedPackages)
102
- }
103
-
104
- debug("1 Found %o directories to search for actions", 2, dirsToSearch.length)
105
- debug("2 Found directories to search for actions: %o", 3, dirsToSearch)
106
-
107
- const visibleDirs = dirsToSearch.filter(d => !d.name.startsWith("."))
108
-
109
- for(const dir of visibleDirs) {
110
- const packageJsonFile = composeFilename(dir, "package.json")
111
-
112
- if(!fileExists(packageJsonFile))
113
- continue
114
-
115
- const packageJson = loadJson(packageJsonFile)
116
- if(!packageJson.bedoc)
117
- continue
118
-
119
- const {modules} = packageJson.bedoc ?? null
120
- if(!modules || !Array.isArray(modules))
121
- continue
122
-
123
- const moduleFiles = modules
124
- .map(f => composeFilename(dir, f))
125
- .filter(f => fileExists(f))
126
-
127
- debug("Discovered %d modules from package.json file: %o", 2,
128
- modules.length,
129
- packageJsonFile.absolutePath
130
- )
131
- debug("Discovered from package.json files: %o", 3, modules)
132
-
133
- files.push(...moduleFiles)
134
- }
135
- }
136
- }
137
-
138
- debug("Discovered %d modules", 2, files.length)
139
- debug("Discovered modules", 2, files.map(f => f.path))
140
- debug("Discovered modules %o", 3, files)
141
-
142
- // const available = files.map(f => this.#getModuleExports(f))
143
-
144
- return await this.#loadActionsAndContracts(files, specific)
145
- }
146
-
147
- /**
148
- * Process the discovered file objects and return the action and their
149
- * respective contracts.
150
- *
151
- * @param {object[]} moduleFiles The module file objects to process
152
- * @param {object} specificModules The specific modules to load
153
- * @returns {Promise<object>} The discovered action
154
- */
155
- async #loadActionsAndContracts(moduleFiles, specificModules) {
156
- const debug = this.#debug
157
-
158
- debug("Loading actions and contracts", 2)
159
- debug("Loading %d module files", 2, moduleFiles.length)
160
- debug("Specific modules to load: %o", 3, specificModules)
161
-
162
- const resultActions = {}
163
- actionTypes.forEach(actionType => (resultActions[actionType] = []))
164
-
165
- // Tag the specific actions to load, so we can filter them later
166
- for(const [type, file] of Object.entries(specificModules)) {
167
- if(file) {
168
- debug("Tagging specific module `%s` as `%s`", 3, file.absolutePath, type)
169
- file.specificType = file.specificType || []
170
- file.specificType.push(type)
171
- }
172
- }
173
-
174
- const toLoad = [
175
- ...moduleFiles,
176
- ...Object.values(specificModules).filter(Boolean),
177
- ]
178
-
179
- debug("Loading %d discovered modules", 2, toLoad.length)
180
- debug("Modules to load: %o", 3, toLoad)
181
-
182
- const loadedActions = []
183
- for(const file of toLoad) {
184
- debug("Loading module `%s`", 2, file.absoluteUri)
185
-
186
- const loading = await this.#loadModule(file)
187
- for(let index = 0; index < loading.actions.length; index++) {
188
- const action = loading.actions[index]
189
-
190
- if(!file.directory)
191
- file.directory = resolveDirectory(path.dirname(file.path))
192
-
193
- debug(`Loading %o contract from %o`, 2, action.meta.action, file.path)
194
-
195
- const terms = parse(loading.contracts[index], file.directory)
196
- const contract = await newContract(action.meta.action, terms)
197
-
198
- loadedActions.push({file, action, contract})
199
- }
200
- }
201
-
202
- debug("Loaded %d actions", 2, loadedActions.length)
203
- debug("Loaded actions", 3, loadedActions)
204
-
205
- const filteredActions = []
206
- for(const actionType of actionTypes) {
207
- const module = specificModules[actionType]
208
- const matchingActions = []
209
- if(module) {
210
- debug("Filtering actions for specific: %o", 2, actionType)
211
- const found = loadedActions.find(
212
- e => e.file.specificType?.includes(actionType) &&
213
- e.action.meta?.action === actionType
214
- )
215
-
216
- if(!found)
217
- throw new Error(`Could not find specific action: ${module.absolutePath}`)
218
-
219
- matchingActions.push(found)
220
- } else {
221
- debug("No specific action required for `%s`", 2, actionType)
222
-
223
- const found = loadedActions.filter(
224
- e => e.action.meta.action === actionType
225
- )
226
- matchingActions.push(...found)
227
- }
228
-
229
- debug("Filtered %d actions for `%s`", 2,
230
- matchingActions.length, actionType
231
- )
232
-
233
- filteredActions.push(...matchingActions)
234
- }
235
-
236
- debug("Filtered %d actions", 2, filteredActions.length)
237
- debug("Filtered actions %o", 3, filteredActions)
238
-
239
- // Now check the metas for validity
240
- for(const filtered of filteredActions) {
241
- const {action, contract, file: moduleFile} = filtered
242
- const meta = action.meta
243
-
244
- if(!meta)
245
- throw new TypeError("Action has no meta object:\n" +
246
- JSON.stringify(moduleFile, null, 2) + "\n" +
247
- JSON.stringify(action, null, 2))
248
-
249
- const metaAction = meta.action
250
- if(!metaAction)
251
- throw new TypeError("Action has no meta action:\n" +
252
- JSON.stringify(moduleFile, null, 2) + "\n" +
253
- JSON.stringify(action, null, 2))
254
-
255
- debug("Checking action %o", 2, metaAction)
256
-
257
- const isValid = this.#validMeta(metaAction, {action, contract})
258
-
259
- debug("Meta in action %o in %o is %o", 3,
260
- metaAction, moduleFile.module, isValid ? "valid" : "invalid"
261
- )
262
-
263
- if(isValid) {
264
- debug("Action is a valid `%s` action", 3, metaAction)
265
-
266
- resultActions[metaAction].push({file: moduleFile, action, contract})
267
- } else {
268
- debug("Action is not a valid `%s` action", 3, metaAction)
269
- }
270
-
271
- debug("Processed action `%s`", 2, metaAction)
272
- }
273
-
274
- for(const actionType of actionTypes) {
275
- const total = resultActions[actionType].length
276
- debug("Found %o %o actions", 2, total, actionType)
277
- }
278
-
279
- const total = Object.keys(resultActions).reduce((acc, curr) => {
280
- return acc + resultActions[curr].length
281
- }, 0)
282
-
283
- debug("Loaded %d action definitions from %d modules", 2,
284
- total, moduleFiles.length
285
- )
286
-
287
- return resultActions
288
- }
289
-
290
- satisfyCriteria(actions, validatedConfig) {
291
- const debug = this.#debug
292
-
293
- debug("Available actions to check %o", 3, actions)
294
-
295
- const satisfied = {parse: [], print: []}
296
- const toMatch = {
297
- parse: {criterion: "language", config: "parser"},
298
- print: {criterion: "format", config: "printer"}
299
- }
300
-
301
- debug("Satisfying criteria for actions", 2)
302
- for(const [actionType, search] of Object.entries(toMatch)) {
303
- debug("Satisfying criteria for `%s` actions", 2, actionType)
304
-
305
- const {criterion, config} = search
306
- debug("Criterion: %s, Config: %s", 3, criterion, config)
307
-
308
- // First let's check if we wanted something specific
309
- if(validatedConfig[config]) {
310
- debug("Checking for specific %o action", 3, actionType)
311
- const found = actions[actionType].find(
312
- a => a.file.specificType.includes(actionType)
313
- )
314
- if(found) {
315
- debug("Found specific %o action", 3, actionType)
316
- satisfied[actionType].push(found)
317
- continue
318
- }
319
-
320
- debug("No specific `%s` action found", 3, actionType)
321
- }
322
-
323
- // Hmm! We didn't find anything specific. Let's check the criterion
324
- debug("Checking for %o actions with criterion %o", 3, actionType, criterion)
325
- debug("Validated config to check against: %o", 3, validatedConfig)
326
- const found = actions[actionType].filter(a => {
327
- debug("Meta criterion value: %o", 4, a.action.meta[criterion])
328
- debug("Config criterion value: %o", 4, validatedConfig[criterion])
329
- return a.action.meta[criterion] === validatedConfig[criterion]
330
- })
331
-
332
- debug("Found %o %o actions with criterion %o", 3,
333
- found.length, actionType, criterion
334
- )
335
-
336
- // Shove them into the result!
337
- satisfied[actionType].push(...found)
338
-
339
- // That should about cover it!
340
- }
341
-
342
- return satisfied
343
- }
344
-
345
- /**
346
- * Load a module and return its exports
347
- *
348
- * @param {object} module The module object to load
349
- * @returns {Promise<object>} The module exports {actions, contracts}
350
- */
351
- async #loadModule(module) {
352
- const debug = this.#debug
353
-
354
- debug("Loading module `%j`", 2, module)
355
-
356
- const {absoluteUri} = module
357
- const moduleExports = await import(absoluteUri)
358
-
359
- return {file: module, ...moduleExports}
360
- }
361
-
362
- /**
363
- * Validates the meta requirements for an action
364
- *
365
- * @param {string} actionType The action type to validate
366
- * @param {object} toValidate - The action object to validate
367
- * @returns {boolean} Whether the action object meets the meta requirements
368
- */
369
- #validMeta(actionType, toValidate) {
370
- const debug = this.#debug
371
- debug("Checking meta requirements for %o", 3, actionType)
372
-
373
- const requirements = actionMetaRequirements[actionType]
374
- if(!requirements)
375
- throw new Error(
376
- `No meta requirements found for action type \`${actionType}\``,
377
- )
378
-
379
- for(const requirement of requirements) {
380
- debug("Checking requirement %o", 4, requirement)
381
-
382
- if(isType(requirement, "object")) {
383
- for(const [key, value] of Object.entries(requirement)) {
384
- debug("Checking object requirement %o", 4, {key, value})
385
-
386
- if(toValidate.action.meta[key] !== value)
387
- return false
388
-
389
- debug("Requirement met: %o", 4, {key, value})
390
- }
391
- } else if(isType(requirement, "string")) {
392
- debug("Checking string requirement: %s", 4, requirement)
393
-
394
- if(!toValidate.action.meta[requirement])
395
- return false
396
-
397
- debug("Requirement met: %s", 4, requirement)
398
- }
399
- }
400
-
401
- return true
402
- }
403
- }
@@ -1,143 +0,0 @@
1
- import {setTimeout as timeoutPromise} from "timers/promises"
2
- import * as DataUtil from "./util/DataUtil.js"
3
- import * as ValidUtil from "./util/ValidUtil.js"
4
-
5
- const {isEmpty, isType, allocateObject} = DataUtil
6
- const {assert} = ValidUtil
7
-
8
- const freeze = Object.freeze
9
-
10
- const hookEvents = freeze(["start", "section_load", "enter", "exit", "end"])
11
- export const HookPoints = freeze(
12
- await allocateObject(
13
- hookEvents.map(event => event.toUpperCase()),
14
- hookEvents,
15
- ),
16
- )
17
-
18
- export default class HookManager {
19
- #hooksFile = null
20
- #log = null
21
- #hooks = null
22
- #action = null
23
- #timeout = 1
24
-
25
- constructor({action, hooksFile, logger, timeOut: timeout}) {
26
- this.#action = action
27
- this.#hooksFile = hooksFile
28
- this.#log = logger
29
- this.#timeout = timeout
30
- }
31
-
32
- get action() {
33
- return this.#action
34
- }
35
-
36
- get hooksFile() {
37
- return this.#hooksFile
38
- }
39
-
40
- get hooks() {
41
- return this.#hooks
42
- }
43
-
44
- get log() {
45
- return this.#log
46
- }
47
-
48
- get timeout() {
49
- return this.#timeout
50
- }
51
-
52
- get setup() {
53
- return this.hooks?.setup || null
54
- }
55
-
56
- get cleanup() {
57
- return this.hooks?.cleanup || null
58
- }
59
-
60
- static async new(arg) {
61
- const instance = new HookManager(arg)
62
- const debug = instance.log.newDebug()
63
-
64
- debug("Creating new HookManager instance with args: `%o`", 2, arg)
65
-
66
- const hooksFile = instance.hooksFile
67
-
68
- debug("Loading hooks from `%s", 2, hooksFile.absoluteUri)
69
-
70
- debug("Checking hooks file exists: %j", 2, hooksFile)
71
- const hooksFileContent = await import(hooksFile.absoluteUri)
72
-
73
- debug("Hooks file loaded successfully", 2)
74
-
75
- if(!hooksFileContent)
76
- throw new Error(`Hooks file is empty: ${hooksFile.absoluteUri}`)
77
-
78
- const hooks = hooksFileContent.default || hooksFileContent.Hooks
79
-
80
- if(!hooks)
81
- throw new Error(`\`${hooksFile.absoluteUri}\` contains no hooks.`)
82
-
83
- const hooksObj = hooks[instance.action]
84
- if(isEmpty(hooksObj))
85
- return null
86
-
87
- debug("Hooks found for action: `%s`", 2, instance.action)
88
-
89
- if(!hooksObj)
90
- return null
91
-
92
- hooksObj.log = instance.log
93
- hooksObj.timeout = this.timeout
94
- instance.#hooks = hooksObj
95
-
96
- debug("Hooks loaded successfully for `%s`", 2, instance.action)
97
-
98
- return instance
99
- }
100
-
101
- /**
102
- * Trigger a hook
103
- *
104
- * @param {string} event - The type of hook to trigger
105
- * @param {object} args - The hook arguments as an object
106
- * @returns {Promise<any>} The result of the hook
107
- */
108
- async on(event, args) {
109
- const debug = this.log.newDebug()
110
-
111
- debug("Triggering hook for event `%s`", 4, event)
112
-
113
- if(!event)
114
- throw new Error("Event type is required for hook invocation")
115
-
116
- if(!hookEvents.includes(event))
117
- throw new Error(`Invalid event type: ${event}`)
118
-
119
- const hook = this.hooks[event]
120
-
121
- if(hook) {
122
- assert(isType(hook, "function"), `Hook "${event}" is not a function`, 1)
123
-
124
- const hookExecution = await hook.call(this.hooks, args)
125
- const hookTimeout = this.timeout
126
- const expireAsync = () =>
127
- timeoutPromise(
128
- hookTimeout,
129
- new Error(`Hook execution exceeded timeout of ${hookTimeout}ms`),
130
- )
131
- const result = await Promise.race([hookExecution, expireAsync()])
132
-
133
- if(result?.status === "error")
134
- throw result.error
135
-
136
- debug("Hook executed successfully for event: `%s`", 4, event)
137
-
138
- return result
139
- } else {
140
- return null
141
- }
142
- }
143
- }
@@ -1,7 +0,0 @@
1
- import ActionManager from "../ActionManager.js"
2
-
3
- export default class ParseManager extends ActionManager {
4
- constructor(actionDefinition, logger) {
5
- super(actionDefinition, logger)
6
- }
7
- }
@@ -1,7 +0,0 @@
1
- import ActionManager from "../ActionManager.js"
2
-
3
- export default class PrintManager extends ActionManager {
4
- constructor(actionDefinition, logger) {
5
- super(actionDefinition, logger)
6
- }
7
- }
@@ -1,7 +0,0 @@
1
- import {Contract} from "../ContractManager.js"
2
-
3
- export default class ParseContract extends Contract {
4
- constructor(actionDefinition, logger) {
5
- super(actionDefinition, logger)
6
- }
7
- }
@@ -1,7 +0,0 @@
1
- import {Contract} from "../ContractManager.js"
2
-
3
- export default class PrintContract extends Contract {
4
- constructor(actionDefinition, logger) {
5
- super(actionDefinition, logger)
6
- }
7
- }
@@ -1,53 +0,0 @@
1
- import * as FDUtil from "./FDUtil.js"
2
- import process from "node:process"
3
- import JSON5 from "json5"
4
-
5
- const {readFile, fileExists, composeFilename} = FDUtil
6
-
7
- const freeze = Object.freeze
8
-
9
- const actionTypes = freeze(["parse", "print"])
10
-
11
- const actionMetaRequirements = freeze({
12
- parse: [{action: "parse"}, "language"],
13
- print: [{action: "print"}, "format"],
14
- })
15
-
16
- /**
17
- * Loads a JSON file asynchronously
18
- *
19
- * @param {object} jsonFileObject - The JSON file to load
20
- * @returns {object} The parsed JSON content
21
- */
22
- function loadJson(jsonFileObject) {
23
- // Read the file
24
- const jsonContent = readFile(jsonFileObject)
25
- const json = JSON5.parse(jsonContent)
26
- return json
27
- }
28
-
29
- /**
30
- * Loads the package.json file asynchronously
31
- *
32
- * @param {string|object|null} basePath - The base path to use
33
- * @returns {object?} The parsed package.json content or null if the file does
34
- * not exist
35
- */
36
- function loadPackageJson(basePath = process.cwd()) {
37
- const packageJsonFileObject = composeFilename(basePath, "./package.json")
38
- if(fileExists(packageJsonFileObject)) {
39
- const jsonContent = readFile(packageJsonFileObject)
40
- const json = JSON5.parse(jsonContent)
41
- return json
42
- } else
43
- return null
44
- }
45
-
46
- export {
47
- // Constants
48
- actionMetaRequirements,
49
- actionTypes,
50
- // Functions
51
- loadJson,
52
- loadPackageJson,
53
- }
@@ -1,63 +0,0 @@
1
- import fetch from "node-fetch"
2
- import JSON5 from "json5"
3
- import Ajv from "ajv"
4
- import {fileURLToPath,URL} from "node:url"
5
-
6
- import * as FDUtil from "./FDUtil.js"
7
-
8
- const {composeFilename,fileExists,readFile,writeFile} = FDUtil
9
-
10
- const schemaUrl = "https://bedoc.gesslar.dev/schemas/v1/bedoc.action.json"
11
- const localSchema = "./dist/bedoc.action.json"
12
-
13
- /**
14
- * Takes a schema and returns a validator function
15
- *
16
- * @param {object} schema The schema to compile
17
- * @returns {Function} The schema validator function
18
- */
19
- function getValidator(schema) {
20
- const ajv = new Ajv({allErrors: true, verbose: true})
21
- const f = ajv.compile(schema)
22
-
23
- return f
24
- }
25
-
26
- /**
27
- * Downloads and preserves a copy of the action schema
28
- * within the dist/ folder.
29
- *
30
- * @returns {object} The schema validator
31
- */
32
- async function fetchSchema() {
33
- const response = await fetch(schemaUrl)
34
- const schema = await response.text()
35
-
36
- const output = composeFilename(fileURLToPath(new URL("../../../", import.meta.url)), localSchema)
37
- writeFile(output, schema)
38
-
39
- return JSON5.parse(schema)
40
- }
41
-
42
- /**
43
- * Loads a schema from file or fetches it if it is missing.
44
- *
45
- * @returns {object} The schema object
46
- */
47
- async function loadSchema() {
48
- const schemaFile = composeFilename(fileURLToPath(new URL("../../../", import.meta.url)), localSchema)
49
-
50
- if(fileExists(schemaFile)) {
51
- const schema = readFile(schemaFile)
52
-
53
- return JSON5.parse(schema)
54
- }
55
-
56
- return await fetchSchema()
57
- }
58
-
59
- export {
60
- fetchSchema,
61
- getValidator,
62
- loadSchema,
63
- }