Documentation
¶
Overview ¶
Package manifest reads and checks aicoded.yaml, the app's permission list.
Runners, the delivery pipeline and the aicoded CLI import it. App code may not: E-LINT-001 refuses the import.
Index ¶
Examples ¶
Constants ¶
const FileName = "aicoded.yaml"
FileName is the name of the permission list in an app's directory.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Access ¶
type Access struct {
Require []string `yaml:"require"`
Guard bool `yaml:"guard"`
Calls []string `yaml:"calls"`
}
Access is one entry of the access section aicoded generate writes.
type Audience ¶
Audience is who may use the app: people of the company, as group:<name> or everyone, and outside people, as idp:<name> or magic-link.
type Change ¶
type Change struct{ Field, Key, Before, After string }
Change is one difference between two permission lists. Key names the entry of a keyed field and is empty otherwise; Before is empty for what was added, After for what was removed.
func Diff ¶
Diff returns the differences between before and after, nil when there are none.
The changes come in the order of the fields, then by key. A list, such as egress, changes by each item removed or added, removals first, each sorted; a new order is no change, and a field left out equals an empty one. A keyed entry changes as a whole, written as text: a data source's classes, sorted; an access path's "require <rules>", then "; guard" and "; calls <names>" when they apply, its lists in written order; a served function's "callers <apps>", then "; require <rules>" and "; apps" when they apply, its lists sorted; a job's cron. The functions called from another app change one by one, keyed by that app.
Example ¶
Diff lists what changed between two permission lists, field by field, as the platform's change records show it. A new order of a list is no change.
package main
import (
"fmt"
"aicoded.dev/framework/manifest"
)
func main() {
before := manifest.Manifest{
App: "rooms",
Access: map[string]manifest.Access{"/rooms/{id}": {Require: []string{"staff"}}},
Settings: []string{"greeting", "report_day"},
}
after := manifest.Manifest{
App: "rooms",
Access: map[string]manifest.Access{"/rooms/{id}": {Require: []string{"staff"}, Guard: true}},
Egress: []string{"api.partner.example"},
Settings: []string{"report_day", "greeting"},
}
for _, c := range manifest.Diff(before, after) {
fmt.Printf("%+v\n", c)
}
}
Output: {Field:access Key:/rooms/{id} Before:require staff After:require staff; guard} {Field:egress Key: Before: After:api.partner.example}
type Data ¶
Data is one source of data the app reaches: sqldb, filestore:<name> or connector:<name>, with the classes of data it holds.
type Manifest ¶
type Manifest struct {
App string `yaml:"app"`
Class string `yaml:"class"`
Owner string `yaml:"owner"`
Audience Audience `yaml:"audience"`
Data []Data `yaml:"data"`
Access map[string]Access `yaml:"access"`
Services Services `yaml:"services"`
Egress []string `yaml:"egress"`
Email *Email `yaml:"email"`
Schedule []Job `yaml:"schedule"`
Settings []string `yaml:"settings"`
Secrets []string `yaml:"secrets"`
Modules []string `yaml:"modules"`
Size string `yaml:"size"`
Resources string `yaml:"resources"`
TTL string `yaml:"ttl"`
}
Manifest is the permission list, aicoded.yaml. A field left out or empty is not stated.
func Parse ¶
Parse checks the manifest data and returns it. Path is used only in the positions of problems. It reports every problem it finds as one coded error each: its error unwraps, with Unwrap() []error, to them, sorted by line. Data that is not one YAML document of the expected shape, or that uses an anchor, an alias or a merge key, is not checked any further.
Example ¶
Parse checks a permission list and returns its fields. A list with problems returns every problem, each with a code and its position.
package main
import (
"fmt"
"aicoded.dev/framework/manifest"
)
func main() {
m, err := manifest.Parse(manifest.FileName, []byte("app: rooms\negress: [api.partner.example]\n"))
if err != nil {
fmt.Println(err)
return
}
fmt.Println(m.Egress)
}
Output: [api.partner.example]
func (Manifest) Connectors ¶
Connectors returns the names of the connectors the app declares, sorted.
func (Manifest) Roles ¶
Roles returns every role the access and services sections name, sorted, without "*".
type Serve ¶
type Serve struct {
Callers []string `yaml:"callers"`
Require []string `yaml:"require,omitempty"`
Apps bool `yaml:"apps,omitempty"`
}
Serve says who may call one function the app serves: the calling apps, the role rules a viewer must meet, written as in the access section, and whether a calling app may call it with no viewer. A function without role rules takes no call on behalf of a viewer.