bare-script 3.8.7 → 3.8.9

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.
@@ -6,7 +6,7 @@ include <dataTable.bare>
6
6
 
7
7
  # The URL arguments model
8
8
  argsTypes = schemaParse( \
9
- 'group "<args.bare>"', \
9
+ 'group "args.bare"', \
10
10
  '', \
11
11
  '', \
12
12
  '# An argument model list', \
@@ -2,10 +2,11 @@
2
2
  # https://github.com/craigahobbs/bare-script/blob/main/LICENSE
3
3
 
4
4
  include <args.bare>
5
+ include <schemaDoc.bare>
5
6
 
6
7
 
7
8
  # $function: baredocMain
8
- # $group: baredocMain.bare
9
+ # $group: baredoc.bare
9
10
  # $doc: The BareScript library documentation application main entry point
10
11
  # $arg url: The library documentation JSON resource URL
11
12
  # $arg title: The library title
@@ -22,7 +23,7 @@ async function baredocMain(url, title, menuLinks, groupURLs):
22
23
  # Render library JSON documentation page?
23
24
  if objectGet(args, 'doc'):
24
25
  documentSetTitle('Library')
25
- elementModelRender(schemaElements(baredocTypes, 'Library'))
26
+ markdownPrint(schemaDocMarkdown(baredocTypes, 'Library'))
26
27
  return
27
28
  endif
28
29
 
@@ -195,13 +196,14 @@ async function baredocSinglePage(args, title, menuLinks, groupURLs, groups):
195
196
  # Render the library function index
196
197
  for groupName in arraySort(objectKeys(groups)):
197
198
  markdownPrint('', '---', '')
198
- baredocGroupPage(args, title, groupURLs, groups, groupName, true)
199
+ baredocGroupPage(args, title, groupURLs, groups, groupName)
199
200
  endfor
200
201
  endfunction
201
202
 
202
203
 
203
204
  # Render a library documentation group page
204
205
  async function baredocGroupPage(args, title, groupURLs, groups, groupName):
206
+ publish = objectGet(args, 'publish')
205
207
  single = objectGet(args, 'single')
206
208
  baseHeader = if(single, '##', '#')
207
209
 
@@ -221,7 +223,7 @@ async function baredocGroupPage(args, title, groupURLs, groups, groupName):
221
223
  markdownPrint(argsLink(baredocArguments, 'Index', {'group': null}), '')
222
224
  endif
223
225
  markdownPrint(baseHeader + ' ' + markdownEscape(groupName))
224
- if single:
226
+ if single && !publish:
225
227
  markdownPrint('', argsLink(baredocArguments, 'Back to top', null, false, '_top'))
226
228
  endif
227
229
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # The data table model's Schema Markdown
6
6
  dataTableTypes = schemaParse( \
7
- 'group "<dataTable.bare>"', \
7
+ 'group "dataTable.bare"', \
8
8
  '', \
9
9
  '', \
10
10
  '# A data table model', \
@@ -4,7 +4,7 @@
4
4
 
5
5
  # The text line difference model
6
6
  diffTypes = schemaParse( \
7
- 'group "<diff.bare>"', \
7
+ 'group "diff.bare"', \
8
8
  '', \
9
9
  '', \
10
10
  '# A list of text line differences', \
@@ -7,7 +7,7 @@ include <args.bare>
7
7
 
8
8
  # The pager model
9
9
  pagerTypes = schemaParse( \
10
- 'group "<pager.bare>"', \
10
+ 'group "pager.bare"', \
11
11
  '', \
12
12
  '', \
13
13
  '# A pager application model', \
@@ -0,0 +1,734 @@
1
+ # Licensed under the MIT License
2
+ # https://github.com/craigahobbs/bare-script/blob/main/LICENSE
3
+
4
+ include <args.bare>
5
+ include <dataTable.bare>
6
+ include <schemaDoc.bare>
7
+
8
+
9
+ # $function: schemaDocMain
10
+ # $group: schemaDoc.bare
11
+ # $doc: The Schema Markdown documentation viewer main entry point
12
+ # $arg url: Optional (default is null). The Schema Markdown text or JSON resource URL. If null, the Schema Markdown type model is displayed.
13
+ # $arg title: Optional. The schema title.
14
+ # $arg hideNoGroup: Optional (default is false). If true, hide types with no group.
15
+ async function schemaDocMain(url, title, hideNoGroup):
16
+ # Parse arguments
17
+ args = argsParse(schemaDocArguments)
18
+ name = objectGet(args, 'name')
19
+ publish = objectGet(args, 'publish')
20
+ single = objectGet(args, 'single')
21
+ url = objectGet(args, 'url', url)
22
+ title = if(title != null && !objectHas(args, 'url'), title, url)
23
+
24
+ # If no URL was provided, use the Schema Markdown type model schema
25
+ if !url:
26
+ types = schemaTypeModel()
27
+ title = 'The Schema Markdown Type Model'
28
+ else:
29
+ # Fetch the Schema Markdown resource
30
+ types = null
31
+ schemaText = systemFetch(url)
32
+ if schemaText != null:
33
+ if stringEndsWith(url, '.json'):
34
+ schemaJSON = jsonParse(schemaText)
35
+ if schemaJSON != null:
36
+ types = schemaValidateTypeModel(schemaJSON)
37
+ endif
38
+ else:
39
+ types = schemaParse(schemaText)
40
+ endif
41
+ endif
42
+
43
+ # Error?
44
+ if types == null:
45
+ markdownPrint('**Error:** Failed to fetch Schema Markdown resource "' + url + '"')
46
+ return
47
+ endif
48
+ endif
49
+
50
+ # Type page?
51
+ if name:
52
+ # Set the type page title
53
+ documentSetTitle(title + ' - ' + name)
54
+ markdownPrint(argsLink(schemaDocArguments, 'Index', {'name': null}))
55
+
56
+ # Type exist?
57
+ if !objectHas(types, name):
58
+ markdownPrint('', '**Error:** Unknown type "' + name + '"')
59
+ return
60
+ endif
61
+
62
+ # Render the type's documentation
63
+ markdownPrint(schemaDocMarkdown(types, name))
64
+ return
65
+ endif
66
+
67
+ # Render the index page title
68
+ documentSetTitle(title)
69
+ markdownPrint('# ' + markdownEscape(title))
70
+
71
+ # Render the single page toggle
72
+ if !publish:
73
+ markdownPrint('', argsLink(schemaDocArguments, if(single, 'Multi Page', 'Single Page'), {'single': !single}))
74
+ endif
75
+
76
+ # Group the types
77
+ groups = {}
78
+ typeNames = arraySort(objectKeys(types))
79
+ typeGroups = {'action': 'Actions', 'enum': 'Enums', 'struct': 'Structs', 'typedef': 'Typedefs'}
80
+ for typeName in typeNames:
81
+ type = objectGet(types, typeName)
82
+ group = objectGet(objectGet(type, arrayGet(objectKeys(type), 0)), 'docGroup')
83
+
84
+ # No group? Use the type's default group.
85
+ if group == null:
86
+ if hideNoGroup:
87
+ continue
88
+ endif
89
+ group = objectGet(typeGroups, arrayGet(objectKeys(type), 0))
90
+ endif
91
+
92
+ # Add the type to the group
93
+ if !objectHas(groups, group):
94
+ objectSet(groups, group, [])
95
+ endif
96
+ arrayPush(objectGet(groups, group), type)
97
+ endfor
98
+ groupNames = arraySort(objectKeys(groups))
99
+
100
+ # The table of contents
101
+ if single:
102
+ markdownPrint('', '## Table of Contents', '')
103
+ for groupName in groupNames:
104
+ markdownPrint('- ' + argsLink(schemaDocArguments, groupName, null, false, groupName))
105
+ endfor
106
+ endif
107
+
108
+ # Render the index groups
109
+ for groupName in groupNames:
110
+ if single:
111
+ markdownPrint('', '---')
112
+ endif
113
+ markdownPrint('', '## ' + markdownEscape(groupName))
114
+ if single && !publish:
115
+ markdownPrint('', argsLink(schemaDocArguments, 'Back to top', null, false, '_top'))
116
+ endif
117
+
118
+ # Render the group type links
119
+ groupTypes = objectGet(groups, groupName)
120
+ for groupType in groupTypes:
121
+ groupTypeName = objectGet(objectGet(groupType, arrayGet(objectKeys(groupType), 0)), 'name')
122
+ if single:
123
+ markdownPrint('', schemaDocMarkdown(types, groupTypeName, {'headerPrefix': '###', 'hideReferenced': true}))
124
+ else:
125
+ markdownPrint('', argsLink(schemaDocArguments, groupTypeName, {'name': groupTypeName}, false, '_top'))
126
+ endif
127
+ endfor
128
+ endfor
129
+ endfunction
130
+
131
+
132
+ # The Schema Markdown documentation viewer arguments
133
+ schemaDocArguments = argsValidate([ \
134
+ {'name': 'name'}, \
135
+ {'name': 'publish', 'type': 'bool', 'default': false}, \
136
+ {'name': 'single', 'type': 'bool', 'default': false}, \
137
+ {'name': 'url', 'global': 'vURL'} \
138
+ ])
139
+
140
+
141
+ # $function: schemaDocMarkdown
142
+ # $group: schemaDoc.bare
143
+ # $doc: Generate the Schema Markdown user type documentation as an array of Markdown text lines
144
+ # $arg types: The [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
145
+ # $arg typeName: The type name
146
+ # $arg options: Optional (default is null). The options object with optional members:
147
+ # $arg options: - **actionURLs** - The [action URLs](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='ActionURL') override
148
+ # $arg options: - **actionCustom** - If true, the action has a custom response (default is false)
149
+ # $arg options: - **headerPrefix** - The top-level header prefix string (default is "#")
150
+ # $arg options: - **hideReferenced** - If true, referenced types are not rendered (default is false)
151
+ # $return: The array of Markdown text lines
152
+ function schemaDocMarkdown(types, typeName, options):
153
+ headerPrefix = if(options != null, objectGet(options, 'headerPrefix', '#'), '#')
154
+ hideReferenced = if(options != null, objectGet(options, 'hideReferenced', false), false)
155
+
156
+ # Get the user type
157
+ if !objectHas(types, typeName):
158
+ systemLogDebug('schemaDoc.bare: Unknown type "' + typeName + '"')
159
+ return null
160
+ endif
161
+ userType = objectGet(types, typeName)
162
+ action = objectGet(userType, 'action')
163
+
164
+ # Compute the referenced types
165
+ referencedTypes = schemaDocGetReferencedTypes(types, typeName)
166
+ if action != null:
167
+ typesFilter = [ \
168
+ typeName, objectGet(action, 'path'), objectGet(action, 'query'), objectGet(action, 'input'), \
169
+ objectGet(action, 'output'), objectGet(action, 'errors') \
170
+ ]
171
+ else:
172
+ typesFilter = [typeName]
173
+ endif
174
+
175
+ # Filter and sort referenced types
176
+ filteredTypeNames = []
177
+ for refTypeName in arraySort(objectKeys(referencedTypes)):
178
+ if arrayIndexOf(typesFilter, refTypeName) == -1:
179
+ arrayPush(filteredTypeNames, refTypeName)
180
+ endif
181
+ endfor
182
+
183
+ # The user type documentation
184
+ lines = []
185
+ arrayExtend(lines, schemaDocUserTypeMarkdown(types, typeName, options, headerPrefix))
186
+
187
+ # Referenced type documentation
188
+ if filteredTypeNames && !hideReferenced:
189
+ arrayPush(lines, '')
190
+ arrayPush(lines, '---')
191
+ arrayPush(lines, '')
192
+ arrayPush(lines, headerPrefix + '# Referenced Types')
193
+ for refTypeName in filteredTypeNames:
194
+ arrayPush(lines, '')
195
+ arrayExtend(lines, schemaDocUserTypeMarkdown(types, refTypeName, options, headerPrefix + '##'))
196
+ endfor
197
+ endif
198
+
199
+ return lines
200
+ endfunction
201
+
202
+
203
+ # Helper function to generate user type documentation
204
+ function schemaDocUserTypeMarkdown(types, typeName, options, headerPrefix, title, introLines):
205
+ userType = objectGet(types, typeName)
206
+ lines = []
207
+
208
+ # Title
209
+ arrayPush(lines, headerPrefix + ' ' + if(title != null, title, schemaDocTypeTitle(userType)))
210
+
211
+ # Struct?
212
+ if objectHas(userType, 'struct'):
213
+ struct = objectGet(userType, 'struct')
214
+
215
+ # Bases
216
+ if objectHas(struct, 'bases'):
217
+ bases = objectGet(struct, 'bases')
218
+ basesLinks = []
219
+ for base in bases:
220
+ arrayPush(basesLinks, '[' + markdownEscape(base) + '](#' + schemaDocTypeHref(objectGet(types, base)) + ')')
221
+ endfor
222
+ arrayPush(lines, '')
223
+ arrayPush(lines, 'Bases: ' + arrayJoin(basesLinks, ', '))
224
+ endif
225
+
226
+ # Documentation
227
+ if objectHas(struct, 'doc'):
228
+ arrayPush(lines, '')
229
+ arrayExtend(lines, objectGet(struct, 'doc'))
230
+ endif
231
+
232
+ # Members table
233
+ members = schemaDocGetStructMembers(types, struct)
234
+ if !members:
235
+ arrayPush(lines, '')
236
+ arrayPush(lines, 'The struct is empty.')
237
+ else:
238
+ # Any attributes or documentation?
239
+ hasAttr = false
240
+ hasDoc = false
241
+ for member in members:
242
+ hasAttr = hasAttr || schemaDocAttrText(member) != null
243
+ hasDoc = hasDoc || objectGet(member, 'doc')
244
+ endfor
245
+
246
+ # Members table data
247
+ tableData = []
248
+ for member in members:
249
+ memberName = objectGet(member, 'name')
250
+ row = { \
251
+ 'Name': memberName, \
252
+ 'Type': schemaDocTypeText(types, objectGet(member, 'type')) \
253
+ }
254
+ if hasAttr:
255
+ objectSet(row, 'Attributes', schemaDocAttrText(member) || '')
256
+ endif
257
+ if hasDoc:
258
+ doc = objectGet(member, 'doc')
259
+ objectSet(row, 'Description', if(doc != null, arrayJoin(doc, ' '), ''))
260
+ endif
261
+ arrayPush(tableData, row)
262
+ endfor
263
+
264
+ # Members table
265
+ tableFields = ['Name', 'Type']
266
+ if hasAttr:
267
+ arrayPush(tableFields, 'Attributes')
268
+ endif
269
+ if hasDoc:
270
+ arrayPush(tableFields, 'Description')
271
+ endif
272
+ tableModel = {'fields': tableFields}
273
+ arrayPush(lines, '')
274
+ arrayExtend(lines, dataTableMarkdown(tableData, tableModel))
275
+ endif
276
+
277
+ # Enum?
278
+ elif objectHas(userType, 'enum'):
279
+ enum = objectGet(userType, 'enum')
280
+
281
+ # Bases
282
+ if objectHas(enum, 'bases'):
283
+ bases = objectGet(enum, 'bases')
284
+ basesLinks = []
285
+ for base in bases:
286
+ arrayPush(basesLinks, '[' + markdownEscape(base) + '](#' + schemaDocTypeHref(objectGet(types, base)) + ')')
287
+ endfor
288
+ arrayPush(lines, '')
289
+ arrayPush(lines, 'Bases: ' + arrayJoin(basesLinks, ', '))
290
+ endif
291
+
292
+ # Documentation
293
+ if objectHas(enum, 'doc'):
294
+ arrayPush(lines, '')
295
+ arrayExtend(lines, objectGet(enum, 'doc'))
296
+ endif
297
+
298
+ # Intro markdown
299
+ if systemType(introLines) == 'array':
300
+ arrayPush(lines, '')
301
+ arrayExtend(lines, introLines)
302
+ endif
303
+
304
+ # Values table
305
+ values = if(objectHas(enum, 'values'), schemaDocGetEnumValues(types, enum), null)
306
+ if values == null || !values:
307
+ arrayPush(lines, '')
308
+ arrayPush(lines, 'The enum is empty.')
309
+ else:
310
+ # Compute value documentation
311
+ hasDoc = false
312
+ for value in values:
313
+ hasDoc = hasDoc || objectGet(value, 'doc')
314
+ endfor
315
+
316
+ # Values table data
317
+ tableData = []
318
+ for value in values:
319
+ valueName = objectGet(value, 'name')
320
+ row = {'Value': valueName}
321
+ if hasDoc:
322
+ doc = objectGet(value, 'doc')
323
+ objectSet(row, 'Description', if(doc != null, arrayJoin(doc, ' '), ''))
324
+ endif
325
+ arrayPush(tableData, row)
326
+ endfor
327
+
328
+ # Values table
329
+ tableFields = ['Value']
330
+ if hasDoc:
331
+ arrayPush(tableFields, 'Description')
332
+ endif
333
+ tableModel = {'fields': tableFields}
334
+ arrayPush(lines, '')
335
+ arrayExtend(lines, dataTableMarkdown(tableData, tableModel))
336
+ endif
337
+
338
+ # Typedef?
339
+ elif objectHas(userType, 'typedef'):
340
+ typedef = objectGet(userType, 'typedef')
341
+
342
+ # Documentation
343
+ if objectHas(typedef, 'doc'):
344
+ arrayPush(lines, '')
345
+ arrayExtend(lines, objectGet(typedef, 'doc'))
346
+ endif
347
+
348
+ # Type table data
349
+ attrText = if(objectHas(typedef, 'attr'), schemaDocAttrText(typedef))
350
+ tableData = [{'Type': schemaDocTypeText(types, objectGet(typedef, 'type'))}]
351
+ if attrText != null:
352
+ objectSet(arrayGet(tableData, 0), 'Attributes', attrText)
353
+ endif
354
+
355
+ # Type table
356
+ tableFields = ['Type']
357
+ if attrText != null:
358
+ arrayPush(tableFields, 'Attributes')
359
+ endif
360
+ tableModel = {'fields': tableFields}
361
+ arrayPush(lines, '')
362
+ arrayExtend(lines, dataTableMarkdown(tableData, tableModel))
363
+
364
+ # Action?
365
+ elif objectHas(userType, 'action'):
366
+ action = objectGet(userType, 'action')
367
+
368
+ # Documentation
369
+ if objectHas(action, 'doc'):
370
+ arrayPush(lines, '')
371
+ arrayExtend(lines, objectGet(action, 'doc'))
372
+ endif
373
+
374
+ # URLs
375
+ actionURLs = if(options != null && objectHas(options, 'actionURLs'), objectGet(options, 'actionURLs'), objectGet(action, 'urls'))
376
+ if actionURLs:
377
+ arrayPush(lines, '')
378
+ arrayPush(lines, '**Note:** The request is exposed at the following ' + if(arrayLength(actionURLs) == 1, 'URL:', 'URLs:'))
379
+ for actionURL in actionURLs:
380
+ method = objectGet(actionURL, 'method')
381
+ path = objectGet(actionURL, 'path', '/' + typeName)
382
+ arrayPush(lines, '')
383
+ arrayPush(lines, '- [' + if(method, method + ' ', '') + markdownEscape(path) + '](' + urlEncode(path) + ')')
384
+ endfor
385
+ endif
386
+
387
+ # Path struct
388
+ if objectHas(action, 'path'):
389
+ arrayPush(lines, '')
390
+ arrayExtend( \
391
+ lines, \
392
+ schemaDocUserTypeMarkdown(types, objectGet(action, 'path'), options, headerPrefix + '#', 'Path Parameters') \
393
+ )
394
+ endif
395
+
396
+ # Query struct
397
+ if objectHas(action, 'query'):
398
+ arrayPush(lines, '')
399
+ arrayExtend( \
400
+ lines, \
401
+ schemaDocUserTypeMarkdown(types, objectGet(action, 'query'), options, headerPrefix + '#', 'Query Parameters') \
402
+ )
403
+ endif
404
+
405
+ # Input struct
406
+ if objectHas(action, 'input'):
407
+ arrayPush(lines, '')
408
+ arrayExtend( \
409
+ lines, \
410
+ schemaDocUserTypeMarkdown(types, objectGet(action, 'input'), options, headerPrefix + '#', 'Input Parameters') \
411
+ )
412
+ endif
413
+
414
+ # Output struct
415
+ actionCustom = options != null && objectGet(options, 'actionCustom')
416
+ if objectHas(action, 'output') && !actionCustom:
417
+ arrayPush(lines, '')
418
+ arrayExtend( \
419
+ lines, \
420
+ schemaDocUserTypeMarkdown(types, objectGet(action, 'output'), options, headerPrefix + '#', 'Output Parameters') \
421
+ )
422
+ endif
423
+
424
+ # Error enum
425
+ if !actionCustom:
426
+ # Add "UnexpectedError" to the action's errors
427
+ if objectHas(action, 'errors'):
428
+ actionErrorTypeName = objectGet(action, 'errors')
429
+ actionErrorTypes = schemaDocGetReferencedTypes(types, actionErrorTypeName)
430
+ actionErrorEnum = objectCopy(objectGet(objectGet(types, actionErrorTypeName), 'enum'))
431
+ if objectHas(actionErrorEnum, 'values'):
432
+ objectSet(actionErrorEnum, 'values', arrayCopy(objectGet(actionErrorEnum, 'values')))
433
+ else:
434
+ objectSet(actionErrorEnum, 'values', [])
435
+ endif
436
+ else:
437
+ actionErrorTypeName = typeName + '_errors'
438
+ actionErrorTypes = {}
439
+ actionErrorEnum = {'name': actionErrorTypeName, 'values': []}
440
+ endif
441
+
442
+ # Add UnexpectedError if not already present
443
+ values = objectGet(actionErrorEnum, 'values')
444
+ hasUnexpectedError = false
445
+ for value in values:
446
+ if objectGet(value, 'name') == 'UnexpectedError':
447
+ hasUnexpectedError = true
448
+ break
449
+ endif
450
+ endfor
451
+ if !hasUnexpectedError:
452
+ arrayPush(values, {'name': 'UnexpectedError'})
453
+ endif
454
+ objectSet(actionErrorTypes, actionErrorTypeName, {'enum': actionErrorEnum})
455
+ arrayPush(lines, '')
456
+ arrayExtend( \
457
+ lines, \
458
+ schemaDocUserTypeMarkdown( \
459
+ actionErrorTypes, actionErrorTypeName, options, headerPrefix + '#', 'Error Codes', schemaDocActionErrorIntroLines \
460
+ ) \
461
+ )
462
+ endif
463
+ endif
464
+
465
+ return lines
466
+ endfunction
467
+
468
+
469
+ # Action error enum introduction text
470
+ schemaDocActionErrorIntroLines = [ \
471
+ 'If an application error occurs, the response is of the form:', \
472
+ '', \
473
+ '```json', \
474
+ '{', \
475
+ ' "error": "<error>",', \
476
+ ' "message": "<message>"', \
477
+ '}', \
478
+ '```', \
479
+ '', \
480
+ '`message` is optional. `error` is one of the following values:' \
481
+ ]
482
+
483
+
484
+ # Helper function to get a type's title
485
+ function schemaDocTypeTitle(userType):
486
+ if objectHas(userType, 'struct'):
487
+ struct = objectGet(userType, 'struct')
488
+ return if(objectGet(struct, 'union'), 'union ' + objectGet(struct, 'name'), 'struct ' + objectGet(struct, 'name'))
489
+ elif objectHas(userType, 'enum'):
490
+ return 'enum ' + objectGet(objectGet(userType, 'enum'), 'name')
491
+ elif objectHas(userType, 'typedef'):
492
+ return 'typedef ' + objectGet(objectGet(userType, 'typedef'), 'name')
493
+ endif
494
+ # objectHas(userType, 'action'):
495
+ return 'action ' + objectGet(objectGet(userType, 'action'), 'name')
496
+ endfunction
497
+
498
+
499
+ # Helper function to get a type href
500
+ function schemaDocTypeHref(userType):
501
+ return markdownHeaderId(schemaDocTypeTitle(userType))
502
+ endfunction
503
+
504
+
505
+ # Helper function to get a type's text
506
+ function schemaDocTypeText(types, type):
507
+ if objectHas(type, 'array'):
508
+ return schemaDocTypeText(types, objectGet(objectGet(type, 'array'), 'type')) + ' []'
509
+ elif objectHas(type, 'dict'):
510
+ dict = objectGet(type, 'dict')
511
+ keyType = objectGet(dict, 'keyType')
512
+ if keyType != null && !objectHas(keyType, 'builtin'):
513
+ return schemaDocTypeText(types, keyType) + ' : ' + schemaDocTypeText(types, objectGet(dict, 'type')) + ' {}'
514
+ endif
515
+ return schemaDocTypeText(types, objectGet(dict, 'type')) + ' {}'
516
+ elif objectHas(type, 'user'):
517
+ userName = objectGet(type, 'user')
518
+ userType = objectGet(types, userName)
519
+ return '[' + markdownEscape(userName) + '](#' + schemaDocTypeHref(userType) + ')'
520
+ endif
521
+ # objectHas(type, 'builtin'):
522
+ return objectGet(type, 'builtin')
523
+ endfunction
524
+
525
+
526
+ # Helper function to get a type's attribute text
527
+ function schemaDocAttrText(member):
528
+ type = objectGet(member, 'type')
529
+ attr = objectGet(member, 'attr')
530
+ optional = objectGet(member, 'optional')
531
+
532
+ # Collect attribute parts
533
+ parts = []
534
+ typeName = if(objectHas(type, 'array'), 'array', if(objectHas(type, 'dict'), 'dict', 'value'))
535
+ schemaDocAttrParts(parts, typeName, attr, optional)
536
+
537
+ # Array or dict key/value attributes
538
+ if objectHas(type, 'array'):
539
+ array = objectGet(type, 'array')
540
+ if objectHas(array, 'attr'):
541
+ schemaDocAttrParts(parts, 'value', objectGet(array, 'attr'), false)
542
+ endif
543
+ elif objectHas(type, 'dict'):
544
+ dict = objectGet(type, 'dict')
545
+ if objectHas(dict, 'keyAttr'):
546
+ schemaDocAttrParts(parts, 'key', objectGet(dict, 'keyAttr'), false)
547
+ endif
548
+ if objectHas(dict, 'attr'):
549
+ schemaDocAttrParts(parts, 'value', objectGet(dict, 'attr'), false)
550
+ endif
551
+ endif
552
+
553
+ return if(parts, arrayJoin(parts, '<br>'), null)
554
+ endfunction
555
+
556
+
557
+ # Helper function to get a type's attribute parts
558
+ function schemaDocAttrParts(parts, noun, attr, optional):
559
+ if optional:
560
+ arrayPush(parts, 'optional')
561
+ endif
562
+
563
+ if attr != null:
564
+ if objectHas(attr, 'nullable'):
565
+ arrayPush(parts, 'nullable')
566
+ endif
567
+ if objectHas(attr, 'gt'):
568
+ arrayPush(parts, noun + ' > ' + objectGet(attr, 'gt'))
569
+ endif
570
+ if objectHas(attr, 'gte'):
571
+ arrayPush(parts, noun + ' >= ' + objectGet(attr, 'gte'))
572
+ endif
573
+ if objectHas(attr, 'lt'):
574
+ arrayPush(parts, noun + ' < '+ objectGet(attr, 'lt'))
575
+ endif
576
+ if objectHas(attr, 'lte'):
577
+ arrayPush(parts, noun + ' <= ' + objectGet(attr, 'lte'))
578
+ endif
579
+ if objectHas(attr, 'eq'):
580
+ arrayPush(parts, noun + ' == ' + objectGet(attr, 'eq'))
581
+ endif
582
+ if objectHas(attr, 'lenGT'):
583
+ arrayPush(parts, 'len(' + noun + ')' + ' > ' + objectGet(attr, 'lenGT'))
584
+ endif
585
+ if objectHas(attr, 'lenGTE'):
586
+ arrayPush(parts, 'len(' + noun + ')' + ' >= ' + objectGet(attr, 'lenGTE'))
587
+ endif
588
+ if objectHas(attr, 'lenLT'):
589
+ arrayPush(parts, 'len(' + noun + ')' + ' < ' + objectGet(attr, 'lenLT'))
590
+ endif
591
+ if objectHas(attr, 'lenLTE'):
592
+ arrayPush(parts, 'len(' + noun + ')' + ' <= ' + objectGet(attr, 'lenLTE'))
593
+ endif
594
+ if objectHas(attr, 'lenEq'):
595
+ arrayPush(parts, 'len(' + noun + ')' + ' == ' + objectGet(attr, 'lenEq'))
596
+ endif
597
+ endif
598
+ endfunction
599
+
600
+
601
+ # Helper function to get struct members (with base members)
602
+ function schemaDocGetStructMembers(types, struct):
603
+ members = []
604
+
605
+ # Add base members first
606
+ if objectHas(struct, 'bases'):
607
+ for baseName in objectGet(struct, 'bases'):
608
+ if objectHas(types, baseName):
609
+ baseType = objectGet(types, baseName)
610
+ if objectHas(baseType, 'struct'):
611
+ baseMembers = schemaDocGetStructMembers(types, objectGet(baseType, 'struct'))
612
+ arrayExtend(members, baseMembers)
613
+ endif
614
+ endif
615
+ endfor
616
+ endif
617
+
618
+ # Add this struct's members
619
+ if objectHas(struct, 'members'):
620
+ arrayExtend(members, objectGet(struct, 'members'))
621
+ endif
622
+
623
+ return members
624
+ endfunction
625
+
626
+
627
+ # Helper function to get enum values (with base values)
628
+ function schemaDocGetEnumValues(types, enum):
629
+ values = []
630
+
631
+ # Add base values first
632
+ if objectHas(enum, 'bases'):
633
+ for baseName in objectGet(enum, 'bases'):
634
+ if objectHas(types, baseName):
635
+ baseType = objectGet(types, baseName)
636
+ if objectHas(baseType, 'enum'):
637
+ baseValues = schemaDocGetEnumValues(types, objectGet(baseType, 'enum'))
638
+ if baseValues != null:
639
+ arrayExtend(values, baseValues)
640
+ endif
641
+ endif
642
+ endif
643
+ endfor
644
+ endif
645
+
646
+ # Add this enum's values
647
+ if objectHas(enum, 'values'):
648
+ arrayExtend(values, objectGet(enum, 'values'))
649
+ endif
650
+
651
+ return values
652
+ endfunction
653
+
654
+
655
+ # Helper function to get a user type's referenced type model
656
+ function schemaDocGetReferencedTypes(types, typeName, referencedTypes):
657
+ referencedTypes = if(referencedTypes, referencedTypes, {})
658
+ return schemaDocGetReferencedTypesHelper(types, {'user': typeName}, referencedTypes)
659
+ endfunction
660
+
661
+
662
+ function schemaDocGetReferencedTypesHelper(types, type, referencedTypes):
663
+ # Array?
664
+ if objectHas(type, 'array'):
665
+ array = objectGet(type, 'array')
666
+ schemaDocGetReferencedTypesHelper(types, objectGet(array, 'type'), referencedTypes)
667
+
668
+ # Dict?
669
+ elif objectHas(type, 'dict'):
670
+ dict = objectGet(type, 'dict')
671
+ schemaDocGetReferencedTypesHelper(types, objectGet(dict, 'type'), referencedTypes)
672
+ if objectHas(dict, 'keyType'):
673
+ schemaDocGetReferencedTypesHelper(types, objectGet(dict, 'keyType'), referencedTypes)
674
+ endif
675
+
676
+ # User type?
677
+ elif objectHas(type, 'user'):
678
+ typeName = objectGet(type, 'user')
679
+
680
+ # Already encountered?
681
+ if !objectHas(referencedTypes, typeName):
682
+ userType = objectGet(types, typeName)
683
+ objectSet(referencedTypes, typeName, userType)
684
+
685
+ # Struct?
686
+ if objectHas(userType, 'struct'):
687
+ struct = objectGet(userType, 'struct')
688
+ if objectHas(struct, 'bases'):
689
+ for base in objectGet(struct, 'bases'):
690
+ schemaDocGetReferencedTypesHelper(types, {'user': base}, referencedTypes)
691
+ endfor
692
+ endif
693
+ for member in schemaDocGetStructMembers(types, struct):
694
+ schemaDocGetReferencedTypesHelper(types, objectGet(member, 'type'), referencedTypes)
695
+ endfor
696
+
697
+ # Enum?
698
+ elif objectHas(userType, 'enum'):
699
+ enum = objectGet(userType, 'enum')
700
+ if objectHas(enum, 'bases'):
701
+ for base in objectGet(enum, 'bases'):
702
+ schemaDocGetReferencedTypesHelper(types, {'user': base}, referencedTypes)
703
+ endfor
704
+ endif
705
+
706
+ # Typedef?
707
+ elif objectHas(userType, 'typedef'):
708
+ typedef = objectGet(userType, 'typedef')
709
+ schemaDocGetReferencedTypesHelper(types, objectGet(typedef, 'type'), referencedTypes)
710
+
711
+ # Action?
712
+ elif objectHas(userType, 'action'):
713
+ action = objectGet(userType, 'action')
714
+ if objectHas(action, 'path'):
715
+ schemaDocGetReferencedTypesHelper(types, {'user': objectGet(action, 'path')}, referencedTypes)
716
+ endif
717
+ if objectHas(action, 'query'):
718
+ schemaDocGetReferencedTypesHelper(types, {'user': objectGet(action, 'query')}, referencedTypes)
719
+ endif
720
+ if objectHas(action, 'input'):
721
+ schemaDocGetReferencedTypesHelper(types, {'user': objectGet(action, 'input')}, referencedTypes)
722
+ endif
723
+ if objectHas(action, 'output'):
724
+ schemaDocGetReferencedTypesHelper(types, {'user': objectGet(action, 'output')}, referencedTypes)
725
+ endif
726
+ if objectHas(action, 'errors'):
727
+ schemaDocGetReferencedTypesHelper(types, {'user': objectGet(action, 'errors')}, referencedTypes)
728
+ endif
729
+ endif
730
+ endif
731
+ endif
732
+
733
+ return referencedTypes
734
+ endfunction
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "bare-script",
4
- "version": "3.8.7",
4
+ "version": "3.8.9",
5
5
  "description": "BareScript; a lightweight scripting and expression language",
6
6
  "keywords": [
7
7
  "expression",