aontu 0.61.0 → 0.63.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.
- package/README.md +4 -4
- package/dist/agentsmd.d.ts +1 -0
- package/dist/agentsmd.js +7 -28
- package/dist/agentsmd.js.map +1 -1
- package/dist/alias.js.map +1 -1
- package/dist/allow.d.ts +23 -0
- package/dist/allow.js +138 -0
- package/dist/allow.js.map +1 -0
- package/dist/aontu.d.ts +4 -2
- package/dist/aontu.js +4 -80
- package/dist/aontu.js.map +1 -1
- package/dist/aontumodel.d.ts +4 -0
- package/dist/aontumodel.js +33 -0
- package/dist/aontumodel.js.map +1 -0
- package/dist/cli.d.ts +10 -1
- package/dist/cli.js +877 -479
- package/dist/cli.js.map +1 -1
- package/dist/ctx.js +0 -48
- package/dist/ctx.js.map +1 -1
- package/dist/diff.js +0 -32
- package/dist/diff.js.map +1 -1
- package/dist/err.js +0 -40
- package/dist/err.js.map +1 -1
- package/dist/escape.js +0 -45
- package/dist/escape.js.map +1 -1
- package/dist/exactjson.d.ts +0 -35
- package/dist/exactjson.js +0 -131
- package/dist/exactjson.js.map +1 -1
- package/dist/format.js +55 -189
- package/dist/format.js.map +1 -1
- package/dist/grammar.d.ts +9 -0
- package/dist/grammar.js +54 -0
- package/dist/grammar.js.map +1 -0
- package/dist/graph.js +0 -26
- package/dist/graph.js.map +1 -1
- package/dist/hcanon.js +0 -82
- package/dist/hcanon.js.map +1 -1
- package/dist/helpdoc.d.ts +16 -0
- package/dist/helpdoc.js +59 -0
- package/dist/helpdoc.js.map +1 -0
- package/dist/hints.d.ts +0 -6
- package/dist/hints.js +59 -47
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.js +0 -114
- package/dist/jsonschema.js.map +1 -1
- package/dist/keyorder.d.ts +0 -7
- package/dist/keyorder.js +0 -41
- package/dist/keyorder.js.map +1 -1
- package/dist/lang.js +32 -877
- package/dist/lang.js.map +1 -1
- package/dist/lower.d.ts +3 -0
- package/dist/lower.js +14 -61
- package/dist/lower.js.map +1 -1
- package/dist/lsp-server.js +0 -16
- package/dist/lsp-server.js.map +1 -1
- package/dist/lsp.d.ts +1 -1
- package/dist/lsp.js +12 -159
- package/dist/lsp.js.map +1 -1
- package/dist/mcp-server.js +0 -26
- package/dist/mcp-server.js.map +1 -1
- package/dist/mcp.js +0 -113
- package/dist/mcp.js.map +1 -1
- package/dist/mod-tool.js +0 -130
- package/dist/mod-tool.js.map +1 -1
- package/dist/mod.js +0 -162
- package/dist/mod.js.map +1 -1
- package/dist/patch.js +0 -217
- package/dist/patch.js.map +1 -1
- package/dist/provenance.js +0 -140
- package/dist/provenance.js.map +1 -1
- package/dist/query.js +0 -75
- package/dist/query.js.map +1 -1
- package/dist/reach.js +0 -43
- package/dist/reach.js.map +1 -1
- package/dist/relation.d.ts +2 -0
- package/dist/relation.js +3 -58
- package/dist/relation.js.map +1 -1
- package/dist/render.js +33 -143
- package/dist/render.js.map +1 -1
- package/dist/report-sarif.d.ts +0 -11
- package/dist/report-sarif.js +0 -28
- package/dist/report-sarif.js.map +1 -1
- package/dist/sig.js +0 -35
- package/dist/sig.js.map +1 -1
- package/dist/sigdecl.js +1 -1
- package/dist/sigdecl.js.map +1 -1
- package/dist/siggate.js +0 -4
- package/dist/siggate.js.map +1 -1
- package/dist/site.js +3 -29
- package/dist/site.js.map +1 -1
- package/dist/subsume.d.ts +0 -10
- package/dist/subsume.js +0 -137
- package/dist/subsume.js.map +1 -1
- package/dist/template.d.ts +2 -1
- package/dist/template.js +58 -138
- package/dist/template.js.map +1 -1
- package/dist/trim.js +0 -41
- package/dist/trim.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type.js.map +1 -1
- package/dist/unify.js +12 -242
- package/dist/unify.js.map +1 -1
- package/dist/utility.js +0 -22
- package/dist/utility.js.map +1 -1
- package/dist/val/AbnfFuncVal.d.ts +18 -0
- package/dist/val/AbnfFuncVal.js +132 -0
- package/dist/val/AbnfFuncVal.js.map +1 -0
- package/dist/val/AbsentVal.d.ts +11 -0
- package/dist/val/AbsentVal.js +30 -0
- package/dist/val/AbsentVal.js.map +1 -0
- package/dist/val/AggFuncVal.d.ts +10 -1
- package/dist/val/AggFuncVal.js +104 -116
- package/dist/val/AggFuncVal.js.map +1 -1
- package/dist/val/ArithFuncVal.js +0 -12
- package/dist/val/ArithFuncVal.js.map +1 -1
- package/dist/val/BagVal.js +1 -78
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/BigDecimalVal.js +0 -16
- package/dist/val/BigDecimalVal.js.map +1 -1
- package/dist/val/BigIntegerVal.js +0 -16
- package/dist/val/BigIntegerVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +0 -9
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/CmpFuncVal.d.ts +20 -0
- package/dist/val/CmpFuncVal.js +188 -0
- package/dist/val/CmpFuncVal.js.map +1 -0
- package/dist/val/ConjunctVal.js +0 -29
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.js +0 -500
- package/dist/val/ConstraintVal.js.map +1 -1
- package/dist/val/ContainerKindVal.js +0 -2
- package/dist/val/ContainerKindVal.js.map +1 -1
- package/dist/val/CopyFuncVal.js +0 -3
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.js +0 -179
- package/dist/val/Decimal.js.map +1 -1
- package/dist/val/DeprecateFuncVal.js.map +1 -1
- package/dist/val/DisjunctVal.js +0 -152
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/EachFuncVal.d.ts +1 -2
- package/dist/val/EachFuncVal.js +12 -29
- package/dist/val/EachFuncVal.js.map +1 -1
- package/dist/val/EmitFuncVal.d.ts +1 -1
- package/dist/val/EmitFuncVal.js +6 -119
- package/dist/val/EmitFuncVal.js.map +1 -1
- package/dist/val/ExpectVal.js +0 -62
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FilterFuncVal.js +0 -25
- package/dist/val/FilterFuncVal.js.map +1 -1
- package/dist/val/FuncBaseVal.d.ts +1 -0
- package/dist/val/FuncBaseVal.js +7 -127
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/GraphAtomVal.js +0 -15
- package/dist/val/GraphAtomVal.js.map +1 -1
- package/dist/val/HideFuncVal.js +0 -13
- package/dist/val/HideFuncVal.js.map +1 -1
- package/dist/val/IntegerVal.js +0 -61
- package/dist/val/IntegerVal.js.map +1 -1
- package/dist/val/JunctionVal.js +0 -20
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.js +0 -46
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +0 -57
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js +11 -6
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.js +0 -151
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MatchFuncVal.js +0 -27
- package/dist/val/MatchFuncVal.js.map +1 -1
- package/dist/val/{FormFuncVal.d.ts → MaybeFuncVal.d.ts} +5 -5
- package/dist/val/MaybeFuncVal.js +50 -0
- package/dist/val/MaybeFuncVal.js.map +1 -0
- package/dist/val/MoveFuncVal.js +0 -18
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.js +2 -36
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/NomFuncVal.d.ts +12 -0
- package/dist/val/NomFuncVal.js +153 -0
- package/dist/val/NomFuncVal.js.map +1 -0
- package/dist/val/NumberVal.js +0 -15
- package/dist/val/NumberVal.js.map +1 -1
- package/dist/val/OpBaseVal.d.ts +1 -0
- package/dist/val/OpBaseVal.js +3 -15
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/PackFuncVal.js +0 -34
- package/dist/val/PackFuncVal.js.map +1 -1
- package/dist/val/PathFuncVal.js +0 -6
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PathVal.js +0 -41
- package/dist/val/PathVal.js.map +1 -1
- package/dist/val/PlaceVal.js +0 -25
- package/dist/val/PlaceVal.js.map +1 -1
- package/dist/val/PlusOpVal.d.ts +1 -7
- package/dist/val/PlusOpVal.js +13 -74
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js +0 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.js +0 -167
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RecurseVal.js +0 -55
- package/dist/val/RecurseVal.js.map +1 -1
- package/dist/val/RefVal.js +0 -282
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.js +0 -232
- package/dist/val/ReferFuncVal.js.map +1 -1
- package/dist/val/ScalarKindVal.js +0 -49
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/ScalarVal.js +0 -11
- package/dist/val/ScalarVal.js.map +1 -1
- package/dist/val/StrFuncVal.js +0 -18
- package/dist/val/StrFuncVal.js.map +1 -1
- package/dist/val/SuperFuncVal.js +0 -32
- package/dist/val/SuperFuncVal.js.map +1 -1
- package/dist/val/TopVal.js +0 -1
- package/dist/val/TopVal.js.map +1 -1
- package/dist/val/TranslateFuncVal.d.ts +12 -0
- package/dist/val/TranslateFuncVal.js +99 -0
- package/dist/val/TranslateFuncVal.js.map +1 -0
- package/dist/val/UpperFuncVal.js +11 -6
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +1 -0
- package/dist/val/Val.js +2 -133
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js +0 -12
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/arith.js +0 -37
- package/dist/val/arith.js.map +1 -1
- package/dist/val/caserange.d.ts +3 -0
- package/dist/val/caserange.js +49 -0
- package/dist/val/caserange.js.map +1 -0
- package/dist/val/members.js +0 -6
- package/dist/val/members.js.map +1 -1
- package/dist/val/numcmp.js +0 -11
- package/dist/val/numcmp.js.map +1 -1
- package/dist/val/numkind.js +0 -145
- package/dist/val/numkind.js.map +1 -1
- package/dist/val/valutil.js +0 -16
- package/dist/val/valutil.js.map +1 -1
- package/dist/vet.d.ts +12 -0
- package/dist/vet.js +159 -412
- package/dist/vet.js.map +1 -1
- package/dist/view.js +0 -414
- package/dist/view.js.map +1 -1
- package/dist/walk.js +0 -41
- package/dist/walk.js.map +1 -1
- package/grammar/aontu.abnf +9 -7
- package/grammar/aontu.gbnf +5 -5
- package/grammar/aontu.lark +5 -5
- package/grammar/aontu.tmLanguage.json +1 -1
- package/package.json +4 -2
- package/skill/SKILL.md +8 -0
- package/skill/init/check.sh +28 -0
- package/skill/init/data.aon +12 -0
- package/skill/init/model.aon +19 -0
- package/skill/tasks.md +151 -0
- package/src/agentsmd.ts +8 -32
- package/src/alias.ts +0 -39
- package/src/allow.ts +221 -0
- package/src/aontu.ts +10 -108
- package/src/aontumodel.ts +32 -0
- package/src/cli.ts +1009 -540
- package/src/ctx.ts +0 -103
- package/src/diff.ts +0 -40
- package/src/err.ts +0 -40
- package/src/escape.ts +0 -46
- package/src/exactjson.ts +0 -131
- package/src/format.ts +63 -234
- package/src/grammar.ts +72 -0
- package/src/graph.ts +0 -61
- package/src/hcanon.ts +0 -82
- package/src/helpdoc.ts +77 -0
- package/src/hints.ts +72 -49
- package/src/jsonschema.ts +0 -123
- package/src/keyorder.ts +0 -42
- package/src/lang.ts +39 -895
- package/src/lower.ts +15 -65
- package/src/lsp-server.ts +0 -16
- package/src/lsp.ts +12 -180
- package/src/mcp-server.ts +0 -31
- package/src/mcp.ts +0 -130
- package/src/mod-tool.ts +0 -158
- package/src/mod.ts +0 -178
- package/src/patch.ts +0 -232
- package/src/provenance.ts +0 -183
- package/src/query.ts +0 -84
- package/src/reach.ts +0 -53
- package/src/relation.ts +7 -71
- package/src/render.ts +33 -180
- package/src/report-sarif.ts +0 -48
- package/src/sig.ts +0 -35
- package/src/sigdecl.ts +1 -1
- package/src/siggate.ts +0 -30
- package/src/site.ts +3 -29
- package/src/subsume.ts +1 -161
- package/src/template.ts +69 -140
- package/src/trim.ts +0 -53
- package/src/type.ts +2 -45
- package/src/unify.ts +13 -251
- package/src/utility.ts +0 -31
- package/src/val/AbnfFuncVal.ts +181 -0
- package/src/val/AbsentVal.ts +54 -0
- package/src/val/AggFuncVal.ts +152 -188
- package/src/val/ArithFuncVal.ts +0 -20
- package/src/val/BagVal.ts +1 -78
- package/src/val/BigDecimalVal.ts +0 -16
- package/src/val/BigIntegerVal.ts +0 -16
- package/src/val/CloseFuncVal.ts +0 -9
- package/src/val/CmpFuncVal.ts +249 -0
- package/src/val/ConjunctVal.ts +0 -33
- package/src/val/ConstraintVal.ts +2 -537
- package/src/val/ContainerKindVal.ts +0 -18
- package/src/val/CopyFuncVal.ts +0 -5
- package/src/val/Decimal.ts +1 -185
- package/src/val/DeprecateFuncVal.ts +0 -10
- package/src/val/DisjunctVal.ts +0 -157
- package/src/val/EachFuncVal.ts +12 -53
- package/src/val/EmitFuncVal.ts +8 -208
- package/src/val/ExpectVal.ts +0 -62
- package/src/val/FilterFuncVal.ts +0 -55
- package/src/val/FuncBaseVal.ts +9 -130
- package/src/val/GraphAtomVal.ts +0 -42
- package/src/val/HideFuncVal.ts +0 -15
- package/src/val/IntegerVal.ts +0 -61
- package/src/val/JunctionVal.ts +0 -20
- package/src/val/KeyFuncVal.ts +0 -48
- package/src/val/ListVal.ts +0 -59
- package/src/val/LowerFuncVal.ts +12 -7
- package/src/val/MapVal.ts +0 -151
- package/src/val/MatchFuncVal.ts +0 -59
- package/src/val/MaybeFuncVal.ts +86 -0
- package/src/val/MoveFuncVal.ts +0 -20
- package/src/val/NilVal.ts +2 -36
- package/src/val/NomFuncVal.ts +200 -0
- package/src/val/NumberVal.ts +0 -16
- package/src/val/OpBaseVal.ts +4 -17
- package/src/val/PackFuncVal.ts +0 -63
- package/src/val/PathFuncVal.ts +0 -32
- package/src/val/PathVal.ts +0 -66
- package/src/val/PlaceVal.ts +0 -45
- package/src/val/PlusOpVal.ts +18 -75
- package/src/val/PrefFuncVal.ts +0 -1
- package/src/val/PrefVal.ts +0 -179
- package/src/val/RecurseVal.ts +0 -81
- package/src/val/RefVal.ts +1 -285
- package/src/val/ReferFuncVal.ts +0 -255
- package/src/val/ScalarKindVal.ts +0 -50
- package/src/val/ScalarVal.ts +0 -12
- package/src/val/StrFuncVal.ts +0 -44
- package/src/val/SuperFuncVal.ts +0 -42
- package/src/val/TopVal.ts +0 -1
- package/src/val/TranslateFuncVal.ts +132 -0
- package/src/val/UpperFuncVal.ts +12 -7
- package/src/val/Val.ts +3 -192
- package/src/val/VarVal.ts +0 -15
- package/src/val/arith.ts +0 -92
- package/src/val/caserange.ts +53 -0
- package/src/val/members.ts +0 -23
- package/src/val/numcmp.ts +1 -27
- package/src/val/numkind.ts +0 -149
- package/src/val/valutil.ts +0 -16
- package/src/vet.ts +209 -504
- package/src/view.ts +0 -507
- package/src/walk.ts +0 -41
- package/dist/std.d.ts +0 -3
- package/dist/std.js +0 -637
- package/dist/std.js.map +0 -1
- package/dist/val/FormFuncVal.js +0 -55
- package/dist/val/FormFuncVal.js.map +0 -1
- package/src/std.ts +0 -648
- package/src/val/FormFuncVal.ts +0 -119
package/src/allow.ts
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { Aontu } from './aontu'
|
|
5
|
+
import { ConjunctVal } from './val/ConjunctVal'
|
|
6
|
+
import { anchorAt } from './vet'
|
|
7
|
+
import type { VetFinding } from './vet'
|
|
8
|
+
import { evalFailure, nearestKey, pathParts } from './query'
|
|
9
|
+
import { includeOpts } from './utility'
|
|
10
|
+
import type { IncludeOptions } from './utility'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// Where the roles map lives when the caller does not say.
|
|
14
|
+
export const ALLOW_AT = '$.roles'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export type AllowVerdict = 'allowed' | 'refused' | 'error'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
// What decided one path: the entry that covers it, the entry that
|
|
21
|
+
// intersects it, nothing at all, or a role the model does not declare.
|
|
22
|
+
export type AllowReason = 'allow' | 'deny' | 'uncovered' | 'no_role'
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export type AllowDecision = {
|
|
26
|
+
path: string
|
|
27
|
+
allowed: boolean
|
|
28
|
+
reason: AllowReason
|
|
29
|
+
by?: string // the deciding entry's path in the role model
|
|
30
|
+
pattern?: string // that entry's text, as the author wrote it
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
export type AllowReport = {
|
|
35
|
+
verdict: AllowVerdict
|
|
36
|
+
role: string
|
|
37
|
+
paths: AllowDecision[]
|
|
38
|
+
findings: VetFinding[]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
export type AllowOptions = IncludeOptions & {
|
|
43
|
+
// Where the role model came from: relative loads resolve against
|
|
44
|
+
// its directory, and a finding's site names it.
|
|
45
|
+
path?: string
|
|
46
|
+
// The path of the roles map inside the model (default `$.roles`).
|
|
47
|
+
at?: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
const ENTRY = 'string & re("^[$]") & re("[^.]$")'
|
|
52
|
+
|
|
53
|
+
// The shape every role must satisfy, in the language: a list of
|
|
54
|
+
// subtree entries to allow, and optionally one to deny.
|
|
55
|
+
const ROLE_SHAPE = `{ allow: [&: ${ENTRY}] deny?: [&: ${ENTRY}] }`
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
function shapeSource(at: string): string {
|
|
59
|
+
const keys = pathParts(at).map((p) => JSON.stringify(p))
|
|
60
|
+
return 0 === keys.length
|
|
61
|
+
? '&: ' + ROLE_SHAPE
|
|
62
|
+
: keys.join(': ') + ': { &: ' + ROLE_SHAPE + ' }'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
// `$.a.b` for a segment list, `$` for none: the spelling every report
|
|
67
|
+
// uses for a path, whatever the caller wrote.
|
|
68
|
+
function pathText(parts: string[]): string {
|
|
69
|
+
return '$' + (0 < parts.length ? '.' + parts.join('.') : '')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
function finding(
|
|
74
|
+
code: string, path: string, message: string, note?: string): VetFinding {
|
|
75
|
+
return {
|
|
76
|
+
code,
|
|
77
|
+
class: 'reference',
|
|
78
|
+
severity: 'error',
|
|
79
|
+
path,
|
|
80
|
+
message,
|
|
81
|
+
sites: [],
|
|
82
|
+
...(null == note ? {} : { note }),
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
type Entry = {
|
|
88
|
+
parts: string[]
|
|
89
|
+
text: string
|
|
90
|
+
by: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
function readEntries(
|
|
95
|
+
list: any, by: string, ctx: any,
|
|
96
|
+
): { entries: Entry[], finding?: VetFinding } {
|
|
97
|
+
const entries: Entry[] = []
|
|
98
|
+
for (let i = 0; i < list.peg.length; i++) {
|
|
99
|
+
const el: any = list.peg[i]
|
|
100
|
+
const before = ctx.err.length
|
|
101
|
+
const text: string = true === el.isString ? el.peg : el.gen(ctx)
|
|
102
|
+
if (before < ctx.err.length) {
|
|
103
|
+
const err: any = ctx.err[before]
|
|
104
|
+
return { entries, finding: finding(err.why, `${by}.${i}`, err.msg) }
|
|
105
|
+
}
|
|
106
|
+
entries.push({ parts: pathParts(text), text, by: `${by}.${i}` })
|
|
107
|
+
}
|
|
108
|
+
return { entries }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
// One segment of an entry against one segment of a path: `*` matches
|
|
113
|
+
// any key, anything else matches itself.
|
|
114
|
+
function segmentMatches(pattern: string, segment: string): boolean {
|
|
115
|
+
return '*' === pattern || pattern === segment
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
function intersects(entry: string[], path: string[]): boolean {
|
|
120
|
+
const n = Math.min(entry.length, path.length)
|
|
121
|
+
for (let i = 0; i < n; i++) {
|
|
122
|
+
if (!segmentMatches(entry[i], path[i])) {
|
|
123
|
+
return false
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return true
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
function covers(entry: string[], path: string[]): boolean {
|
|
131
|
+
return entry.length <= path.length && intersects(entry, path)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
function decide(asked: string, allows: Entry[], denies: Entry[]): AllowDecision {
|
|
136
|
+
const parts = pathParts(asked)
|
|
137
|
+
const path = pathText(parts)
|
|
138
|
+
|
|
139
|
+
for (const d of denies) {
|
|
140
|
+
if (intersects(d.parts, parts)) {
|
|
141
|
+
return { path, allowed: false, reason: 'deny', by: d.by, pattern: d.text }
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
for (const a of allows) {
|
|
145
|
+
if (covers(a.parts, parts)) {
|
|
146
|
+
return { path, allowed: true, reason: 'allow', by: a.by, pattern: a.text }
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { path, allowed: false, reason: 'uncovered' }
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
function errorReport(role: string, f: VetFinding): AllowReport {
|
|
154
|
+
return { verdict: 'error', role, paths: [], findings: [f] }
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
// Evaluate the role model, select the role, and decide every path.
|
|
159
|
+
export function allow(
|
|
160
|
+
src: string, role: string, paths: string[], opts?: AllowOptions,
|
|
161
|
+
): AllowReport {
|
|
162
|
+
const options = opts ?? {}
|
|
163
|
+
const at = pathText(pathParts(options.at ?? ALLOW_AT))
|
|
164
|
+
|
|
165
|
+
const aontu = new Aontu(includeOpts(options))
|
|
166
|
+
const ctx = aontu.ctx({ collect: true })
|
|
167
|
+
const parseOpts = null == options.path ? undefined : { path: options.path }
|
|
168
|
+
|
|
169
|
+
const shape = aontu.parse(shapeSource(at), undefined, ctx)
|
|
170
|
+
const model = aontu.parse(src, parseOpts, ctx)
|
|
171
|
+
if (0 < ctx.err.length) {
|
|
172
|
+
return errorReport(role, evalFailure(ctx))
|
|
173
|
+
}
|
|
174
|
+
const root: any = aontu.unify(
|
|
175
|
+
new ConjunctVal({ peg: [model, shape] }, ctx), undefined, ctx)
|
|
176
|
+
if (0 < ctx.err.length || true === root.isNil) {
|
|
177
|
+
return errorReport(role, evalFailure(ctx))
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const roles: any = anchorAt(root, at)
|
|
181
|
+
const atRole = `${at}.${role}`
|
|
182
|
+
if (!Object.prototype.hasOwnProperty.call(roles.peg, role)) {
|
|
183
|
+
const near = nearestKey(role, Object.keys(roles.peg))
|
|
184
|
+
return {
|
|
185
|
+
verdict: 'refused',
|
|
186
|
+
role,
|
|
187
|
+
paths: paths.map((p) => ({
|
|
188
|
+
path: pathText(pathParts(p)), allowed: false, reason: 'no_role',
|
|
189
|
+
})),
|
|
190
|
+
findings: [finding(
|
|
191
|
+
'no_path',
|
|
192
|
+
atRole,
|
|
193
|
+
`The role ${role} is not declared at ${at} in this document.`,
|
|
194
|
+
null == near ? undefined : `did you mean ${near}?`)],
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const node: any = roles.peg[role]
|
|
198
|
+
|
|
199
|
+
const allows = readEntries(node.peg.allow, `${atRole}.allow`, ctx)
|
|
200
|
+
if (null != allows.finding) {
|
|
201
|
+
return errorReport(role, allows.finding)
|
|
202
|
+
}
|
|
203
|
+
const denies = readEntries(node.peg.deny, `${atRole}.deny`, ctx)
|
|
204
|
+
if (null != denies.finding) {
|
|
205
|
+
return errorReport(role, denies.finding)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const decisions = paths.map((p) => decide(p, allows.entries, denies.entries))
|
|
209
|
+
|
|
210
|
+
// Nothing asked is nothing allowed: a gate that answered `allowed`
|
|
211
|
+
// to an empty question would let a caller that dropped its
|
|
212
|
+
// arguments through.
|
|
213
|
+
const allowed = 0 < decisions.length && decisions.every((d) => d.allowed)
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
verdict: allowed ? 'allowed' : 'refused',
|
|
217
|
+
role,
|
|
218
|
+
paths: decisions,
|
|
219
|
+
findings: [],
|
|
220
|
+
}
|
|
221
|
+
}
|
package/src/aontu.ts
CHANGED
|
@@ -22,6 +22,10 @@ import { get, why } from './query'
|
|
|
22
22
|
import { patch } from './patch'
|
|
23
23
|
import { diff } from './diff'
|
|
24
24
|
import { agentsMd } from './agentsmd'
|
|
25
|
+
import { allow } from './allow'
|
|
26
|
+
export type {
|
|
27
|
+
AllowDecision, AllowOptions, AllowReason, AllowReport, AllowVerdict,
|
|
28
|
+
} from './allow'
|
|
25
29
|
import { graphOf } from './graph'
|
|
26
30
|
import { relationCheck, relationErrors } from './relation'
|
|
27
31
|
import { view, viewSet, viewTree } from './view'
|
|
@@ -31,22 +35,9 @@ import { format, unifiedDiff } from './format'
|
|
|
31
35
|
export type { LintFinding, FormatReport, FormatOptions } from './format'
|
|
32
36
|
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
// go/aontu.go's `Version` (which tracks the Go module version
|
|
36
|
-
// separately — the two version series are independent).
|
|
37
|
-
//
|
|
38
|
-
// Kept in step with package.json by the `version` npm lifecycle script,
|
|
39
|
-
// which runs on `npm version` / `npm run repo-bump`. version.test.ts
|
|
40
|
-
// fails if the two ever drift.
|
|
41
|
-
const VERSION = '0.61.0'
|
|
38
|
+
const VERSION = '0.63.0'
|
|
42
39
|
|
|
43
40
|
|
|
44
|
-
// A module file's VALUE, as far as it goes. COLLECTED, not raised: a
|
|
45
|
-
// module file that does not stand up has no `mod.main` to read, and
|
|
46
|
-
// the default entry name is the answer -- the resolution itself fails
|
|
47
|
-
// later, on the file that is not there, rather than here on a metadata
|
|
48
|
-
// read. That is what a collecting context does, so there is nothing to
|
|
49
|
-
// catch: it answers what it could generate and records the rest.
|
|
50
41
|
function genQuiet(val: any, aontu: Aontu): any {
|
|
51
42
|
return val.gen(aontu.ctx({ collect: true }))
|
|
52
43
|
}
|
|
@@ -60,25 +51,9 @@ class Aontu {
|
|
|
60
51
|
constructor(popts?: AontuOptions) {
|
|
61
52
|
this.opts = popts ?? {}
|
|
62
53
|
|
|
63
|
-
// THE MODULE EVALUATOR (G6 phase 2, ts/src/mod.ts). Resolving a
|
|
64
|
-
// module import needs two answers that only evaluation can give:
|
|
65
|
-
// what a module file SAYS (its `mod.main`), and what a module
|
|
66
|
-
// MEANS (its canon-hash, for the integrity check). Injected here
|
|
67
|
-
// rather than imported there, because the resolver runs inside a
|
|
68
|
-
// parse that this class started, and the file it runs in cannot
|
|
69
|
-
// import this one without closing a cycle around the language.
|
|
70
|
-
//
|
|
71
|
-
// COLLECTED, not raised: a module that leans on consumer context
|
|
72
|
-
// (a `$.x` its importer supplies) does not stand up alone, and its
|
|
73
|
-
// hash is still the hash of what it says — that residue is part of
|
|
74
|
-
// the hashed meaning, which is why `hcanon` keeps it in textual
|
|
75
|
-
// form (docs/capability-review/g6-distribution.md).
|
|
76
54
|
;(this.opts as any).mod = {
|
|
77
55
|
...((this.opts as any).mod ?? {}),
|
|
78
56
|
eval: (this.opts as any).mod?.eval ?? ((src: string, path: string) => {
|
|
79
|
-
// One deeper: a module verified from inside a module
|
|
80
|
-
// verification is one more level of nesting, and the resolver
|
|
81
|
-
// refuses past its bound (MODULE_MAX_DEPTH in ts/src/mod.ts).
|
|
82
57
|
const inner = new Aontu({
|
|
83
58
|
...this.opts,
|
|
84
59
|
mod: {
|
|
@@ -114,12 +89,6 @@ class Aontu {
|
|
|
114
89
|
}
|
|
115
90
|
|
|
116
91
|
|
|
117
|
-
// Parse source into a matching Val AST, not yet unified.
|
|
118
|
-
//
|
|
119
|
-
// NOTE: the returned Val is SINGLE-USE — unify()/generate() refine the
|
|
120
|
-
// tree in place (see Val.unify), so do not unify or generate the same
|
|
121
|
-
// parsed Val more than once, and do not share it across threads. Call
|
|
122
|
-
// parse() again for a fresh tree.
|
|
123
92
|
parse(src: string, opts?: AontuOptions, ac?: AontuContext): Val | undefined {
|
|
124
93
|
let out: Val | undefined
|
|
125
94
|
let errs: any[] = []
|
|
@@ -136,12 +105,6 @@ class Aontu {
|
|
|
136
105
|
errs.push(out)
|
|
137
106
|
}
|
|
138
107
|
else {
|
|
139
|
-
// A version-control conflict marker is refused BEFORE the parse
|
|
140
|
-
// (issue #5). None of `<`, `=` or `>` is an aontu operator, so a
|
|
141
|
-
// marker line is ordinary text and `<<<<<<< HEAD` parsed happily
|
|
142
|
-
// into the two-string list ["<<<<<<<","HEAD"] -- an unresolved
|
|
143
|
-
// merge became a plausible document instead of an error, and the
|
|
144
|
-
// report of it read as a failed `<` operation.
|
|
145
108
|
const marker = findConflictMarker(src)
|
|
146
109
|
if (-1 !== marker.offset) {
|
|
147
110
|
const nil: any = makeNilErr(ac, 'merge_conflict')
|
|
@@ -154,10 +117,6 @@ class Aontu {
|
|
|
154
117
|
|
|
155
118
|
if (0 === errs.length) {
|
|
156
119
|
out = runparse(src, this.lang, ac)
|
|
157
|
-
// The include MANIFEST (G5, docs/trust.md): the resolved include
|
|
158
|
-
// closure as `{ path, capability }`, sorted and deduplicated so
|
|
159
|
-
// it is deterministic — the "file set" of hermeticity clause 1
|
|
160
|
-
// made observable. Content hashing and pinning stay with G6.
|
|
161
120
|
out.deps = manifestOf(ac.manifest)
|
|
162
121
|
ac.root = out
|
|
163
122
|
}
|
|
@@ -203,10 +162,6 @@ class Aontu {
|
|
|
203
162
|
out = uni.res
|
|
204
163
|
|
|
205
164
|
out.deps = pval.deps
|
|
206
|
-
// THE DERIVED STRUCTURE (G4 phase 3): the edge set, computed
|
|
207
|
-
// once from the unified tree. Cheap on a document with no links
|
|
208
|
-
// — one guarded walk — and the thing impact analysis and the
|
|
209
|
-
// relation checks are traversals over.
|
|
210
165
|
out.graph = graphOf(out)
|
|
211
166
|
out.err = errs
|
|
212
167
|
ac.root = out
|
|
@@ -218,19 +173,6 @@ class Aontu {
|
|
|
218
173
|
}
|
|
219
174
|
|
|
220
175
|
|
|
221
|
-
// Generate output structure from source, which must parse and fully unify.
|
|
222
|
-
//
|
|
223
|
-
// The result is made of NATIVE values, and D9 puts two beyond what
|
|
224
|
-
// `JSON.stringify` can write: a `biginteger` (a `0d` literal with no
|
|
225
|
-
// fraction or exponent) generates as a native `bigint`, and a
|
|
226
|
-
// `bigdecimal` generates as a `Decimal`. Both are exact at any
|
|
227
|
-
// magnitude, which is the whole point of the leaves -- and both are
|
|
228
|
-
// confined to documents that opt in, so a `0d`-free document generates
|
|
229
|
-
// exactly what it always did.
|
|
230
|
-
//
|
|
231
|
-
// Serialise the result with `exactJSON` (exported alongside this
|
|
232
|
-
// class), NOT with `JSON.stringify`: the latter throws on a bigint and
|
|
233
|
-
// has no way to write exact digits as a JSON number.
|
|
234
176
|
generate(src: string, opts?: any, ac?: AontuContext): any {
|
|
235
177
|
try {
|
|
236
178
|
let out = undefined
|
|
@@ -243,7 +185,6 @@ class Aontu {
|
|
|
243
185
|
if (undefined !== pval && 0 === pval.err.length) {
|
|
244
186
|
|
|
245
187
|
let uval = this.unify(pval, undefined, ac)
|
|
246
|
-
// console.log('AONTU-GENERATE-UVAL', uval.constructor, uval.mark)
|
|
247
188
|
|
|
248
189
|
if (undefined !== uval && 0 === uval.err.length) {
|
|
249
190
|
|
|
@@ -251,23 +192,6 @@ class Aontu {
|
|
|
251
192
|
: 0 < ac.err.length ? undefined
|
|
252
193
|
: uval.gen(ac as any)
|
|
253
194
|
|
|
254
|
-
// The relation verdict (RELATIONS P2): declarations the
|
|
255
|
-
// graph atoms registered during unification are decided
|
|
256
|
-
// HERE, where no more information can arrive -- the sizing
|
|
257
|
-
// atoms' model. A violated declaration is a located
|
|
258
|
-
// evaluation error at the offending edge, and the generated
|
|
259
|
-
// value is discarded below.
|
|
260
|
-
//
|
|
261
|
-
// AFTER GENERATION, and only when generation SUCCEEDED. A
|
|
262
|
-
// document that cannot be generated has no finished model
|
|
263
|
-
// to have a graph verdict about: an unsettled disjunction
|
|
264
|
-
// leaves alternatives the graph walk cannot read, so a
|
|
265
|
-
// mirror the document writes is absent from the edge set
|
|
266
|
-
// and `inverse(n)` reports it missing -- a false finding,
|
|
267
|
-
// and one that buried the `disjunct_no_gen` that actually
|
|
268
|
-
// stopped the document. The check that a broken document is
|
|
269
|
-
// not blamed on its relations (`relations` verb, finding F)
|
|
270
|
-
// holds here too.
|
|
271
195
|
if (!uval.isNil && 0 === ac.err.length) {
|
|
272
196
|
relationErrors(ac as any, uval)
|
|
273
197
|
if (0 < ac.err.length) {
|
|
@@ -329,17 +253,6 @@ function handleErrors(errs: any[], out: Val | undefined, ac: AontuContext) {
|
|
|
329
253
|
}
|
|
330
254
|
|
|
331
255
|
|
|
332
|
-
// Locate the first version-control conflict marker in a source, as a
|
|
333
|
-
// 1-based row and column (offset -1 when there is none).
|
|
334
|
-
//
|
|
335
|
-
// The shape is git's, and it is matched exactly: SEVEN of `<`, `=` or `>`
|
|
336
|
-
// at the very start of a line, then either the end of that line or a
|
|
337
|
-
// space before the branch label. Requiring the run length and the line
|
|
338
|
-
// start is what keeps a document that legitimately writes `a:"<<<<<<<"`,
|
|
339
|
-
// or a row of `=` inside a string, from being refused -- the marker is
|
|
340
|
-
// recognised as the artifact it is, not as a suspicious character.
|
|
341
|
-
//
|
|
342
|
-
// Kept byte-identical to findConflictMarker in go/lang.go.
|
|
343
256
|
function findConflictMarker(src: string): {
|
|
344
257
|
offset: number, row: number, col: number
|
|
345
258
|
} {
|
|
@@ -440,17 +353,9 @@ export {
|
|
|
440
353
|
util,
|
|
441
354
|
formatExplain,
|
|
442
355
|
|
|
443
|
-
// D9 -- the generate contract. `exactJSON` is the supported way to
|
|
444
|
-
// turn `generate()` output into JSON when a document uses the exact
|
|
445
|
-
// leaves, and `Decimal` is the type a `bigdecimal` generates as (a
|
|
446
|
-
// `biginteger` generates as the language's own `bigint`).
|
|
447
356
|
exactJSON,
|
|
448
357
|
Decimal,
|
|
449
358
|
|
|
450
|
-
// G2 phase 2 -- the validation verb. The engine only: the CLI verb
|
|
451
|
-
// and the text/JSON renderers are phase 3, the Go port phase 4.
|
|
452
|
-
// `sarifReport` (phase 5) is library API so an embedder can emit the
|
|
453
|
-
// interchange form without shelling out.
|
|
454
359
|
vet,
|
|
455
360
|
sarifReport,
|
|
456
361
|
|
|
@@ -460,10 +365,6 @@ export {
|
|
|
460
365
|
subsume,
|
|
461
366
|
trimCheck,
|
|
462
367
|
|
|
463
|
-
// G6 -- the hash form and the canon-hash pin. `hcanon` is the
|
|
464
|
-
// unify-level canon plus the close()/type()/hide() wrappers that
|
|
465
|
-
// close its semantic gaps; `canonHash` is
|
|
466
|
-
// "aon1-" + base64url(SHA-256(UTF-8(hcanon(v)))).
|
|
467
368
|
hcanon,
|
|
468
369
|
canonHash,
|
|
469
370
|
|
|
@@ -475,6 +376,11 @@ export {
|
|
|
475
376
|
patch,
|
|
476
377
|
diff,
|
|
477
378
|
agentsMd,
|
|
379
|
+
|
|
380
|
+
// The role gate (docs/design/ALLOW.0.md): may a role modify a
|
|
381
|
+
// subtree, by a role model that is itself an aontu document. The
|
|
382
|
+
// question an agent asks before `set`.
|
|
383
|
+
allow,
|
|
478
384
|
graphOf,
|
|
479
385
|
relationCheck,
|
|
480
386
|
view,
|
|
@@ -488,10 +394,6 @@ export {
|
|
|
488
394
|
renderValue,
|
|
489
395
|
renderProfile,
|
|
490
396
|
|
|
491
|
-
// The template surface (docs/design/TEMPLATE.0.md): the two text
|
|
492
|
-
// transforms behind `aontu template`, and the marker an extension
|
|
493
|
-
// names. Neither evaluates anything -- a template is a spelling of
|
|
494
|
-
// a generator, so the transforms are text in and text out.
|
|
495
397
|
desugarTemplate,
|
|
496
398
|
resugarTemplate,
|
|
497
399
|
markerFor,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
// GENERATED by ts/scripts/aontu.cjs (`make aontu`) from aontu/ —
|
|
4
|
+
// DO NOT EDIT. The tree is the source;
|
|
5
|
+
// ts/test/aontumodel.test.ts asserts this copy is identical with
|
|
6
|
+
// it.
|
|
7
|
+
|
|
8
|
+
const AONTU_SCHEME = 'aontu:'
|
|
9
|
+
|
|
10
|
+
const AONTU_SOURCES: Record<string, string> = {
|
|
11
|
+
"aontu:code": "# aontu:code --- THE OUTPUT VOCABULARY. A transform evaluates to an\n# instance of this schema and 'aontu render' turns it into bytes. The\n# root is not type()-marked because render reads the instance through\n# generate(). EXPERIMENTAL until the distribution layer can version it\n# by canon-hash.\n\n%name = string & re(\"^[A-Za-z_][A-Za-z0-9_]*$\") & length(min(1) & max(255))\n\n%text = close({ k:\"text\" lang:string & length(min(1)) text:string })\n\n%doc = close({\n text: string\n deprecated?: close({ msg?:string use?:string since?:string })\n})\n\n%check = close({ c:\"min\" n:number exclusive: *false|boolean })\n | close({ c:\"max\" n:number exclusive: *false|boolean })\n | close({ c:\"re\" p:string })\n | close({ c:\"len\" min?:integer & min(0) max?:integer & min(0) })\n | close({ c:\"unique\" key?:%name })\n | close({ c:\"ne\" n: [&: string|number|boolean] })\n | close({ c:\"must\" note:string })\n\n%prim = close({\n k: \"prim\"\n prim: \"string\"|\"int\"|\"bigint\"|\"float\"|\"decimal\"|\"bool\"|\"null\"|\"any\"\n})\n\n%ref = close({ k:\"ref\" name:%name unit?:string })\n%leaf = %prim|%ref|%text\n\n%type = %leaf\n | close({ k:\"list\" n:%leaf })\n | close({ k:\"map\" key:%leaf n:%leaf })\n | close({ k:\"opt\" n:%leaf })\n | close({ k:\"union\" n: [&: %leaf] })\n | close({ k:\"lit\" n: [&: string|number|boolean|null] })\n\n%field = close({\n name: %name\n type: %type\n optional: *false|boolean\n doc?: %doc\n default?: string|number|boolean|null\n check?: [&: %check]\n rel?: close({ to:string name?:string })\n x?: {}\n})\n\n%member = close({ name:%name value?:string|number doc?:%doc x?: {} })\n\n%param = close({\n name: %name\n type: %type\n default?: string|number|boolean|null\n x?: {}\n})\n\n# THE FRAGMENT ALGEBRA. A line's inline pieces hold no terminator; a\n# blank is its terminators alone; a raw is the one piece that may carry\n# terminators, re-indented to its depth unless it says not to.\n%inline = string & re(\"^[^\\n\\r]*$\")|%ref\n%line = close({ k:\"line\" at: *0|integer & min(0) & max(64) n: [&: %inline] })\n%blank = close({ k:\"blank\" n: *1|integer & min(1) & max(16) })\n\n%raw = close({\n k: \"raw\"\n at: *0|integer & min(0) & max(64)\n text: string\n reindent: *true|boolean\n})\n\n%piece = %line|%blank|%raw|string & re(\"^[^\\n\\r]*$\")\n%frag = close({ k:\"frag\" n: [&: %piece] })\n%body = %frag|close({ k:\"abstract\" })\n\n%record = close({\n k: \"record\"\n name: %name\n doc?: %doc\n open: *false|boolean\n fields: [&: %field]\n entity?: string\n check?: [&: %check]\n x?: {}\n})\n\n%enum = close({ k:\"enum\" name:%name doc?:%doc members: [&: %member] x?: {} })\n\n%alias = close({\n k: \"alias\"\n name: %name\n doc?: %doc\n type: %type\n check?: [&: %check]\n x?: {}\n})\n\n%const = close({\n k: \"const\"\n name: %name\n doc?: %doc\n type?: %type\n value: string|number|boolean|null\n x?: {}\n})\n\n%func = close({\n k: \"func\"\n name: %name\n doc?: %doc\n params: [&: %param]\n returns?: %type\n body: %body\n x?: {}\n})\n\n%decl = %record|%enum|%alias|%const|%func|%text|%frag\n\n%import = close({\n from: string & length(min(1))\n names?: [&: %name]\n alias?: %name\n x?: {}\n})\n\n%unit = close({\n path: string & length(min(1))\n lang: string & length(min(1))\n pkg?: string\n doc?: %doc\n imports?: [&: %import]\n decls: [&: %decl]\n profile?: {}\n x?: {}\n})\n\n%source = close({ path?:string hash?:string & re(\"^aon1-[A-Za-z0-9_-]+$\") })\n\naontu: Code: close({ source?:%source units: [&: %unit] })\n",
|
|
12
|
+
"aontu:render": "# aontu:render --- THE RENDER VOCABULARY. A profile is the data\n# 'aontu render' applies to a unit of one language, and only data: a\n# field belongs here if the renderer applies it without looking at the\n# shape of any node. The root is not type()-marked because a profile is\n# read through generate(). EXPERIMENTAL, versioned by canon-hash later.\n\n%name = string & re(\"^[A-Za-z_][A-Za-z0-9_]*$\")\n\n%case = \"as-is\"|\"camel\"|\"pascal\"|\"snake\"|\"screaming\"|\"kebab\"\n\n%comment = close({ open?:string prefix?:string close?:string })\n\n%form = close({\n open: *\"\"|string\n close: *\"\"|string\n prec: *9|integer & min(0) & max(9)\n childPrec: *0|integer & min(0) & max(9)\n})\n\n%profile = close({\n lang: string & length(min(1))\n lowering?: \"typescript\"|\"go\"\n indent: close({\n unit: *\" \"|string & length(min(1))\n width: *2|integer & min(0) & max(16)\n })\n comment?: close({ line?:%comment block?:%comment doc?:%comment })\n str?: close({\n quote: *\"\\\"\"|string & length(min(1) & max(1))\n escape: { &: string }\n })\n ident?: close({\n chars: *\"ascii-word\"|\"ascii-word\"\n reserved?: [&: string]\n case?: close({\n record?: %case\n field?: %case\n enum?: %case\n member?: %case\n const?: %case\n func?: %case\n param?: %case\n alias?: %case\n })\n acronyms?: [&: %name]\n })\n types?: close({\n prim?: { &: string }\n list?: %form\n map?: %form\n opt?: %form\n union?: %form\n lit?: %form\n })\n template?: close({\n marker: string & length(min(1))\n close?: string & length(min(1))\n ext?: [&: string & re(\"^[A-Za-z0-9_+-]+$\")]\n })\n banner?: string\n})\n\n# Profile names the schema; Lang is where one lands. type() so naming\n# the schema neither generates it nor asks a document to fill it.\naontu: render: { Profile:type(%profile) Lang:%profile }\n",
|
|
13
|
+
"aontu:render/lang/go": "# aontu:render/lang/go --- THE GO PROFILE. Indentation, comment forms, string\n# escapes, identifier case and type forms. Lowering a declaration to a\n# struct is code; what the renderer applies without looking at a node's\n# shape is here. EXPERIMENTAL until the distribution layer can version\n# it by canon-hash.\n\n@\"aontu:render\"\n\naontu: render: Lang: {\n lang: \"go\"\n lowering: \"go\"\n indent: { unit:\"\\t\" width:1 }\n comment: line: prefix: \"// \"\n comment: block: { open:\"/*\" close:\"*/\" }\n comment: doc: prefix: \"// \"\n str: quote: \"\\\"\"\n str: escape: {\n \"7\": \"\\\\a\"\n \"8\": \"\\\\b\"\n \"9\": \"\\\\t\"\n \"10\": \"\\\\n\"\n \"11\": \"\\\\v\"\n \"12\": \"\\\\f\"\n \"13\": \"\\\\r\"\n \"34\": \"\\\\\\\"\"\n \"92\": \"\\\\\\\\\"\n }\n ident: {\n chars: \"ascii-word\"\n reserved: [\n \"break\"\n \"case\"\n \"chan\"\n \"const\"\n \"continue\"\n \"default\"\n \"defer\"\n \"else\"\n \"fallthrough\"\n \"for\"\n \"func\"\n \"go\"\n \"goto\"\n \"if\"\n \"import\"\n \"interface\"\n \"map\"\n \"package\"\n \"range\"\n \"return\"\n \"select\"\n \"struct\"\n \"switch\"\n \"type\"\n \"var\"\n ]\n case: record: \"pascal\"\n case: field: \"pascal\"\n case: enum: \"pascal\"\n case: member: \"pascal\"\n case: const: \"pascal\"\n case: func: \"pascal\"\n case: param: \"camel\"\n case: alias: \"pascal\"\n acronyms: [\n \"ACL\"\n \"API\"\n \"ASCII\"\n \"CPU\"\n \"CSS\"\n \"DNS\"\n \"EOF\"\n \"GUID\"\n \"HTML\"\n \"HTTP\"\n \"HTTPS\"\n \"ID\"\n \"IP\"\n \"JSON\"\n \"LHS\"\n \"QPS\"\n \"RAM\"\n \"RHS\"\n \"RPC\"\n \"SLA\"\n \"SMTP\"\n \"SQL\"\n \"SSH\"\n \"TCP\"\n \"TLS\"\n \"TTL\"\n \"UDP\"\n \"UI\"\n \"UID\"\n \"UUID\"\n \"URI\"\n \"URL\"\n \"UTF8\"\n \"VM\"\n \"XML\"\n \"XMPP\"\n \"XSRF\"\n \"XSS\"\n ]\n }\n types: prim: {\n string: \"string\"\n int: \"int64\"\n bigint: \"string\"\n float: \"float64\"\n decimal: \"string\"\n bool: \"bool\"\n null: \"any\"\n any: \"any\"\n }\n types: list: open: \"[]\"\n types: map: open: \"map[\"\n types: opt: open: \"*\"\n banner: \"Code generated by aontu from {path}. DO NOT EDIT.\"\n}\n",
|
|
14
|
+
"aontu:render/lang/markdown": "# aontu:render/lang/markdown --- THE MARKDOWN PROFILE. No declarations to\n# lower, so this is the text profile plus markdown's own two: the HTML\n# comment form and the template marker its files carry. EXPERIMENTAL\n# until the distribution layer can version it by canon-hash.\n\n@\"aontu:render\"\n\naontu: render: Lang: lang: \"markdown\"\naontu: render: Lang: indent: { unit:\" \" width:2 }\naontu: render: Lang: comment: block: { open:\"<!--\" close:\"-->\" }\naontu: render: Lang: template: { marker:\"<!---\" ext: [\"md\" \"markdown\"] }\n",
|
|
15
|
+
"aontu:render/lang/text": "# aontu:render/lang/text --- THE TEXT PROFILE. Indentation and nothing else:\n# a fold over fragments applies nothing else. Every language without a\n# lowering renders under it. EXPERIMENTAL until the distribution layer\n# can version it by canon-hash.\n\n@\"aontu:render\"\n\naontu: render: Lang: { lang:\"text\" indent: { unit:\" \" width:2 } }\n",
|
|
16
|
+
"aontu:render/lang/typescript": "# aontu:render/lang/typescript --- THE TYPESCRIPT PROFILE. Indentation,\n# comment forms, string escapes, identifier case and type forms.\n# Lowering a declaration to an interface is code; what the renderer\n# applies without looking at a node's shape is here. EXPERIMENTAL until\n# the distribution layer can version it by canon-hash.\n\n@\"aontu:render\"\n\naontu: render: Lang: {\n lang: \"typescript\"\n lowering: \"typescript\"\n indent: { unit:\" \" width:2 }\n comment: line: prefix: \"// \"\n comment: block: { open:\"/*\" prefix:\" * \" close:\" */\" }\n comment: doc: { open:\"/**\" prefix:\" * \" close:\" */\" }\n str: quote: \"\\\"\"\n str: escape: {\n \"8\": \"\\\\b\"\n \"9\": \"\\\\t\"\n \"10\": \"\\\\n\"\n \"12\": \"\\\\f\"\n \"13\": \"\\\\r\"\n \"34\": \"\\\\\\\"\"\n \"92\": \"\\\\\\\\\"\n }\n ident: {\n chars: \"ascii-word\"\n reserved: [\n \"await\"\n \"break\"\n \"case\"\n \"catch\"\n \"class\"\n \"const\"\n \"continue\"\n \"debugger\"\n \"default\"\n \"delete\"\n \"do\"\n \"else\"\n \"enum\"\n \"export\"\n \"extends\"\n \"false\"\n \"finally\"\n \"for\"\n \"function\"\n \"if\"\n \"implements\"\n \"import\"\n \"in\"\n \"instanceof\"\n \"interface\"\n \"let\"\n \"new\"\n \"null\"\n \"package\"\n \"private\"\n \"protected\"\n \"public\"\n \"return\"\n \"static\"\n \"super\"\n \"switch\"\n \"this\"\n \"throw\"\n \"true\"\n \"try\"\n \"typeof\"\n \"var\"\n \"void\"\n \"while\"\n \"with\"\n \"yield\"\n ]\n case: record: \"pascal\"\n case: field: \"camel\"\n case: enum: \"pascal\"\n case: member: \"pascal\"\n case: const: \"camel\"\n case: func: \"camel\"\n case: param: \"camel\"\n case: alias: \"pascal\"\n acronyms: []\n }\n types: prim: {\n string: \"string\"\n int: \"number\"\n bigint: \"bigint\"\n float: \"number\"\n decimal: \"string\"\n bool: \"boolean\"\n null: \"null\"\n any: \"unknown\"\n }\n types: list: { close:\"[]\" childPrec:2 }\n types: map: { open:\"Record<\" close:\">\" }\n types: opt: { close:\" | null\" prec:1 childPrec:2 }\n types: union: { prec:1 childPrec:2 }\n types: lit: prec: 1\n banner: \"Code generated by aontu from {path}. DO NOT EDIT.\"\n}\n",
|
|
17
|
+
"aontu:system": "# aontu:system --- the SYSTEM VOCABULARY. EXPERIMENTAL until the\n# distribution layer can version it by canon-hash.\n\naontu: System: {\n Port: type({ direction: *in|out|inout protocol?:string })\n\n Component: type({ ports?: { &: $.aontu.System.Port } })\n\n # Written out rather than Component & { kind: service }: a reference\n # to a type()-marked member does not survive the include.\n Service: type({ kind:service ports?: { &: $.aontu.System.Port } })\n\n # A grammar, not re(): the identifier shape is a quantified group\n # holding a quantifier, which re() refuses. hide()n so a schema's\n # grammar does not generate into the document it checks.\n semverPreRelease: hide(\n abnf(\n `pre-release = pre-release-id *( \".\" pre-release-id )\npre-release-id = \"0\" [ *digit alnum-tail ]\n / positive-digit *digit [ alnum-tail ] / alnum-tail\nalnum-tail = non-digit *id-char\nid-char = digit / non-digit\nnon-digit = letter / \"-\"\ndigit = \"0\" / positive-digit\npositive-digit = %x31-39\nletter = %x41-5A / %x61-7A\n`\n )\n )\n semverBuild: hide(\n abnf(\n `build = build-id *( \".\" build-id )\nbuild-id = 1*id-char\nid-char = digit / non-digit\nnon-digit = letter / \"-\"\ndigit = \"0\" / positive-digit\npositive-digit = %x31-39\nletter = %x41-5A / %x61-7A\n`\n )\n )\n\n # major minor patch pre-release build, tail defaulted.\n Semver: type(\n [\n integer & min(0)\n *0|(integer & min(0))\n *0|(integer & min(0))\n *\"\"|parse($.aontu.System.semverPreRelease)\n *\"\"|parse($.aontu.System.semverBuild)\n ] & length(5)\n )\n}\n",
|
|
18
|
+
"aontu:view": "# aontu:view --- the FIGURE VOCABULARY. EXPERIMENTAL until the\n# distribution layer can version it by canon-hash.\n\naontu: View: Figure: type({\n kind: doc|lattice|tree|matrix|graph|layer|sets|layers\n | ladder\n out: string\n\n # Every kind.\n as?: text|mermaid|dot|er|svg\n at?: string\n maxRows?: integer & min(0)\n\n # doc.\n depth?: integer & min(0)\n\n # tree, matrix, layer, graph.\n relation?: string\n relations?: [&: string]\n roots?: [&: string]\n\n # matrix.\n order?: canon|partition\n closure?: boolean\n\n # graph, layer.\n groupBy?: string\n label?: string\n layers?: [&: string]\n edges?: upward|all|none\n\n # sets, layers.\n sets?: string\n member?: string\n universe?: string\n minDegree?: integer & min(0)\n maxCols?: integer & min(0)\n minSize?: integer & min(0)\n})\n"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const AONTU_MODELS: string[] = [
|
|
22
|
+
"aontu:code",
|
|
23
|
+
"aontu:render",
|
|
24
|
+
"aontu:render/lang/go",
|
|
25
|
+
"aontu:render/lang/markdown",
|
|
26
|
+
"aontu:render/lang/text",
|
|
27
|
+
"aontu:render/lang/typescript",
|
|
28
|
+
"aontu:system",
|
|
29
|
+
"aontu:view"
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
export { AONTU_SCHEME, AONTU_SOURCES, AONTU_MODELS }
|